Microsoft KB Archive/172336

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 20:48, 20 July 2020 by X010 (talk | contribs) (Text replacement - ">" to ">")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Base


An assertion is hit in the Afxwin2.inl file when you try to launch an MFC MDI application through a document

Article ID: 172336

Article Last Modified on 6/3/2005



APPLIES TO

  • The Component Gallery, when used with:
    • Microsoft Visual C++ 4.0 Standard Edition
    • Microsoft Visual C++ 4.1 Subscription
    • Microsoft Visual C++ 4.2 Enterprise Edition
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 4.2 Professional Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++ 6.0 Standard Edition



This article was previously published under Q172336

SYMPTOMS

When launching an MFC MDI application through a document from Explorer, an assertion is hit in the Afxwin2.inl file. This assertion only occurs if the application contains the Tip of the Day and Splash Screen components from the Component Gallery.

CAUSE

When an application is launched by opening its document, MFC delays showing the main frame window. This delay is enough to cause the Tip of the Day modal dialog box to be parented off the modeless Splash Screen dialog box instead of the main frame. When the timer expires for the Splash Screen, it destroys itself and its children including the Tip of the Day dialog box. MFC still tries to process messages for that dialog box, thereby causing the assertion.

RESOLUTION

Delay showing the Tip of the Day dialog until after the Splash Screen destroys itself.

STATUS

This behavior is by design.

MORE INFORMATION

When an MFC application is normally launched (from the .exe file), the default behavior is to create the MDI Main frame window and to show it at the end of InitInstance(). When a splash screen is inserted from the component gallery, the Splash Screen modeless dialog box is displayed during CMDIFrameWnd::LoadFrame() which is called before the main window is shown. When the Tip of the Day component is inserted, its modal dialog box is shown after the main window is shown. A modal dialog box by default uses the last activated popup window as returned from ::GetLastActivePopup() as its parent. The code in CWnd::GetSafeOwner() which is called by CDialog::PreModal() uses the main window as the parameter to GetLastActivePopup() thereby returning the main window because it was the most recently active. As a result, the Tip of the Day dialog box is parented off the main window. For example:

   BOOL CTipApp::InitInstance()
   {
      ...
      if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) // Display splash screen.
         return FALSE;
      m_pMainWnd = pMainFrame;
      ...
      if (!ProcessShellCommand(cmdInfo))  // Handle FileDDE or FileOpen
         return FALSE;
      ...
      pMainFrame->ShowWindow(m_nCmdShow);
      ...
      ShowTipAtStartup();  // Display Tip of the Day dialog box.
      ...
   }
                

When an MFC application is launched from opening a document from the Explorer, the shell sends a DDE message to the MFC application and the shell command line information contains a DDE flag. This flag sets m_nCmdShow to FALSE so that the window can be shown later when the DDE message is processed by CDocManager::OnDDECommand(). This allows the Splash Screen to be the last activated window, so the Tip of the Day dialog box is parented off of it.

Because the Splash Screen kills itself by using a timer, it takes the tip of the day dialog box with it. This causes an assertion in line 35 (or line 39 in Visual C versions 5.0 and 6.0) in the CWnd::SendMessage() inline function in the Afxwin2.inl file. This is because MFC is still running its RunModalLoop() and is trying to send a message to an invalid hWnd.

One workaround is to remove the call to ShowTipAtStartup() from InitInstance() and to simply display the Tip of the Day dialog box after the Splash Screen is destroyed. For example:

   void CSplashWnd::HideSplashScreen()
   {
      // Destroy the window, and update the mainframe.
      DestroyWindow();
      AfxGetMainWnd()->UpdateWindow();
      AfxGetMainWnd()->PostMessage(WM_COMMAND, CG_IDS_TIPOFTHEDAY);
   }
                

(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Adam Kim, Microsoft Corporation

Keywords: kbtshoot kbuidesign kbprb kbwizard KB172336