Снимок экрана с другого рабочего стола - PullRequest
1 голос
/ 09 марта 2019

Я создал второй рабочий стол, используя CreateDesktop, и я не переключаюсь на него. Также я создал несколько процессов, таких как Explorer.exe и Winrar.exe. Далее у меня есть код, который принимает скриншот текущего рабочего стола в буфер обмена. И CreateDesktop, и Screenshot работают, но Снимок экрана этого нового рабочего стола или окна возвращает черное растровое изображение :

Это скриншот окна рабочего стола, которое возвращает текущий рабочий стол:

// hwnd is handle to winrar or ... created in a new desktop retrieved by EnumDesktopWindow
RECT rc;
GetClientRect(hwnd, &rc);
const HDC hScreenDC = GetDC(nullptr);
const HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
const int width = GetDeviceCaps(hScreenDC, HORZRES);
const int height = GetDeviceCaps(hScreenDC, VERTRES);
const HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
HBITMAP(SelectObject(hMemoryDC, hBitmap));
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();

DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);

Я реализовал оба этих метода в c #, но там происходит то же самое.

Есть большие ресурсы, такие как:

Снимок экрана скрытого рабочего стола

сделать снимок экрана рабочего стола, созданного с помощью createdesktop api

C # - СЪЕМКА ЭКРАНА С VISTA DWM (ОБЩАЯ ПОВЕРХНОСТЬ DIRECT3D)

Захват содержимого окна с использованием сообщения WM_PRINT

как захватить экран с другого рабочего стола? (CreateDesktop)

Также это как мертвая тема, нет новой статьи, объяснения или решения.

Я прочитал большинство из них, но не повезло, это была моя самая близкая попытка, я думаю. Также язык не имеет значения для меня: C #, C ++, Python или ....

1 Ответ

0 голосов
/ 09 марта 2019

Я нашел решение, это интересно, но не идеально, Просто решает мои проблемы.

После CreateDesktop, позвонив OpenDesktop, затем SetThreadDesktop, затем используя код скриншота, вы получите скриншотокно, которое создается внутри CreateDesktop, также нет необходимости создавать внутри него Explorer.exe, если вы просто хотите окно:

CreateDesktopW(L"NewDesktop"); // CreateDesktop code here. This is my function
const HDESK Handle = OpenDesktopW(L"NewDesktop", 0, 0, GENERIC_ALL);
SetThreadDesktop(Handle);

// Above ScreenShot code here ...

Код скриншота требует PrintWindow:

RECT rc;
GetClientRect(hwnd, &rc);
const HDC hScreenDC = GetDC(nullptr);
const HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
const int width = GetDeviceCaps(hScreenDC, HORZRES);
const int height = GetDeviceCaps(hScreenDC, VERTRES);
const HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
HBITMAP(SelectObject(hMemoryDC, hBitmap));
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);

/// ADDED CODE
PrintWindow(hWnd, hMemoryDC, PW_CLIENTONLY);
///

OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();

DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);

Мой работал с окном winrar.exe внутри неактивного рабочего стола.Вы можете попробовать это, а затем вставить его, чтобы нарисовать, чтобы увидеть результат.

Есть только одна вещь, вся область растрового изображения на скриншоте черная, за исключением дескриптора окна, который я хочу, и это хорошо для меня.Я думаю, что я должен получить дескриптор каждого окна снизу вверх, чтобы затем смешать их.

Все дополнения к этому приветствуются.

...