Microsoft KB Archive/238989

= OLE is not uninitialized correctly when you try to use the RichEdit control in an application that calls OleInitialize =

Article ID: 238989

Article Last Modified on 11/21/2006

-

APPLIES TO

 Microsoft Foundation Class Library 4.2, when used with:  Microsoft Visual C++ 5.0 Enterprise Edition

 Microsoft Visual C++ 6.0 Enterprise Edition

 Microsoft Visual C++ 5.0 Professional Edition

 Microsoft Visual C++ 6.0 Professional Edition</li></ul>

 Microsoft Visual C++ 6.0 Standard Edition</li></ul>

 Microsoft Visual C++ .NET 2002 Standard Edition</li></ul>

 Microsoft Visual C++ .NET 2003 Standard Edition</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q238989

<div class="notice_section">

Note Microsoft Visual C++ .NET 2002 and Microsoft Visual C++ .NET 2003 support both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model. The information in this article applies only to unmanaged Visual C++ code.

<div class="symptoms_section">

SYMPTOMS
When using the RichEdit control in an application that calls OleInitialize, if the control is destroyed during a Component Object Model (COM) call, then OLE will not be uninitialized correctly.

<div class="cause_section">

CAUSE
The problem occurs because the RichEdit control, by default, calls OleInitialize when it is initialized, and calls OleUninitialize when it is destroyed. If the application is in the context of a COM call when it destroys the RichEdit window, then OleUninitialize will not run correctly, because OleUninitialize ends up calling CoUninitialize, and CoUninitialize will return immediately if the thread is in the context of another COM call. This results in an unbalanced call to CoInitialize, and therefore the OLE libraries are not uninitialized correctly.

Please note this problem applies only to RichEdit 1.0.

A known issue with this problem is if the RichEdit control is used in an Active Document Server, and the server destroys the RichEdit control within the context of the IOleObject::Close call. This happens in MFC when the RichEdit control is destroyed when the view, or the document, is being destroyed.

<div class="workaround_section">

WORKAROUND
To work around this problem, the RichEdit control should be created so that it will not call OleInitialize and OleUninitialize. To do this, set the ES_EX_NOCALLOLEINIT style during the WM_NCCREATE message, before the RichEdit control handles this message.

The following steps describe how to do this in MFC: <ol>  Create a class that is derived from CRichEditCtrl: class CMyRichEdit : public CRichEditCtrl {   DECLARE_DYNCREATE(CMyRichEdit) public: CMyRichEdit{}; ~CMyRichEdit{};

//AFX_MSG DECLARE_MESSAGE_MAP

};                   </li>  Add the message map and entries as follows in the *.cpp file for the class: IMPLEMENT_DYNCREATE(CMyRichEdit, CRichEditCtrl)

BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl) //AFX_MSG_MAP END_MESSAGE_MAP </li>  Handle the OnNcCreate function as follows: BOOL CMyRichEdit::OnNcCreate(LPCREATESTRUCT lpCreateStruct) {   LONG gwlEx = ::GetWindowLong(m_hWnd, GWL_EXSTYLE); gwlEx |= ES_EX_NOCALLOLEINIT;

gwlEx = ::SetWindowLong(m_hWnd, GWL_EXSTYLE, gwlEx); if (!CRichEditCtrl::OnNcCreate(lpCreateStruct)) return FALSE; return TRUE; }                   </li></ol>

Use GetWindowLong and SetWindowLong to add the ES_EX_NOCALLOLEINIT style to the control. This method must be used because the RichEdit control does not pay attention to this extended style when creating the control through CreateWindowEx.

<div class="status_section">

STATUS
This behavior is by design.

<div class="moreinformation_section">

Steps to reproduce the behavior
<ol> Use AppWizard to create an MFC MDI Active Document Container.</li> Build the Active Document Container.</li> Use AppWizard to create an MFC Active Document Server.</li> Make sure that AfxOleInit is called in the InitInstance function in the Active Document Server's CWinApp-derived class.</li>  Add the following member variable declaration to the CView-derived class of the server: CRichEditCtrl m_RichEdit; </li> Use class wizard to add a message handler for WM_CREATE in the CView-derived class of the server.</li>  Add the following code to the OnCreate message handler added above: m_RichEdit.Create(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_NOHIDESEL | ES_SAVESEL      , CRect(0,0,1,1), this, 2001); </li> <li> Add the following code to the destructor of the CView-derived class: m_RichEdit.DestroyWindow; </li> <li>Build the Active Document Server.</li> <li>Run the Active Document Container and insert the Active Document Server.</li> <li>Close the MDI Child window that the server is in.</li> <li>Close the Active Document Container.</li></ol>

Notice that the container process is still running.

Keywords: kboleapp kbtshoot kbactivedocs kbcontainer kbctrl kbprb kbrichedit KB238989

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.