Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PrintWindow causes flicker, strange artifacts in titlebar

I'm trying to take a screenshot of a Chrome window. It looks like this:

Chrome window

When I use PrintWindow to get the screenshot, I can see a flicker on the window titlebar/Chrome tab area. The captured screenshot contains a strange rendering of a titlebar in Windows Basic style (even though my machine runs the Aero theme):

Captured image

I've noticed that some other apps also exhibit a similar behavior where they flicker on-screen but the titlebar artifact is not visible in the captured screenshot. Apps that do this include Office 2010, IE 10, and the Trillian tabbed chat window — in other words, windows that extend the non-client area seem to have this issue.

The code that reproduces this is simple:

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);

}

Why am I seeing flickering and strange visual artifacts? What can I do to stop it?

like image 482
josh3736 Avatar asked Nov 01 '22 10:11

josh3736


2 Answers

For those, who have the same problem, do this:

const uint PW_RENDERFULLCONTENT = 0x00000002;
PrintWindow(hWnd, hDC, PW_RENDERFULLCONTENT);
like image 177
РСИТ _ Avatar answered Nov 12 '22 17:11

РСИТ _


If Aero is enabled, use BitBlt instead.

This comment in the chromium desktop capture source code was especially helpful:

// 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.
like image 20
squibman Avatar answered Nov 12 '22 16:11

squibman