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

    • With 81% of employees using their phones at work, companies have stopped asking: "Is corporate data leaking from personal devices?" and started asking: "How do we effectively prevent corporate data from leaking from personal devices?" The answer has not been simple. ZixOne raises the bar on BYOD security by not allowing email data to reside on the device. In addition, Zix allows employees to maintain complete control of their personal device, therefore satisfying privacy demands of valued employees and the …

    • Do you know where your data is? Consumer cloud-based file sharing services store your sensitive company data on servers outside of your control, outside of your policy and regulatory guidelines – maybe even outside your country – and not managed by you. The potential for data leakage, security breaches, and harm to your business is enormous. Download this white paper to learn about file sync and share alternatives that allow you to manage and protect your sensitive data while integrating and …

    Most Popular Programming Stories

    More for Developers

    Latest Developer Headlines

    RSS Feeds