C++ PrintWindow在标题栏中引起闪烁和奇怪的瑕疵

C++ PrintWindow在标题栏中引起闪烁和奇怪的瑕疵,c++,windows,winapi,screenshot,C++,Windows,Winapi,Screenshot,我正在尝试拍摄一个Chrome窗口的截图。看起来是这样的: 当我使用屏幕截图时,我可以看到窗口标题栏/Chrome选项卡区域闪烁。捕获的屏幕截图包含以Windows Basic样式对标题栏的奇怪渲染(即使我的机器运行Aero主题): 我注意到,其他一些应用程序也表现出类似的行为,它们在屏幕上闪烁,但标题栏工件在捕获的屏幕截图中不可见。这样做的应用包括Office 2010、IE 10和Trillian选项卡式聊天窗口——换句话说,扩展非客户端区域的窗口似乎有这个问题 再现这一点的代码很简单:

我正在尝试拍摄一个Chrome窗口的截图。看起来是这样的:

当我使用屏幕截图时,我可以看到窗口标题栏/Chrome选项卡区域闪烁。捕获的屏幕截图包含以Windows Basic样式对标题栏的奇怪渲染(即使我的机器运行Aero主题):

我注意到,其他一些应用程序也表现出类似的行为,它们在屏幕上闪烁,但标题栏工件在捕获的屏幕截图中不可见。这样做的应用包括Office 2010、IE 10和Trillian选项卡式聊天窗口——换句话说,扩展非客户端区域的窗口似乎有这个问题

再现这一点的代码很简单:

void Screenshot(HWND hWnd) {

    RECT rc;
    GetClientRect(hWnd, &rc);

    HDC hdcScreen = GetDC(NULL);
    HDC hdc = CreateCompatibleDC(hdcScreen);
    HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, 
        rc.right - rc.left, rc.bottom - rc.top);
    SelectObject(hdc, hbmp);

    //Print to memory hdc
    PrintWindow(hWnd, hdc, PW_CLIENTONLY);

}

为什么我看到闪烁和奇怪的视觉伪影?如何停止它?

如果启用了Aero,请改用BitBlt

该评论在以下方面特别有用:

// When desktop composition (Aero) is enabled each window is rendered to a
// private buffer allowing BitBlt() to get the window content even if the
// window is occluded. PrintWindow() is slower but lets rendering the window
// contents to an off-screen device context when Aero is not available.

对于那些有相同问题的人,请执行以下操作:

const uint PW_RENDERFULLCONTENT = 0x00000002;
PrintWindow(hWnd, hDC, PW_RENDERFULLCONTENT);

用你的代码,我无法复制。Windows 7 64。使用32b或64b版本。仅使用PW_客户端或0。目标:Chrome主窗口或Excel 2010主窗口。无闪烁,“几乎”良好的PNG(使用GDIPLUS)@manuell:有趣的是,从我的实际应用程序来看,每次调用
PrintWindow
(在窗口获得焦点后不久)时,闪烁都会发生。在一个赤裸裸的测试应用程序中,当(1){Screenshot(hWnd);Sleep(100);}时,闪烁是间歇性的。应用程序处理“focus”和“activity”窗口消息的时间很长/在/实际绘制发生之前,imho。我打赌你的要求来得太早了。尽量多拖延。没有上下文很难帮助。用好的老BitBblt截图不会闪烁,消耗更少的资源,但当windows只是“最小化”或“恢复”时,会产生一些有趣的结果@manuell:我试着推迟通话,但没有用。无论如何,在循环中从测试线束调用screenshot函数会导致闪烁,即使在不切换窗口的情况下也是如此?