Using PrintWindow to capture screen or to take snapshot of a window!

PrintWindow is a cool function which helps us in printing a windows contents to a DC. Normal usage will be that we pass a printer DC, but here we pass a custom DC with a bitmap selected into this DC. Internally PrintWindow uses WM_PRINT and WM_PRINTCLIENT(This is my assumption).

Here is a simple function which uses PrintWindow to get screen shots of a given window and prints the resultant capture bitmap to a given window.

[sourcecode language=’cpp’]// Sample call CaptureWindow( FindWindow(…), &MyDlg )
void CaptureWindow( CWnd* WindowToCapture, CWnd* PaintToWindow )
{
if( !WindowToCapture ||
!PaintToWindow ||
!IsWindow( WindowToCapture->m_hWnd ) ||
!IsWindow( PaintToWindow->m_hWnd ))
return;

CDC* WindowToCaptureDC = WindowToCapture->GetWindowDC();
CDC* PaintToWindowDC = PaintToWindow->GetDC();

CDC CaptureDC;
VERIFY( CaptureDC.CreateCompatibleDC( WindowToCaptureDC ));
const int RestorePoint = CaptureDC.SaveDC();

CRect CaptureWndRect;
WindowToCapture->GetWindowRect( &CaptureWndRect );

CBitmap CaptureBmp;
VERIFY( CaptureBmp.CreateCompatibleBitmap( WindowToCaptureDC, CaptureWndRect.Width(), CaptureWndRect.Height() ));
CaptureDC.SelectObject( &CaptureBmp );

// Capture window now
if( WindowToCapture->PrintWindow( &CaptureDC, 0 ))
{
CRect PaintToWindowRect;
PaintToWindow->GetClientRect( &PaintToWindowRect );

// To prevent unwanted stretching while drawing
const int BltWidth = min( PaintToWindowRect.Width(), CaptureWndRect.Width() );
const int BltHeight = min( PaintToWindowRect.Height(), CaptureWndRect.Height() );

PaintToWindow->Invalidate();
PaintToWindow->UpdateWindow();
PaintToWindowDC->StretchBlt( PaintToWindowRect.left,
PaintToWindowRect.top,
BltWidth,
BltHeight,
&CaptureDC,
0,
0,
CaptureWndRect.Width(),
CaptureWndRect.Height(),
SRCCOPY );
}// End if

CaptureDC.RestoreDC( RestorePoint );
CaptureDC.DeleteDC();

WindowToCapture->ReleaseDC( WindowToCaptureDC );
PaintToWindow->ReleaseDC( PaintToWindowDC );
}[/sourcecode]

If you need to print just the client area of a window use PW_CLIENTONLY in nFlags parameter to this function! Note that if you are using PW_CLIENTONLY then change from GetWindowDC to GetDC.

A sample project for download (rename to zip). But there is a problem while capturing desktop window, whole desktop window painting goes haywire. I am working on it, will update this post with my fixes!

9 thoughts on “Using PrintWindow to capture screen or to take snapshot of a window!

  1. Hi Nibu,
    i m developing a GUI using VC++ and i need to print the currently displaying screen whenever print command is given. at that perticular time there may be 3-4 windows open and one of them may be partially visible. i need to take a snap shot of the screen and print it. i got we solutions but in those it will display the screenshot from which againg we need to select print command to print it. but i require it to print directly at one go.

    pls help me out…

    Regards,
    Jasmine

  2. Hey,

    PrintWindow() does not take snapshot of complete window? I am trying to take snapshot at 1280X1024 resolution? any idea?

    Thanks.

  3. Since popup menus are also basically windows we can capture them, but problem is that they vanish too quickly. So we’ve got to hook its creation. Have a look at WH_CBT!

  4. but how can i capture a TreeView window? when i used to pass the tree handle to PrintWindow(), it fails to take the screenprint..

Appreciate your comments...