1.00 1.50
WINDOWS
kbprg
The information in this article applies to:
- The Microsoft Foundation Classes (MFC) included with:
Microsoft Visual C++ for Windows, versions 1.0 and 1.5
SUMMARY
To implement accurate print margins, applications should use the
GETPHYSPAGESIZE and GETPRINTINGOFFSET printer escapes, as well as
CDC::GetDeviceCaps() with LOGPIXELSX/LOGPIXELSY, HORZRES/VERTRES,
and/or HORZSIZE/VERTSIZE.
MORE INFORMATION
For a detailed description of the above functions, see the Microsoft
Knowledge Base article Q11863 "Printer Page Area in Windows."
The following example demonstrates one method to implement print
margins in the SuperPad Microsoft Foundation Class (MFC) Libraries
sample. Because SuperPad already uses the m_rectDraw member of
CPrintInfo, the method demonstrated here modifies this rectangle
during OnPrint(). Note that modifying m_rectDraw during
OnBeginPrinting() or OnPrepareDC() has no effect because
CView::OnFilePrint() initializes m_rectDraw immediately after calling
OnPrepareDC().
- Use App Studio and ClassWizard to add controls and corresponding
variables for the margin settings to the Page Setup dialog box in
SuperPad (CPageSetupDlg). CPageSetupDlg is not related to the
common dialog CPrintDialog, but is a CDialog used by SuperPad to
set the header and footer strings that SuperPad adds to each page
when it prints, and is an intuitive place to add controls for
setting margins. The units used for input should be
device-independent units, such as inches or centimeters.
The code below assumes that CPageSetupDlg has a CRect member named
m_rMargin that contains the current margin values in MM_HIMETRIC
units. To use this code, add m_rMargin to CPageSetupDlg and modify
CPageSetupDlg::DoDataExchange to convert new margin values to
MM_HIMETRIC units; save them in m_rMargin.
- Add a CRect member named m_rectMargins to the CPadView class and
add the following function to CPadView. This function converts the
device-independent margins in CPageSetupDlg::m_rMargin into
device-dependent values for the current printer. The printing
rectangle (CPrintInfo::m_rectDraw) representing the printable area
of the page is then reduced by these amounts in OnPrint().
Sample Code
-----------
void CPadView::CalculateMargins(CDC* pDC)
{
POINT pt;
// Start by getting the dimensions of the unprintable part of the
// page (in device units). GETPRINTINGOFFSET will tell us the left
// and upper unprintable area.
pDC->Escape(GETPRINTINGOFFSET, 0, NULL, &pt);
m_rectMargins.left = pt.x;
m_rectMargins.top = pt.y;
// To get the right and lower unprintable area, we need to take
// the entire width and height of the paper (GETPHYSPAGESIZE) and
// subtract everything else.
pDC->Escape(GETPHYSPAGESIZE, 0, NULL, &pt);
m_rectMargins.right = pt.x // total paper width
- pDC->GetDeviceCaps(HORZRES) // printable width
- m_rectMargins.left; // left unprtable margin
m_rectMargins.bottom = pt.y // total paper height
- pDC->GetDeviceCaps(VERTRES) // printable ht
- m_rectMargins.top; // rt unprtable margin
// At this point, m_rectMargins contains the widths of the
// unprintable regions on all four sides of the page in device units.
// Convert the Hi-Metric margin values from the Page Setup dialog
// to device units and subtract the unprintable part we just
// calculated. Save the results back in m_rectMargins.
// (2540 == # of Hi-Metric units in an inch)
pt.x = pDC->GetDeviceCaps(LOGPIXELSX); // dpi in X direction
pt.y = pDC->GetDeviceCaps(LOGPIXELSY); // dpi in Y direction
m_rectMargins.left = MulDiv(dlgPageSetup.m_rMargin.left, pt.x, 2540)
- m_rectMargins.left;
m_rectMargins.top = MulDiv(dlgPageSetup.m_rMargin.top, pt.y, 2540)
- m_rectMargins.top;
m_rectMargins.right = MulDiv(dlgPageSetup.m_rMargin.right, pt.x, 2540)
- m_rectMargins.right;
m_rectMargins.bottom = MulDiv(dlgPageSetup.m_rMargin.bottom, pt.y,2540)
- m_rectMargins.bottom;
// m_rectMargins now contains the values used to shrink the printable
// area of the page. Could check m_rectMargins here for negative values
// to prevent setting margins outside the printable area of the page.
// Convert to logical units and we're done!
pDC->DPtoLP(m_rectMargins);
}
- Call CalculateMargins() in CPadView::OnBeginPrinting() or another
appropriate place. If a mapping mode other than MM_TEXT were used,
it would be necessary to call CalculateMargins() after the mapping
mode is set (normally in OnPrepareDC).
void CPadView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
CEditView::OnBeginPrinting(pDC, pInfo);
CalculateMargins(pDC); // add this line
// etc.
}
- Finally, in CPadView::OnPrint(), add the following four lines to
shrink the printing rectangle according to the values calculated
previously. m_rectDraw is initialized to the entire printable area
(in logical units) for every page.
...
CRect rectPage = pInfo->m_rectDraw; // existing code in OnPrint
rectPage.left += m_rectMargins.left; // add these four lines
rectPage.top += m_rectMargins.top;
rectPage.right -= m_rectMargins.right;
rectPage.bottom -= m_rectMargins.bottom;
if (!strHeader.IsEmpty()) // existing code
...
SuperPad automatically adjusts its printed output to be contained in
the rectPage rectangle.
|