Windows-菜单编程基本技术

来源:互联网 发布:奇兔刷机软件怎么样 编辑:程序博客网 时间:2024/04/27 22:24

Windows-菜单编程基本技术
一,简介
在许多的框架中都免不了对菜单进行操作,不管是QT,Android还是IOS,基本的应用程序框架都会涉及到对菜单的API的调用,但是万变不其宗,菜单的基本概念我们清楚之后,我们就能否更好的理解和调用,MFC中对菜单的基本操作相对简单,其中有点复杂的也就算自己实现菜单的命令响应函数的步骤,这其中涉及到对MFC消息映射机制的运用。

二,MFC菜单的分类
1.弹出式菜单
默认顶层菜单为弹出式菜单,不能响应菜单命令,将菜单应用为弹出式需要勾选Pop-Up属性,如下图。
这里写图片描述

2.菜单栏,子菜单,菜单项三者的区分
这里写图片描述
相信大家应该能够看明白吧,这是博主在书中总结出的,绝对正确。

三,MFC菜单命令的路由
基本路线是:View->Doc->Frame->App
具体过程分析:当我们点击某个菜单项的时候,最先接受的是Frame类。Frame类将接收的消息交给子窗口View类,View类首先处理。View类根据消息映射机制判断自身是否对此消息相应,响应就处理,消息路由结束。不响应就交给Doc类,Doc类同样判断自身是否对该消息进行响应,响应就处理,不响应就将此消息还给View类,View类再将此消息交给Frame类,Frame再判断自己是否对这个命令消息进行响应,响应就处理,不响应就再交给App类处理。

四,Windows消息分类
1.标准消息
除了WM_COMMAND之外,所有以WM_开头的都是标准消息。
2.命令消息
来自菜单,加速键或者工具栏的按钮的消息,这类消息都以WM_COMMAND形式呈现,通过ID来区分不同的命令。
3.通告消息
控件产生的消息,例如按钮的单击等,目的是为了向其父窗口通知事件的发生,这类消息也是以WM_COMMAND形式呈现。
从CWnd派生的类,三种消息都可以接收。
从CCmdTarget派生的类,不能接收标准消息。

五,基本菜单操作
1.注意:分隔栏也是一个菜单项,必须注意。

2.标记菜单
图片:
这里写图片描述
创建代码:

    #if 0        //通过索引设置标记菜单        GetMenu()->GetSubMenu(0)->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED);        /*许多的菜单函数的第一个参数的取值由第二个参数来确定*/    #endif    #if 0        //通过ID来设置标记菜单        GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW, MF_BYCOMMAND | MF_CHECKED);    #endif

3.默认菜单项(以粗体显示的菜单项)
注意:一个子菜单分支只能有一个默认菜单项
图片:
这里写图片描述
创建代码:

    #if 0        //通过索引设置默认的菜单项        GetMenu()->GetSubMenu(0)->SetDefaultItem(1, TRUE);    #endif    #if 0        //通过ID设置默认的菜单项        GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN, FALSE);    #endif    #if 0        //设置分隔线后面一个菜单项打印为默认菜单项,分割线也算一个菜单项,所以打印的索引是4(分割线) + 1 = 5        GetMenu()->GetSubMenu(0)->SetDefaultItem(5, TRUE);    #endif

4.图形标记菜单
简介:就是菜单项前面有一个相对应的图形标记。
图片:
这里写图片描述
一定要注意设置的位图的尺寸要跟系统规定的尺寸差不多,可以利用GetSystemMetrics函数

#if 1    //设置图形标记菜单    CString str;    /*    //x = 15 y = 15所以默认的图形标记菜单的位图大小为15 * 15    str.Format(_T("x = %d, y = %d"), GetSystemMetrics(SM_CXMENUCHECK),   GetSystemMetrics(SM_CYMENUCHECK));    MessageBox(str);    */    //设置图形标记菜单    GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0, MF_BYPOSITION, &m_bitmap, &m_bitmap);#endif

