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

Capture Screenshot from another desktop

我已经使用 CreateDesktop 创建了第二个桌面,但我没有切换到它。此外,我还在其中创建了一些进程,例如 Explorer.exe 和 Winrar.exe。接下来我有一个代码将当前桌面的屏幕截图带到剪贴板。 CreateDesktop 和屏幕截图都有效,但是 新桌面的屏幕截图或 window returns 黑色位图 :

这是 window 桌面的屏幕截图,returns 当前桌面为:

// 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# 中实现了这两种方法,但同样的事情发生在那里。

有很多很棒的资源,例如:

Capture screenshot of hidden desktop

take a screenshot of a desktop created using createdesktop api

C# – SCREEN CAPTURE WITH VISTA DWM (SHARED DIRECT3D SURFACE)

Window Contents Capturing using WM_PRINT Message

how to capture screen from another desktop?(CreateDesktop)

这也是一个死题,没有新的文章,解释或解决方案。

我已经阅读了其中的大部分内容,但运气不佳,我认为这是我最接近的尝试。语言对我来说也无关紧要:C#、C++、Python 或…….

我找到了解决方案,很有趣但并不完美,只是解决了我的需求。

CreateDesktop 之后通过调用 OpenDesktop 然后 SetThreadDesktop 然后使用屏幕截图代码你可以获得在 CreateDesktop 中创建的 window 的屏幕截图,也不需要如果您只想要 window:

,则在其中创建 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 window。您可以试试这个,然后将其粘贴到绘画中以查看结果。

只有一件事,屏幕截图位图的整个区域都是黑色的,除了我想要的 window 句柄,这对我来说很好。我想我应该按顺序从下到上处理每个 window,然后将它们混合起来。

感谢所有补充。