Printing with CRichEditCtrl control
-
Hi, I am trying to print the content of the CRichEditCtrl. The problem is that when I want to use pagination (with A4 pages), the printed text (which is just 4 sample line with 40 chars at most) at the code
lTextPrinted =FormatRange(&fr,TRUE);
is always lesser than the actual text pointed by the
lTextLength
variable making the loop run for ever. What is the problem with the following code ?CPrintDialog printDialog(false); if (bShowPrintDialog) { int r = printDialog.DoModal(); if (r == IDCANCEL) return; // User pressed cancel, don't print. } else { printDialog.GetDefaults(); } HDC hPrinterDC = printDialog.GetPrinterDC(); CDC pMyPrinterDC; pMyPrinterDC.Attach(hPrinterDC); // This code basically taken from MS KB article Q129860 FORMATRANGE fr; int nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES); int nVertRes = GetDeviceCaps(hPrinterDC, VERTRES); int nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX); int 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 = pMyPrinterDC.m\_hDC; fr.hdcTarget = pMyPrinterDC.m\_hDC; // Get the page width and height from the printer. long lPageWidth = ::MulDiv(pMyPrinterDC.GetDeviceCaps(PHYSICALWIDTH), 1440, pMyPrinterDC.GetDeviceCaps(LOGPIXELSX)); long lPageHeight = ::MulDiv(pMyPrinterDC.GetDeviceCaps(PHYSICALHEIGHT), 1440, pMyPrinterDC.GetDeviceCaps(LOGPIXELSY)); CRect rcPage(0, 0, lPageWidth, lPageHeight); SetTargetDevice(hPrinterDC,lPageWidth); fr.rc = rcPage; fr.rcPage = rcPage; // Default the range of text to print as the entire document. fr.chrg.cpMin = 0; fr.chrg.cpMax = -1; this->FormatRange(&fr,TRUE); // Set up the print job (standard printing stuff here). DOCINFO di; ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "GnosisExplorerNotes"; // Do not print to file. di.lpszOutput = NULL; // Update the display with the new formatting. RECT rcClient; GetClientRect(&rcClient); DisplayBand(&rcClient); // Start the document. StartDoc(hPrinterDC, &di); // Find out real size of
-
Hi, I am trying to print the content of the CRichEditCtrl. The problem is that when I want to use pagination (with A4 pages), the printed text (which is just 4 sample line with 40 chars at most) at the code
lTextPrinted =FormatRange(&fr,TRUE);
is always lesser than the actual text pointed by the
lTextLength
variable making the loop run for ever. What is the problem with the following code ?CPrintDialog printDialog(false); if (bShowPrintDialog) { int r = printDialog.DoModal(); if (r == IDCANCEL) return; // User pressed cancel, don't print. } else { printDialog.GetDefaults(); } HDC hPrinterDC = printDialog.GetPrinterDC(); CDC pMyPrinterDC; pMyPrinterDC.Attach(hPrinterDC); // This code basically taken from MS KB article Q129860 FORMATRANGE fr; int nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES); int nVertRes = GetDeviceCaps(hPrinterDC, VERTRES); int nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX); int 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 = pMyPrinterDC.m\_hDC; fr.hdcTarget = pMyPrinterDC.m\_hDC; // Get the page width and height from the printer. long lPageWidth = ::MulDiv(pMyPrinterDC.GetDeviceCaps(PHYSICALWIDTH), 1440, pMyPrinterDC.GetDeviceCaps(LOGPIXELSX)); long lPageHeight = ::MulDiv(pMyPrinterDC.GetDeviceCaps(PHYSICALHEIGHT), 1440, pMyPrinterDC.GetDeviceCaps(LOGPIXELSY)); CRect rcPage(0, 0, lPageWidth, lPageHeight); SetTargetDevice(hPrinterDC,lPageWidth); fr.rc = rcPage; fr.rcPage = rcPage; // Default the range of text to print as the entire document. fr.chrg.cpMin = 0; fr.chrg.cpMax = -1; this->FormatRange(&fr,TRUE); // Set up the print job (standard printing stuff here). DOCINFO di; ZeroMemory(&di, sizeof(di)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "GnosisExplorerNotes"; // Do not print to file. di.lpszOutput = NULL; // Update the display with the new formatting. RECT rcClient; GetClientRect(&rcClient); DisplayBand(&rcClient); // Start the document. StartDoc(hPrinterDC, &di); // Find out real size of
I ended up that the RichEditCtrl version 2 causes this problem. Using RichEditCtrl version 1 it works fine. Any solution ? I am attaching the source code. Please check that the lTextPrinted is always lesser than lTextLength. https://rapidshare.com/files/2018160716/RichEditDlg.zip[^]
sdancer75
-
I ended up that the RichEditCtrl version 2 causes this problem. Using RichEditCtrl version 1 it works fine. Any solution ? I am attaching the source code. Please check that the lTextPrinted is always lesser than lTextLength. https://rapidshare.com/files/2018160716/RichEditDlg.zip[^]
sdancer75
Here is the code that prints very well:
// this code is taken from Vadim Z.'s article RTF based Tooltips
// www.codeguru.com
//----------------------------------------------------------------------------
// Function CMyRichEditCtrl::Print
// @func print the rich edit control content
// @parm bool | bShowPrintDialog | show the dialog box CPrintDialog
//----------------------------------------------------------------------------
// @todo
//----------------------------------------------------------------------------
void CSpscRichEditCtrl::Print(bool bShowPrintDialog, CWnd* pParent /*=NULL*/)
{
CPrintDialog printDialog(false, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
| PD_HIDEPRINTTOFILE | PD_NOSELECTION, pParent);if (bShowPrintDialog)
{
int r = printDialog.DoModal();
if (r == IDCANCEL)
return; // User pressed cancel, don't print.
}
else
{
printDialog.GetDefaults();
}HDC hPrinterDC = printDialog.GetPrinterDC();
// This code basically taken from MS KB article Q129860
FORMATRANGE fr;
int nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES);
int nVertRes = GetDeviceCaps(hPrinterDC, VERTRES);
int nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX);
int 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 );// Tell the control to release cached information.
FormatRange(NULL,false);// 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 0" 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).
DOCINFO di;
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(DOCINFO);di.lpszDocName = _T("eClinic Pharmacy SMS Authorisation Form");
// Do not print to file.
di.lpszOutput = NUL -
Here is the code that prints very well:
// this code is taken from Vadim Z.'s article RTF based Tooltips
// www.codeguru.com
//----------------------------------------------------------------------------
// Function CMyRichEditCtrl::Print
// @func print the rich edit control content
// @parm bool | bShowPrintDialog | show the dialog box CPrintDialog
//----------------------------------------------------------------------------
// @todo
//----------------------------------------------------------------------------
void CSpscRichEditCtrl::Print(bool bShowPrintDialog, CWnd* pParent /*=NULL*/)
{
CPrintDialog printDialog(false, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
| PD_HIDEPRINTTOFILE | PD_NOSELECTION, pParent);if (bShowPrintDialog)
{
int r = printDialog.DoModal();
if (r == IDCANCEL)
return; // User pressed cancel, don't print.
}
else
{
printDialog.GetDefaults();
}HDC hPrinterDC = printDialog.GetPrinterDC();
// This code basically taken from MS KB article Q129860
FORMATRANGE fr;
int nHorizRes = GetDeviceCaps(hPrinterDC, HORZRES);
int nVertRes = GetDeviceCaps(hPrinterDC, VERTRES);
int nLogPixelsX = GetDeviceCaps(hPrinterDC, LOGPIXELSX);
int 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 );// Tell the control to release cached information.
FormatRange(NULL,false);// 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 0" 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).
DOCINFO di;
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(DOCINFO);di.lpszDocName = _T("eClinic Pharmacy SMS Authorisation Form");
// Do not print to file.
di.lpszOutput = NULThank you Andrew, The offending code was the
GetTextLength()
that it should be changed the way you showed me in your example with :
lTextLength = GetTextLengthEx(GTL_PRECISE | GTL_NUMCHARS);
I didn't bothered until now, with the GetTextLengthEx and I had a really hard time with this functionality. Now it works that way it should be. MSDN reports : GetTextLengthEx provides additional ways of determining the length of the text. It supports the Rich Edit 2.0 functionality. For more information, see About Rich Edit Controls in the Platform SDK. My very best regards for your help, George
sdancer75