从另一个桌面捕获屏幕截图

3
我使用CreateDesktop创建了第二个桌面,但无法切换到它。我在其中创建了一些进程,如Explorer.exe和Winrar.exe。接下来,我有一段代码可以将当前桌面的屏幕截图复制到剪贴板中。虽然CreateDesktop和截图功能都可以正常工作,但是新桌面或窗口的截图返回一张黑色位图
下面是一个窗口的截图,它返回的是当前桌面的截图:
// 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个回答

3

我找到了解决方案,虽然不是完美的,但满足我的需求。

在调用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窗口。你可以试一下,然后把它复制到画图板上查看结果。

有一件事情需要注意,截图位图的整个区域都是黑色的,除了我想要的窗口句柄,这对我来说没问题。我认为应该从底部到顶部获取每个窗口的句柄,然后混合它们。

欢迎提出任何修改意见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接