MFC技术积累——基于MFC对话框类的那些事儿5
4. 菜单
4.1 弹出菜单
本节主要讲解如何在主对话框的指定区域内通过鼠标右击来弹出一个菜单选项。最终效果图如图4.1。

如图4.1鼠标只能在指定区域(图中深色区域)内右击时弹出菜单,在指定区域外点击时不执行创建菜单操作。具体操作步骤如下:
(1) 首先在指定区域响应鼠标右击消息,需要在主对话框类中添加消息句柄WM_RBUTTONUP,并在该消息响应函数void CFDlg::OnRButtonUp(UINT nFlags, CPoint point)中进行坐标判断,示例代码如下:
void CFDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
RECT myrc;//指定窗口区域
RECT wndrc;//主对话框窗口区域
RECT myrc_to_wndrc;//指定区域相对主窗口坐标
int pt_to_wndrcX;//光标X位置相对主窗口坐标
int pt_to_wndrcY;//光标Y位置相对主窗口坐标
CPoint pt_to_screen(point);//建立一个相对屏幕坐标系下的光标位置坐标
//获取指定区域的窗口指针
CWnd* mywnd = GetDlgItem(IDC_BITMAPAREA);
//获取指定窗口的客户坐标
mywnd->GetClientRect(&myrc);
//指定区域相对屏幕坐标系下的坐标
mywnd->ClientToScreen(&myrc);
//获取主窗口的客户区域坐标
GetClientRect(&wndrc);
//主窗口的客户区域相对屏幕坐标系下的坐标
ClientToScreen(&wndrc);
//光标位置相对屏幕坐标下的坐标
ClientToScreen(&pt_to_screen);
//计算指定窗口区域和光标位置相对主窗口客户区域的坐标
myrc_to_wndrc.left = myrc.left - wndrc.left;
myrc_to_wndrc.right = myrc.right - wndrc.left;
myrc_to_wndrc.top = myrc.top - wndrc.top;
myrc_to_wndrc.bottom = myrc.bottom - wndrc.top;
pt_to_wndrcX = pt_to_screen.x - wndrc.left;
pt_to_wndrcY = pt_to_screen.y - wndrc.top; if ( pt_to_wndrcX > myrc_to_wndrc.left && pt_to_wndrcX < myrc_to_wndrc.right &&
pt_to_wndrcY > myrc_to_wndrc.top && pt_to_wndrcY < myrc_to_wndrc.bottom)
{
//在指定区域进行鼠标右击消息响应操作,本节是创建弹出式菜单
}
CDialog::OnRButtonUp(nFlags, point);
}
(2) 其次创建弹出式菜单,示例代码如下:
CMenu mymenu;
if (mymenu.CreatePopupMenu())
{
//定义两条菜单项显示的字符串,其中‘&’比较有用,用于对弹出菜单通过指定键盘字符来响应
CString strFSR("第 1 条(&F)");
CString strWH("第 2 条(&S)");
//增加第1条菜单项,函数的第二个参数在Resource.h文件已经定义:
// #define IDM_FSRMENU 0x0020
// #define IDM_WHMENU 0x0030
mymenu.AppendMenu(MF_STRING, IDM_FSRMENU, strFSR);
//添加一条分割线
mymenu.AppendMenu(MF_SEPARATOR);
mymenu.AppendMenu(MF_STRING, IDM_WHMENU, strWH );
//在指定位置显示一个弹出式菜单
mymenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, pt_to_screen.x, pt_to_screen.y,this);
}
(3) 查看MSDN对CMenu::TrackPopupMenu的解释可知,TrackPopupMenu的第4个参数表示哪个窗口拥有这个菜单,该窗口处理菜单的WM_COMMAND消息。因此还需要添加对菜单条目的响应处理,示例代码如下:
BOOL CFDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
//添加菜单条目的命令消息代码
if (wParam = = IDM_FSRMENU)
{
MessageBox("选择第 1 条菜单选项");
}
else if (wParam = = IDM_WHMENU)
{
MessageBox("选择第 2 条菜单选项");
}
else
{
CDialog::OnCommand(wParam,lParam);
}
return TRUE;
}
此外还需要对OnCommand函数进行申明:
virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );系统框架调用该函数。
最后,结合图文方式介绍几个菜单条目操作:
(1) 菜单条目前添加位图,示例代码如下:
CString strFSR("第 1 条(&F)");
CString strWH("第 2 条(&S)");
// 增加第1条菜单条目,函数的第一个参数选择了MF_CHECKED,表示该菜单条目前有一个选中位图
//(形如“√”),如图4.2的第1条菜单条目所示
mymenu.AppendMenu(MF_STRING | MF_CHECKED , IDM_FSRMENU, strFSR );
mymenu.AppendMenu(MF_SEPARATOR);//添加分割线
mymenu.AppendMenu(MF_STRING, IDM_WHMENU, strWH );//添加第2条菜单条目
//添加第3条菜单条目,函数的第1个参数选择了MF_CHECKED
mymenu.AppendMenu(MF_CHECKED, 0x0040,"第 3 条(&T)");
// 为第3条菜单条目前增加一个位图,函数的第3、4参数分别表示当菜单未选中时使用的位图和菜单选
// 中时所用的位图。因此首先之前已经创建了两幅CBitmap对象。如图4.2所示,第3条菜单的状态是选
// 中,因此前面的“√”消失,取而代之的是一幅位图。而当第3条菜单条目是未被选中(AppendMenu
// 第1个参数是MF_UNCHECKED)那么此时该条目前显示的是未选中状态的位图,如图4.3。
mymenu.SetMenuItemBitmaps(0x0040,MF_BYCOMMAND,&uncheck_map,&check_map);
mymenu.AppendMenu(MF_STRING, 0x0050,"第 4 条(&D)");//添加第4条菜单条目
实现效果如图4.2和4.3:


