2
votes

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:

  1. 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.

  2. 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.

1
I'm sure in later VS versions, OnMouseMove returns a BOOL. Could this be the problem?user1793036
VS 2005 - 2013 all have afx_msg void OnMouseMove(..) according to MSDNZord

1 Answers

1
votes

Just a different approach. It is not solving your problem with the messages maps directly.

Why don't you use classic subclassing for such an "interface"?

I use CSubclassWnd (from Paul DiLascia), CHookWnd (from PJ Naughter) or just the ATL subclassing features.

This helps me to attach an interface to an existing window and I can implement standard function upon the specific window actions...

Using one of the libraries above you can even more than one "interface" to a window.