?
Solved

Print Preview of a large sized CFormView

Posted on 2008-11-17
17
Medium Priority
?
1,495 Views
Last Modified: 2013-11-20
Hi!
I have a CFormView based application. The view size is pretty big and it goes beyong 1024x768 or to very high dimensions. We dynamically place the controls in this view and it includes static text, edit boxes and lines.
My requirement is to print and print preview the contents of the CFormView. For eg. if my CFormView is of size 2048, 768, then I should get the print preview as two pages. The first should have left 1024x768 first half od trhe view and the second page with the second half.
This should be the case, it should appear in the Print Preview window and the same way get printed also as two pages.
How do I proceed with this?
I haven't used Print functionalities in MFC at all?

Looking forward your kind inputs.

Thank you,
Babu
0
Comment
Question by:sayebabu
  • 9
  • 8
17 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 22980997
I'm sure you know that even 2048x768 is very small in terms of printer resolution.  A landscaped laser printer will typically have 6,600 horizontal pixels to work with -- so a single screen pixel scalled up to printer resolution will be a 3x3 dot in the printout -- usually easily readable.
To test this possibility, use Alt+PrintScreen and open PaintBrush and Ctrl+V paste the image.  In Page Setup, select Landscape and in Scaling, set "Fit to 1x1 page(s)"  I don't even need my reading glasses to read the printed page.
If you decide that you absolutely must output two printer pages for the formview, then you will need to use the basic technique described in these artivles:
Printing from CFormView
http://www.codeguru.com/cpp/w-p/printing/article.php/c2945
How to print CFormView
http://www.codeproject.com/KB/printing/printformview.aspx
which amounts to: Create a bitmap of the on-screen image and then do a bit of handling in OnBeginPrinting() and OnPrint().  The only thing that is not in these articles is a description of how to split the image and generate two pages.  Get the first steps working (print on one page) and post the code here.  I'll describe how to change it so that it prints two pages.
0
 

Author Comment

by:sayebabu
ID: 22982348
Hello!
Thank you for the inputs. I checked the links and seems to be useful. But my problem is I wanted to print the big dimension CFormView in different pages. My form size may even go upto 10000x10000, the requirement is like that.
I have attached the sample code (CFormView derived class), with which I was trying to do the same. Can you please see that and suggest what needs to be done to print all the contents of my form in multiple pages.
Thank you in great anticipation.
Best Regards!
Babu

// Try2View.h : interface of the CTry2View class
//
/////////////////////////////////////////////////////////////////////////////
 
#if !defined(AFX_TRY2VIEW_H__5877492E_9B79_45E4_892C_CD4CE434095F__INCLUDED_)
#define AFX_TRY2VIEW_H__5877492E_9B79_45E4_892C_CD4CE434095F__INCLUDED_
 
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
 
 
class CTry2View : public CFormView
{
protected: // create from serialization only
	CTry2View();
	DECLARE_DYNCREATE(CTry2View)
 
public:
	//{{AFX_DATA(CTry2View)
	enum{ IDD = IDD_TRY2_FORM };
		// NOTE: the ClassWizard will add data members here
	//}}AFX_DATA
 
// Attributes
public:
	CTry2Doc* GetDocument();
 
	CDC * m_pMemDC;  //A memory device context compatible with our printer DC.
	CRect m_rect;    //To hold the dimensions of our printing area while scaling.
	CBitmap * m_pBm; //Capture the screen image as a Bitmap
 
 
// Operations
public:
 
// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CTry2View)
	public:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	virtual void OnInitialUpdate(); // called first time after construct
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
	//}}AFX_VIRTUAL
 
// Implementation
public:
	virtual ~CTry2View();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
 
protected:
 
// Generated message map functions
protected:
	//{{AFX_MSG(CTry2View)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};
 
#ifndef _DEBUG  // debug version in Try2View.cpp
inline CTry2Doc* CTry2View::GetDocument()
   { return (CTry2Doc*)m_pDocument; }
#endif
 
/////////////////////////////////////////////////////////////////////////////
 
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
 
#endif // !defined(AFX_TRY2VIEW_H__5877492E_9B79_45E4_892C_CD4CE434095F__INCLUDED_)
 
 
 
 
// Try2View.cpp : implementation of the CTry2View class
//
 
#include "stdafx.h"
#include "Try2.h"
 
#include "Try2Doc.h"
#include "Try2View.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
/////////////////////////////////////////////////////////////////////////////
// CTry2View
 
IMPLEMENT_DYNCREATE(CTry2View, CFormView)
 
BEGIN_MESSAGE_MAP(CTry2View, CFormView)
	//{{AFX_MSG_MAP(CTry2View)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()
 
/////////////////////////////////////////////////////////////////////////////
// CTry2View construction/destruction
 
CTry2View::CTry2View()
	: CFormView(CTry2View::IDD)
{
	//{{AFX_DATA_INIT(CTry2View)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	
	m_pMemDC = new CDC ;
	m_pBm = new CBitmap;
}
 
CTry2View::~CTry2View()
{
	delete m_pMemDC; //CLEAN UP OUR VARIABLES
	delete	m_pBm;
}
 
void CTry2View::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTry2View)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}
 
