• 基本菜单操作(一)


    本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6271011.html 

      认识菜单:

      有菜单栏、子菜单和菜单项三个概念。如图示:菜单栏包括若干子菜单,每个子菜单里有若干菜单项。

      对于菜单来说,子菜单和菜单项的访问是有所不同的。子菜单只能通过索引号进行访问;而菜单项既可以通过位置索引号实现访问,也可以通过菜单项的标识ID操作。

      标记菜单:

      带对号标记的菜单。

      如何标记菜单项?在框架类的OnCreate函数中依次:获得菜单栏GetMenu函数(即在框架窗口中获得指向菜单栏的指针);获取子菜单GetSubMenu函数为菜单项添加或移除标记CheckMenuItem函数。具体代码如下:

      //标记New菜单项,使用索引号访问菜单项
         GetMenu() -> GetSubMenu(0) -> CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED); 
      //使用菜单项ID访问
        GetMenu() -> GetSubMenu(0) -> CheckMenuItem(ID_FILE_NEW,MF_BYPOSITION | MF_CHECKED);

      注:索引号是从0开始的。

      这样我们就标记了File子菜单下的New菜单项了。如下图示:

      默认菜单项:

      子菜单下以粗体显示的菜单项,一个子菜单只能有一个默认菜单项。分隔栏在子菜单中是占据索引位置的。

    方法一,利用菜单项位置索引实现。

             默认菜单项的设置代码如下:

      //设置默认菜单-利用位置索引

      GetMenu() -> GetSubMenu(0) -> SetDefaultItem(0,TRUE);

    方法二,利用菜单项标识实现。

      默认菜单项的设置代码如下:

      //设置默认菜单-利用菜单项标识

      GetMenu() -> GetSubMenu(0) -> SetDefaultItem(ID_FILE_NEW,FALSE);

    运行可见,New菜单项已经以粗体显示。

      图形标记菜单:

      即菜单项前带有图形。如图VS中的图形标记菜单:

      利用CMenu类的SetMenuItemBitmaps函数,将指定的位图与菜单项关联起来。

        首先,新建一个位图资源。如图示:

        为了使位图可以作为标记菜单的内容使用,需要把位图对象设置为CMainFrame的成员变量。添加一个CBitmap类型的成员变量:m_bitmap。如果不知道如何添加成员变量,请查看此分类下之前的相应文章。

             接下来,就可以在CMainFrame类的OnCreate函数中添加实现图形标记代码了,代码如下:

             m_bitmap.LoadBitmap(IDB_BITMAP1);

         GetMenu() -> GetSubMenu(0) -> SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);

      运行,效果如下:可以看到New菜单项前显示了我们的位图标记。

      禁用菜单项:

      即是屏蔽某一个或多个菜单项的功能.

      我们可以利用CMenu类的成员函数EnableMenuItem来完成,该函数可以设置菜单项的状态:可以使用、禁用或变灰显示。通常情况下,我们会把禁用MF_DISABLED和变灰显示MF_GRAYED同时使用,但这并不是必需的。

      因为菜单栏在框架类上,通过实践可知,在框架类的OnCreate函数中可以实现禁用菜单项。代码如下:

      //禁用文件菜单下的打开菜单项

           GetMenu() -> GetSubMenu(0) -> EnableMenuItem(1,MF_BYPOSITION | MF_DISABLED);

      运行发现,打开功能仍可使用。

      问题在于:MFC为菜单提供了一个命令更新机制,程序默认会根据此机制判断菜单的可用性,然后显示其状态。默认状态下,所有的菜单项的更新都是由MFC命令更新机制完成的。如果我们想自己更改菜单项状态,需要将变量m_bAutoMenuEnable设置为FALSE,这样我们自己对菜单的状态更新才起作用。

      运行效果如图示:

     

      经VS2010测试发现,将菜单项设置为MF_GRAYED或MF_DISABLED均会导致菜单项不可用并灰色显示。(有待查阅相关技术文档)

      移除和装载菜单:

      利用CWnd类的成员函数SetMenu可以实现菜单的移除和装载:

        BOOL SetMenu(CMenu* pMenu);

      在框架类的OnCreate函数中,添加此函数:SetMenu(NULL);运行会发现已经没有了菜单栏了。

      当然也可以装载菜单资源并显示,下面把菜单资源加载进来并显示。

          //加载菜单栏

          CMenu menu;

          menu.LoadMenuW(IDR_MAINFRAME);

          SetMenu(&menu);

      运行,可以发现菜单栏已经加载成功。

      但是当我们单击菜单时会提示如下错误, 

      这个错误是由于CMenu对象menu是一个局部对象造成的。当menu的生命周期结束后就会去销毁其关联的菜单对象。

      解决方法一:将menu设置为框架类的成员变量

                  即将此定义:CMenu menu; 放到框架类的头文件中即可。

      解决方法二:在调用SetMenu()将此对象设置为窗口的菜单之后,立即利用CMenu类的成员函数Detach(),把菜单句柄与此菜单对象分离。

      理解:SetMenu()函数会把窗口的菜单设置为其参数指定的新菜单,导致窗口重绘,以反应菜单的变化,同时也将该菜单对象的所有权交给窗口对象。Detach()函数会将菜单句柄与菜单对象分离,这样当这个句柄菜单对象的生命周期结束时,它就不会去销毁一个它不再具有拥有权的菜单了。由于此菜单的所有权已经交给了窗口,因此当窗口销毁时这个菜单会自动销毁。

      //加载菜单栏

           CMenu menu;

           menu.LoadMenuW(IDR_MAINFRAME);

           SetMenu(&menu);

           menu.Detach();

      运行,可以看到程序已经正常了。

     

      如果有疑问,可以联系giserdev@163.com,更多内容请参考:http://www.cnblogs.com/mxbs/,技术交流请加QQ群:586571286。

  • 相关阅读:
    委托-张子扬博客
    委托-雾中人博客
    委托基础
    C# 字典
    相机标定目的<3>
    相机标定程序详解<2>
    相机标定 <1>
    Opencv 几何变换<9>
    Opencv ROI<8>
    Opencv 通道分离合并<7>
  • 原文地址:https://www.cnblogs.com/mxbs/p/6271011.html
Copyright © 2020-2023  润新知