BUG: Conflicting Versions of MFC May Stop Responding Upon Shutdown (234194)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++, 32-bit Editions 2.0
- Microsoft Visual C++, 32-bit Editions 2.1
- Microsoft Visual C++, 32-bit Editions 2.2
- Microsoft Visual C++, 32-bit Editions 4.0
- Microsoft Visual C++, 32-bit Editions 4.0a
- Microsoft Visual C++, 32-bit Editions 4.1
- Microsoft Visual C++, 32-bit Editions 4.2
- Microsoft Visual C++, 32-bit Editions 4.2b
- Microsoft Visual C++, 32-bit Editions 5.0
This article was previously published under Q234194 SYMPTOMS
If a Microsoft Foundation Classes (MFC) application built with Visual C++ 4.x or 5.0 is run on Windows 95 concurrently with a MFC application built with
Visual C++ 2.x (MFC version 3.x), then when the user logs off or shuts down the computer, a dialog box stating that "An illegal operation occurred" in the
MFC 4.x application may appear. This error only occurs if the MFC version 3.x has the focus upon shutdown.
CAUSE
The MFC classes version 3.0 adds atoms, by calling the AddAtom function, to the global atom table by calling the atoms in a different manner than MFC
4.0 and later. All versions of MFC store the original window procedure of a subclassed window in the window property list before replacing it. MFC version
3.0 sets the property by using an atom as the following code sample illustrates:
static const ATOM _afxOldWndProcAtom = GlobalAddAtom(_T("AfxOldWndProc"));
The SetProp method does not call the GlobalAddAtom function if an atom is passed to it. Therefore GlobalAddAtom is called only once in
the MFC 3.x application instance (during the initialization of _afxOldWndProcAtom), even if the atom is used in several subclassed windows. MFC Versions 4.0
and later set this property using a string as follows:
static const TCHAR szAfxOldWndProc[] = _T("AfxOldWndProc");
In this case, SetProp calls GlobalAddAtom once for each subclassed window. During shutdown, if Windows 95 detects that a process is shutting
down without destroying all of its windows, then Windows 95 cleans them up for the application. Specifically, Windows 95 calls GlobalDeleteAtom for
each atom that is used in a window's property list. When an MFC 3.x application has several subclassed windows, Windows 95 deletes the AfxOldWndProc
atom several times, even though the application added it only once. In this situation, the atom is removed from the global atom table before the MFC 4.x
application is done using it. As a result, the MFC 4.x application is not able to access the stored window procedure when handling the WM_NCDESTROY window in
the _AfxActivationWndProc function, which results in the illegal operation (general protection fault).
RESOLUTION
If the MFC 4.x application adds the atom more times than it is deleted during the shutdown of any MFC 3.x applications, then the atom is still available
when the MFC 4.x application references it. Making the atom constantly available can be done by adding the following statement to the MFC 4.x application's
CWinApp::InitInstance function:
for( int i = 0; i<50; i++)
GlobalAddAtom(_T("AfxOldWndProc"));
STATUSMicrosoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article. MORE INFORMATION
The Windows global atom table maintains a reference count on each atom that is added. If the same atom is added more than once, Windows does not add a new
entry in the global atom table; instead, it increments the atom's reference count. Similarly, Windows decrements an atom's reference count whenever it is
deleted. When the reference count reaches zero, Windows then removes the atom from the global atom table.
The reference count is maintained in a 16-bit unsigned word. Therefore, the reference count may reach 2 to the 16th power minus one (65535) before it rolls
over to zero. If a MFC 4.x application implements the code in the suggested resolution, then it requires over 1300 active instances of the application
before the reference count limit is reached. In addition, calling GlobalAddAtom for an atom that already exists does not cause any additional
consumption of system resources, other than the processor time used on the function call. Therefore, the suggested resolution may be safely deployed in a
production environment with no appreciable side effects.
MFC subclasses non-MFC windows and uses the atom with the name AfxOldWndProc as the key for retrieving the subclassed Window's window procedure. MFC
3.0 and MFC 4.2 uses the same name for the atom. _AfxActivationWndProc uses the atom to retrieve the subclassed window procedure prior to calling it.
Destruction of a window MFC replaces the window procedure of the non-MFC window with its original window procedure. This is done in code in the
_AfxActivationWndProc procedure that handles WM_NCDESTROY.
This issue is encountered sporadically but is more common on Japanese, Chinese, and computers running Korean Windows 95 due to MFC subclassing the Input
Method Editor (IME) window.
This problem may be observed by using certain accessories that ship with Windows 95. The Imaging accessory is a MFC 4.x application, while Paint and WordPad
are both MFC 3.0 applications. If a user starts an instance of Imaging, then Paint, then WordPad, then leaves the focus on WordPad while shutting down, they
may encounter the illegal operation error message, or the applications may simply hang, or stop responding. The Windows 98 versions of WordPad and Paint do
not use MFC.
A conflict does not occur between any two applications if one of the applications is using the version of MFC shipped with Visual C++ 6.0 or later. Steps to Reproduce Behavior
Method One:
On a computer running Japanese Windows 95: - Create a MFC dialog-based application with AppWizard using Visual C++ 4.2.
- Run this application.
- Run WordPad.
- While the WordPad application window is the topmost window, shut down the computer.
Method Two: - On a computer running Windows 95, run Imaging for Windows 95 and then run WordPad.
- When the WordPad application window is the topmost window, shut down the computer.
REFERENCES- For additional information, click the article number below
to view the article in the Microsoft Knowledge Base:
164166 PRB: Assert in Wincore.cpp with MFC in an NT Service
- For additional information, click the article number Windows 95 OSR2 Accessories below
to view the article Windows 95 OSR2 Accessories in the Microsoft Knowledge Base:
234615 Some Windows 95 OSR2 Accessories May Cause GPF During Shutdown
-
See the \MFC\SRC\WinCore.cpp file for the _AfxActivationWndProc and _AfxCbtFilterHook functions and to see how _afxOldWndProc is
defined.
Modification Type: | Major | Last Reviewed: | 12/1/2003 |
---|
Keywords: | kbArchitecture kbbug KB234194 |
---|
|