YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


VC++ MFC example: Micrsoft Visio 12 like Print Preview Source Code

 
 

Introduction

A print preview window that showing the printer's paper margins is a very good idea, for most flow diagramming or printing applications (such as Micrsoft Visio 2007, GADWin, E-XD++ Flow Diagramming Kit, etc.), they all have this feature, below is a screen shot of the latest edition of Micrsoft Visio 2007:

There is no topic with this on codeguru or codeproject, so I created it by myself, below is how it works:

1. At first, We need to create a new class that use CPreviewView as base class, please remember to include afxpriv.h.

2. Override the OnDraw method of CPreviewView, and change it's code to below:

void CExtPreviewView::OnDraw(CDC* pDC)
{
ASSERT_VALID(pDC);

// don't do anything if not fully initialized
if (m_pPrintView == NULL || m_dcPrint.m_hDC == NULL)
return;

CPoint ViewportOrg = pDC->GetViewportOrg();

CPen rectPen;
rectPen.CreatePen(PS_SOLID, 2, GetSysColor(COLOR_WINDOWFRAME));
CPen shadowPen;
shadowPen.CreatePen(PS_SOLID, 3, GetSysColor(COLOR_BTNSHADOW));

m_pPreviewInfo->m_bContinuePrinting = TRUE; // do this once each paint

for (UINT nPage = 0; nPage < m_nPages; nPage++)
{
int nSavedState = m_dcPrint.SaveDC(); // Save pristine state of DC

// Use paint DC for print preview output
m_pPreviewDC->SetOutputDC(pDC->GetSafeHdc());

m_pPreviewInfo->m_nCurPage = m_nCurrentPage + nPage;

// Only call PrepareDC if within page range, otherwise use default
// rect to draw page rectangle
if (m_nCurrentPage + nPage <= m_pPreviewInfo->GetMaxPage())
m_pPrintView->OnPrepareDC(m_pPreviewDC, m_pPreviewInfo);

// Set up drawing rect to entire page (in logical coordinates)
m_pPreviewInfo->m_rectDraw.SetRect(0, 0,
m_pPreviewDC->GetDeviceCaps(HORZRES),
m_pPreviewDC->GetDeviceCaps(VERTRES));
m_pPreviewDC->DPtoLP(&m_pPreviewInfo->m_rectDraw);

// Draw empty page on screen

pDC->SaveDC(); // save the output dc state

CSize* pRatio = &m_pPageInfo[nPage].sizeScaleRatio;
CRect* pRect = &m_pPageInfo[nPage].rectScreen;

if (pRatio->cx == 0)
{ // page position has not been determined
PositionPage(nPage); // compute page position
if (m_nZoomState != ZOOM_OUT)
ViewportOrg = -GetDeviceScrollPosition();
}

pDC->SetMapMode(MM_TEXT); // Page Rectangle is in screen device coords
pDC->SetViewportOrg(ViewportOrg);
pDC->SetWindowOrg(0, 0);

pDC->SelectStockObject(HOLLOW_BRUSH);
pDC->SelectObject(&rectPen);
pDC->Rectangle(pRect);

pDC->SelectObject(&shadowPen);

pDC->MoveTo(pRect->right + 1, pRect->top + 3);
pDC->LineTo(pRect->right + 1, pRect->bottom + 1);
pDC->MoveTo(pRect->left + 3, pRect->bottom + 1);
pDC->LineTo(pRect->right + 1, pRect->bottom + 1);

// erase background to white (most paper is white)
CRect rectFill = *pRect;
rectFill.left += 1;
rectFill.top += 1;
rectFill.right -= 2;
rectFill.bottom -= 2;

CBrush brush(RGB(240,240,240));
::FillRect(pDC->m_hDC, rectFill, (HBRUSH)brush);
brush.DeleteObject();

pDC->RestoreDC(-1); // restore to synchronized state

if (!m_pPreviewInfo->m_bContinuePrinting ||
m_nCurrentPage + nPage > m_pPreviewInfo->GetMaxPage())
{
m_pPreviewDC->ReleaseOutputDC();
m_dcPrint.RestoreDC(nSavedState); // restore to untouched state

// if the first page is not displayable, back up one page
// but never go below 1
if (nPage == 0 && m_nCurrentPage > 1)
SetCurrentPage(m_nCurrentPage - 1, TRUE);
break;
}

// Display page number
OnDisplayPageNumber(m_nCurrentPage, nPage + 1);

// Set scale ratio for this page
m_pPreviewDC->SetScaleRatio(pRatio->cx, pRatio->cy);

CSize PrintOffset;
VERIFY(m_pPreviewDC->Escape(GETPRINTINGOFFSET, 0, NULL, (LPVOID)&PrintOffset));
m_pPreviewDC->PrinterDPtoScreenDP((LPPOINT)&PrintOffset);
PrintOffset += (CSize)pRect->TopLeft();
PrintOffset += CSize(1, 1);
PrintOffset += (CSize)ViewportOrg; // For Scrolling

m_pPreviewDC->SetTopLeftOffset(PrintOffset);

m_pPreviewDC->ClipToPage();

CTestPreviewView *pView = static_cast<CTestPreviewView *>(m_pPrintView);
pView->OnPrint(m_pPreviewDC, m_pPreviewInfo);

m_pPreviewDC->ReleaseOutputDC();

m_dcPrint.RestoreDC(nSavedState); // restore to untouched state

}

rectPen.DeleteObject();
shadowPen.DeleteObject();
}

3. Add a new global method at the head of class CExtPreviewView, as below:

// Print preview.
void AFX_API FOPrintPreview(CTestPreviewView* pView);

and

void FOPrintPreview (CTestPreviewView* pView)
{
ASSERT_VALID (pView);

CPrintPreviewState *pState= new CPrintPreviewState;
#if (_MFC_VER < 0x0700) // Visual Studio 6.0
if (!pView->DoPrintPreview (IDD_FO_PREVIEW_TOOLBAR, pView, 
RUNTIME_CLASS(CExtPreviewView), pState))
{
TRACE0("Error: OnFilePrintPreview failed.\n");
AfxMessageBox (AFX_IDP_COMMAND_FAILURE);
delete pState; // preview failed to initialize, delete State now
}
#else
if (!pView->DoPrintPreview (IDD_FO_PREVIEW_TOOLBAR, pView, 
RUNTIME_CLASS(CExtPreviewView), pState))
{
TRACE0("Error: OnFilePrintPreview failed.\n");
AfxMessageBox (AFX_IDP_COMMAND_FAILURE);
delete pState; // preview failed to initialize, delete State now
}
#endif
}

If you want to change the color of paper margins, you need change the following codes:

CBrush brush(RGB(240,240,240));
::FillRect(pDC->m_hDC, rectFill, (HBRUSH)brush);
brush.DeleteObject();

4. Add a method for menu item ID_FILE_PRINT_PREVIEW, and then change it's codes to:

void CTestPreviewView::OnFilePrintPreview() 
{
// TODO: Add your command handler code here
FOPrintPreview(this);
}

That's all, I created a test program on testing this feature, below is a screen shot of how it looks like:

and

For testing, choose "File | Print Preview" menu item, these codes are full tested on Visual C++ 6.0, Visual C++.NET 2003, and Visual C++.NET 2005, it should also works with MDI, SDI applications. 

 

Copyright ?1998-2009 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net