CFrameWnd::OnSetPreviewMode ASSERTs in VC 2005 but not VC 6.0

CFrameWnd::OnSetPreviewMode ASSERTs in VC 2005 but not VC 6.0

I have a VC++ 6.0 MDI project that uses a class derived from CPreviewView to provide some mildly enhanced Print Preview functions. The class is invoked according to the MSDN documentation by calling DoPrintPreview. In Visual Studio 2005 the program asserts in Debug mode at the last line of this fragment from winfrm.cpp:

void CFrameWnd::OnSetPreviewMode(BOOL bPreview, CPrintPreviewState* pState) {

 ...etc...

if (bPreview)

{

// Entering Print Preview

ASSERT(m_lpfnCloseProc == NULL); // no chaining

m_lpfnCloseProc = pState->lpfnCloseProc;

// show any modeless dialogs, popup windows, float tools, etc

ShowOwnedWindows(FALSE);

// Hide the main pane

HWND hWnd = ::GetDlgItem(m_hWnd, pState->nIDMainPane);

ASSERT(hWnd != NULL); // must be one that we are hiding!

The program asserts because in Visual Studio 2005 the handle returned by ::GetDlgItem is NULL. If I ignore the assertion the program continues normally. I have checked our project's behaviour under the same conditions on Visual C++ 6.0 and the ::GetDlgItem function returns a valid window handle. In Release mode the assertion is disregarded and the program behaves as expected.

Is there a fix/workaround for this issue ?

I don't think you're going to get an good answer, so you're going to have to dig in a bit more.

Use Spy++ to gather more information.  Set a breakpoint on the line for GetDlgItem, get the value of m_hWnd and pState->nIDMainPane.

Then use Spy++ to locate the m_hWnd (there is a Find Window tool).  Then see if it has a child with the aforementioned ID.  Is it there.  Do you see the pane, and it has a different ID?

Do this in VC6 and compare. 

These might be clues that can lead you back to the cause of the problem.  If you end up deciding there a bug in MFC 8.0, then you can submit a bug report.
It doesn't make much sense to ask why m_hWnd "points" to a CView instead of the frame window.  The member can only belong to class (a certain CWnd derived class).  I think you need to be clearer in your observations.  If the organization of your app's windows have changed in VS2005 such that a certain window ID is no longer a child of a certain Window type, then you need to confirm this (I don't see a confirmation here, only some additional confusion.)  Then use the debugger to see how that certain child got created by its certain parent under VC6, and determine what's different by debugging the same under VS2005. 

Note that HWND values will change between runs, but the relationships (parentage) and IDs should not.

You can't modify the MFC sources without recompiling the MFC libraries, and I'm not really sure that this is something Microsoft really supports.  You could have found a bug in MFC however, and if you can get it into a reproable case to submit the bug, you ought to do that so that the bug can get fixed in SP1.

I'd recommend looking for a way to workaround the problem.  If you can break down the VC6 behavior in terms of a sequence of Win32 API calls (use m_hWnd on the Windows APIs, e.g. GetDlgItem), then you ought to be able to make those calls in your VS2005 version.

Copyright © 2007-2012 www.chuibin.com Chuibin Copyright