我使用的是Microsoft Visual Studio 2010和Windows 7 Professional。 这是我将窗口图像复制到剪贴板的代码:
void PrintWindowEx( HWND hWnd )
{
HDC hDCMem = CreateCompatibleDC(NULL);
RECT rect;
GetWindowRect(hWnd, &rect);
HBITMAP hBmp = NULL;
HDC hDC = GetDC(hWnd);
hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
HGDIOBJ hOld = SelectObject(hDCMem, hBmp);
PrintWindow(hWnd, hDCMem, 0);
SelectObject(hDCMem, hOld);
DeleteObject(hDCMem);
OpenClipboard(hWnd);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBmp);
CloseClipboard();
ReleaseDC(hWnd, hDC);
}
除谷歌Chrome主窗口外,它适用于所有窗口。我认为这是因为Chrome使用直接渲染,所以我在chrome://settings
中禁用了硬件加速。仍然无法正常工作。然后我意识到由于Chrome Sandbox中的限制,处理邮件可能会受到限制,因此我使用--no-sandbox
命令行选项启动了Chrome。仍然无效。
我怎样才能让它发挥作用?适用于Chrome和Chrome等任何其他窗口。 BitBlt()
是不可接受的,因为窗口的某些部分窗口可能会被另一个窗口重叠,窗口可以放在其他桌面上等等。有没有可行的解决方案?也许将DLL加载到另一个进程或类似的东西。
UPD :它会在RedrawWindow()
后重绘;所以我可以截取屏幕截图(部分 - 左侧部分(宽度~20px),右侧部分不复制)。那么,它是否支持WM_PRINT
?如何获取窗口的完整屏幕截图?
答案 0 :(得分:12)
我被困多年了,然后发现我可以将PW_RENDERFULLCONTENT参数作为PrintWindow的最后一个参数传递。谷歌搜索显示它是Windows 8.1中的新功能所以可能不适用于7.虽然可能值得尝试,但Winuser.h将其定义为
#if(_WIN32_WINNT >= 0x0603)
#define PW_RENDERFULLCONTENT 0x00000002
#endif /* _WIN32_WINNT >= 0x0603 */
答案 1 :(得分:3)
PrintWindow的工作原理是向目标窗口发送WM_PRINT或WM_PRINTCLIENT。虽然DefWindowProc处理标准窗口类的WM_PRINT
,但自定义窗口类必须处理WM_PRINT
,以便PrintWindow
生成所需的结果。如果Chrome无法处理WM_PRINT
或WM_PRINTCLIENT
,那么您无能为力。
在定位Windows Vista及更高版本时,您可以使用DWM Thumbnail API强制窗口将其内容呈现到客户端提供的目标窗口中。