菜单基本操作



版权声明:本文为博主原创文章,博未经主网求允许不得转载 https://blog.csdn.net/xiao3404/article/details/52810679


前言


本主要介绍菜单的基本使用,在MFC中用于指定菜单项位置有两种方式,它们是MF_BYCOMMAND和MF_BYPOSITION,在菜单操作中经常用到,具体含义如下:

MF_BYCOMMAND是指将相关参数解释为菜单项ID(缺省值)
MF_BYPOSITION是指将相关参数解释为零基偏移的菜单项,需要特别注意,菜单中的分隔符也占据一个位置


如图1是一个MFC窗口,其中文件,编辑,所在视图的位置的英文菜单栏,其中“文件(F)”,“编辑(E)”都是子菜单 “新建(N)”,‘保存(S)’等是菜单项。菜单项可以通过菜单项的标识ID进行访问,而子菜单只能通过索引号进行访问


                                               图1 MFC窗口

在CWnd类中,MFC提供了5个关于菜单的接口,同时MFC还为我们提供了CMenu类,该类是Windows HMENU的封装类。它提供了成员函数以用于创建,追踪,更新及销毁菜单,在文章末尾给出它们成员函数,这里主要介绍的CWnd类的5个接口和CMenu的类中基本菜单操作接口。


CWnd的类菜单


。DrawMenu函数用于重画菜单条如果在视窗创建窗口以后菜单条发生了改变,则应调用这个函数以画出改变了的菜单条,声明如下:

void DrawMenuBar( );
 
 

使用getMenu函数用于获得主窗口菜单栏指针,其函数声明如下:

CMenu* GetMenu( ) const;
 
 

GetSystemMenu用于应用程序访问控制菜单,用于拷贝和修改,其函数声明如下:

CMenu* GetSystemMenu( BOOL bRevert ) const;
 
 

HiliteMenuItem用于加亮显示一个顶层(菜单条)菜单项或清除其加亮显示状态,其函数声明如下:

BOOL HiliteMenuItem( CMenu* pMenu, UINT nIDHiliteItem, UINT nHilite );
 
 

。的SetMenu将当前菜单设为指定的菜单它使窗口被重画以反映菜单的变化,其函数声明如下:

BOOL SetMenu( CMenu* pMenu );
 
 


CMenu的类菜单操作


我们可以通过使用getMenu获得菜单栏的指针,而子菜单的指针是通过CMenu的类中的GetSubMenu来完成的,其函数声明如下:

CMenu* GetSubMenu( int nPos ) const;
 
 

由于程序的主菜单属于框架窗口,所以需要在框架窗口创建完成之后,再去访问菜单对象,我们可以在框架类的OnCreate中函数返回之前添加相应的代码,如果在CMainFrame的类中没有的OnCreate响应函数,需要我们手动添加该函数。


标记菜单


视图在子菜单下面有“工具栏(T)”和”状态栏(S)”两个菜单项,在它们前面都有一个对号(√),我们称这种类型的菜单为“标记菜单“,如图2所示。


                                图2标记菜单

为了实现这样的标记菜单,我们可以调用的CMenu中的CheckItem函数来完成这样的效果,其函数声明如下:

UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck );

 
 

现在我们将“文件(F)”下的“打开(O)”菜单项设置为标记菜单,实现代码如下:


 
 
  1. int CMainFrame :: OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. ...
  4. //标记菜单
  5. GetMenu() - > GetSubMenu( 0 ) - > CheckMenuItem(ID_FILE_OPEN,MF_BYCOMMAND | MF_CHECKED);
  6. 返回 0 ;
  7. }
 

运行效果:

默认菜单

一些在应用程序中的子菜单下有一个菜单项,它是以粗体形式出现的,以这种形式显示的就是该子菜单的默认菜单,我们可以利用SetDefaultItem函数来完成这个设置,其函数声明如下:

BOOL SetDefaultItem(UINT uItem,BOOL fByPos = FALSE);
 
 

实现代码如下:


 
 
  1. int CMainFrame :: OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. ...
  4. //默认菜单
  5. GetMenu() - > GetSubMenu( 0 ) - > SetDefaultItem(ID_FILE_NEW,FALSE);
  6. 返回 0 ;
  7. }

 

运行效果:

图形标记菜单

为了实现图形标记菜单项的效果,可以利用SetMenuItemBitmaps函数来显示,这个函数的作用是将制定的位图和菜单项关联起来,其函数声明如下:

BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked );
 
 
在图形标记菜单中, 显示的位图尺寸有固定的大小,其高度和宽度都是13 * 13

代码实现如下:


 
 
  1. int CMainFrame :: OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. ...
  4. //图形标记菜单
  5. m_BmpItem.LoadBitmap(IDB_BITMAP1);
  6. GetMenu() - > GetSubMenu( 0 ) - > SetMenuItemBitmaps( 2 ,MF_BYPOSITION,&m_BmpItem,&m_BmpItem);
  7. 返回 0 ;
  8. }
运行效果:



禁用菜单


为了达到屏蔽某些菜单功能,我们可以使用EnableMenuItem函数来实现,该函数的功能是设置菜单状态:能够使用,禁用或变灰显示,其函数如下:

UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );
 
 
为了将EnalbeMenuItem函数正常生效,需要在大型机构造函数中将m_bAutoEnableMenus设置为False,则此时MFC菜单项的显示状态不会自动更新,需要我们自己维护菜单显示状态

