Introduction
The Doc/View architecture in MFC is not the fastest way to create a simple print preview. This article will explain how to create your own print preview.
MFC Doc/View is designed to make the MSVC programmers get their work done in minutes, including print preview. Sometimes, we do not need to use Doc/View framework but we really do need its print-preview power.
The key to Print Preview is in the following functions:
CreateCompatibleBitmap
CreateCompatibleDC
GetDeviceCaps
GetTextExtent
Besides those four functions, Print Preview needs a function that will work for scaling and painting on the screen DC.
Luckily, we have StretchBlt
and BitBlt
ready to do the dirty work, but sometimes StretchBlt
might need to be replaced by your favourite routine (for dithering, filtering, antialiasing, etc.).
The function to perform print preview in a window is as follows:
void PrintPreview(CWnd *pWnd)
{
CString strWords;
CWnd* pWnd = GetDlgItem(IDC_STATIC_PREVIEW); CDC* dc;
CDC memoriDC;
CBitmap memBMP;
CBitmap* pOldBMP;
CFont fnt;
CFont* pOldFnt;
CRect rect;
CRect rectMemory;
CSize zMetrix;
CPrintDialog pdlg(FALSE);
DOCINFO di;
CDC prnDC;
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "This string will appear in Printer Queue";
di.lpszOutput = NULL;
di.lpszDatatype = NULL;
di.fwType = 0;
pdlg.GetDefaults();
dc = pWnd->GetDC();
pWnd->GetClientRect(&rect);
if( !prnDC.Attach(pdlg.GetPrinterDC()) )
AfxMessageBox("Invalid Printer DC");
memoriDC.CreateCompatibleDC(&prnDC);
int iPrnX = prnDC.GetDeviceCaps(HORZRES);
int iPrnY = prnDC.GetDeviceCaps(VERTRES);
int iMonX = dc->GetDeviceCaps(HORZRES); int iMonY = dc->GetDeviceCaps(VERTRES);
rectMemory.top = 0;
rectMemory.left = 0;
rectMemory.bottom = iPrnY;
rectMemory.right = iPrnX;
memBMP.CreateCompatibleBitmap(&prnDC, rectMemory.Width(), rectMemory.Height());
pOldBMP = memoriDC.SelectObject(&memBMP);
memoriDC.SetBkMode(TRANSPARENT);
memoriDC.SetTextColor(RGB(0, 0, 0));
memoriDC.PatBlt(0, 0, rectMemory.Width(), rectMemory.Height(), WHITENESS);
int iPointz = 100;
fnt.CreatePointFont(iPointz, "OCR A", &memoriDC);
strWords.Format("This is line number "); pOldFnt = memoriDC.SelectObject(&fnt);
zMetrix = memoriDC.GetTextExtent(strWords);
int iPos = 0;
int iMaksimal = 0;
int iLineHeight = 1;
int iLoop;
CString strPuncak;
for(iLoop = 1; iLoop < 100; iLoop++)
{
if( ((zMetrix.cy+iLineHeight)*iLoop) < iPrnY )
iMaksimal++;
}
strPuncak.Format("Maximum Amount of line(s) for %d points are %d lines",
iPointz, iMaksimal);
for(iLoop = 0; iLoop < iMaksimal; iLoop++)
{
strWords.Format("This is line %d", iLoop);
memoriDC.TextOut(0, iLoop*(zMetrix.cy+iLineHeight), strWords);
}
memoriDC.SelectObject(pOldFnt);
float fXRatio = (float) iMonX/iPrnX;
float fYRatio = (float) iMonY/iPrnY;
int iLebar = rect.Width()*fXRatio;
int iTinggi = rect.Height()*fYRatio;
int iXPosisiPreview = (rect.Width() - iLebar)/2;
int iYPosisiPreview = (rect.Height() - iTinggi)/2;
CPen pen(PS_SOLID, 2, RGB(255, 0, 0));
CPen* pOldPen;
pOldPen = dc->SelectObject(&pen);
dc->Rectangle(iXPosisiPreview, iYPosisiPreview,iXPosisiPreview + iLebar + 2,
iYPosisiPreview + iTinggi + 2);
dc->SelectObject(pOldPen);
dc->StretchBlt(iXPosisiPreview , iYPosisiPreview, iLebar, iTinggi,
&memoriDC, 0, 0, rectMemory.Width(), rectMemory.Height(), SRCCOPY);
fnt.DeleteObject();
memoriDC.SelectObject(pOldBMP);
memoriDC.DeleteDC();
memBMP.DeleteObject();
prnDC.Detach();
pWnd->ReleaseDC(dc);
}
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below. A list of licenses authors might use can be found here.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.