这种情况可能发生在许多应用程序中,其中目标窗口只是一个容器,不负责绘制消息。标准 win32 应用程序(如记事本)的行为并非如此。但例如,您可能会在使用许多浏览器时遇到此问题。
您始终可以截取桌面窗口的屏幕截图。您可以获取目标窗口的屏幕坐标,然后bitblt
目标窗口的该部分。对您的代码进行以下更改:
//GetClientRect(handle, &client_rect);
GetWindowRect(handle, &client_rect);
//HDC hdcScreen = GetDC(handle);
HDC hdcScreen = GetDC(HWND_DESKTOP);
//BitBlt(hdc, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY);
BitBlt(hdc, 0, 0, width, height, hdcScreen, client_rect.left, client_rect.top, SRCCOPY);
//ReleaseDC(NULL, hdcScreen);
ReleaseDC(HWND_DESKTOP, hdcScreen);
在进行屏幕截图之前,目标窗口必须是屏幕上最顶层的可见窗口。例如你可以打电话screenshot_window
按此顺序:
HWND hwnd = FindWindow(0, L"Calculator");
SetForegroundWindow(hwnd);
Sleep(1000);
screenshot_window(hwnd);
或者,您可以使用Dwm 缩略图 https://msdn.microsoft.com/en-us/library/windows/desktop/aa969541(v=vs.85).aspx用于在您自己的窗口中绘制目标窗口的 API。但同样,你不能使用GetDC(my_hWnd)
从窗口上的“Dwm Thumbnail”访问位图。同样,您必须使用以下命令截取桌面窗口的屏幕截图GetDC(HWND_DESKTOP)
。这次确保您自己的窗口是顶部窗口。
应用程序必须支持 DPI,否则屏幕坐标将不匹配。
原始代码中还存在资源泄漏。GetDC
应清理ReleaseDC
使用相同的handle
, not NULL
HDC hdcScreen = GetDC(handle);
...
//ReleaseDC(NULL, hdcScreen);
ReleaseDC(handle, hdcScreen);