3.8 快捷菜单
Windows95和Windows 3.x在界面上的一个重大差别就是Windows95增加了功能强大的右键快捷菜单。在任何一个对象上按鼠标右键,就会弹出一个与所选当前对象相关的菜单,菜单中列出了一组针对当前对象的操作。在Visual Studio中就有大量这样的菜单。比如,在项目工作区中单击右键时弹出菜单,让用户选择Docking View(停泊视图)、Hide(隐藏)和Properties(属性)操作。现在我们来讨论如何使用Visual C++为应用程序增加右键菜单。
这里我们也不是手工编程,而是使用Visual Studio提供的构件工具Component Gallery(组件画廊)向框架窗口添加快捷菜单。有关Componet Gallery的概念参见第二课2.1.5节。选择Project->Add to Project->Component and Controls菜单,弹出Component and Controls Gallery对话框,选择Developer Studio Components目录,在该目录下选择Popup Menu构件,如图3-15所示。
图3-15
按Insert按钮。弹出Poup Menu对话框,在Add popup menu to下拉列表框中选择CMainFrame,点OK按钮,关闭Popup Menu对话框。按Close按钮关闭Component and Controls Gallery对话框。编译运行Hello,弹出窗口后按右键,就弹出如图3-16所示的快捷菜单。菜单中包含三项:cut、copy、paste。因为没有对应的消息矗立函数,所有这些菜单都是灰色的、非活动的。
图 3-16
现在,我们看看Component Gallery是如何实现快捷菜单的。首先看资源视图的菜单资源,Component Gallery在其中增加了一个ID为CG_IDR_POPUP_MAIN_FRAME的菜单,菜单中包含了刚才我们看到的三个菜单项:cut、copy、paste。切换到类视图,浏览CMainFrame类,可以看到CMainFrame增加了一个OnContextMenu的成员函数,它是CWnd的一个方法,用于处理鼠标右键单击消息,原型如下:
afx_msg void OnContextMenu(CWnd* pWnd,CPoint point);
其中pWnd指向右键单击的窗口,它可以是一个本窗口的一个子窗口。比如,我们在工具条上单击右键时也弹出同样的菜单,工具条就是框架窗口的一个子窗口。OnContextMenu函数定义如清单3.6所示。
清单3.6 右键菜单
void CMainFrame::OnContextMenu(CWnd*, CPoint point)
{
// CG: This block was added by the Pop-up Menu component
{
if (point.x == -1 && point.y == -1){
//如果是键盘激活的快捷菜单,则在窗口左上角5,5的位置显示快捷菜单
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
}
//载入快捷菜单资源
CMenu menu;
VERIFY(menu.LoadMenu(CG_IDR_POPUP_MAIN_FRAME));
//取得本菜单的第一个子菜单
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
//如果当前窗口是一个子窗口,取其父窗口作为弹出菜单的拥有者
while (pWndPopupOwner->GetStyle() & WS_CHILD)
pWndPopupOwner = pWndPopupOwner->GetParent();
//在point.x,point.y处显示弹出式菜单并跟踪其选择项
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,pWndPopupOwner);
}
}
一般的,我们都可以使用Component Gallery的Popup menu构件为某个窗口、对话框、视图等增加快捷菜单而无需手工编程。我们要做的只是编辑修改缺省的菜单为我们自己的快捷菜单,并用ClassWizard生成必要的成员函数,在加入自己的代码。如果确实要手工做的话,首先应当用菜单编辑器增加一个菜单,然后为对应的窗口添加OnContextMenu方法,OnContextMenu的定义可以参考上面的程序。
Component Gallery的功能远不止向程序添加快捷菜单这一项,它还可以增加启动画面(Splash Window)、多页式对话框、口令检查对话框等多种功能。读者可以试着往Hello程序中添加Splash Window和口令对话框,体验一下Component Gallery的强大功能。
小 结
在这一章里,我们主要向读者介绍:
如何使用AppWizard生成Hello框架程序,并手工修改代码,让窗口显示 “Hello,World!”,并介绍了AppWizard所生成的文件。
应用程序的执行机制:框架调用缺省的WinMain函数,首先执行InitInstance初始化应用程序类的一个实例,然后调用Run进入消息循环。
框架窗口的使用:包括窗口的创建、注册类、窗口的关闭和撤消。
在窗口中加入菜单,分为三步工作:第一步,用菜单编辑器编辑菜单;第二步,用ClassWizard生成消息处理函数;第三步,手工编辑消息处理函数,完成特定的功能。
用户接口更新消息:接口更新机制原理,如何控制菜单的使能、灰化、选中。
快捷菜单编程:使用Component Gallery给应用程序添加快捷菜单。