Сделать screenshot неактивного десктопа

Тема в разделе "WASM.WIN32", создана пользователем retmas, 21 авг 2007.

  1. retmas

    retmas New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2005
    Сообщения:
    100
    Господа! Вот метод создания screenshot десктопа:

    int CreateScreenshot(HBITMAP *Screenshot, HDC *hDC)
    {
    HDC hdcScreen = GetDC(GetDesktopWindow());
    HDC hdcCompatible = CreateCompatibleDC(hdcScreen);

    HBITMAP hbmScreen = CreateCompatibleBitmap(
    hdcScreen,
    GetDeviceCaps(hdcScreen, HORZRES),
    GetDeviceCaps(hdcScreen, VERTRES));
    if (hbmScreen == 0) {
    return 0;
    }

    if (!SelectObject(hdcCompatible, hbmScreen)) {
    return 0;
    }

    if (!BitBlt(hdcCompatible,
    0,
    0,
    GetDeviceCaps(hdcScreen, HORZRES),
    GetDeviceCaps(hdcScreen, VERTRES),
    hdcScreen,
    0,
    0,
    SRCCOPY | CAPTUREBLT)) {
    /* here */
    int err = GetLastError();
    return 0;
    }

    *Screenshot = hbmScreen;
    *hDC = hdcCompatible;

    return 1;
    }



    Вызывается так:

    HDC hdc;
    HBITMAP hScreenshot;
    SetThreadDesktop(hDesktop);
    int res = CreateScreenshot(&hScreenshot, &hdc);

    Если перед этим делается SwitchDesktop(hDesktop), десктоп становится активным, то
    все работает отлично. Если десктоп неактивный, функция BitBlt возвращает ошибку:
    err = ERROR_INVALID_HANDLE. Не понимаю, почему! Нужна ваша помощь!
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    вероятно возвращается NULL в
    HDC hdcScreen = GetDC(GetDesktopWindow());

    Попробуй там проверить hdcScreen!=NULL и если равен, то GetLastError
     
  3. int2eh

    int2eh Alexander Leevy

    Публикаций:
    0
    Регистрация:
    19 авг 2007
    Сообщения:
    106
    Адрес:
    Москва
    А так?
    Код (Text):
    1. hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
    2. hdcCompatible = CreateCompatibleDC(hdcScreen);
     
  4. retmas

    retmas New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2005
    Сообщения:
    100
    Нет! Пробовал различные варианты.. Ошибку возвращает BitBlt, err = INVALID_HANDLE (6)
    Хотя все функции, которые возвращают handle, работают без ошибок, возвращают != NULL.
    И GetLastError для них возвращает 0.
    Я не знаю.. как решить.. видно дело дейсвительно в NtGdiBitBlt (win32k.sys), но трассировать
    пока не стал.. может кто-нить встречался с такой проблемой?
     
  5. asmlamo

    asmlamo Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    1.742
    Вот рабочий пример.
     
  6. retmas

    retmas New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2005
    Сообщения:
    100
    Это пример того, как получить screenshot активного десктопа..
    Если запустить так:

    hDesktop = CreateDesktop(L"Default1", NULL, NULL, 0, GENERIC_ALL, NULL);

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    ZeroMemory(&pi, sizeof(pi));
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.lpDesktop = _tcsdup(L"WinSta0\\Default1");
    res = CreateProcess(NULL, _tcsdup("screen.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

    то screenshot'а не будет!