BOOL CTry2View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
 
	return CFormView::PreCreateWindow(cs);
}
 
void CTry2View::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
 
}
 
/////////////////////////////////////////////////////////////////////////////
// CTry2View printing
 
BOOL CTry2View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}
 
void CTry2View::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	if (m_pMemDC->GetSafeHdc()) m_pMemDC->DeleteDC();
	m_pMemDC->CreateCompatibleDC(pDC);
 
	CClientDC dc(this);
	CRect rect;
	GetClientRect(rect);
	m_pMemDC->SetMapMode(MM_ANISOTROPIC);
	m_pMemDC->SetWindowExt(dc.GetDeviceCaps(LOGPIXELSX),dc.GetDeviceCaps(LOGPIXELSY));
	m_pMemDC->SetViewportExt(m_pMemDC->GetDeviceCaps(LOGPIXELSX),m_pMemDC->GetDeviceCaps(LOGPIXELSY));
 
	if (m_pBm->GetSafeHandle()) m_pBm->DeleteObject();
	m_pBm->CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
	m_pMemDC->SelectObject(m_pBm);
	dc.DPtoLP(rect); //Convert to Logical Coordinates
	m_rect = rect;   //Save Logical Coordinates
	m_pMemDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
 
}
 
void CTry2View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}
 
void CTry2View::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/)
{
	//The Following code scales the image based on printer resolution.
	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowExt(m_pMemDC->GetDeviceCaps(LOGPIXELSX),m_pMemDC->GetDeviceCaps(LOGPIXELSY));
	pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),pDC->GetDeviceCaps(LOGPIXELSY));
	pDC->StretchBlt(0,0,m_rect.Width(),m_rect.Height(),m_pMemDC,0,0,m_rect.Width(),m_rect.Height(),SRCCOPY);
}
 
/////////////////////////////////////////////////////////////////////////////
// CTry2View diagnostics
 
#ifdef _DEBUG
void CTry2View::AssertValid() const
{
	CFormView::AssertValid();
}
 
void CTry2View::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
 
CTry2Doc* CTry2View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTry2Doc)));
	return (CTry2Doc*)m_pDocument;
}
#endif //_DEBUG
 
/////////////////////////////////////////////////////////////////////////////
// CTry2View message handlers

Open in new window

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 22990136
Before we continue, I'd still like some clarification:
The above described technique takes a snapshot of the visible CFormView window and outputs to the printer.
Unless you have a 10,000 x 10,000 window, it will not work for you.
So, how are you currently displaying such a large window?  Please provide some background information that will help me to help you.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:sayebabu
ID: 22991375
Hi!
Thank you for your suggestions.
The window in created dynamically. Please see the attached code snippet. In this case I am creating a MainFrame of size 1700 x 1700 and in the MainFrame's OnSize I'll set the same size for the view also.
Thank you,
Babu

We have a SDI application. When a toolbar button is clicked it displays another Mainframe with a CFormView attached to that mainframe.
 
Here is the code in which we create a MainFrame on click of a toolbar button.
 
