Link to home
Start Free TrialLog in
Avatar of nicolees
nicolees

asked on

Form base class which inherits from FormView does not call OnPreparePrinting

I have a base class which inherits from FormView.  I have implemented printing functions to print the current form, but it is not calling the OnPreparePrinting overloaded function I created.

What am I missing?
BOOL MyBaseFormView::OnPreparePrinting(CPrintInfo* pInfo)
{
	pInfo->SetMaxPage(1);

	// default preparation
	return DoPreparePrinting(pInfo);
}

void MyBaseFormView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void MyBaseFormView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

void MyBaseFormView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
	// TODO: add customized printing code here
		
	//Some code here.....
}


void MyBaseFormView::OnFilePrint() 
{
	// TODO: Add your command handler code here

	//Some code here

	CFormView::OnFilePrint( );	
}


void MyBaseFormView::OnPrepareDC(CDC* pDC, 
                      CPrintInfo* pInfo /* = NULL */)
{
    // 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 );
    }
}


//from the header file
// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CGSFormView)
	public:
	virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);

	protected:
	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);

Open in new window

Avatar of pgnatyuk
pgnatyuk
Flag of Israel image

MESSGE_MAP?
What you have BEGIN_MESSAGE_MAP and END_MESSAGE_MAP() in your implementation file?
Also it is a view, so check your frame class, probably there you can receive this message and handle it.

Here is a tutorial:
http://www.codersource.net/mfc/mfc-tutorials/mfc-print-tutorial.aspx
Have you this line in your view class?

ON_COMMAND(ID_FILE_PRINT, &CFormView::OnFilePrint)
Avatar of nicolees
nicolees

ASKER

This is what I have in my message map

      ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
but have tried this:

      ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
and this
      ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)

with the same result

alb66, when I try your version of the messagemap I get compile errors
"error C2059: syntax error : '&&'"
am I missing something?

Thank you for the tutorial link pgnatyuk, that is one of the documents I have reviewed (along with a couple others including MSDN help).  I believe I am following all of the recommendations in that article, but I am definitely missing something here.
May be you have an old Visual Stuido version; anyway your Message Map seems to be OK, symply you map your class method instead of the base class method.
I tried with VS2008 and it is working OK.
OnPreparePrinting() is called from CView::OnFilePrint.

Try to put a breakpoint in your MyBaseFormView::OnFilePrint() and step into CFormView::OnFilePrint() to see how it doesn't call OnPreparePrinting()
alba66, for this project I am unfortunately using an older VS (6.0).  I have stepped in, it goes into CView::OnFilePrint, but then it calls the default implementation of OnPreparePrinting instead of the one I have overloaded.

SOLUTION
Avatar of pgnatyuk
pgnatyuk
Flag of Israel image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
http://www.codersource.net/mfc/mfc-tutorials/mfc-print-tutorial.aspx
There is a sample project attached. Simply download it and debug.
pgnatyuk

Yes I have a PreTranslate, I left it out for brevity of code.  I will check the message handlers, but I don't think I am having a problem recieving the print message (I am calling it from a button on my toolbar).  My "OnFilePrint" code is being called, then it goes into the CView:OnFilePrint but when CView::OnFilePRint runs it does not call my overloaded OnPreparePrinting.

So something wrong here:
void MyBaseFormView::OnFilePrint()
{
        // TODO: Add your command handler code here
        //Some code here
        CFormView::OnFilePrint( );      
}

Please check the sample attached to that tutorial. It is very short. It will work for VS 6.
how OnPreparePrinting is declared in CView in VS6 ?
alba66:
See code below



pgnatyuk:
I changed my code to call CView::OnFilePrint instead of my overridden implementation of OnFilePrint.  That appears to be the only difference between the code in that sample and mine.  This did not make a difference.  It still went into the CView::OnFilePrint method but that method does not call my overriden implementation of OnPreparePrinting

