Print Preview in MDI Frame
Between Visual C++ 4.2 and 5.0 the behavior of displaying the print preview in MDI applications has changed. This issue is covered by MSDN Article ID: Q166135
In 5.0 the preview is not longer displayed in the MDI-Frame, it's in the MDI-Child. This results in a small preview area which is even smaller, if there are docking toolbars, and the user interface is fully functioning during preview. I think that this is unusable for many applications.
The reason is the following determination of the parent frame:
// VC 4.2
BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
...
CFrameWnd* pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
ASSERT_VALID(pParent);
ASSERT_KINDOF(CFrameWnd, pParent);
...
}
// VC 5.0
BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
...
CFrameWnd* pParent;
CWnd* pNaturalParent = pPrintView->GetParentFrame();
pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
if (pParent == NULL || pParent->IsIconic())
pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
...
}
To get back the old behavior the following this must be done:
1. Write your own DoPrintPreview() in your MDI View class
This function is mostly a copy of CView::DoPrintPreview() with 2 changes.
BOOL CMDIView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
...
// 1.) Use the MDI Frame as the parent
CFrameWnd* pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
ASSERT_VALID(pParent);
ASSERT_KINDOF(CFrameWnd, pParent);
...
...
// 2.) Deactivate the MDIChild and display the desired menu
CChildFrame *pChildFrame = DYNAMIC_DOWNCAST (CChildFrame, pParent->GetActiveFrame());
if (pChildFrame)
{
// Save the original shared menu
HMENU hMenuShared = pChildFrame->GetSharedMenu ();
// Set the displayed menu during preview to NULL or to the desired menu
pChildFrame->SetSharedMenu (NULL);
// Deactivate the MDIChild
pChildFrame->SendMessage (WM_MDIACTIVATE, 0, 0);
// Restore the shared menu
pChildFrame->SetSharedMenu (hMenuShared);
}
...
}
2. Make a derivation of CPreviewView
In CView::DoPrintPreview(), lots of protected members from CPreviewView are used. This isn't longer possible in your own DoPrintPreview().
The solution is to declare the CMDIView as a friend of CMyPreviewView.
class CMyPreviewView : public CPreviewView
{
protected:
CMyPreviewView();
DECLARE_DYNCREATE(CMyPreviewView)
...
friend class CMDIView;
};
3. Write menu access function in the MDI Child Frame
class CChildFrame : public CMDIChildWnd
{
DECLARE_DYNCREATE(CChildFrame)
public:
CChildFrame();
// Operations
public:
HMENU GetSharedMenu () const { return m_hMenuShared; }
void SetSharedMenu (HMENU hMenuShared) { m_hMenuShared = hMenuShared; }
...
};

Comments
probably user can try the [zoom in] button?
Posted by Legacy on 02/03/1999 12:00amOriginally posted by: levin
probably user can try the [zoom in] button?
Reply
MFC behaviour changements
Posted by Legacy on 01/20/1999 12:00amOriginally posted by: Michael Walz
The main reason why I have not yet switched to VC5 and MFC 4.2 is
the fact that he behavior of displaying the print preview in MDI
applications has changed. In my application this new behaviour
was inacceptable because the user interface is still fully functioning
during preview and some on the user interface commands could result
in strange behaviours. I'm sure that there are many more programmers
that had to deal with this.
It's unbelievable that the folks at M$ dare change the behaviour
of MFC in such a way and didn't even offer an easy way to make
print preview behave as before. New features and bug corrections are
ok but old features should remain exactly as they are.
Reply