ID: Q186736
The information in this article applies to:
This article demonstrates one technique for capturing the entire contents of a window (including the non-client area) and printing it to the default printer. To do this, the code creates an intermediate surface that is 24- bits per pixel, copies the contents of the specified window to the intermediate surface, and then stretches the intermediate surface to fill the entire display area in the printer DC.
// Return a HDC for the default printer.
HDC GetPrinterDC(void)
{
PRINTDLG pdlg;
memset( &pdlg, 0, sizeof( PRINTDLG ) );
pdlg.lStructSize = sizeof( PRINTDLG );
pdlg.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
PrintDlg( &pdlg );
return pdlg.hDC;
}
// Create a copy of the current system palette.
HPALETTE GetSystemPalette()
{
HDC hDC;
HPALETTE hPal;
HANDLE hLogPal;
LPLOGPALETTE lpLogPal;
// Get a DC for the desktop.
hDC = GetDC(NULL);
// Check to see if you are a running in a palette-based video mode.
if (!(GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE)) {
ReleaseDC(NULL, hDC);
return NULL;
}
// Allocate memory for the palette.
lpLogPal = GlobalAlloc(GPTR, sizeof(LOGPALETTE) + 256 *
sizeof(PALETTEENTRY));
if (!hLogPal)
return NULL;
// Initialize.
lpLogPal->palVersion = 0x300;
lpLogPal->palNumEntries = 256;
// Copy the current system palette into the logical palette.
GetSystemPaletteEntries(hDC, 0, 256,
(LPPALETTEENTRY)(lpLogPal->palPalEntry));
// Create the palette.
hPal = CreatePalette(lpLogPal);
// Clean up.
GlobalFree(lpLogPal);
ReleaseDC(NULL, hDC);
return hPal;
}
// Create a 24-bit-per-pixel surface.
HBITMAP Create24BPPDIBSection(HDC hDC, int iWidth, int iHeight)
{
BITMAPINFO bmi;
HBITMAP hbm;
LPBYTE pBits;
// Initialize to 0s.
ZeroMemory(&bmi, sizeof(bmi));
// Initialize the header.
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = iWidth;
bmi.bmiHeader.biHeight = iHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
// Create the surface.
hbm = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, &pBits, NULL, 0);
return(hbm);
}
// Print the entire contents (including the non-client area) of
// the specified window to the default printer.
BOOL PrintWindowToDC(HWND hWnd)
{
HBITMAP hbm;
HDC hdcPrinter;
HDC hdcMemory;
HDC hdcWindow;
int iWidth;
int iHeight;
DOCINFO di;
RECT rc;
DIBSECTION ds;
HPALETTE hPal;
// Do you have a valid window?
if (!IsWindow(hWnd))
return FALSE;
// Get a HDC for the default printer.
hdcPrinter = GetPrinterDC();
if (!hdcPrinter)
return FALSE;
// Get the HDC for the entire window.
hdcWindow = GetWindowDC(hWnd);
// Get the rectangle bounding the window.
GetWindowRect(hWnd, &rc);
// Adjust coordinates to client area.
OffsetRect(&rc, -rc.left, -rc.top);
// Get the resolution of the printer device.
iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
// Create the intermediate drawing surface at window resolution.
hbm = Create24BPPDIBSection(hdcWindow, rc.right, rc.bottom);
if (!hbm) {
DeleteDC(hdcPrinter);
ReleaseDC(hWnd, hdcWindow);
return FALSE;
}
// Prepare the surface for drawing.
hdcMemory = CreateCompatibleDC(hdcWindow);
SelectObject(hdcMemory, hbm);
// Get the current system palette.
hPal = GetSystemPalette();
// If a palette was returned.
if (hPal) {
// Apply the palette to the source DC.
SelectPalette(hdcWindow, hPal, FALSE);
RealizePalette(hdcWindow);
// Apply the palette to the destination DC.
SelectPalette(hdcMemory, hPal, FALSE);
RealizePalette(hdcMemory);
}
// Copy the window contents to the memory surface.
BitBlt(hdcMemory, 0, 0, rc.right, rc.bottom,
hdcWindow, 0, 0, SRCCOPY);
// Prepare the DOCINFO.
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(di);
di.lpszDocName = "Window Contents";
// Initialize the print job.
if (StartDoc(hdcPrinter, &di) > 0) {
// Prepare to send a page.
if (StartPage(hdcPrinter) > 0) {
// Retrieve the information describing the surface.
GetObject(hbm, sizeof(DIBSECTION), &ds);
// Print the contents of the surface.
StretchDIBits(hdcPrinter,
0, 0, iWidth, iHeight,
0, 0, rc.right, rc.bottom,
ds.dsBm.bmBits,
(LPBITMAPINFO)&ds.dsBmih,
DIB_RGB_COLORS,
SRCCOPY);
// Let the driver know the page is done.
EndPage(hdcPrinter);
}
// Let the driver know the document is done.
EndDoc(hdcPrinter);
}
// Clean up the objects you created.
DeleteDC(hdcPrinter);
DeleteDC(hdcMemory);
ReleaseDC(hWnd, hdcWindow);
DeleteObject(hbm);
if (hPal)
DeleteObject(hPal);
}
For more information on capturing images from the screen, see the WINCAP32 sample in the Microsoft Platform SDK.
Additional query words: kbDSupport kbdsd kbGDI kbPrinting kbBitmap kbDisplay
Version : WINNT:
Platform : winnt
Issue type : kbhowto
Last Reviewed: June 2, 1998