How to Avoid an MFC Active Document Container from Hanging

  • Click the Finish button
  • Creating an Active Document Server That Contains a Rich Edit Control

    1. Using Visual Studio, create an MFC project (any name will do for the purposes of this demo).
    2. Click mini-server and check Active document server checkbox.
    3. Select a CFormView instead of the CView.
    4. Click the Finish button.
    5. In the resource editor, drag a rich edit control to the form.
    6. Insert a call to AfxInitRichEdit() in the application object's InitInstance function.
    7. Compile and run the server to get it registered in registry.

    Understanding the Problem

    Now that you've created a demo application, let's see the problem up close.
    1. Run the test container application
    2. Select to inplace active an object.
    3. From the dialog, select the server you just created.
    4. Close the application
    5. The program hangs every time!

    How the Problem Can Be Solved

    Ok. Now we see there's a proble. How can it be solved?

    In the OnCloseDocument method in the container the COleClientItem(COleDocObjectItem) object is released with a call to InternalRelease(). But since the member variable m_dwRef is 8 InternalRelease does not call OnFinalRelease and therefore the server is never totally released. For a server that does not contain a rich edit control m_dwRef is 1. Well, what can we do about that? The obvious is to call release on the COleClientItem until it is one, but that causes an exception in Ole32.dll, so that's not the solution.

    I found a way to deal with the problem by adding some code to the OnClose method in the CMainFrame class. MFC uses an AFX_MODULE_STATE object to manage the MDI windows used in the container. During a normal CMDIFrameWnd::OnClose() call a call to CloseAllDocuments(...) is made, but if the m_nObjectCount in the AFX_MODULE_STATE is not 0 then the application is not closed down. What I did was to call CloseAllDocuments() before calling OnClose(), but before the call to OnClose is made the m_nObjectCount value is checked. If it's not 0 then AfxOleUnlockApp() is called. In the OnClose() ObjectCount is now 0 and the call to AfxOleCanExitApp() in OnClose returns true which causes the application to shutdown!

    Code to Fix the Problem

    Here's the code I used to finally fix this problem.
    void CMainFrame::OnClose()
    {
     AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
     TRACE("module count %d\n", pModuleState->m_nObjectCount);
    
     try
     { 
      int incOleLock=0;
    
      // m_nObjectCount is telling how many mdi windows 
      // that are open (I guess)
    
      // This is called to make the objectCount go as low as possible.
      AfxGetApp()->CloseAllDocuments(FALSE);  
      while(pModuleState->m_nObjectCount > 0) 
      { 
       // If we end up here then and object "hangs"
    
       // This is called BEFORE OnClose to make the OnClose destroy the window
       AfxOleUnlockApp();
    
       // This tells us to remember to increment the object count
       // AFTER the window is destroyed
       incOleLock++; 
      }
      CMDIFrameWnd::OnClose();
      while(incOleLock)
      {
       // incerement ObjectCount to let the hanging object close
       // down itself.
       AfxOleLockApp(); 
    
       incOleLock--;
      }
     }
     catch(...)
     {
      TRACE("Exception thrown during void CMainFrame::OnClose() shutdown\n");
      }
    }
    

    Downloads

    Download source - 79 Kb


    Comments

    • problem with ActiveX control instantiation

      Posted by Legacy on 05/27/2002 12:00am

      Originally posted by: monica shah

      I am presently working on a projetc that uses Visaul C++ 6.0 and
      MapObjects(An OLE library provided by ESRI for customizization
      using Visual Languages) on Windows NT 4.0 platform .The ActiveX
      Control uses MapControls for MapObjects. When the project is
      opened the error message :"ActiveX Control cannot be instantiated"
      is displayed and the system hangs(non -operational),which is to be
      dealt by task manager.

      if another workspace working properly is being opened and then we
      open our project(VC++ and Mapobjects one) workspace then no error
      is encountered and we can run the project but then our project
      shows some problem in taking some files,resource and ActiveX
      Control for this project(VC++ and Mapobjects one) .

      Will anyone be helpful in removing my bug, I am running short of
      time as the completion date is approaching fast.

      • problem with ActiveX control instantiation

        Posted by kanjali on 04/30/2009 05:42am

        Check OnSize() method of you your project if present,becoz it could be possible that it use to be called before OnInit() method, and there could be some code that should be executed after instantiation, so just put a instatiation check code before that code.I was facing same kind of problem.

        Reply
      Reply
    • problem with ActiveX control instantiation

      Posted by Legacy on 05/27/2002 12:00am

      Originally posted by: monica shah

      I am presently working on a projetc that uses Visaul C++ 6.0 and
      MapObjects(An OLE library provided by ESRI for customizization
      using Visual Languages) on Windows NT 4.0 platform .The ActiveX
      Control uses MapControls for MapObjects. When the project is
      opened the error message :"ActiveX Control cannot be instantiated"
      is displayed and the system hangs(non -operational),which is to be
      dealt by task manager.

      if another workspace working properly is being opened and then we
      open our project(VC++ and Mapobjects one) workspace then no error
      is encountered and we can run the project but then our project
      shows some problem in taking some files,resource and ActiveX
      Control for this project(VC++ and Mapobjects one) .

      Will anyone be helpful in removing my bug, I am running short of
      time as the completion date is approaching fast.

      Reply
    Leave a Comment
    • Your email address will not be published. All fields are required.

    Top White Papers and Webcasts

    • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

    • Some of the statistics about the growth of enterprise mobility are surprising, not the least of which is the 4X increase in mobile malware from 2013 to 2014. Many employees today not only expect to be able to use their own personal devices at work, but will even contravene policies that restrict personal device use for work.  IT must find the right approach that balances the benefits of mobility with the risks involved.  This on-demand webcast offers steps toward developing a winning mobile strategy, and …

    Most Popular Programming Stories

    More for Developers

    RSS Feeds