if(m_frame == NULL)
	{
		CRuntimeClass *pClass = RUNTIME_CLASS(CBlockDiagFrame);		
		m_frame = (CBlockDiagFrame*)pClass->CreateObject();
		
		ASSERT(m_frame);
		
		if(!m_frame->Create(NULL, L"Block Diagram", WS_OVERLAPPEDWINDOW  , 
					 CRect(0, 0, 1700, 1700), this, NULL, 0, NULL ))
		{
			AfxMessageBox(L"Frame Window not created");
			return ;
		}
		
		m_frame->ModifyStyle(NULL, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
		m_frame->ShowWindow(SW_SHOW);
	}
	else
	{
		m_frame->ShowWindow(SW_RESTORE);	
	}
 
 
 
 
 
 
 
 
And in the created Mainframe's OncreateClient handler, I am creating the view as follows.
 
BOOL CBlockDiagFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	
	if(pFrame != NULL && IsWindow(pFrame->m_hWnd))
	{
		CCreateContext context;		
		context.m_pNewViewClass = RUNTIME_CLASS(CBlock_DiagramView);
		context.m_pCurrentFrame = this;		
		context.m_pCurrentDoc = pFrame->GetActiveDocument();
		context.m_pLastView = NULL;
 
		m_view = (CBlock_DiagramView*)CreateView(&context);	
 
		if(!m_view)
		{
			TRACE("Failed to create View in CPopupFrame::OnCreateClient\n");
			return FALSE;
		}
 
		SetActiveView(m_view);
		m_view->ShowWindow(SW_SHOW);
 
	}
 
	return TRUE;
}

Open in new window

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 23009598
Again, I'm confused.  Do you have a form that extends some considerable distance below the bottom of the screen?  If so, how can anyone enter data into the input fields?
0
 

Author Comment

by:sayebabu
ID: 23010302
Hi!
Yes, we can have such way. This is derived from CScrollView, so the the scrolling enables to use the controls beyond the screen limit.
For eg. even in design time I can create a form with 1700 x 1700 and then the scroll bar appears by default, with which I can use the controls beyond the screen height/width.
Thank you,
Babu
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 23010442
OK, then we have a problem.  Most of the examples that I could find print the visible window -- not the portion of the form that is off screen.
I think that the second method in http://www.codeproject.com/KB/printing/printformview.aspx could be coerced into creating a bitmap of the entire form, but it would depend on the controls that are in the form -- some controls do not honor the WM_PRINT message.
What sorts of controls are in the form?  Are any of the controls ActiveX controls?
0
 

Author Comment

by:sayebabu
ID: 23010496
Hi!
Thank you for the swift response.
These are simple controls. Only Edit Boxes and Static Texts along with some Lines drawn using CDCs MoveTo/LineTo.
Yes, I did went through the Codeguru example that you referred. But that too didn't help.
Please let me know, your suggestion.
Thank you,
Babu
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 23011257
Here's the first step:
Download the projects from http://www.codeproject.com/KB/printing/printformview.aspx
Unzip the FormViewPrint2 folder and load the project into Visual Stuido.  Build it and run it.
We'll work with Print Preview for now and the project will print just the visible portion of the form.  
TRY IT.  Modify the form so that it is very long and has some static controls, etc near the bottom and the right sides.  Use File/Print Preview to see that it is showing only the visible portion of the form.
Now make the changes in the code snippet below.
You should be able to see the entire form in the print preview window, regadless of the size of the on-screen window or the scroll position.
When you get that done, let me know and we can work on the next part.

in
  CFormViewPrint2View::OnPrint
make this change:
 
  ::StretchDIBits( pDC->GetSafeHdc( ),
    pInfo->m_rectDraw.left,   // destination rect
    pInfo->m_rectDraw.top,
    //pBMI->biWidth,  // changed
    //pBMI->biHeight,
    pInfo->m_rectDraw.right,  // the screen rect for preview output
    pInfo->m_rectDraw.bottom,
    0, 
    0, 
    pBMI->biWidth,   // source is bmp saved in OnFilePrintPreview()
    pBMI->biHeight,
    (LPBYTE)pBMI + (pBMI->biSize + nColors * sizeof(RGBQUAD)),
    (BITMAPINFO*)pBMI,
    DIB_RGB_COLORS, 
    SRCCOPY);
 
