• MFC 菜单编程 总结 .


    菜单结构

    1. 一个菜单栏可以有若干个子菜单,而一个子菜单又可有若干个菜单项。
      对于菜单栏的子菜单,由左至右从0开始索引。
      对于特定的子菜单的菜单项,由上至下建立从0开始的索引。
      访问子菜单和菜单项,均可通过其索引或标识进行。
    2. 对于在窗口客户区右键弹出的菜单,如果弹出菜单归属View 类窗口,则菜单项只能响应View 和Doc 类消息点击。
    3. 如果弹出菜单归属框架窗口,弹出菜单上的消息的路由遵循View -DOC-MainFrame-APP的响应顺序 。

     

    菜单的相关重要函数

    1. CMenu*    GetMenu( ) ;                  // 得到菜单指针
    2. CMenu*    GetSubMenu( ) ;           // 得到子菜单指针,也就是弹出菜单指针
    3. UINT CheckMenuItem( );              // 将菜单项加上或去掉√(对号)标记
      a.如果第一个参数是ID号,    第二个参数必须是MF_BYCOMMAND | MF_CHECKED的组合
      b.如果第一个参数是索引号, 第二个参数必须是MF_BYPOSITION   | MF_CHECKED的组合
    4. BOOL SetDefaultItem();                // 设置缺省菜单,也就是将菜单项粗体显示
      a.如果第一个参数是索引号,第二个参数必须是true
      b.如果第一个参数是ID号,第二个参数必须是false
      *注 :一个子菜单最多只能有一个缺省菜单项
    5. BOOL SetMenuItemBitmaps( );      // 设置位图标记,标记大小为13*13像素
      a.如果第一个参数是ID号,第二个参数必须是MF_BYCOMMAND
      b.如果第一个参数是索引号,第二个参数必须是MF_BYPOSITION
      ,第三个参数是没有选中时的位图,第四个参数是标记时的位图
    6. UINT EnableMenuItem();                //使菜单项有效,无效,或变灰
      a.如果第一个参数是ID号,第二个参数必须是MF_BYCOMMAND 和有效,无效,或变灰 的组合
      b.如果第一个参数是索引号,第二个参数必须是MF_BYPOSITION 和有效,无效,或变灰 的组合
      *注 :若让此函数生效,必须在mainfrm构造函数中添加:m_bAutoMenuEnable =false,
      此时,其他变灰的菜单项也就恢复为不变灰状态了,会有副作用的
    7. BOOL SetMenu( CMenu* pMenu );  //在当前窗口上设置新菜单或移除菜单。
      如果参数为0,则是移除菜单。
      自己创建菜单{CMenu menu;menu.LoadMenu(IDR_MENU1);
      SetMenu(&menu);menu.Detach();}
    8. HMENU Detach( );  // 如果将CMenu 对象设置为局部对象,使用Detach()从menu对象中分离窗口菜单句柄,从而当menu对象析构的时候窗口菜单资源不随之销毁

     

    菜单的相关操作的实现方法

    a.添加对号标记:
    方法一:   GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED );                          //通过索引
    方法二:   GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_CHECKED );     //通过ID

     

    b.设置缺省菜单项:

    每个子菜单最多只能有一个缺省菜单项
    方法一: GetMenu()->GetSubMenu(0)->SetDefaultItem(1,true);                             //通过索引
    方法二: GetMenu( )->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN,false);     //通过ID

     

    c.添加图形标记:
    方法一:通过ID
    CBitmap bitmap;       //必须设置为全局对象
    bitmap.LoadBitmap(IDB_BITMAP1);
    GetMenu( )->GetSubMenu(0)->SetMenuItemBitmaps(ID_FILE_NEW,MF_BYCOMMAND,&bitmap,&bitmap);

    方法二:通过索引
    CBitmap bitmap;       //必须设置为全局对象
    bitmap.LoadBitmap(IDB_BITMAP1);
    GetMenu( )->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION ,&bitmap,&bitmap);


    d.使菜单无效,变灰

    //必须在构造函数中添加:   m_bAutoMenuEnable = false;
    GetMenu( )->GetSubMenu(0)->EnableMenuItem(ID_FILE_OPEN,MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

     

    e.移除菜单
    SetMenu(0);

     

    f.添加菜单
    CMenu menu;
    menu.LoadMenu(IDR_MAINFRAME);
    SetMenu(&menu);
    menu.Detach();

     

    图形标记大小

    系统获得位图标记的大小:
    CString str;
    str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK));
    MessageBox(str);

    命令更新机制

    菜单的UPDATE_COMMAND_UI消息响应

    {
         pCmdUI->Enable(false);       // true和false 来设置能否使用或变灰
         pCmdUI->SetCheck(true);   // true和false 来设置标记
         pCmdUI->SetText(“cut”);    //改变菜单项文本内容

    }

     

     

    动态创建菜单

    先定义几个常量:
    #define IDM_MENU0 0
    #define IDM_MENU1 1
    #define IDM_MENU2 2
    #define IDM_MENU3 3
    #define IDM_ITEM0 10
    #define IDM_ITEM1 11
    #define IDM_ITEM2 12
    #define IDM_ITEM3 13
    #define IDM_ITEM4 14
    #define IDM_ITEM5 15
    #define IDM_ITEM6 16

     

    // 在最后一个菜单项后面添加菜单项
    BOOL AppendMenu ( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL);
    BOOL AppendMenu ( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

    // 插入菜单项
    BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );
    BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

    // 移除菜单项
    BOOL RemoveMenu( UINT nPosition, UINT nFlags );

    // 删除菜单项
    BOOL DeleteMenu( UINT nPosition, UINT nFlags );

    一 、创建非Popup类型菜单,不使用资源。
    (一)创建非下拉菜单。
    1。在窗口类的OnCreate函数里创建CMenu对象。如果是创建运用程序主框架窗口
    的话,也可以在InitInstance()函数里。
    2。声明一个CMenu对象:CMenu MyMenu;
    3。调用MyMenu.CreateMenu()或MyMenu.LoadMenu()
    4。调用若干次MyMenu.AppendMenu()或MyMenu.InsertMenu(),每调用一次创建一
    个菜单项。
    5。调用MyMneu.SetMenu()将菜单Attach到窗口上。
    6。调用MyMenu.Detach()。

    例子:
    int CMyWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
    {
         CMenu MyMenu;
         MyMenu.CreateMenu();
         MyMenu.AppendMenu(MF_STRING,IDM_MENU0,"文件");
         MyMenu.AppendMenu(MF_STRING,IDM_MENU1,"编辑");
         MyMenu.AppendMenu(MF_STRING,IDM_MENU2,"查看");
         MyMenu.AppendMenu(MF_STRING,IDM_MENU3,"帮助");
         MyMenu.InsertMenu(IDM_MENU2,MF_BYCOMMAND,IDM_ITEM0,"有关");
         this->SetMenu(&MyMenu);
         MyMenu.Detach();
         return 0;
    }//各个函数的细节就不讲解了,看联机帮助是最好的。
    这个方法是先把菜单创建好后再贴到窗口上去,然后用Detach()使菜单和MyMenu对象脱离关系,因为MyMenu对象马上就要超出作用域了,这一步是必须的。


    (二)创建下拉菜单,不使用资源。
        这种菜单当鼠标移动到菜单条目上面点击时不是去执行某段程序,而是弹出
    一个下拉菜单。这需要用前面的方法创建两个菜单。第一个是鼠标未点击时看到
    的那个菜单,另一个就是扮演下拉菜单的菜单。例子:
    int CMyWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
    {
            CMenu MyMenu0,MyMenu1;
            //下面这几条创建下拉菜单
            MyMenu1.CreateMenu();
            MyMenu1.AppendMenu(MF_STRING,IDM_ITEM0,"拷贝");
            MyMenu1.AppendMenu(MF_STRING,IDM_ITEM1,"剪切");
            MyMenu1.AppendMenu(MF_STRING,IDM_ITEM2,"粘贴");
            MyMenu1.AppendMenu(MF_SEPARATOR,IDM_ITEM3,"");
            MyMenu1.AppendMenu(MF_STRING,IDM_ITEM4,"全选");
            MyMenu1.AppendMenu(MF_SEPARATOR,IDM_ITEM5,"");
            MyMenu1.AppendMenu(MF_STRING,IDM_ITEM6,"删除");
            //下面这两条创建鼠标未点击时看到的那个菜单
            //其中第二句将下拉菜单张贴到第一个菜单上。
            MyMenu0.CreateMenu();
            MyMenu0.AppendMenu(MF_POPUP,(UINT)MyMenu1.m_hMenu,"编辑");

            this->SetMenu(&MyMenu0);//将菜单张贴到窗口上
            MyMenu0.Detach();//必须有
            MyMenu1.Detach();//必须有
            return 0;
    }

    二、创建Popup类型的菜单,也不用资源。
        很多程序里,只要用鼠标右键点一下窗口客户区,就会在鼠标的位置弹出一
    个菜单,这叫右键菜单。我们可以用CMenu类来制作。
        制作这种菜单比制作第一类菜单稍微复杂点。首先要在窗口类里加个成员变
    量:CMenu *MyMenu2;
        然后在窗口类的构造函数里(或OnCreate()函数里)加上创建菜单的语句,再
    在析构函数里加上销毁菜单的语句,最后在OnRButtonDown()函数里加上显示菜单
    的语句。
        创建菜单时,CMenu类对象应该用new来分配。
        例子:

    CMyWnd::CMyWnd()
    {
         //CMyWnd是从CWnd派生来的。
         //先把菜单创建起来。
         MyMenu2=new CMenu;
         MyMenu2->CreatePopupMenu();
         MyMenu2->AppendMenu(MF_STRING,IDM_ITEM0,"拷贝");
         MyMenu2->AppendMenu(MF_STRING,IDM_ITEM1,"剪切");
         MyMenu2->AppendMenu(MF_STRING,IDM_ITEM2,"粘贴");
    MyMenu2->AppendMenu(MF_SEPARATOR,IDM_ITEM3,"");
         MyMenu2->AppendMenu(MF_STRING,IDM_ITEM4,"全选");
         MyMenu2->AppendMenu(MF_SEPARATOR,IDM_ITEM3,"");
         MyMenu2->AppendMenu(MF_STRING,IDM_ITEM5,"删除");

    }
    CMyWnd::~CMyWnd()
    {
         MyMenu2->DestroyMenu();//销毁菜单所占用的系统资源
         delete MyMenu2;//销毁菜单类对象
    }
    void CMyWnd::OnRButtonDown(UINT nFlags, CPoint point)
    {
         RECT rect;
         GetWindowRect(&rect);
         //显示菜单
         MyMenu2->TrackPopupMenu(TPM_RIGHTALIGN,point.x+rect.left,point.y+
    rect.top,this,NULL);
    }

    from:http://blog.csdn.net/ltag0110rtag/article/details/7368633

  • 相关阅读:
    (转)CortexM3 (NXP LPC1788)之启动代码分析
    (转)CortexM3 (NXP LPC1788)之RTC
    (转)CortexM3 (NXP LPC1788)之外部中断操作
    (原创)TCP/IP学习笔记之ARP(地址解析协议)
    (原创)CheckTool:CRC校验、累加和校验、异或和校验专业校验工具V1.0
    (转)CortexM3 (NXP LPC1788)之SysTick系统节拍定时器
    (转)CortexM3 (NXP LPC1788)之UART用法
    工具 MyEclipse8.5注册码
    Delphi – UtWinHttp_API.pas From winhttp.h
    Delphi – TCanvas.CopyRect方法中参数CopyMode的意义
  • 原文地址:https://www.cnblogs.com/lidabo/p/2598720.html
Copyright © 2020-2023  润新知