(2) 创建层叠菜单,效果图如图4.4:

示例代码如下:
CMenu mymenu;
CMenu newmenu;//--
//创建一个层叠菜单,在后续操作时将其关联到主菜单的指定条目上
newmenu.CreatePopupMenu();
newmenu.AppendMenu(MF_UNCHECKED,0x0060,"层叠1");
newmenu.AppendMenu(MF_CHECKED,0x0070,"层叠2");
newmenu.AppendMenu(MF_STRING,0x0080,"层叠3");
CBitmap check_map;
CBitmap uncheck_map;
if (mymenu.CreatePopupMenu())
{
check_map.LoadBitmap(IDB_BITMAP3);
uncheck_map.LoadBitmap(IDB_BITMAP4);
CString strFSR("第 1 条(&F)");
CString strWH("第 2 条(&S)");
mymenu.AppendMenu(MF_STRING | MF_CHECKED , IDM_FSRMENU, strFSR );
mymenu.AppendMenu(MF_SEPARATOR);
//创建层叠菜单时,AppendMenu的第2个参数是层叠菜单的句柄,第1个参数为MF_POPUP
mymenu.AppendMenu(MF_POPUP, (UINT)newmenu.m_hMenu, strWH ); mymenu.AppendMenu(MF_CHECKED, 0x0040,"第 3 条(&T)");
mymenu.SetMenuItemBitmaps(0x0040,MF_BYCOMMAND,&uncheck_map,&check_map);
mymenu.AppendMenu(MF_STRING, 0x0050,"第 4 条(&D)"); mymenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, pt_to_screen.x, pt_to_screen.y, this);
}
4.2 窗口菜单
最后介绍一下如何在对话框窗口创建菜单,如图4.5所示:

方法很简单,只需要在BOOL CFDlg::OnInitDialog()函数中添加如下代码:
CMenu mymenu;
mymenu.LoadMenu(IDR_MENU1);
SetMenu(&mymenu);
mymenu.DestroyMenu();
其中ID号IDR_MENU1是在资源中创建一个菜单资源如图4.6所示:

