Microsoft KB Archive/103806

= PRB: C2642 Error When Adding Message Handler =

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</li></ul>

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

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

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

 Microsoft Visual C++ 2.1</li></ul>

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

-

<div class="notice_section">

This article was previously published under Q103806

<div class="notice_section">

<div class="symptoms_section">

SYMPTOMS
The following error message can occur after adding a message handler for a class when using the Microsoft Foundation Classes (MFC):

error C2642: cast to pointer to member must be from related pointer to member

<div class="cause_section">

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) (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) (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.

<div class="resolution_section">

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.

<div class="moreinformation_section">

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.

<div class="references_section">