生成的mfc消息映射无效

时间:2013-03-05 09:26:57

标签: visual-studio-2008 visual-c++ mfc

我在MFC中有一个简单的测试应用程序,但它不起作用。消息处理程序根本不会被调用。窗口接收消息,但不调用在消息映射中注册的处理程序。

这是一个标准的mfc单一对话框应用程序,它有一个巨大的按钮块,并在推送它时对库进行各种调用。但它并没有打电话给处理程序。

我已经跟踪过,消息地图似乎已损坏。有标准声明如:

BEGIN_MESSAGE_MAP(CommLib_test_x86Dlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDCANCEL, &CommLib_test_x86Dlg::OnBnClickedCancel)
    ON_BN_CLICKED(IDOK, &CommLib_test_x86Dlg::OnBnClickedOk)
    ON_BN_CLICKED(IDC_BUTTON1, &CommLib_test_x86Dlg::OnBnClickedButton1)
    ON_BN_CLICKED(IDC_BUTTON2, &CommLib_test_x86Dlg::OnBnClickedButton2)
    ON_BN_CLICKED(IDC_BUTTON3, &CommLib_test_x86Dlg::OnBnClickedButton3)
    ON_BN_CLICKED(IDC_BUTTON4, &CommLib_test_x86Dlg::OnBnClickedButton4)
    ON_BN_CLICKED(IDC_BUTTON5, &CommLib_test_x86Dlg::OnBnClickedButton5)
    // many more buttons, but I commented the rest out for test
END_MESSAGE_MAP()

如果我在第一个ON_WM_ *(即进入GetThisMessageMap静态方法)中放置断点并查看消息映射的内容,则第一个条目是正确的,但其余的是大多数是0 数组大小与实际定义不对应。调试器将值报告为

[0] {nMessage=274 nCode=0 nID=0 ...}
[1] {nMessage=0 nCode=0 nID=0 ...}
[2] {nMessage=0 nCode=19 nID=4206192 ...}
[3] {nMessage=55 nCode=0 nID=0 ...}
[4] {nMessage=0 nCode=0 nID=0 ...}
[5] {nMessage=0 nCode=0 nID=0 ...}
[6] {nMessage=0 nCode=0 nID=0 ...}
[7] {nMessage=0 nCode=0 nID=0 ...}
[8] {nMessage=0 nCode=0 nID=0 ...}
[9] {nMessage=0 nCode=0 nID=0 ...}
[10] {nMessage=0 nCode=0 nID=0 ...}
[11] {nMessage=0 nCode=0 nID=0 ...}
[12] {nMessage=0 nCode=0 nID=0 ...}
[13] {nMessage=0 nCode=0 nID=0 ...}
[14] {nMessage=0 nCode=0 nID=0 ...}
[15] {nMessage=0 nCode=0 nID=0 ...}

代码编译良好,没有任何警告或任何东西。

值得注意的是,应用程序是大量项目集合的一部分,并且这些项目共享编译器选项。我们实际上生成了visual studio项目,但在我们使用.vsprops文件之前。我没有使用该项目一段时间,可以想象编译器标志同时发生了变化。

1 个答案:

答案 0 :(得分:2)

好的,我找到了。编译器标志确实发生了变化。添加了可怕的/vmg标志(我们在其他一些库中使用它,并在重构期间将其传播到不正确的项目)。此标志与MFC不兼容,因为它更改了消息映射项的定义。

长篇故事:为了节省一些空间,Microsoft决定根据该类是使用单个,多个还是虚拟继承来指向成员的指针。虽然它在理论上看起来很好,但实际上它在以下情况下存在问题:

  • 声明了指向不完整类型成员的指针(在C ++中是合法的)。

我怀疑它在以下情况下也会引起问题:

  • 指向具有更复杂指针的类成员的指针需要使用更简单的指针转换为指向基类成员的指针。

文档没有提到这种情况,但它显而易见。这正是MFC所做的。

规范(ISO / IEC 14882-2011)仅要求static_cast指向基本成员,如果基础不是虚拟继承的,但在Microsoft编译器中,即使基类只有线性,它也不起作用继承,但子类具有多重继承,并且基础是非第一个。好吧,大家都知道编译器已经不符合。