最后对每个菜单选项进行ID号编辑后,即可在OnCommand函数中进行消息响应操作。
MFC技术积累——基于MFC对话框类的那些事儿5的更多相关文章
- MFC技术积累——基于MFC对话框类的那些事儿
1. 创建对话框类 (1)打开VC++6.0环境,点击:文件→新建: (2)在弹出的新建对话框中选择:工程→MFC AppWizard (exe)→输入工程名称(例如:功能调试)→工程保存路径名→确定 ...
- MFC技术积累——基于MFC对话框类的那些事儿2
3. 绘图 3.1 对话框资源编辑 首先通过添加控件的方式来创建一个简单的绘图对话框如图所示,创建步骤为: 第一.在VC++6.0软件环境的灰色空白区域右击,选中Controls,然后会弹出一个控件对 ...
- MFC技术积累——基于MFC对话框类的那些事儿3
3.3.2 创建图形画刷来实现位图加载 1.首先在Resource View中导入一幅位图,位图大小96×96像素: 2.其次在主对话框中添加一个静态文本资源,ID号是IDC_BITMAPAREA,添 ...
- MFC技术积累——基于MFC对话框类的那些事儿4
3.3.4 借助兼容DC加载DIB位图 创建一个与设备环境相兼容的DC,通过将位图暂时导入至兼容DC,然后利用CDC::BitBlt 或者CDC::StretchBlt函数将位图绘制到设备环境中. 示 ...
- MFC技术内幕系列之(四)---MFC消息映射与消息传递内幕
//////////////////////////////////////////////////////////////////////////////////// ...
- MFC编程入门之八(对话框:创建对话框类和添加控件变量)
创建好对话框资源后要做的就是生成对话框类了.生成对话框类主要包括新建对话框类.添加控件变量和控件的消息处理函数. 例程Addition是基于对话框的程序,所以程序自动创建了对话框模板IDD_ADDIT ...
- mfc 在VC的两个对话框类中传递参数的三种方法
弄了好久,今天终于把在VC中的对话框类之间传递参数的问题解决了,很开心,记录如下: 1. 我所建立的工程是一个基于MFC对话框的应用程序,一共有三个对话框,第一个对话框为主对话框,所对应的类为CTMD ...
- 【转】VS2010/MFC编程入门之八(对话框:创建对话框类和添加控件变量)
原文网址:http://www.jizhuomi.com/software/153.html 前两讲中鸡啄米为大家讲解了如何创建对话框资源.创建好对话框资源后要做的就是生成对话框类了.鸡啄米再声明下, ...
- VS2010/MFC对话框三:创建对话框类和添加控件变量
创建对话框类和添加控件变量 前两讲中讲解了如何创建对话框资源.创建好对话框资源后要做的就是生成对话框类了.生成对话框类主要包括新建对话框类.添加控件变量和控件的消息处理函数等. 例程Addition是 ...
随机推荐
- GDUT 积木积水 2*n 时间复杂度
题意 Description 现有一堆边长为1的已经放置好的积木,小明(对的,你没看错,的确是陪伴我们成长的那个小明)想知道当下雨天来时会有多少积水.小明又是如此地喜欢二次元,于是他把这个三维的现实问 ...
- [Selenium] Automation Test Manual(Selenium)
http://www.cnblogs.com/puresoul/p/3483055.html http://www.360doc.com/content/14/0913/10/13497042_409 ...
- Servlet初始配置 监听器和过滤器
ServletContext:application范围内的参数 此所设定的参 来源: http://note.sdo.com/my 数,在JSP网页中可以使用下列方法来取得: ${initParam ...
- 预处理指令#pragram
#pragma介绍 #pragma是一个预处理指令,pragma的中文意思是『编译指示』.它不是Objective-C中独有的东西(貌似在C/C++中使用比较多),最开始的设计初衷是为了保证代码在不同 ...
- 「LuoguT36048」 Storm in Lover
Description 平成二十四年(2012年),5月11日,东京,某弓道场. "呐,呐,海未酱,你听说了吗?几天后的那场弓道大会?啊-!"橙发少女兴奋地拿着一张传单一样的纸跑向 ...
- Spss22安装与破解教程
Spss22安装与破解教程 Spss22安装与破解教程 1.下载安装包 可以去IBM官网.人大论坛等网站下载,全部文件应包括spss22安装包(含32位及64位)和破解文件,这里提供一个64位的百度网 ...
- Git如何删除自己创建的项目
版本管理器第二行最右边,找到倒三角,下面的Edit Project,拖动鼠标到最下面,Remove project ,弹出框Confirmation required里面输入项目名字,如项目名字为“w ...
- 杂项-公司:Aspose
ylbtech-杂项-公司:Aspose Aspose 于2002年3月在澳大利亚悉尼创建,旗下产品覆盖文档.图表.PDF.条码.OCR.CAD.HTML.电子邮件等各个文档管理领域,为全球.NET ...
- B. Vanya and Books
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- 039--CSS
一.CSS定义 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. ''' selector { property: value; property: value; ... propert ...