Next, change the OnFilePrintPreview fn to this:
void CFormViewPrint2View::OnFilePrintPreview() 
{
     CRect rect;
     CDC memDC; 
     CClientDC dc( this );
     memDC.CreateCompatibleDC( &dc ); 
     //---------- changed so we get snapshot pf entire form
     // this->GetClientRect( rect );  // we dont want the client rect
     CSize cSz= GetTotalSize(); // in logical units.
     rect.SetRect(0,0,cSz.cx,cSz.cy );    // rect is now the entire form 
     CBitmap bitmap;
     bitmap.CreateCompatibleBitmap( &dc, rect.Width(), rect.Height() );
     {
      LocalGDI local( &memDC, &bitmap );
      //  this->Print( &memDC, PRF_ERASEBKGND|PRF_CLIENT|PRF_CHILDREN );
      CBrush brshWhite;   //----------------- added from here
      brshWhite.CreateSolidBrush(RGB(255,255,255));
      memDC.FillRect(rect, &brshWhite );      // else the bkgd is black
      Print( &memDC, PRF_CLIENT|PRF_CHILDREN ); // does WM_PRINT to all ctrls
     }
     m_dib.Attach( GDIUtil::DDBToDIB( bitmap ) ); 
     CFormView::OnFilePrintPreview( );
}

Open in new window

0
 

Author Comment

by:sayebabu
ID: 23011396
Hi!
Many Thanks for the suggestion.
Yes, it is coming as a full (single) page in the Print Preview window. And while printing it is clipping the non-visble areas.
Can it be displayed as pages. Something like how MS Paint program works. If I have a big sized bitmap also the print preview comes in pages taking the full images into small pieces.
Please provide me more details. Thank you once again for your time and effort.
Best Regards!
Babu
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 23011751
The next step is to divide the bitmap into pieces and print them one at a time.  I'll show you how to divide it into four, and you can do the rest. OK?
0
 

Author Comment

by:sayebabu
ID: 23011785
Yes, please. That would be great.
Thanking you in anticipation.
Best Regards!
Babu
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 23020178
OK, add this FormViewPrint2View.h as a member of the virw class:
CRect m_arPgRects[4]; // four pages, so four rectangles
In OnPreparePrinting, we'll prepare four rectangles, one for each quadrant of the full bitmap (that we prepared in the earlier step). Then with each pass through OnPrint, we'll copy one of those rectangles into the printer DC (or preview DC, whichever we're working with).
Finally to make the hardcopy printout work like the PrintPreview, just modify OnFilePrint(), making the same changes we made to OnFilePrintPreview() in the earlier step.

BOOL CFormViewPrint2View::OnPreparePrinting(CPrintInfo* pInfo)
{
	//--------------------- changes for four-page handling
	// pInfo->SetMaxPage(1); 
	pInfo->SetMaxPage(4);  // NOTE: four pages
 
	CSize cSz= GetTotalSize(); // in logical units.
	CRect rect(0,0, cSz.cx,cSz.cy );  // left, top, right, bottom
 
	int nWide=     cSz.cx;
	int nHigh=     cSz.cy;
	int nHalfWide= (cSz.cx+1)/2;
	int nHalfHigh= (cSz.cy+1)/2;
 
	// note: The programmer of the example is using DIBs 
	// which are organized bottom-to-top (nHigh is the top, 0 at bottom), 
	//
	m_arPgRects[0].SetRect(0,         nHalfHigh, nHalfWide, nHigh );     // DIB: upper left quadrant
	m_arPgRects[1].SetRect(nHalfWide, nHalfHigh, nWide,     nHigh );     // DIB: upper right quadrant
	m_arPgRects[2].SetRect(0,         0,         nHalfWide, nHalfHigh ); // DIB: lower left quadrant
	m_arPgRects[3].SetRect(nHalfWide, 0,         nWide,     nHalfHigh ); // DIB: lower right quadrant lower right
 
 
	//------------------------------------------------- end of changes 
	pInfo->m_pPD->m_pd.Flags &= ~PD_NOSELECTION;
	pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
 
	// default preparation
	return DoPreparePrinting(pInfo);
}
============= make this change to the OnPrint fn =============
 
		int nPgIdx= pInfo->m_nCurPage -1;
 
		::StretchDIBits( pDC->GetSafeHdc( ),
			pInfo->m_rectDraw.left,   // destination rect
			pInfo->m_rectDraw.top,
			pInfo->m_rectDraw.right,  // the screen rect for preview output
			pInfo->m_rectDraw.bottom,
			m_arPgRects[nPgIdx].left, // the quadrant for this pg
			m_arPgRects[nPgIdx].top,
			m_arPgRects[nPgIdx].Width(),
			m_arPgRects[nPgIdx].Height(),
 
			(LPBYTE)pBMI + (pBMI->biSize + nColors * sizeof(RGBQUAD)),
			(BITMAPINFO*)pBMI,
			DIB_RGB_COLORS, 
			SRCCOPY);

Open in new window

0
 

Author Comment

by:sayebabu
ID: 23040872
Many Thank you for your support. I was out-of-station, so couldn't try this approach. Shall try this now and get back to you.
Thank you once again.
Best Regards!
Babu
0
 

Author Comment

by:sayebabu
ID: 23066440
Many Thanks for the efforts.
The print preview partially works fine. But with one problem. If I have a drawn object like line rect in OnDraw, the same doesn't come in the print preview. Any suggestions?
Thank you.
I have attached the code snippet.
 

// FormViewPrint2View.cpp : implementation of the CFormViewPrint2View class
//
 
#include "stdafx.h"
#include "FormViewPrint2.h"
 
#include "FormViewPrint2Doc.h"
#include "FormViewPrint2View.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
/////////////////////////////////////////////////////////////////////////////
// CFormViewPrint2View
 
IMPLEMENT_DYNCREATE(CFormViewPrint2View, CFormView)
 
BEGIN_MESSAGE_MAP(CFormViewPrint2View, CFormView)
//{{AFX_MSG_MAP(CFormViewPrint2View)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT_DIRECT, OnFilePrint)
END_MESSAGE_MAP()
 
/////////////////////////////////////////////////////////////////////////////
// CFormViewPrint2View construction/destruction
 
CFormViewPrint2View::CFormViewPrint2View()
: CFormView(CFormViewPrint2View::IDD)
{
	//{{AFX_DATA_INIT(CFormViewPrint2View)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// TODO: add construction code here
	m_nNoOfPages = 0;	
}
 
CFormViewPrint2View::~CFormViewPrint2View()
{
}
 
void CFormViewPrint2View::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFormViewPrint2View)
	// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}
 
