MFC创建菜单

来源:互联网 发布:2016年哪家宽带网络快 编辑:程序博客网 时间:2024/05/31 19:47

菜单栏、工具栏、状态栏是组成Windows图形界面的三个主要元素,大多数应用程序都给我们提供了菜单,我们也可以自己制作菜单。

            在编写菜单前必须对菜单的组成部分了解清楚子菜单和菜单项的区别,如果把菜单比作一栋楼,子菜单相当于楼层,菜单项相当于房间。比如当你想要访问301房间,一种方法是你可以直接把301当成索引去找,还一种方法是先找到第3层,然后找01号房间。虽然生活中这两种方法没什么差别,但是在菜单资源里选定菜单项就是这两种方法,既可按菜单项特定的ID寻找,也可以先找到2号子菜单,在从02子菜单中选定0号菜单项(子菜单和菜单项都是基于0开始的)。

    另外子菜单属于弹出式菜单,没有自己的控件ID,也没有对应的响应函数。一个特例就是子菜单唯一的菜单项就是它本身,将其Popup属性改成False就和普通子菜单下的菜单项没区别了。

         首先我创建了一个CMenuPro的对话框程序,删掉对话框上自带的3个控件后编译OK。然后自添加一个菜单资源,控件ID=IDR_MENU1,然后编辑了2个子菜单和各自的菜单项,如下:


        接下来要做的就是加载这个菜单资源,否则一切都是白搭。于是我在CCMenuProDlg类定义了一个CMenu成员对象m_menu,在对话框初始化函数 CCMenuProDlg::OnInitDialog()中用m_menu对象关联刚刚创建的菜单资源,然后设置到对话框加载这个菜单资源。

//装载一个菜单m_menu.LoadMenu(IDR_MENU1);SetMenu(&m_menu);
编译后发现菜单出现在了对话框中,如果显示的情况是这样的,怎么办呢?


这里只要改下菜单的显示方式即可,如下图所示:

加载好了菜单资源之后最重要的当然是编写响应函数啦。按照系统的步奏很简单,当然我们也可以分三步自己手动完成。

第一步:在对话框类中添加菜单项test的响应函数声明(注意前面的afx_msg!)

afx_msg void OnTest();

第二步:在源文件中做消息映射(注意格式)

BEGIN_MESSAGE_MAP(CCMenuProDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_COMMAND(ID_TEST, &CCMenuProDlg::OnTest)END_MESSAGE_MAP()

第三步:在源文件中编写响应函数

void CCMenuProDlg::OnTest(){// TODO: Add your command handler code hereMessageBox("clicked test");}
编译通过,点击对话框菜单项test,弹出对应的对话框。

        接下来可以给菜单项左边添加位图,可以设置标记菜单项,可以设置默认菜单项,可以禁用菜单项,也可以移除菜单项等,这些操作都在初始化窗口函数中完成。其中GetMenu函数返回CWnd类型指针,而GetSubMenu函数返回CMenu类型指针。下面前几个设置函数前2个的参数含义大致相同,第一个参数类型由第二个参数决定:当参数2表示的搜索方式为MF_BYPOSITION时,参数1表示基于0开始的按位置索引菜单项,当参数2表示的搜索方式为MF_BYCOMMAND时,参数1表示对应菜单项的控件ID(详MSDN)。

//装载一副位图m_bitmap.LoadBitmap(IDB_BITMAP);//设置子菜单位图GetMenu()->GetSubMenu(1)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);//设置标记菜单GetMenu()->GetSubMenu(1)->CheckMenuItem(1,MF_BYPOSITION|MF_CHECKED);//设置默认菜单GetMenu()->GetSubMenu(1)->SetDefaultItem(2,TRUE);//禁用菜单项GetMenu()->GetSubMenu(1)->EnableMenuItem(3,MF_BYPOSITION|MF_DISABLED);//移除菜单SetMenu(NULL);
除此之外,还可以动态创建子菜单,在CCMenuProDlg类再定义了一个CMenu成员对象m_addMenu,然后在初始化对话框函数中添加如下代码:

//动态添加菜单项m_addMenu.CreateMenu();GetMenu()->AppendMenu(MF_POPUP,(UINT)m_addMenu.m_hMenu,"addMenu");GetMenu()->GetSubMenu(2)->AppendMenu(MF_ENABLED,123,"help");
然后给新建的子菜单插入菜单项,删除菜单项,在子菜单末尾追加菜单项并添加响应函数,值得注意的是动态创建的菜单项并没有对应的控件ID

//插入新菜单GetMenu()->GetSubMenu(2)->InsertMenu(0,MF_ENABLED|MF_BYPOSITION,124,"find");//删除子菜单GetMenu()->GetSubMenu(2)->DeleteMenu(1,MF_BYPOSITION);//追加菜单项GetMenu()->GetSubMenu(2)->AppendMenu(MF_STRING,ID_HELLO,"hello");

但是我们可以在Resource.h这个头文件自己定义一个宏,如下图:


接下来消息映射的三个步骤见上文。编译通过!








0 0