c++ - 具有多重继承的消息映射 MFC : how to avoid warning C4407 and runtime crashes

标签 c++ visual-c++ mfc multiple-inheritance

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

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

编译器在 ON_WM_MOUSEMOVE() 语句和运行时堆栈中发出“警告 C4407:在指向成员表示的不同指针之间进行转换,编译器可能生成不正确的代码”每当处理 WM_MOUSEMOVE 消息时都会损坏。

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

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

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

但是,此解决方案有几个缺点 - 扩展宏可能会导致与 future 的 MFC 版本不兼容,并且可能会使其他开发人员感到困惑,让 MFC 消息处理程序使用不同的名称。

所以我有两个问题:

  1. 这是编译器错误吗?只要 CWnd 派生基类是类定义中列出的第一个基类,多重继承就不能与 MFC 一起使用吗?宏显式地将函数转换为 CWnd::*,因此两个 OnMouseMove(...) 函数之间不应有歧义。

  2. 是否有更好的解决方法?重命名 CInternalInterface 中的 OnMouseMove() 是不可行的,因为它在代码库中被大量使用,并且在各种实现中判断何时调用重命名的函数以及何时使用 OnMouseMove 并非易事。

最佳答案

只是一种不同的方法。它不能直接通过消息映射解决您的问题。

为什么不对这样的“接口(interface)”使用经典的子类化?

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

这有助于我将接口(interface)附加到现有窗口,并且我可以根据特定的窗口操作实现标准功能...

使用上面的库之一,您甚至可以将多个“界面”连接到一个窗口。

关于c++ - 具有多重继承的消息映射 MFC : how to avoid warning C4407 and runtime crashes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24179534/

相关文章:

c++ - 如何避免在不适当的线程上下文中破坏 shared_ptr?

c++ - 为什么这段代码不会产生编译错误?

c++ - 按引用返回与按值返回。 C++

c++ - 不完整类型不允许错误

c++ - Visual Studio C++ MFC : Displaying bitmap from imagelist

c++ - 在 Linux 上运行 MFC 程序

windows - 如何使用MFC统计Windows中每个进程的线程数

c# - 使用 C# 的 Windows 10 凭据提供程序

c++ - 在 C++11 中创建指针 vector 的惯用方法?

C++11:std ref 全局变量和非函数局部 thread_local 初始化顺序?