BOOL CFormViewPrint2View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	
	return CFormView::PreCreateWindow(cs);
}
 
void CFormViewPrint2View::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
}
 
/////////////////////////////////////////////////////////////////////////////
// CFormViewPrint2View printing
 
BOOL CFormViewPrint2View::OnPreparePrinting(CPrintInfo* pInfo)
{
	CSize cSz= GetTotalSize(); // in logical units.
	CRect rect(0,0, cSz.cx,cSz.cy );  // left, top, right, bottom
 
	m_CArrPgRects.RemoveAll();		// Flush the previous contents.
	m_nNoOfPages = 0;				// Initialize the number of pages to zero
	GetPages( cSz );				// Invoke to determine the number of pages and fill the array
 
	pInfo->SetMaxPage(m_nNoOfPages);// The number of pages as computed.
 
 	//------------------------------------------------- end of changes 
	pInfo->m_pPD->m_pd.Flags &= ~PD_NOSELECTION;
	pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
 
	// default preparation
	return DoPreparePrinting(pInfo);
}
 
void CFormViewPrint2View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}
 
void CFormViewPrint2View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}
 
void CFormViewPrint2View::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
	if( pInfo == NULL )
		return;
 
	if( m_dib.GetHandle( ) == NULL )
		return;
	{
		GLock lock( m_dib );
		BITMAPINFOHEADER *pBMI = (BITMAPINFOHEADER*)(LPVOID)lock;
		
		int nColors = 0;
		if( pBMI->biBitCount <= 8 )
			nColors = ( 1<< pBMI->biBitCount );
		 
		int nPgIdx= pInfo->m_nCurPage - 1;
 
		::StretchDIBits( pDC->GetSafeHdc( ),
			pInfo->m_rectDraw.left,   // destination rect
			pInfo->m_rectDraw.top,
			pInfo->m_rectDraw.right,  // the screen rect for preview output
			pInfo->m_rectDraw.bottom,
			m_CArrPgRectsRes[nPgIdx].left, // the quadrant for this pg
			m_CArrPgRectsRes[nPgIdx].top,
			m_CArrPgRectsRes[nPgIdx].Width(),
			m_CArrPgRectsRes[nPgIdx].Height(),
 
			(LPBYTE)pBMI + (pBMI->biSize + nColors * sizeof(RGBQUAD)),
			(BITMAPINFO*)pBMI,
			DIB_RGB_COLORS, 
			SRCCOPY);
	}
}
 