I am wondering if the problem is how I am calling the print. I do not have it attached to a button on my form, I am actually calling it from my mainFrm by sending an ID_FILE_PRINT to the active view.  I am going to change this so that the button is directly calling my OnFilePrint to see if that helps.
//declaration
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

//Default implementation in CView
BOOL CView::OnPreparePrinting(CPrintInfo*)
{
	// Do print DC initialization here
	// override and call DoPreparePrinting (in viewprnt.cpp)

	return TRUE;
}

//implementation of OnFilePrint (my code gets into this but then calls the wrong implementation of OnPreparePrinting)
void CView::OnFilePrint()
{
	// get default print info
	CPrintInfo printInfo;
	ASSERT(printInfo.m_pPD != NULL);    // must be set

	if (LOWORD(GetCurrentMessage()->wParam) == ID_FILE_PRINT_DIRECT)
	{
		CCommandLineInfo* pCmdInfo = AfxGetApp()->m_pCmdInfo;

		if (pCmdInfo != NULL)
		{
			if (pCmdInfo->m_nShellCommand == CCommandLineInfo::FilePrintTo)
			{
				printInfo.m_pPD->m_pd.hDC = ::CreateDC(pCmdInfo->m_strDriverName,
					pCmdInfo->m_strPrinterName, pCmdInfo->m_strPortName, NULL);
				if (printInfo.m_pPD->m_pd.hDC == NULL)
				{
					AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
					return;
				}
			}
		}

		printInfo.m_bDirect = TRUE;
	}

	if (OnPreparePrinting(&printInfo))
	{
		// hDC must be set (did you remember to call DoPreparePrinting?)
		ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);

Open in new window

Okay the code works if I move OnPreparePrinting to the implementation of my baseclass.  Why do yuo think it will not work when the code is in the base class?


/////////////////////////////////////////////////////////////////////////////
// CMainForm

IMPLEMENT_DYNCREATE(CMainForm, MyBaseFormView)

CMainForm::CMainForm() : MyBaseFormView(CMainForm::IDD)
{
	//{{AFX_DATA_INIT(CMainForm)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CMainForm::~CMainForm()
{
}


BOOL CMainForm::OnPreparePrinting(CPrintInfo* pInfo)
{
	pInfo->SetMaxPage(1);

	pInfo->m_pPD->m_pd.Flags &= ~PD_NOSELECTION;
	pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();

	// default preparation
	return DoPreparePrinting(pInfo);
}

Open in new window

Compare how you declared this method in your view with the one you see in CView. Probably there is a mistake.
You debug this code and you see that you do no come to your function, right?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I do not understand what does it mean "my baseclass".
Now this code woks because it is in the right place. I told you that in my first comment here.
Here you said how these messages work:
IMPLEMENT_DYNCREATE(CMainForm, MyBaseFormView)
>>>> Why do yuo think it will not work when the code is in the base class?

If you want to call OnPreparePrinting in MyBaseFormView you must have no OnPreparePrinting in CMainForm (even if it is empty)
alba66,
I don't have any implementation of OnPreparePrinting in my CMainForm

pgnatyuk,
I have a base class called MyBaseFormView.  It inherits from CFormView.  I have about 600 classes (forms) that inherit from MyBaseFormView.  98% of my code resides in MyBaseFormView.  The 600 classes I have contain very little code (relative to the base class).  I would like to put OnPreparePrinting in the base class (instead of adding it to 600+ other modules).

Your example above, while helpful, does not provide details about how to implement the printing functionality in a base class, and as far as I can tell they do not explain why a function that I have decleared as protected in the base class is not being called by the CView::OnFilePrint.  The example only addresses using the printing functionality in a class that directly inherits from CFormView or CView.
I'm glad that we, maybe, gave you a direction or explained something.
I believe the problem, once I had all of the code correct, was that I was only building (not cleaning and rebuilding) the class that inherited from my base class.  Everything is working now.  Thanks for all of your help alba66 and pgnatyuk
You are welcome