我们将m_bAutoEnableMenu设置为假后,那些没有设置功能的菜单项也都会显示为非灰色,造成误解,为了将某些功能禁用需要调用EnableMenuItem函数,具体代码:


 
 
  1. int CMainFrame :: OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. ...
  4. //禁用编辑下的所有菜单项功能
  5. CMenu * SubEditMenu = GetMenu() - > GetSubMenu( 1 );
  6. SubEditMenu-> EnableMenuItem( 0 ,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
  7. SubEditMenu-> EnableMenuItem( 2 ,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
  8. SubEditMenu-> EnableMenuItem( 3 ,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
  9. SubEditMenu-> EnableMenuItem( 4 ,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
  10. 返回 0 ;
  11. }
运行效果:



移除和装载菜单


在程序中,如果希望移除一个菜单的话或同时加载一个新的菜单可以利用的CWnd类提供的的SetMenu函数来实现移除和装载一个菜单代码实现如下:


 
 
  1. int CMainFrame :: OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. ...
  4. //默认的菜单栏从窗口中移除
  5. SetMenu( NULL );
  6. //设置新的菜单栏
  7. CMenu菜单;
  8. menu.LoadMenu(IDR_MENU_TEST); //自定义的菜单栏
  9. //将自定义菜单栏绑定到窗口
  10. 的SetMenu(菜单);
  11. //将菜单对象中的m_hMenu和菜单栏资源分离,
  12. //避免菜单对象析构时,菜单栏资源也被析构
  13. menu.Detach();
  14. / *
  15. HMENU CMenu :: Detach()
  16. {
  17. HMENU h = m_hMenu;
  18. m_hMenu = NULL;
  19. 返回h;
  20. }
  21. * /
  22. 返回 0 ;
  23. }
运行效果:



快捷菜单


如果我们想要提供一个右键快捷菜单功能,我们可以添加ON_WM_CONTEXTMENU或者ON_WM_RBUTTONDOWN消息响应函数,在消息响应函数中调用TrackPopupMenu函数来完成,其函数声明如下:

BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd,LPCRECT lpRect = NULL );

 
 

具体代码如下:

方式一:


 
 
  1. void CCMenuView :: OnContextMenu(CWnd * / * pWnd * / ,CPoint point)
  2. {
  3. // TODO:在此处添加消息处理程序代码
  4. CMenu菜单;
  5. VERIFY(menu.LoadMenu(IDR_MENU_RBUTTON));
  6. CMenu * pPopup = menu.GetSubMenu( 0 );
  7. pPopup-> TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,
  8. point.y, this );
  9. }

方式二:


 
 
  1. void CCMenuView :: OnRButtonDown(UINT nFlags,CPoint point)
  2. {
  3. // TODO:在此添加消息处理程序代码和/或调用默认值
  4. //该消息响应函数需要将转换鼠标点击坐标
  5. ClientToScreen(点);
  6. CMenu菜单;
  7. VERIFY(menu.LoadMenu(IDR_MENU_RBUTTON));
  8. CMenu * pPopup = menu.GetSubMenu( 0 );
  9. pPopup-> TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,
  10. point.y, this );
  11. CView :: OnRButtonDown(nFlags,point);
  12. }
运行效果:



CMenu的类的成员函数


构造函数



CMenu的构造一个CMenu的对象

初始化




















连接附加一个的Windows菜单句柄给CMenu的对象
分离从CMenu的对象中分离的Windows菜单的句柄,并返回该句柄
FromHandle返回一个指向给定的Windows菜单句柄的CMenu的对象的指针
GetSafeHmenu返回由CMenu的对象包含的m_hMenu值
DeleteTempMap删除由FromHandle成员函数创建的所有临时的CMenu对象
CreateMenu创建一个空菜单,并将其附加给CMenu的对象
CreatePopupMenu创建一个空的弹出菜单,并将其附加给CMenu的对象
LoadMenu从可执行文件中装载菜单资源,并将其附加给CMenu的对象
LoadMenuIndirect从内存的菜单模板中装载菜单,并将其附加给CMenu的对象
DestroyMenu销毁附加给CMenu的对象的菜单,并释放菜单占用的内存

菜单操作




DeleteMenu从菜单中删除指定的项。如果菜单项与弹出菜单相关联,那么将销毁弹出菜单的句柄,并释放它占用的内存
TrackPopupMenu在指定的位置显示浮动菜单,并跟踪弹出菜单的选择项

菜单项操作




































AppendMenu在该菜单末尾添加新的菜单项
CheckMenuItem在弹出菜单的菜单项中放置或删除检测标记
CheckMenuRadioItem将单选钮放置在菜单项之前,或从组中所有的其它菜单项中删除单选钮
SetDefaultItem为指定的菜单设置缺省的菜单项
GetDefaultItem获取指定的菜单缺省的菜单项
EnableMenuItem使菜单项有效,无效或变灰
GetMenuItemCount决定弹出菜单或顶层菜单的项数
GetMenuItemID获取位于指定位置菜单项的菜单项标识
GetMenuState返回指定菜单项的状态或弹出菜单的项数
GetMenuString获取指定菜单项的标签
GetMenuItemInfo获取有关菜单项的信息
GetSubMenu获取指向弹出菜单的指针
InsertMenu在指定位置插入新菜单项,并顺次下移其它菜单项
ModifyMenu改变指定位置的已存在的菜单项
RemoveMenu从指定的菜单中删除与弹出菜单相关联的菜单项
SetMenuItemBitmaps将指定检测标记的位图与菜单项关联
GetMenuCountextHelpID获取与菜单关联的帮助文本的ID号
SetMenuCountextHelpID设置与菜单关联的帮助文本的ID号 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值