/////////////////////////////////////////////////////////////////////////////
// CFormViewPrint2View diagnostics
 
#ifdef _DEBUG
void CFormViewPrint2View::AssertValid() const
{
	CFormView::AssertValid();
}
 
void CFormViewPrint2View::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
 
CFormViewPrint2Doc* CFormViewPrint2View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFormViewPrint2Doc)));
	return (CFormViewPrint2Doc*)m_pDocument;
}
#endif //_DEBUG
 
/////////////////////////////////////////////////////////////////////////////
// CFormViewPrint2View message handlers
 
void CFormViewPrint2View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	// TODO: Add your specialized code here and/or call the base class
	if( pInfo )
	{
		CClientDC dc( this );
		pDC->SetMapMode(MM_ANISOTROPIC);
		
		CSize sz( dc.GetDeviceCaps(LOGPIXELSX), dc.GetDeviceCaps(LOGPIXELSY) );
		pDC->SetWindowExt( sz );
		sz = CSize( pDC->GetDeviceCaps(LOGPIXELSX),pDC->GetDeviceCaps(LOGPIXELSY) );
		pDC->SetViewportExt( sz );
	}
}
 
void CFormViewPrint2View::OnFilePrintPreview() 
{
	CRect rect;
	CDC memDC; 
	CClientDC dc( this );
	memDC.CreateCompatibleDC( &dc ); 
	//---------- changed so we get snapshot pf entire form
	// this->GetClientRect( rect );  // we dont want the client rect
	CSize cSz= GetTotalSize(); // in logical units.
	rect.SetRect(0,0,cSz.cx,cSz.cy );    // rect is now the entire form 
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap( &dc, rect.Width(), rect.Height() );
	{
		LocalGDI local( &memDC, &bitmap );
		//  this->Print( &memDC, PRF_ERASEBKGND|PRF_CLIENT|PRF_CHILDREN );
		CBrush brshWhite;   //----------------- added from here
		//brshWhite.CreateSolidBrush(RGB(255,255,255));//BBB
		brshWhite.CreateSolidBrush(RGB(236,233,213));
		memDC.FillRect(rect, &brshWhite );      // else the bkgd is black
		Print( &memDC, PRF_CLIENT|PRF_CHILDREN ); // does WM_PRINT to all ctrls
	}
	m_dib.Attach( GDIUtil::DDBToDIB( bitmap ) );
	CFormView::OnFilePrintPreview();
 
 
}
 
void CFormViewPrint2View::OnFilePrint()
{
	CRect rect;
	this->GetClientRect( rect );
	CDC memDC;
	
	CClientDC dc( this );
	memDC.CreateCompatibleDC( &dc );
	
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap( &dc, rect.Width(), rect.Height() );
	{
		LocalGDI local( &memDC, &bitmap );
		this->Print( &memDC, PRF_ERASEBKGND|PRF_CLIENT|PRF_CHILDREN );
	}
	m_dib.Attach( GDIUtil::DDBToDIB( bitmap ) );
	
	CFormView::OnFilePrint( );	
}
 
