HOWTO: Capture and Print an Entire Window
ID: Q186736
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
-
Microsoft Windows 2000
SUMMARY
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.
MORE INFORMATION
Sample Code
// 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);
}
REFERENCES
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
Keywords : kbWinOS2000
Version : WINDOWS:
Platform : WINDOWS
Issue type : kbhowto