其他分享
首页 > 其他分享> > c – 具有多重继承的消息映射MFC:如何避免警告C4407和运行时崩溃

c – 具有多重继承的消息映射MFC:如何避免警告C4407和运行时崩溃

作者:互联网

我最近移植了一个从VS2008到VS2013的项目,并遇到了一些堆栈损坏问题.
经过一些研究,我可以找出以下代码的原因:

class CInternalInterface
{
  afx_msg void onm ouseMove(UINT, CPoint) = 0; 
};
class CMyDlg : public CDialog, public CInternalInterface
{
  afx_msg void onm ouseMove(UINT, CPoint); 
}
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
  ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

编译器在ON_WM_MOUSEMOVE()语句中发出“警告C4407:在指向成员表示的不同指针之间强制转换,编译器可能生成错误的代码”,并且在运行时,只要处理了WM_MOUSEMOVE消息,堆栈就会被破坏.

代码在VS2008上运行良好(没有警告,没有运行时问题),虽然我同意在非CWnd派生的接口中定义MFC消息处理函数首先不是一个好主意.

现在我通过使用OnMouseMove处理程序的不同函数名明显扩展ON_WM_MOUSEMOVE来解决它

...
class CMyDlg : public CDialog, public CInternalInterface
{
  afx_msg void OnCWndMouseMove(UINT, CPoint); 
  afx_msg void onm ouseMove(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()

但是,此解决方案有几个缺点 – 扩展宏可能导致与未来MFC版本不兼容,并且可能会使其他开发人员混淆使用不同名称的MFC消息处理程序.

所以我有两个问题:

>这是编译器错误吗?只要CWnd派生的基类是类定义中列出的第一个,是不是多重继承应该与MFC一起使用?宏显式地将函数强制转换为CWnd :: *,因此两个OnMouseMove(…)函数之间不应存在歧义.
>有更好的方法来解决它吗?在CInternalInterface中重命名OnMouseMove()是不可行的,因为它在代码库中大量使用并且判断何时调用重命名的函数以及何时在各种实现中使用OnMouseMove并非易事.

解决方法:

只是一种不同的方法.它不是直接解决消息映射的问题.

为什么不将经典子类用于这样的“接口”?

我使用CSubclassWnd(来自Paul DiLascia),CHookWnd(来自PJ Naughter)或仅使用ATL子类化功能.

这有助于我将接口附加到现有窗口,我可以在特定的窗口操作上实现标准功能……

使用上面的其中一个库,您甚至可以在窗口中使用多个“接口”.

标签:c,visual-c,mfc,multiple-inheritance
来源: https://codeday.me/bug/20191008/1873792.html