FIX: GP Fault from ON_REGISTERED_MESSAGE() in _USRDLL

ID: Q99787


The information in this article applies to:


SYMPTOMS

In an application developed with the Microsoft Foundation Class Library, the ON_REGISTERED_MESSAGE() macro is used to process messages created with the RegisterWindowMessage() function. However, if a _USRDLL dynamic-link library (DLL) uses the ON_REGISTERED_MESSAGE() macro, the DLL generates a general protection (GP) fault when it processes the message.


CAUSE

In the WINCORE.CPP file, on line 851, pMessageMap is declared as follows:


   AFX_MSGMAP* pMessageMap; 
AFX_MSGMAP is a NEAR structure. Consequently, pMessageMap is a NEAR pointer. Later in the WINCORE.CPP file, on line 914, the code uses the _AFX_FP_SEG() macro to determine the segment in which the message map is stored. Because pMessageMap is a NEAR pointer, _AFX_FP_SEG() gives an incorrect result.


RESOLUTION

Modify the DLL code to remove the ON_REGISTERED_MESSAGE() macro and add code that overrides WindowProc(). The WindowProc() function is called for each message a window receives. In WindowProc(), test the wMessage parameter to determine if it is the registered message and process the message when it arrives. Call the base class version of WindowProc() to dispatch other messages according to the message map.


STATUS

Microsoft has confirmed this to be a problem in the Microsoft Foundation Class Library version 2.0 for Windows. The problem was fixed and the ON_REGISTERED_MACRO now can be used in a USRDLL with version 2.5 of the Microsoft Foundation Classes.


MORE INFORMATION

The code example below demonstrates the method described above. The CMyWnd class is derived from CWnd.


   UINT nRegMessage; // contains result from RegisterWindowMessage()
   ...

   LRESULT CMyWnd::WindowProc(UINT message, WPARAM wParam,
      LPARAM lParam)
   {
      // If the message is the registered message,
      // call the handler for that message
      if (message == nRegMessage)
         return OnMyRegisteredMessage(wParam, lParam);

      // Otherwise, call the base class version
      // of WindowProc to process other messages
      CWnd::WindowProc(message, wParam, lParam);
   } 

Additional query words:


Keywords          : kb16bitonly kbDLL kbMFC kbVC 
Version           : 1.0
Platform          : WINDOWS 
Issue type        : kbbug 

Last Reviewed: July 27, 1999