Microsoft KB Archive/186736

{|
 * width="100%"|

HOWTO: Capture and Print an Entire Window

 * }

Q186736

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK)
 * Microsoft Windows 2000 Advanced Server
 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Professional

-

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.

Sample Code
  // Return a HDC for the default printer. HDC GetPrinterDC(void) {     PRINTDLG pdlg;

"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-&gt;palVersion = 0x300; lpLogPal-&gt;palNumEntries = 256;

      // Copy the current system palette into the logical palette. GetSystemPaletteEntries(hDC, 0, 256,          (LPPALETTEENTRY)(lpLogPal-&gt;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);"   }

<pre class="CODESAMP">  // 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;

<pre class="CODESAMP">      // Do you have a valid window? if (!IsWindow(hWnd)) return FALSE;

<pre class="CODESAMP">      // Get a HDC for the default printer. hdcPrinter = GetPrinterDC; if (!hdcPrinter) return FALSE;

<pre class="CODESAMP">      // Get the HDC for the entire window. hdcWindow = GetWindowDC(hWnd);

<pre class="CODESAMP">      // Get the rectangle bounding the window. GetWindowRect(hWnd, &rc);

<pre class="CODESAMP">      // Adjust coordinates to client area. OffsetRect(&rc, -rc.left, -rc.top);

<pre class="CODESAMP">      // Get the resolution of the printer device. iWidth = GetDeviceCaps(hdcPrinter, HORZRES); iHeight = GetDeviceCaps(hdcPrinter, VERTRES);

<pre class="CODESAMP">      // Create the intermediate drawing surface at window resolution. hbm = Create24BPPDIBSection(hdcWindow, rc.right, rc.bottom); if (!hbm) { DeleteDC(hdcPrinter); ReleaseDC(hWnd, hdcWindow); return FALSE; }

<pre class="CODESAMP">      // Prepare the surface for drawing. hdcMemory = CreateCompatibleDC(hdcWindow); SelectObject(hdcMemory, hbm);

<pre class="CODESAMP">      // Get the current system palette. hPal = GetSystemPalette;

<pre class="CODESAMP">      // If a palette was returned. if (hPal) { // Apply the palette to the source DC. SelectPalette(hdcWindow, hPal, FALSE); RealizePalette(hdcWindow);

<pre class="CODESAMP">          // Apply the palette to the destination DC. SelectPalette(hdcMemory, hPal, FALSE); RealizePalette(hdcMemory); }

<pre class="CODESAMP">      // Copy the window contents to the memory surface. BitBlt(hdcMemory, 0, 0, rc.right, rc.bottom,          hdcWindow, 0, 0, SRCCOPY);

<pre class="CODESAMP">      // Prepare the DOCINFO. ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(di); di.lpszDocName = "Window Contents";

<pre class="CODESAMP">      // Initialize the print job. if (StartDoc(hdcPrinter, &di) &gt; 0) {

<pre class="CODESAMP">          // Prepare to send a page. if (StartPage(hdcPrinter) &gt; 0) {

<pre class="CODESAMP">              // Retrieve the information describing the surface. GetObject(hbm, sizeof(DIBSECTION), &ds);

<pre class="CODESAMP">              // 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);

<pre class="CODESAMP">              // Let the driver know the page is done. EndPage(hdcPrinter); }

<pre class="CODESAMP">          // Let the driver know the document is done. EndDoc(hdcPrinter); }

<pre class="CODESAMP">      // Clean up the objects you created. DeleteDC(hdcPrinter); DeleteDC(hdcMemory); ReleaseDC(hWnd, hdcWindow); DeleteObject(hbm); if (hPal) DeleteObject(hPal); }