vinnitu
vinnitu

Reputation: 4364

What is wrong with PrintWindow?

What is wrong with the following code? Why does PrintWindow return 0?

HWND hwnd = GetDesktopWindow();
CHK(hwnd);

HDC hdc = GetWindowDC(hwnd);
CHK(hdc);

if (hdc)
{
    HDC hdcMem = CreateCompatibleDC(hdc);
    CHK(hdcMem);

    if (hdcMem)
    {
        RECT rc;
        CHK(GetWindowRect(hwnd, &rc));

        HBITMAP hbitmap = CreateCompatibleBitmap(hdc, rc.right-rc.left, rc.bottom-rc.top);
        CHK(hbitmap);   

        if (hbitmap)
        {
            SelectObject(hdcMem, hbitmap);

            CHK(PrintWindow(hwnd, hdcMem, 0)); //HERE return 0

            DeleteObject(hbitmap);
        }

        DeleteObject(hdcMem);
    }

    ReleaseDC(hwnd, hdc);
}

Upvotes: 0

Views: 3084

Answers (3)

DuckMaestro
DuckMaestro

Reputation: 15895

PrintWindow is a fairly thin operation. What it really does is send a WM_PRINT message to the window in question, in this case the desktop, and hopes that that window will respond to WM_PRINT correctly if at all (see here and here).

I repro'd your behavior but I'm not 100% sure why it's failing either. Perhaps you cannot call PrintWindow on an HWND that your process does not own, or perhaps the desktop does not respond to WM_PRINT messages.

The second link above includes a comment about using BitBlt instead:

Try getting a handle (HWND) to the desktop window - and use BitBlt to capture all the contents. Mind you - you'll only capture what is visible on the screen.

Maybe this helps.

Upvotes: 2

Jimm Chen
Jimm Chen

Reputation: 3787

It looks like GetDesktopWindow() returns a virtual HWND whose value is universally 0x0010010 on all Windows machines. This virtual HWND does not conform to usual PrintWindow behavior so the PrintWindow() returns FALSE, and GetLastError() reports no error code on this PrintWindow call.

To make PrintWindow() work, you can instead use the HWND from GetShellWindow(), which has the title "Program Manager" from the WinSpy++ figure below.

enter image description here

Upvotes: 1

Mike Kwan
Mike Kwan

Reputation: 24467

Replace:

HWND hwnd = GetDesktopWindow();

With:

HWND hwnd = GetDesktopWindow();
hwnd = FindWindowEx( hwnd, 0, _T("Progman"), _T("Program Manager") );

I'm not sure whether this gets what you want though. If you want to take a screenshot of the entire current desktop (including whatever top level windows are visible) then BitBlt is the route you want to take.

If you want to get the taskbar as well, you can still use this method but you'll have to take 2 screenshots and stitch the results together.

Upvotes: 0

Related Questions