从另一个桌面捕获屏幕截图 [英] Capture Screenshot from another desktop
问题描述
我使用 CreateDesktop
创建了第二个桌面,但我没有切换到它.我还在其中创建了一些进程,例如 Explorer.exe 和 Winrar.exe.接下来我有一个代码,它将当前桌面的屏幕截图带到剪贴板.CreateDesktop 和 Screenshot 都有效,但新桌面或窗口的屏幕截图返回黑色位图:
I have created a second desktop using CreateDesktop
and im not switching to it. Also i have created some processes in it like Explorer.exe and Winrar.exe. Next i have a code which takes Screenshot of current desktop to clipboard. Both CreateDesktop and Screenshot works, But Screenshot of that new desktop or window returns a black bitmap:
这是返回当前桌面的桌面窗口的屏幕截图:
This is the screenshot for a window in a desktop which returns current desktop:
// 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# 中实现了这两种方法,但在那里发生了同样的事情.
I have implemented both this methods in c# but same thing happens there.
有很棒的资源,例如:
C# – 使用 VISTA DWM 的屏幕捕获(SHARED DIRECT3D表面)
这也是一个死题,没有新文章,没有解释或解决方案.
Also this is like a dead topic, No new article, Explanation or solution to it.
我已经阅读了其中的大部分但没有运气,我认为这是我最接近的尝试.语言对我来说也无关紧要:C#、C++、Python 或 ....
I have read most of them but no luck, This was my closest try i think. Also language doesnt matter for me: C#, C++, Python or ... .
推荐答案
我找到了解决方案,很有趣但并不完美,只是解决了我的需求.
I found the solution, It is interesting but no perfect, Just resolves my needs.
在 CreateDesktop
之后,通过调用 OpenDesktop
然后 SetThreadDesktop
然后使用屏幕截图代码,您可以获得在 CreateDesktop 中创建的窗口的屏幕截图,此外如果您只需要窗口,则无需在其中创建 Explorer.exe:
After CreateDesktop
by calling OpenDesktop
then SetThreadDesktop
then using the screenshot code you get the screenshot of the window which is created inside CreateDesktop, Also no need for Creating Explorer.exe inside it if you just want the window:
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 窗口.你可以试试这个,然后把它粘贴到油漆上看看结果.
Mine worked with a winrar.exe window inside a inactive desktop. You can try this then paste it to paint to see the result.
只有一件事,除了我想要的窗口句柄外,屏幕截图位图的整个区域都是黑色的,这对我来说很好.我想我应该从下到上处理每个窗口,然后将它们混合起来.
There is just one thing, The whole area of the screenshot bitmap is black except the window handle that i want which is fine by me. I think i should get handle of every window from bottom to top in order then mix them up.
感谢所有对此的补充.
这篇关于从另一个桌面捕获屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!