Archive
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.
// 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 ); }
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!
How to get color of a pixel from any Bitmap?
It’s easy to get color of a pixel from a bitmap. Here is a function which does this…
#include
#include
// Returns Pixel color from bitmap
COLORREF GetPixelValueFromBitmap( const int x, const int y, CBitmap& bmp )
{
// DC for desktop
CDC dcDesktop;
dcDesktop.Attach( ::GetDC( GetDesktopWindow() ));
// Create a DC compatible with desktop or any other existing window
CDC dc;
dc.CreateCompatibleDC( &dcDesktop );
// Save the DC settings here, so that we can restore it later
const int nRestorePoint = dc.SaveDC();
// Select the bitmap into the DC
dc.SelectObject( &bmp );
// Now get the pixels value from the DC
const COLORREF clr = dc.GetPixel( x, y );
// Restore DC settings
dc.RestoreDC( nRestorePoint );
// Return pixel value/color
return clr;
}// End GetPixelValueFromBitmap
// main function
int main()
{
// initialize MFC and print an error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
std::cerr << _T("Fatal Error: MFC initialization failed") << std::endl;
return 1;
}
// Prepare a bitmap
CBitmap bmp;
// Provide your own bitmap id
bmp.LoadBitmap( IDB_BITMAP1 );
// Get color of given pixel from given bitmap
COLORREF clr = GetPixelValueFromBitmap( 0, 2, bmp );
// Split up the colors and see
const int Red = GetRValue( clr );
const int Green = GetGValue( clr );
const int Blue = GetBValue( clr );
return 0;
}// End main[/sourcecode]