5.禁用菜单项
注意:区分禁用变灰,一般来说禁用一个菜单项都会让这个菜单项变为灰色。
另外,为了禁用菜单项,必须取消MFC的默认命令更新机制,在CMainFrame的构造函数中设置:m_bAutoMenuEnable = FALSE;即可
创建代码:

    #if 0        //通过索引禁用菜单项        GetMenu()->GetSubMenu(0)->EnableMenuItem(1, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);    #endif    #if 0        //通过ID禁用菜单项        GetMenu()->GetSubMenu(0)->EnableMenuItem(ID_FILE_OPEN, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);#endif

6.移除菜单栏
在MFC的框架类中可以设置不显示菜单栏这个对象。
设置的代码

#if 0    //移除菜单    SetMenu(nullptr);#endif

7.创建菜单栏对象
MFC也给我们提供了创建菜单栏对象的方法
创建代码:

#if 0    //创建菜单    CMenu menu;    menu.LoadMenu(IDR_MAINFRAME);    SetMenu(&menu);    //分离菜单句柄与菜单对象,防止局部变量出错    menu.Detach();#endif

8.快捷菜单(上下文菜单)
简介:就是我们再程序中右键弹出的菜单项
这里写图片描述

创建分为3个步骤
第一步:增加菜单资源,设置ID
这里写图片描述

第二步:为需要响应鼠标右键消息的类添加WM_RBUTTONDOWN消息
这里写图片描述

第三步:为菜单资源的菜单项设置响应函数
这里写图片描述

9.动态菜单操作
前面介绍的都是菜单的静态操作,这里介绍下菜单的动态操作。
9**.1菜单栏尾部添加子菜单**

#if 0    //添加弹出式子菜单    CMenu menu;    menu.CreateMenu();    GetMenu()->AppendMenu(MF_POPUP, (UINT_PTR)(menu.m_hMenu), _T("Test2"));    menu.Detach();#endif 

9.2菜单栏中插入子菜单

 #if 0    //插入子菜单    CMenu menu;    //先要创建menu对象    menu.CreateMenu();     //插入子菜单    GetMenu()->InsertMenu(2, MF_POPUP | MF_BYPOSITION, (UINT_PTR)(menu.m_hMenu), _T("Test3"));    //因为是局部变量的menu,所以需要分离    menu.Detach();#endif

9.3根据调用这个函数的对象来删除对应的菜单项

 #if 0    //删除索引为1的子菜单    GetMenu()->DeleteMenu(1, MF_BYPOSITION);#endif#if 0    //删除第一个子菜单的索引为2的菜单项    GetMenu()->GetSubMenu(0)->DeleteMenu(2, MF_BYPOSITION);#endif

六,MFC菜单命令更新机制
每一个子菜单下面的菜单项都需要设置自身的状态,这就需要设置响应的更新机制,MFC给我们提供了这种更新机制,利用MFC编程时,菜单项的状态的维护依赖于UPDATE_COMMAND_UI消息,但是只能应用于菜单项。
下面是一个示例,使得我们可以控制编辑下面的剪切是否可用

1.添加剪切更新处理命令
这里写图片描述

2.定义更新响应函数
这里写图片描述
这样我们就可以对剪切这个菜单项,进行状态的设置。

**下面介绍些MFC命令更新机制的原理:
当要显示菜单的时候,西永发出WM_INITMENUPOPUP消息,然后由程序窗口的基类接管,他会创建一个CCmdUI对象,并与程序子菜单的第一个菜单项关联,调用该对象的一层成员函数DoUpdate(),这个函数发出UPDATE_COMMAND_UI消息,这条消息带有一个指向CCmdUi的对象指针。这时,系统会判断该类是否有ON_UPDATE_COMMAND_UI宏去捕获这个菜单项消息,找到就调用响应函数处理,当更新完第一个菜单项后,同一个CCmdUI对象就设置为与第二个菜单项相关联,依次顺序进行,直到完成所有菜单项的处理。这就是MFC菜单项的命令更新机制。**

七,总结
这次主要介绍了菜单相关的编程技术,都是基本的API使用和概念,打牢基础很重要,下面是本次使用的资料。
自己总结的思维导图
这里写图片描述
网盘资料:https://yunpan.cn/cPbJkXRRvnkNe 访问密码 0a8f

0 0
原创粉丝点击