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

nicoleesAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

pgnatyukCommented:
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
0
alb66Commented:
Have you this line in your view class?

ON_COMMAND(ID_FILE_PRINT, &CFormView::OnFilePrint)
0
nicoleesAuthor Commented:
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.
0
CompTIA Network+

Prepare for the CompTIA Network+ exam by learning how to troubleshoot, configure, and manage both wired and wireless networks.

alb66Commented:
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()
0
nicoleesAuthor Commented:
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.

0
pgnatyukCommented:
Are you sure that another window (an owner of the current view, etc.) does not receive this print message? How you send this message? probably you added it into a popup menu. Can you check that you send correct command with the correct ID?
Can you make a general WM_COMMAND message handler and check the messages you receive there?
http://msdn.microsoft.com/en-us/library/3t3ddsb9(VS.80).aspx

You don't have any PreTranslate function?
0
pgnatyukCommented:
http://www.codersource.net/mfc/mfc-tutorials/mfc-print-tutorial.aspx
There is a sample project attached. Simply download it and debug.
0
nicoleesAuthor Commented:
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.

0
pgnatyukCommented:
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.
0
alb66Commented:
how OnPreparePrinting is declared in CView in VS6 ?
0
nicoleesAuthor Commented:
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

0
nicoleesAuthor Commented:
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

0
pgnatyukCommented:
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?
0
alb66Commented:
mmmmh... very strange behavior
it seems to me all ok



//declaration
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

Is this the declaration in your class or in CView class ?
May be that in CView it is not declared as virtual?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
pgnatyukCommented:
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)
0
alb66Commented:
>>>> 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)
0
nicoleesAuthor Commented:
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.
0
pgnatyukCommented:
I'm glad that we, maybe, gave you a direction or explained something.
0
nicoleesAuthor Commented:
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
0
pgnatyukCommented:
You are welcome
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.