从TrackPopupMenu(创建快捷菜单的函数)看菜单消息路由机制

时间:2021-04-19 15:31:05

先摘段《vc++深入详解》孙鑫的话

 

 从TrackPopupMenu(创建快捷菜单的函数)看菜单消息路由机制

以上讲的是点击主菜单时的消息路由过程,但鼠标右键快捷菜单的消息路由有点区别。

TrackPopupMenu函数用来创建右键快捷菜单。

 

例:

CMenu menu;

 

menu.LoadMenu(MENUID);

menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON

                                                                 , x_position, y_position

                                                                 , this);

注意最后这个参数this。

一般情况下,快捷菜单会在视类(view)中创建,也就是说上面这段代码写进视类中时,那么这个就this代表指向视类的指针。这个时候点击出现的快捷菜单,消息会如何传递呢?

从TrackPopupMenu(创建快捷菜单的函数)看菜单消息路由机制

首先由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());

 

也就是说,最后这个参数指定将消息首先传给谁。之后的消息路由是从上级往下级地毯式搜索对此消息的处理,找到了就处理,找不到就继续向下找,到了最底层还没找到就还给首先接到消息的类,然后用默认处理。