Article ID: 103806
Article Last Modified on 11/21/2006
APPLIES TO
- Microsoft Foundation Class Library 4.2, when used with:
- Microsoft C/C++ Professional Development System 7.0
- Microsoft Visual C++ 1.0 Professional Edition
- Microsoft Visual C++ 1.5 Professional Edition
- Microsoft Visual C++ 1.51
- Microsoft Visual C++ 1.52 Professional Edition
- Microsoft Visual C++ 1.0 Professional Edition
- Microsoft Visual C++ 2.0 Professional Edition
- Microsoft Visual C++ 2.1
- Microsoft Visual C++ 4.0 Standard Edition
This article was previously published under Q103806
SYMPTOMS
The following error message can occur after adding a message handler for a class when using the Microsoft Foundation Classes (MFC):
CAUSE
This compiler error message occurs if a window message handler macro has been added to the message map of a class that is not derived from CWnd. For example, if you declare a class as
class CMyApp: public CWinApp { ... DECLARE_MESSAGE_MAP() afx_msg LRESULT OnMyRegisteredMessage( WPARAM, LPARAM ); ... };
with a message map such as the following
BEGIN_MESSAGE_MAP(CMyApp,CWinApp) ON_REGISTERED_MESSAGE( MyMSGID, OnMyRegisteredMessage ) END_MESSAGE_MAP()
the C2642 error will occur. Examine the macro ON_REGISTERED_MESSAGE() in AFXMSG_.H; you can see why the error occurs. Here is the definition of the macro:
// For registered Windows messages #define ON_REGISTERED_MESSAGE(nMessageVariable, memberFxn) \ { 0xC000, 0, (UINT)(UINT NEAR*)(&nMessageVariable), \ /*implied 'AfxSig_lwl'*/ \ (AFX_PMSG)(AFX_PMSGW) <not actual line break> (LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))memberFxn },
In MFC 4.0 (included with Visual C++ 4.0), this macro is defined as:
// for Registered Windows messages #define ON_REGISTERED_MESSAGE(nMessageVariable, memberFxn) \ { 0xC000, 0, 0, 0, (UINT)(UINT*)(&nMessageVariable), \ /*implied 'AfxSig_lwl'*/ \ (AFX_PMSG)(AFX_PMSGW) <not actual line break> (LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))memberFxn },
Notice that the function pointer is cast to a pointer to a function in the CWnd scope. In the example above, CMyApp is derived only from CWinApp. As it does not have CWnd as a base class, CMyApp will not receive window messages. It only receives command messages that are sent through the command routing process.
RESOLUTION
The following are two possible workarounds to resolve the problem:
- Trap the message in a CWnd object. If necessary, then send a WM_COMMAND message or notification to the CCmdTarget. -or-
- Trap the message in a CWnd object and then call a member function of the intended object directly.
MORE INFORMATION
Message maps contain six different categories of messages:
- Control notification messages
- Update command UI messages
- Command messages
- VBX and OCX event notifications
- Normal window messages
- Registered window messages
The first four categories are notifications that are routed through MFC's command-routing methods. You can handle these messages in any CCmdTarget- derived class.
The last two categories are standard window messages and can be handled only in a CWnd-derived class. These messages are not routed via the framework's command routing mechanism.
REFERENCES
Information about command routing can be found in Chapter 3 of the "Class Library Reference," MFC Technical Note 21, and Chapter 6 of the "Class Library User's Guide."
Additional query words: 7.00 1.00 1.50 1.51 1.52 2.00 2.10 2.50 2.51 2.52 3.00 3.10 4.00
Keywords: kbarchitecture kbprb KB103806