PrintWindow()无法打印Google Chrome窗口(Chrome_WidgetWin_1)

des*_*ect 4 c windows winapi google-chrome window

我使用的是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);
}
Run Code Online (Sandbox Code Playgroud)

它适用于除谷歌Chrome主窗口以外的所有窗口.我认为这是因为Chrome使用直接渲染,因此我已禁用硬件加速chrome://settings.仍然无法正常工作.然后我意识到由于Chrome Sandbox中的限制,处理邮件可能会受到限制,因此我使用--no-sandbox命令行选项启动了Chrome .仍然无法正常工作.

我怎样才能让它发挥作用?适用于Chrome和Chrome等任何其他窗口.BitBlt()是不可接受的,因为窗口的某些部分窗口可能会被另一个窗口重叠,窗口可以在其他桌面上等等.有任何可行的解决方案吗?也许将DLL加载到另一个进程或类似的东西.

UPD:它重绘后RedrawWindow(); 所以我可以截取屏幕截图(部分 - 左侧部分(宽度~20px),右侧部分不复制).那么,是否支持WM_PRINT?如何获取窗口的完整屏幕截图?

小智 19

我被困了很多年,然后发现我可以将PW_RENDERFULLCONTENT参数作为PrintWindow的最后一个参数传递.谷歌搜索显示它是Windows 8.1中的新功能,因此可能不适用于7.虽然可能值得尝试,但Winuser.h将其定义为

#if(_WIN32_WINNT >= 0x0603)
#define PW_RENDERFULLCONTENT    0x00000002
#endif /* _WIN32_WINNT >= 0x0603 */
Run Code Online (Sandbox Code Playgroud)

  • 我花了 3 个小时编写了几种不同的方法来找到这个答案。BitBlt() 也返回黑色图像。干得好,伙计。 (3认同)
  • 你救了我的一天!花了近2个小时搜索,修复。但是,在 MS API 页面 https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-printwindow 我找不到有关此标志的任何信息。 (2认同)

IIn*_*ble 4

PrintWindow通过向目标窗口发送WM_PRINTWM_PRINTCLIENT来工作。虽然DefWindowProc处理WM_PRINT标准窗口类,但自定义窗口类必须处理WM_PRINT才能PrintWindow产生所需的结果。如果 Chrome 不处理WM_PRINTor WM_PRINTCLIENT,则您无能为力。

当面向 Windows Vista 及更高版本时,您可以使用DWM Thumbnail API 强制窗口将其内容呈现到客户端提供的目标窗口中。

  • 我可以确认 Geoff 的答案适用于拍摄 Google Chrome 的屏幕截图。 (2认同)