VC++:菜单的使用总结

本文详细介绍了在VC++中创建、挂载、修改及自定义菜单的方法,包括通过资源文件、编程方式创建菜单,菜单的插入、删除、修改操作,以及如何处理WM_MEASUREITEM和WM_DRAWITEM消息来自定义菜单的显示。此外,还讨论了菜单命令的状态更新和维护,如启用、禁用、选择、复选和单选状态的控制。
摘要由CSDN通过智能技术生成

 

菜单是windows应用程序经常使用的资源之一。从今天开始,把有关菜单的创建及使用等各方面的基本用法总结到一起,算是做个笔记吧!准备一天写一点,陆陆续续完成!

一、菜单的创建:

(一)VC++菜单通过编辑资源文件直接创建菜单

可以自己编写菜单资源文件来完成来手工创建菜单,这与编程方法创建菜单不同。用这种方法创建菜单分两步:

1、在rc资源文件中编写菜单资源:

首先,要用其它文字编辑软件打开rc文件,然后在里面手工编写菜单资源。举例如下:

IDR_MENU1 MENU PRELOAD DISCARDABLE     

(注释:"IDR_MENU1"-->菜单ID名; "MENU"-->资源类名)

BEGIN   

(注释:以BEGIN开始,END结束菜单定义)

           POPUP "&File"  

(注释:POPUP--> 表明是一个弹出菜单 ;“&File"-->为菜单名字。"&"定义紧接后面的字母F快捷键。)

           BEGIN

                     MENUITEM "&New" ID_FILE_NEW

                    (注释:MENUITEM-->子菜单项;ID_FILE_NEW是ID值。)

                     MENUITEM "&Edit" ID_FILE_EDIT

                     MENUITEM SEPARATOR    

                   (注释:SEPARATOR-->分隔水平线;后面不需要跟ID值。)

                      MENUITEM "&Copy" ID_FILE_COPY

                      MENUITEM "E&xit" ID_FILE_EXIT

           END

END

其次,编辑resource.h文件,对菜单中的各种ID进行定义。

#define ID_FILE_NEW 0X8001

#define ID_FILE_EDIT 0X8002

#define ID_FILE_COPY 0X8003

#define ID_FILE_EXIT 0X8004

通过以上两步,就已经成功编辑了一个名为”File",ID为IDR_MENU1的菜单,此菜单弹出时,有“New","Edit","Copy","Exit"等四项菜单命令组成的子菜单。

定义一个CMenu变量,通过CMenu.LoadMenu()方法可以加载上面手工编成的菜单:

CMenu menu;

menu.loadMenu(IDR_MENU1);

然后通过menu变量就可以进一步操作菜单了。

也可以通过CFrameWnd::LoadFrame 加载菜单,直接把菜单挂载到框架窗口上面。如:

((CMainFrame *)pMainWnd)->LoadFrame(IDR_MENU1);

有些菜单是系统编制的,如程序的“系统菜单”。这种菜单你只可以在系统的基础上加以修改、添加和删除一些命令。

通过CMenu *pMenu=CWnd::GetSystemMenu(FALSE);即可获取系统菜单,然后可以对pMenu菜单指针进一步操作了。

(二)、通过编程软件visual studio中的资源视图中创建菜单:

这个比较简单易懂,进入编程环境中的“资源视图”中,右键“添加资源”,选择“Menu",即可开始手工创建工菜单。

直接上图:

(三)、编程创建菜单 

使用CMenu::CreateMenu,CMenu::CreatePopupMenu();CMenu::AppendMenu()可以编程创建菜单。

CMenu mainMenu;//创建一个CMenu变量,用于指向顶级菜单。

mainMenu.CreateMenu();//创建一个空的顶级菜单

CMenu popupMenu;//创建一个CMenu变量,用于指向弹出菜单——子菜单。

popupMenu.CreatePopupMenu();//创建一个空的弹出菜单——子菜单。

popupMenu.AppendMenu(MF_STRING,ID_EDIT_COPY,_T("&Copy"));//添加一个菜单子项。

popupMenu.AppendMenu(MF_STRING,ID_EDIT_CUT,_T("C&ut"));//添加一个菜单子项。

popupMenu.AppendMenu(MF_SEPARATOR);//添加一个菜单子项:水平分隔线。

mainMenu.AppendMenu(MF_POPUP,(UINT_PTR)popupMenu.detach(),_T("&Edit"));//在顶级菜单中挂载一个弹出菜单,其名为:Edit。//有些版本是强制转化为UINT

popupMenu.AppendMenu(MF_STRING,ID_FILE_NEW,_T("&New"));//添加一个菜单子项。

popupMenu.AppendMenu(MF_STRING,ID_FILE_OPEN,_T("&Open"));//添加一个菜单子项。

 

mainMenu.AppendMenu(MF_POPUP,(UINT_PTR)popupMenu.detach(),_T("&File));//有些版本是强制转化为UINT

setMenu(&mainMenu);//把菜单挂载到框架窗口上。

mainMenu.detach();//及时分离,防止因变量mainMenu的生命周期结束而影响菜单,如果不detatch,要影响到菜单不能正确显示。

菜单到此,编程的代码基本完成了。但是,上述代码中涉及的各种“ID”,需要在程序资源里面全部定义为常量才算全部完成。

ID_FILE_NEW,ID_FILE_OPEN,ID_FILE_EXIT,ID_EDIT_COPY,ID_EDIT_CUT等是系统已经定义的ID,不需要重新定义(当然,正常情况下不要使用这些ID)。如果ID为自定义的,需要你自己定义为常量。

 

二、菜单的挂载

有了菜单,当然要挂载到框架窗口上面。挂载的方法有以下几种:

(一)框架窗口创建时挂载

CFrameWnd::Create

BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );

使用这种方法挂载菜单时,菜单一般为拥有 ID,不能直接在此函数中使用。这时需要用到 MAKEINTRESOURCE()宏,其参数为WORD,返回值为:LPTSTR,这就能在函数中使用此菜单参数了。

(二)使用框架窗口类的虚函数CFrameWnd::LoadFrame()挂载菜单

CFrameWnd::LoadFrame

virtual BOOL LoadFrame( UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd* pParentWnd = NULL, CCreateContext* pContext = NULL );

此函数直接使用菜单的ID挂载。

(二)使用窗口类的SetMenu()函数挂载菜单

CWnd::SetMenu

BOOL SetMenu( CMenu* pMenu );

此函数要使用菜单指针,所以多用于编程形成的菜单的挂载。

三、菜单的修改

(一)菜单的插入

CMenu::InsertMenu

BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

菜单的插入,使用CMenu::InsertMenu就可以了。怎样使用它呢?

假设程序的现有菜单如下图所示:

现在我们可以这样插入:

1、插入“分隔线”:

 插入的位置在File菜单的第2个菜单项之后:

CMenu *pMenu=GetMenu();//获取当前菜单指针

pMenu->GetSubMenu(0)->InsertMenu(2,MF_BYPOSITION|MF_SEPARATOR);//在第一个子菜单第3个菜单项之前插入“分隔线”

第一个参数nPosition 要参照第二个参数nFlags的设置来确定含义。当

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值