为什么在cmainframe类中重写oncommand函数就可以截获菜单消息? 
我是在看孙鑫的深入详解vc++中遇到这个问题的,原文是“由于CWnd::OnCommand 是个虚函数,可以在框架类中重写OnCommand函数,从而可以截获菜单消息使它不再往下(VIEW类)路由……”。 
到底是怎么截获的,请大家指教。先谢了。
---------------------------------------
我看了源码,在OnWndMsg 函数中
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
。 if (message == WM_COMMAND)
{
if (OnCommand(wParam, lParam))
{
lResult = 1;
goto LReturnTrue;
}
return FALSE;
}

}
可以看到OnCommand()函数是Cwnd调用的,此时即使在CWnd的框架类中重写了OnCommand函数,那么这里调用的不还是基类的OnCommand()函数吗?
一直搞不懂虚函数,到MFC中就乱套了,不知道我的想法错在哪?有人能给我点拨一下啊。谢啦。

解决方案 »

  1.   

    就是OOP中典型的特点与功能,晚绑定。
    建议楼主仔细复习下虚函数,大道不过三两言,说破不值一分钱。
    这个问题不难的。
      

  2.   

    唉,我就是爱刨根问底,可能问的不清楚,不好回答,我再补充下,比如,
    class Shape
    {
    public:
      virtual void Draw();
    };
    class Circle: public Shape
    {
    public
     void Draw();
    };
    class Angle: public Shape
    {
    public:
      void Draw();
    };
    //other class
    这样假如想调用Angle类的Draw(),不是要这样吗:
    Shape * a;a=new Angle;a->Draw();
    我看OnCommand()前面没有框架类的指针调用么,那样是怎么调用重载的OnCommang()呢?
    不懂,郁闷啊
      

  3.   

    哦 你是纠结在MFC的消息映射“如何用虚函数实现”是把?
    很简单,MFC的消息映射不采用虚函数实现(虽然技术上可以实现,而且这么做会更简单,但由于太费资源所以放弃使用这个方法)。MS自己定义了一套宏来实现MFC的消息映射。如何实现呢?孙鑫的书里应该有讲,主要是头文件中声明消息响应函数的原型,源文件中通过宏把消息(API原生消息诸如:WM_XXX)和消息响应函数(如:OnXXX)联系起来。更具体的看书本里的吧。比我讲的详细。
      

  4.   

    不,消息映射机制我懂。我是不懂为什么在框架类CMainFrame中重写OnCommand函数后,OnWndMsg()函数调用OnCommand()函数时 是调用CMainFrame中重写的OnCommand函数,而不是调用 没有重写OnCommand函数之前应该调用的基类的虚函数。
      

  5.   

    楼主继续往下看就明白了
    你说的也是正确的
    孙鑫说不让他路由应该指在响应菜单命令后就 return TRUE 了吧
      

  6.   

    CMainFrame  >>CFrameWnd  >> CWnd;
    CMainFrame继承自CWnd,
    所以在CWnd里
    BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) ;
    继承到CMainFrame里应该已经变成
    BOOL CMainFrame::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
      

  7.   

    是不是说程序运行时的实例是CMainFrame类,发生菜单消息时,是CMainFrame类的实例调用OnWndMsg()函数以及OnCommand()函数?如果这样的话我就理解了。
      

  8.   

    既然重载了,默然就是调用重载的函数
    除非使用显式CWnd::OnCommand()才会调用父类的函数
      

  9.   

    应该可以理解为OnWndMsg()与路由有关,会判断当前消息是命令消息还是通告消息
    当你点击菜单命令消息时,OnCommand()响应命令消息,就会先调用重载的CMainFrame::OnCommand()
    返回什么由你自己决定,是继续调用其父类的还是 return