// This method determines the number of divisions that can be made to the form
// horizontally and vertically. It takes the value defined in nPAGE_FOR_SPLIT_H and
// nPAGE_FOR_SPLIT_V
void CFormViewPrint2View::GetPages( CSize CSz_Frm )
{
	int nPgCntInterH = ( CSz_Frm.cx % nPAGE_FOR_SPLIT_H );
									// Get the modulus remainder of page count in the Horizontal direction
	int nPgCntH = ( CSz_Frm.cx / nPAGE_FOR_SPLIT_H );
									// Get the page count in the Horizontal direction						
	nPgCntH = ( nPgCntInterH <= nPAGE_NEGLIG_H ) ? ( nPgCntH ) : ( nPgCntH + 1 );
									// If remainder is more than the negligible size identify as a seperate page
									// and add 1 to the page count.
 
	int nPgCntInterV = ( CSz_Frm.cy % nPAGE_FOR_SPLIT_V );
									// Get the modulus remainder of page count in the Horizontal direction
	int nPgCntV = ( CSz_Frm.cy / nPAGE_FOR_SPLIT_V );
									// Get the page count in the Horizontal direction						
	nPgCntV = ( nPgCntInterV <= nPAGE_NEGLIG_V ) ? ( nPgCntV ) : ( nPgCntV + 1 );
									// If remainder is more than the negligible size identify as a seperate page
									// and add 1 to the page count.
 
	m_nNoOfPages = ( nPgCntH * nPgCntV );
									// The number of pages will be the number
 
	INT nPtX = ( -nPAGE_FOR_SPLIT_H ), nPtY = ( -nPAGE_FOR_SPLIT_V );
									// The coordinates set to -split size to just enable the 
									// += in side the for loop. So that initially zero will be assumed.
	
	INT nL = 0, nT = 0, nR = 0, nB = 0;
 
	CRect CRect_Temp;
	for( INT nLoopV = 0; nLoopV < nPgCntV; nLoopV++ )
	{								// For the number of pages in vertical direction
		nPtY += nPAGE_FOR_SPLIT_V;	// Add by the page vertical split width
		nT = nPtY;					// Top value assigned for the rect
		nB = nT + nPAGE_FOR_SPLIT_V;// Bottom value assigned for the rect
		for( INT nLoopH = 0; nLoopH < nPgCntH; nLoopH++ )
		{							// For the number of pages in horizontal direction
			nPtX += nPAGE_FOR_SPLIT_H;
									// Add by the page vertical split width
			nL = nPtX;				// Left value assigned for the rect
			nR = nL + nPAGE_FOR_SPLIT_H;
									// Right value assigned for the rect
			
			if( nR > CSz_Frm.cx )	// If it is beyong the actual screen size in horizontal direction
			{
				nR = CSz_Frm.cx;	// Assign the screen right to the computed right
			}
			
			if( nB > CSz_Frm.cy )	// If it is beyong the actual screen size in vertical direction
			{
				nB = CSz_Frm.cy;	// Assign the screen bottom to the computed bottom
			}
 
			CRect_Temp.left = nL;	 
			CRect_Temp.top = nT;
			CRect_Temp.right = nR;
			CRect_Temp.bottom = nB;	// Assign it to the temporary CRect structure
 
			m_CArrPgRects.Add( CRect_Temp );
									// Add the point structure to the array
		}
		nPtX = ( -nPAGE_FOR_SPLIT_H );
									// Reset back the horizontal coordinate
	}
 
	CRect CRect_T;
	// This code fragment is to swap the lower row as first row and so on.								
	for( INT nLoopProcV = nPgCntV - 1; nLoopProcV >= 0; nLoopProcV -- )
	{								// For the number of vertical pages
		for( INT nLoopProcH = 0; nLoopProcH < nPgCntH; nLoopProcH ++ )
		{							// For the number of horizontal pages
			CRect_T = m_CArrPgRects[ ( ( nLoopProcV * nPgCntH ) + nLoopProcH ) ];
									// Get the rect.
			m_CArrPgRectsRes.Add( CRect_T );
									// Add it to the resultant rect array for print/preview
		}
	}
}
 
 
 
void CFormViewPrint2View::OnDraw(CDC* pDC) 
{
	pDC->MoveTo( 10, 10 );
	pDC->LineTo( 200, 200 );
}

Open in new window

0
 
LVL 49

Accepted Solution

by:
DanRollins earned 1000 total points
ID: 23067297
First, don't do that.  Use the controls that are available in a form.
My guess is that the WM_PRINT handler for CFormView is set to draw the dialog in a default way that does not end up calling you OnDraw function.
If you want such ad-hoc image manipulations to be seen in the printout, then add a call to your OnDraw function before you capture the bitmap image (in OnPrint or elsewhere).
Anyway, this is a separate issue.  What say we close this up and start a new question?
0
 

Author Closing Comment

by:sayebabu
ID: 31517379
Thank you for your support.
And please guide me on how to get the drawn items (line, rect) in the print.

0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question