I recently ported a project from VS2008 to VS2013 and ran into some stack corrupt issues. After some research I could pinpoint the cause to the following code:
class CInternalInterface
{
afx_msg void OnMouseMove(UINT, CPoint) = 0;
};
class CMyDlg : public CDialog, public CInternalInterface
{
afx_msg void OnMouseMove(UINT, CPoint);
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
The compiler issued a "warning C4407: cast between different pointer to member representations, compiler may generate incorrect code" at the ON_WM_MOUSEMOVE() statement and at runtime the stack got corrupted whenever the WM_MOUSEMOVE message was processed.
The code ran fine with VS2008 (no warning, no runtime issues), although I agree that defining an MFC message handler function in a non-CWnd-derived interface wasn't a good idea in the first place.
For now I resolved it by expanding the ON_WM_MOUSEMOVE explicitely using a different function name for OnMouseMove handler
...
class CMyDlg : public CDialog, public CInternalInterface
{
afx_msg void OnCWndMouseMove(UINT, CPoint);
afx_msg void OnMouseMove(UINT, CPoint);
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
{
WM_MOUSEMOVE, 0, 0, 0, AfxSig_vwp,
(AFX_PMSG)(AFX_PMSGW)
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) >(&CMyDlg::OnCWndMouseMove))
},
END_MESSAGE_MAP()
This solution however has several drawbacks - expanding the macro may cause incompatibilities with future MFC versions and it may confuse other developers to have the MFC message handler using a different name.
So I have 2 questions:
Is this a compiler error ? Isn't multiple inheritance supposed to work with MFC as long as the CWnd derived base class is the first one listed in the class definition ? The macro explicitly casts the function to a CWnd::* so there should be no ambiguity between the two OnMouseMove(...) functions.
Is there a better way to resolve it? Renaming the OnMouseMove() in CInternalInterface is not feasible, as it is heavily used in the code base and judging when to call the renamed function and when to use OnMouseMove in the various implementations is not trivial.