先摘段《vc++深入详解》孙鑫的话
以上讲的是点击主菜单时的消息路由过程,但鼠标右键快捷菜单的消息路由有点区别。
TrackPopupMenu函数用来创建右键快捷菜单。
例:
CMenu menu;
menu.LoadMenu(MENUID);
menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON
, x_position, y_position
, this);
注意最后这个参数this。
一般情况下,快捷菜单会在视类(view)中创建,也就是说上面这段代码写进视类中时,那么这个就this代表指向视类的指针。这个时候点击出现的快捷菜单,消息会如何传递呢?
首先由view类接收到消息,然后查看view类是否有对此消息进行处理,如果有,则进入view类消息处理函数进行处理。如果没有,将此消息传递给Doc类,然后再查看Doc类是否有对此消息进行处理,如果有,则进入Doc类消息处理函数进行处理。如果没有,则将此消息返回给view类。因此这个消息最后并没有传达到框架类(MainFrame类)。如果此时框架类定义了该消息的处理函数,等于是废品。
当然,如果把如下代码中的this改成AfxGetMainWnd(),情况就和《vc++深入详解》里面摘录的一样了。
AfxGetMainWnd()函数用来获得框架类窗口的指针。
menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON
, x_position, y_position
, this);
改成
menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON
, x_position, y_position
, AfxGetMainWnd());
也就是说,最后这个参数指定将消息首先传给谁。之后的消息路由是从上级往下级地毯式搜索对此消息的处理,找到了就处理,找不到就继续向下找,到了最底层还没找到就还给首先接到消息的类,然后用默认处理。