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?
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);
Have you this line in your view class?
ON_COMMAND(ID_FILE_PRINT, &CFormView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT, &CFormView::OnFilePrint)
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.
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::OnFilePrin t() and step into CFormView::OnFilePrint() to see how it doesn't call OnPreparePrinting()
I tried with VS2008 and it is working OK.
OnPreparePrinting() is called from CView::OnFilePrint.
Try to put a breakpoint in your MyBaseFormView::OnFilePrin
ASKER
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
http://www.codersource.net/mfc/mfc-tutorials/mfc-print-tutorial.aspx
There is a sample project attached. Simply download it and debug.
There is a sample project attached. Simply download it and debug.
ASKER
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.
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::OnFilePrin t()
{
// 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.
void MyBaseFormView::OnFilePrin
{
// 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 ?
ASKER
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.
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);
ASKER
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);
}
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?
You debug this code and you see that you do no come to your function, right?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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(CMainF orm, MyBaseFormView)
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(CMainF
>>>> 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)
If you want to call OnPreparePrinting in MyBaseFormView you must have no OnPreparePrinting in CMainForm (even if it is empty)
ASKER
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 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.
ASKER
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
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