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

时间: 2024-10-17 18:23:42

MFC 菜单编程 -- 总结的相关文章

MFC菜单、工具栏和状态栏

菜单:CMenu类 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 CMenu类的主要成员函数        BOOL LoadMenu(UINT nIDResource);        加载菜单资源,并将其附加到CMenu对象上.参数nIDResource指定了要

MFC文本编程概述

本节是对文本编程的基本知识介绍 我们通过以下代码熟悉文本编程的基本函数有哪些,并且这些函数各有什么作用. 我们通过CClientDC创建一个设备描述上下文对象dc,然后定义一个TEXTMETRIC对象,TEXTMETRIC结构体对象用来表示目前设备描述表中字体的相关信息,其中最为重要的信息就是tmAveCharWidth平均字符的宽度(因为字符之间的宽度不一样,比如'w'和'i',明显前者比后者宽),tmHeight字符的高度,这个数据是相对于整体字符来说的,它包括tmAscent和tmDesc

【mfc】利用到MFC菜单、字体对话框、OnSize函数实现简易记事本

经过了之前大量mfc已经明白了许多功能,但是之前的项目一直没有使用到mfc的菜单功能,菜单是Win32功能很常见的东西,这个也必须要懂.其实菜单的建立也很简单,配合之前的文件操作功能,已经能够把开始->附件->记事本,就是那个notepad.exe写出来了. 一.基本目标 首先,这个记事本能够最大化,最小化,里面的编辑框也能够跟住最大化最小化,就是记事本里面组件不会失真,这个也不是理所当然的时候,要对OnSize进行写作,否则里面的组件是不会跟着最大化的,这大概就是mfc比vb艰难的原因吧!

实现MFC菜单画笔画圆,并且打钩

这个是用最简单的方法,移动客户区,圆会不见,所以下一篇我还要改进. 首先新建一个MFC单文件,在资源那里的菜单下,建立画笔,可以弹出红画笔,蓝画笔和绿画笔,,给出ID_RED,ID_BLUE,ID_GREEN并且在视类下建立类向导添加command函数,这时候,我们要想下怎么表示这些颜色,我的做法是,在视类定义一个公有整型变量int m_pencolor,还要设置三个布尔变量(表示打钩状态,等下会说)然后在构造函数初始化为1,(可以默认选红色)在视类头文件加上 {... public: bool

mfc socket编程

socket编程用法---- 随着计算机网络化的深入,计算机网络编程在程序设计的过程中变得日益重要.由于C++语言对底层操作的优越性,许多文章都曾经介绍过用VC++进行Socket编程的方法.但由于都是直接利用动态连接库wsock32.dll进行操作,实现比较繁琐.其实,VC++的MFC类库中提供了CAsyncSocket这样一个套接字类,用他来实现Socket编程,是非常方便的. ---- 本文将用一个Echo例程来介绍CAsyncSocket类的用法. ---- 一. 客户端 ---- 1.

《MFC网络编程》学习日记2

VC++的 MFC类库中提供了 CAsyncSocket这样一个套接字类,用他来实现 Socket编程,是非常方便的.本文将用一个 Echo例程来介绍CAsyncSocket类的用法.一. 客户端1. 创建一个 Dialog Based项目: CSockClient.2. 设计对话框去掉Ok和 Cancle两个按钮,增加 ID_Connect(连接) . ID_Send(发送) .ID_Exit ( 关闭)按钮, 增加ListBox控件IDC_LISTMSG和Edit控件IDC_EDITMSG,

《MFC网络编程》学习日记3

一个基于UDP的网络通迅程序:整个例子有两个程序组成,一个发送数据,另一个程序接收数据后,完成绘图工作.本文程序运行效果图如下: 一.发送程序首先建立数据发送程序( Fason) .一共发送四个数据:圆心的 X坐标.圆心的 Y坐标.圆半径 R.圆的颜色.它的实现主要如下:void CFasonDlg::OnSend(){UpdateData(TRUE);CString m_Getstring;this->m_Cob.GetLBText(m_Cob.GetCurSel(),m_Getstring)

Halcon与MFC交互编程

Halcon是商业化的机器视觉软件.网上下了halcon10的破解版,安装后编写了个图像显示的MFC小程序. 编译器用的是VS2008. 1 配置halcon环境 新建为MFC后,在VC++目录中配置包含文件和库文件 include路径:D:\Program Files\MVTec\HALCON-10.0\include D:\Program Files\MVTec\HALCON-10.0\include\cpp 主要是安装halcon的路径 lib文件:  D:\Program Files\M

MFC 网络编程中::connect返回-1问题

在MFC编写网络时遇到了::connect总是返回-1,但是与服务器可以进行接收和发送消息的操作. 原因是在进行连接的时候我没有进行初始化:::WSAStartup(w, &data);//动态链接库初始化 在MFC中进行重新连接是也要进行初始化且要先关闭套接字: ::closesocket(s); ::WSACleanup();