PRB: Assert in Wincore.cpp with MFC in an NT ServiceLast reviewed: August 7, 1997Article ID: Q164166 |
4.00 4.10 4.20
WINDOWS NT
kbprg kbui kbcode kbprb
The information in this article applies to:
SYMPTOMSWhen you use a Visual C++ 4.x MFC application spawned from a NT service or as a NT service, an assertion may occur in Wincore.cpp. Specifically, it occurs on the following line in _AfxActivationWndProc():
LRESULT CALLBACK _AfxActivationWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, szAfxOldWndProc); ASSERT(oldWndProc != NULL); // <----- assert occurs here . . . }The assertion occurs on line 385 with Visual C++ versions 4.2 and 4.2b, and on line 384 with Visual C++ version 4.1.
CAUSEMFC subclasses all non-MFC created windows to handle specific activation issues. While subclassing a non-MFC created window, the old window procedure is stored in the properties of the window. Logging off of an NT session causes the atoms used to identify the properties to be destroyed and the property cannot be retrieved. This causes the assertion to occur. MFC was not designed for Windows NT services. As a result, if an MFC application is spawned from a Windows NT service, minimized, and then a user logs-off, then the assertion will occur. Also keep in mind that there are other problems to consider when spawning an MFC application from a service or as a service. The OnEndSession() message handler for the main frame window closes out the CDocument object. So the WM_ENDSESSION message must be handled to prevent this from happening.
RESOLUTIONYou can do one of the following things:
Unsubclassing the non-MFC WindowsThe first technique listed above may be an easy workaround for developers who have already written an application and don't want to rework their design, rebuild the MFC libraries, or don't need to handle the activation issues MFC handles. You can unsubclass non-MFC Windows in the WM_ENDSESSION handler of your main frame window. The following sample code demonstrates how to enumerate all of the windows for your process and unsubclass them:
static const TCHAR szAfxOldWndProc[] = _T("AfxOldWndProc"); BOOL CALLBACK EnumProc( HWND hWnd, LPARAM lParam) { //check for property and unsubclass if necessary WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, szAfxOldWndProc); if (oldWndProc!=NULL) { SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc); RemoveProp(hWnd, szAfxOldWndProc); } return TRUE; } void CMainFrame::OnEndSession(BOOL bEnding) { // unsubclass the non-MFC windows which MFC has subclassed DWORD dwProcessId; DWORD dwThreadId= GetWindowThreadProcessId(m_hWnd,&dwProcessId); EnumThreadWindows(dwThreadId, EnumProc,(LPARAM) dwThreadId); } |
KBCategory: kbprg kbui kbcode kbprb
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |