I tried doing the same thing I did 5 years ago, to the best of my memory,
and again ran into the slew of protected functions called from
DoPrintPreview. So, I added public wrappers to my CPreviewView derived
class. That worked up until I got to OnActivateView(). Fortunately, that
call doesn't do anything in my app, so I was able to leave it out.
Now, when I hit the close button in the preview, I get asserts about null
window handles, and my application is unusable. I REALLY don't want to spend
any more time fixing this bug AGAIN! I really can't understand how this bug
could have been reintroduced. I need a sample showing me exactly what I need
to do to work around this MFC bug.
The print preview window in VC6 is not a child window of the MDI mainframe
window, when being called it will be displayed to replace the mainframe
window, and the mainframe window would be hidden. But in MFC7, the print
preview window is a child window of the MDI mainframe window, so it will be
contained mainframe window and seems to be somehow "broken".
However, I don't think it is a bug to MFC7, it just a different
implementation from the MFC6's implementation, and under MFC7's scenario I
suggest you can maximize the print preview window while it is been called...
Thanks for your understanding!
Best regards,
Gary Chang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------
Vaclav
""Gary Chang"" <v-ga...@online.microsoft.com> wrote in message
news:VI6R7nH...@cpmsftngxa06.phx.gbl...
Enough people thought it was a bug in MFC 5 that it was changed back for MFC
6.
Based on the behavior of Microsoft Excel 2003, which displays its preview
over the full window, it's a bug.
As far as we, and our users are concerned, it is a bug. Code that worked
perfectly before is now broken. The Print Preview is no longer hiding and
preventing access to the rest of the application's interface.
So, how do I fix this bug?
I was reviewing this issue thread and talked to Gary on it.
As Gary mentioned, this behavior is changed after MFC 7.1 due to the change
of internal implementation. I totally understand your feeling on it. So I
passed it to our product team quickly.
However, based on my experience, if this problem is quite critical and
important to you, it is better for you to submit a service request through
Microsoft Product Support Service. A support engineer will work with you on
it and help you either by providing a workaround or by submited a
DCR(design change request) to product team. The product group may need some
more information such as business impact and etc to determine the action
plan on it.
You can contact Microsoft Product Support directly to discuss additional
support options you may have available, by contacting us at 1-(800)936-5800
or by choosing one of the options listed at
http://support.microsoft.com/default.aspx?scid=sz;en-us;top
Our newsgroup supporting team is also glad to of assistance. If you feel
there is any others we can do for you, please feel free to post here.
Thanks very much for your understanding.
Best regards,
Yanhong Huang
Microsoft Community Support
Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn
How is everything going? Have you contacted PSS on it? If you feel there is
any we can do for you, please feel free to post here. Thanks very much.
Best regards,
Yanhong Huang
Microsoft Community Support
Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Not sure if this will help you. I still have VC++6.0, had VC++5.0
before.
Just as a recall for you, this is how I fixed it for VC++5.0:
In .h file:
/////////////////////////////////////////////////////////////////////////////
class CMyView : public CView
{
...
#if _MSC_VER < 1200
protected:
// Advanced: for implementing custom print preview
BOOL DoPrintPreview(UINT nIDResource, CView* pPrintView,
CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState);
afx_msg void OnFilePrintPreview();
#endif // _MSC_VER < 1200
...
}
#if _MSC_VER < 1200
class CMyPreviewView : public CPreviewView
{
DECLARE_DYNCREATE(CMyPreviewView)
friend class CMyView;
};
#endif // _MSC_VER < 1200
/////////////////////////////////////////////////////////////////////////////
In .cpp file:
/////////////////////////////////////////////////////////////////////////////
#if _MSC_VER < 1200
IMPLEMENT_DYNCREATE(CMyPreviewView, CPreviewView)
#endif // _MSC_VER < 1200
...
#if _MSC_VER < 1200
void CMyView::OnFilePrintPreview()
{
// In derived classes, implement special window handling here
// Be sure to Unhook Frame Window close if hooked.
// must not create this on the frame. Must outlive this function
CPrintPreviewState* pState = new CPrintPreviewState;
// DoPrintPreview's return value does not necessarily indicate that
// Print preview succeeded or failed, but rather what actions are
necessary
// at this point. If DoPrintPreview returns TRUE, it means that
// OnEndPrintPreview will be (or has already been) called and the
// pState structure will be/has been deleted.
// If DoPrintPreview returns FALSE, it means that OnEndPrintPreview
// WILL NOT be called and that cleanup, including deleting pState
// must be done here.
if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
RUNTIME_CLASS(CMyPreviewView), pState))
{
// In derived classes, reverse special window handling here for
// Preview failure case
TRACE0("Error: DoPrintPreview failed.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState; // preview failed to initialize, delete State
now
}
}
BOOL CMyView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
ASSERT_VALID_IDR(nIDResource);
ASSERT_VALID(pPrintView);
ASSERT(pPreviewViewClass != NULL);
ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CMyPreviewView)));
ASSERT(pState != NULL);
CFrameWnd* pParent = STATIC_DOWNCAST(CFrameWnd, AfxGetMainWnd());
ASSERT_VALID(pParent);
CCreateContext context;
context.m_pCurrentFrame = pParent;
context.m_pCurrentDoc = GetDocument();
context.m_pLastView = this;
// Create the preview view object
CMyPreviewView* pView =
(CMyPreviewView*)pPreviewViewClass->CreateObject();
if (pView == NULL)
{
TRACE0("Error: Failed to create preview view.\n");
return FALSE;
}
ASSERT_KINDOF(CMyPreviewView, pView);
pView->m_pPreviewState = pState; // save pointer
pParent->OnSetPreviewMode(TRUE, pState); // Take over Frame Window
// Create the toolbar from the dialog resource
pView->m_pToolBar = new CDialogBar;
if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),
CBRS_TOP, AFX_IDW_PREVIEW_BAR))
{
TRACE0("Error: Preview could not create toolbar dialog.\n");
pParent->OnSetPreviewMode(FALSE, pState); // restore Frame Window
delete pView->m_pToolBar; // not autodestruct yet
pView->m_pToolBar = NULL;
pView->m_pPreviewState = NULL; // do not delete state structure
delete pView;
return FALSE;
}
pView->m_pToolBar->m_bAutoDelete = TRUE; // automatic cleanup
// Create the preview view as a child of the App Main Window. This
// is a sibling of this view if this is an SDI app. This is NOT a
sibling
// if this is an MDI app.
if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context))
{
TRACE0("Error: couldn't create preview view for frame.\n");
pParent->OnSetPreviewMode(FALSE, pState); // restore Frame Window
pView->m_pPreviewState = NULL; // do not delete state structure
delete pView;
return FALSE;
}
// Preview window shown now
pState->pViewActiveOld = pParent->GetActiveView();
// Note: We downcast pActiveView to type "CMyView*" to get access to
the protected "OnActivateView".
// Even if pActiveView points to an object which is not derived
from "CMyView"
// the correct virtual "OnActivateView" will be called.
CMyView* pActiveView =
(CMyView*)pParent->GetActiveFrame()->GetActiveView();
if (pActiveView != NULL)
pActiveView->OnActivateView(FALSE, pActiveView, pActiveView);
if (!pView->SetPrintView(pPrintView))
{
pView->OnPreviewClose();
return TRUE; // signal that OnEndPrintPreview was called
}
pParent->SetActiveView(pView); // set active view - even for MDI
// update toolbar and redraw everything
pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
pParent->RecalcLayout(); // position and size everything
pParent->UpdateWindow();
return TRUE;
}
#endif // _MSC_VER < 1200
/////////////////////////////////////////////////////////////////////////////
This "change in implementation" definitely broke my code. Surely changes in
implementation like these should be made public so that when we upgrade our
projects we don't have to go through all this stress of debugging perfectly
good software.
In my case, this change in implementation meant that a customer could change
the data without realizing it, because the menu was active but changes were
not being reflected in the view.
"Uwe Kotyczka" wrote:
> "GregM" <gr...@newsgroups.nospam> wrote in message news:<D32DEA5D-0314-4B8D...@microsoft.com>...
> > > However, I don't think it is a bug to MFC7, it just a different
> > implementation from the MFC6's implementation
> >
> > Enough people thought it was a bug in MFC 5 that it was changed back for MFC
> > 6.
> >
> > Based on the behavior of Microsoft Excel 2003, which displays its preview
> > over the full window, it's a bug.
> >
> > As far as we, and our users are concerned, it is a bug. Code that worked
> > perfectly before is now broken. The Print Preview is no longer hiding and
> > preventing access to the rest of the application's interface.
> >
> > So, how do I fix this bug?
>
> Not sure if this will help you. I still have VC++6.0, had VC++5.0
> before.
> Just as a recall for you, this is how I fixed it for VC++5.0:
>
> In .h file:
> /////////////////////////////////////////////////////////////////////////////
>
> class CMyView : public CView
> {
> ....
> #if _MSC_VER < 1200
> protected:
> // Advanced: for implementing custom print preview
> BOOL DoPrintPreview(UINT nIDResource, CView* pPrintView,
> CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState);
> afx_msg void OnFilePrintPreview();
> #endif // _MSC_VER < 1200
> ....
> }
>
> #if _MSC_VER < 1200
> class CMyPreviewView : public CPreviewView
> {
> DECLARE_DYNCREATE(CMyPreviewView)
> friend class CMyView;
> };
> #endif // _MSC_VER < 1200
> /////////////////////////////////////////////////////////////////////////////
>
>
> In .cpp file:
> /////////////////////////////////////////////////////////////////////////////
> #if _MSC_VER < 1200
> IMPLEMENT_DYNCREATE(CMyPreviewView, CPreviewView)
> #endif // _MSC_VER < 1200
>
> ....
That is why I suggest Greg to contact Microsoft support directly on it. It
may help me efficiently. Once it is confirmed, the support incident is free
of charge. Thanks.
Best regards,
Yanhong Huang
Microsoft Community Support
Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.