Click here to Skip to main content
6,630,586 members and growing! (17,688 online)
Email Password   helpLost your password?
Desktop Development » Printing » Print Preview     Intermediate

Very Simple Print Preview without the Doc/View architecture

By Danang Suharno

A very simple way of displaying a print preview in a simple window
VC6, MFC, Dev
Posted:8 Feb 2000
Updated:9 Aug 2001
Views:72,658
Bookmarked:24 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
18 votes for this article.
Popularity: 4.67 Rating: 3.72 out of 5

1

2

3
3 votes, 75.0%
4
1 vote, 25.0%
5

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

Beside those four functions Print Preview needs a function that 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.

// pWnd is the window you wish to show the preview

// Design and implementation cinoban@yahoo.com 13 Jan 2000 15:14

//	Danang Suharno

//	Ngadinegaran MJ 3/156

//	Yogyakarta 55143

//	Indonesia

//

void PrintPreview(CWnd *pWnd) 
{
	CString strWords;
	CWnd* pWnd = GetDlgItem(IDC_STATIC_PREVIEW); // This is a rectangle control

	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;

	//

	// Get current printer setting

	//

	pdlg.GetDefaults();

	
	//

	dc = pWnd->GetDC();
	pWnd->GetClientRect(&rect);

	// DC printer???

	if( !prnDC.Attach(pdlg.GetPrinterDC()) )
		AfxMessageBox("Invalid Printer DC");

	memoriDC.CreateCompatibleDC(&prnDC); // Create DC for Preview


	//

	// Get the resolution of Screen and Current Default Printer

	//

	int iPrnX = prnDC.GetDeviceCaps(HORZRES);
	int iPrnY = prnDC.GetDeviceCaps(VERTRES);
	int iMonX = dc->GetDeviceCaps(HORZRES); // Device Target is Monitor

	int iMonY = dc->GetDeviceCaps(VERTRES);


	rectMemory.top = 0;
	rectMemory.left = 0;
	rectMemory.bottom = iPrnY;
	rectMemory.right = iPrnX;

	//

	// Create a Memory Bitmap that is compatible with the Printer DC

	// then select or make the bitmap as current GDI active object

	//

	memBMP.CreateCompatibleBitmap(&prnDC, rectMemory.Width(), rectMemory.Height());
	pOldBMP = memoriDC.SelectObject(&memBMP);

	//

	// Clear memory DC or in other words

	// paint the bitmap with white colour and transparent text

	//

	memoriDC.SetBkMode(TRANSPARENT);
	memoriDC.SetTextColor(RGB(0, 0, 0));
	memoriDC.PatBlt(0, 0, rectMemory.Width(), rectMemory.Height(), WHITENESS);

	//

	// Prepare the font

	//

	int iPointz = 100;
	fnt.CreatePointFont(iPointz, "OCR A", &memoriDC);
	strWords.Format("This is line number    ");        // Test string

	pOldFnt = memoriDC.SelectObject(&fnt);
	zMetrix = memoriDC.GetTextExtent(strWords);
	int iPos = 0;

	//

	// Write string or Paint something

	//

	int iMaksimal = 0;
	int iLineHeight = 1;
	int iLoop;
	CString strPuncak;

	//

	// Calculate how many lines we could fit

	//

	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);
	}
	
	//

	// Reseting font

	//

	memoriDC.SelectObject(pOldFnt);

	//

	// Calculate ratio

	//

	float fXRatio = (float) iMonX/iPrnX;
	float fYRatio = (float) iMonY/iPrnY;
	
	
	//  iLebar = Width

	//  iTinggi = Height

	//  iXPosisiPreview = horisontal location of preview

	//  iYPosisiPreview = vertical location of preview

	//

	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;

	//

	// Create an outline

	//	

	pOldPen = dc->SelectObject(&pen);
	dc->Rectangle(iXPosisiPreview, iYPosisiPreview,iXPosisiPreview + iLebar + 2,
		iYPosisiPreview + iTinggi + 2);
	dc->SelectObject(pOldPen);

	//

	// Put in the box

	//

	dc->StretchBlt(iXPosisiPreview , iYPosisiPreview, iLebar, iTinggi,
		&memoriDC, 0, 0, rectMemory.Width(), rectMemory.Height(), SRCCOPY);
	
	//

	// Cleaning Up

	//

	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

About the Author

Danang Suharno


Member

Location: United States United States

Other popular Printing articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 11 of 11 (Total in Forum: 11) (Refresh)FirstPrevNext
Generaldoesn't work under Vista SP1 PinmemberBeiley10:44 10 May '08  
General[Message Removed] Pinmembernompel3:18 4 Oct '08  
GeneralRe: doesn't work under Vista SP1 PinmemberMember 193415020:16 13 May '09  
GeneralRe: doesn't work under Vista SP1 PinmemberBeiley7:07 14 May '09  
Generalreading data from file when list control is very first shown PinmemberWin32.sality23:43 10 Mar '08  
QuestionHow To Print listView items on A4 paper from VC++ Express Edition? Pinmemberchrisliando14:26 14 Nov '07  
QuestionGetting Data from IP Camera using VC++ PinmemberKirubanandam23:54 6 Jan '06  
Generalimprovement PinmemberFranz Brunner23:48 8 Jan '03  
GeneralGetDlgItem does take 1 argument, if ... PinsussArnt Witteveen23:12 13 Apr '00  
GeneralGetDlgItem does not take 1 argument PinsussArnt Witteveen6:07 12 Apr '00  
GeneralCWnd* pWnd defined twice PinsussChristian8:29 10 Feb '00  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 9 Aug 2001
Editor: Chris Maunder
Copyright 2000 by Danang Suharno
Everything else Copyright © CodeProject, 1999-2009
Web19 | Advertise on the Code Project