Microsoft KB Archive/129860

{|
 * width="100%"|

HOWTO: Use Built-In Printing Features from a Rich Edit Control

 * }

Q129860

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK)

-

SUMMARY
The Rich Edit control contains built-in printing features that can be used to send formatted text to the printer with minimal effort from the programmer.

MORE INFORMATION
Printing from a Rich Edit control involves the use of the standard printing APIs and two Rich Edit control messages, EM_FORMATRANGE and EM_DISPLAYBAND. The EM_FORMATRANGE message can be used by itself or used in combination with the EM_DISPLAYBAND message. Included below at the end of this article is a code sample which demonstrates the usage of these messages.

EM_FORMATRANGE
This message is used to format the text for the printer DC and can optionally send the output to the printer.

The wParam parameter for this message is a Boolean value that indicates whether or not the text should be rendered (printed) to the printer. A zero value only formats the text, while a nonzero value formats the text and renders it to the printer.

The lParam parameter for this message is a pointer to the FORMATRANGE structure. This structure needs to be filled out before sending the message to the control.

FORMATRANGE Members
HDC hdc - Contains the device context (DC) to render to if the wParam parameter is nonzero. The output is actually sent to this DC.

HDC hdcTarget - Contains the device context to format for, which is usually the same as the hdc member but can be different. For example, if you create a print preview module, the hdc member is the DC of the window in which the output is viewed, and the hdcTarget member is the DC for the printer.

RECT rc - Contains the area to render to. This member contains the rectangle that the text is formatted to fit in, and subsequently printed in. It also contains the margins, room for headers and footers, and so forth. The rc.bottom member may be changed after the message is sent. If it is changed, it must indicate the largest rectangle that can fit within the bounds of the original rectangle and still contain the specified text without printing partial lines. It may be necessary to reset this value after each page is printed. These dimensions are given in TWIPS.

RECT rcPage - Contains the entire area of the rendering device. This area can be obtained using the GetDeviceCaps function. These dimensions are given in TWIPS.

CHARRANGE chrg - Contains the range of characters to be printed. Set chrg.cpMin to 0 and chrg.cpMax to -1 to print all characters.

The return value from EM_FORMATRANGE is the index of the first character on the next page. If you are printing multiple pages, you should set chrg.cpMin to this value before the next EM_FORMATRANGE message is sent.

When printing is complete, this message must be sent to the control with wParam = 0 and lParam = NULL to free the information cache by the control.

EM_DISPLAYBAND
If you use 0 for the wParam parameter in the EM_FORMATRANGE message, then you can use the EM_DISPLAYBAND message to send the output to the printer.

The wParam parameter for this message is not used and should be 0.

The lParam parameter for this message is a pointer to a RECT structure. This RECT structure is the area to display to and is usually the same as the rc member of the FORMATRANGE structure used in the EM_FORMATRANGE message but can be different. For example, the rectangles are not the same if you are printing on a certain portion of a page or built-in margins are being used.

This message should only be used after a previous EM_FORMATRANGE message.

Sample Code
  void Print(HDC hPrinterDC, HWND hRTFWnd) {     FORMATRANGE fr; int        nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES), nVertRes = GetDeviceCaps(hPrinterDC, VERTRES), nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX), nLogPixelsY = GetDeviceCaps(hPrinterDC, LOGPIXELSY); LONG       lTextLength;   // Length of document. LONG       lTextPrinted;  // Amount of document printed.

// Ensure the printer DC is in MM_TEXT mode. SetMapMode ( hPrinterDC, MM_TEXT );

// Rendering to the same DC we are measuring. ZeroMemory(&fr, sizeof(fr)); fr.hdc = fr.hdcTarget = hPrinterDC;

// Set up the page. fr.rcPage.left    = fr.rcPage.top = 0; fr.rcPage.right   = (nHorizRes/nLogPixelsX) * 1440; fr.rcPage.bottom  = (nVertRes/nLogPixelsY) * 1440;

// Set up 1" margins all around.     fr.rc.left   = fr.rcPage.left + 1440;  // 1440 TWIPS = 1 inch.      fr.rc.top    = fr.rcPage.top + 1440;      fr.rc.right  = fr.rcPage.right - 1440;      fr.rc.bottom = fr.rcPage.bottom - 1440;

// Default the range of text to print as the entire document. fr.chrg.cpMin = 0; fr.chrg.cpMax = -1;

// Set up the print job (standard printing stuff here). ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(DOCINFO); if (*szFileName) di.lpszDocName = szFileName; else {        di.lpszDocName = "(Untitled)";

// Do not print to file. di.lpszOutput = NULL; }

// Start the document. StartDoc(hPrinterDC, &di);

// Find out real size of document in characters. lTextLength = SendMessage ( hRTFWnd, WM_GETTEXTLENGTH, 0, 0 );

do        { // Start the page. StartPage(hPrinterDC);

// Print as much text as can fit on a page. The return value is        // the index of the first character on the next page. Using TRUE // for the wParam parameter causes the text to be printed.

#ifdef USE_BANDING

lTextPrinted = SendMessage(hRTFWnd,                                   EM_FORMATRANGE,                                    FALSE,                                    (LPARAM)&fr); SendMessage(hRTFWnd, EM_DISPLAYBAND, 0, (LPARAM)&fr.rc);

#else

lTextPrinted = SendMessage(hRTFWnd,                                   EM_FORMATRANGE,                                    TRUE,                                    (LPARAM)&fr);

#endif

// Print last page. EndPage(hPrinterDC);

// If there is more text to print, adjust the range of characters // to start printing at the first character of the next page. if (lTextPrinted < lTextLength) {           fr.chrg.cpMin = lTextPrinted; fr.chrg.cpMax = -1; }        }      while (lTextPrinted < lTextLength);

// Tell the control to release cached information. SendMessage(hRTFWnd, EM_FORMATRANGE, 0, (LPARAM)NULL);

EndDoc (hPrinterDC); } Additional query words:

Keywords : _IK kbCtrl kbOSWinNT351 kbOSWinNT400 kbOSWin2000 kbRichEdit kbSDKWin32 kbGrpDSUser kbOSWin95 kbOSWin98 kbDSupport

Issue type : kbhowto

Technology : kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWin32sSearch