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

标签 c++ screenshot desktop handle window-managers

我已经使用 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# 中实现了这两个方法,但同样的事情发生在那里。

有很棒的资源,例如:

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 中创建的窗口的屏幕截图,另外如果您只想要窗口,则无需在其中创建 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 窗口。您可以试试这个,然后将其粘贴到绘画中以查看结果。

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

在此感谢所有补充。

关于c++ - 从另一个桌面捕获屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55075688/

相关文章:

java - 如何从 Java 应用程序获取文件的图标显示?

c++ - const double 和 double const 有什么区别?

用于本地化的 Xcode 11 导出不起作用,禁用包括屏幕截图功能,并且在测试日志中找不到 XCUITest 屏幕截图附件

ubuntu - 我如何在 ec2 中设置 ubuntu 桌面

python - 内存泄漏/Python windows 7 截图

android - 使用 FileObserver Android 仅检测屏幕截图

java - 将现有的 Web 应用程序转换为桌面应用程序

c++ - 找不到链接目录

c++ - BigNum 类字符串构造函数错误

c++ STL map copy 将 bool 值设置为 true