怎样使用CMenu类

 CMenu类从CObject类派生而来。为什么要使用CMenu类呢?AppWzard不是把菜
单做好了吗?在资源编辑器上修改菜单不是很方便吗? 
    我是个vc++初学者,自从当斑竹以来,天天看贴子,也学到了不少东西。感
觉学vc++稍微深入一点好,至少要能搞清楚AppWizard在背后都干了些什么东西。
事实上mfc就是用CMenu类来生成菜单的。让我们就从CMenu开始吧。 
    CMenu生成的菜单有两种:Popup类型和非Popup类型。这两种方法里又可以分
成使用资源编辑器生成的菜单资源和不使用这个资源。对于非Popup类型的菜单,
必须在创建出来后把它张贴到某个窗口上,它才会显示出来,从而才有用处。Po
pup的菜单却不能张贴到窗口上。 
    说明之前,先定义几个常量: 
#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 

一。创建非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()使菜单和My
Menu对象脱离关系,因为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); 

三。使用资源编辑器做好的菜单,只能做非POPUP类型菜单。 
    如果使用资源的话,创建菜单确实非常简单了,只须在窗口类的OnCreate()
函数里加几句话就行了: 
int CMyWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 

     CMenu  MyMenu3; 
     MyMenu3.LoadMenu(IDR_MENU1);//IDR_MENU1是你的菜单的资源ID。 
     this->SetMenu(&MyMenu3); 
     MyMenu3.Detach(); 
     return 0; 

    CMenu类还有很多成员函数,使你可以在运行中对菜单进行裁剪,比如加上几
项或减去几项等等,使用非常方便。大家可以去看msdn。 

    如果要实验以上的菜单创建方法的话,可以用一个非常简单的mfc程序来搞:

//这是一个非常简单的mfc程序,必要的函数自己去加吧。 
#include <afxwin.h> 

class CMyApp : public CWinApp 

public: 
     virtual BOOL InitInstance(); 
}; 

class CMyWnd : public CWnd 

public: 
      DECLARE_MESSAGE_MAP() 
}; 

CMyApp MyApp; 

BEGIN_MESSAGE_MAP(CMyWnd,CWnd) 
END_MESSAGE_MAP() 

BOOL CMyApp::InitInstance() 

      RECT rect={30,30,400,300}; 
      CMyWnd* pCWindow=new CMyWnd; 
      pCWindow->CreateEx 
      ( 
         NULL, 
         AfxRegisterWndClass(NULL,0,(HBRUSH)::GetStockObject(WHITE_BRU
SH),0), 
         "实验程序", 
         WS_OVERLAPPEDWINDOW, 
         rect,NULL,NULL,NULL 
      ); 
      m_pMainWnd = pCWindow; 
      pCWindow->ShowWindow(m_nCmdShow); 
      pCWindow->UpdateWindow(); 

      return TRUE; 

时间: 2024-09-15 02:22:34

怎样使用CMenu类的相关文章

VB打造超酷个性化菜单(一)

菜单 VB打造超酷个性化菜单(一) 众所周知,MS Office 2003推出已经有一段时间了,但我们依然不会忘记Office XP刚刚推出时其令人耳目一新的菜单给我们留下的深刻印象.突起的悬浮式图标,不同寻常的菜单项填充方式,不仅让办公一族们赞不绝口,更让广大的程序员和编程爱好者对这种风格的菜单的制作产生了浓厚的兴趣.所以,在这篇文章里,我们就来好好地研究研究用VB怎么制作这种风格的菜单,在文章的最后,我将给出源代码的下载地址.事实上,在了解其原理以后,不论是用VB.VC还是Delphi,都能

MFC消息映像实现动态菜单

当我们提到动态菜单的实现时,我们通常的做法是使用GetMenu() 函数获取一个Cmenu 类指针,然后调用CMenu 类方法AppendMenu, InsertMenu, ModifyMenu, RemoveMenu 等.本文介绍一种更加简洁的方法,它利用MFC 的消息映像机制及CCmdUI 类方法来实现. 首先,我们简要说说VC 中MFC 的消息映像.每个Windows 程序员大概都对以前使用的窗口函数WindowProc 记忆犹新,当我们面对各种消息时,我们别无他方,只能使用庞大而机械的s

MFC 菜单编程 -- 总结 .

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

为树形控件添加弹出式菜单,并跟踪所选择的项

[cpp] view plaincopy   <span style="font-size:24px;color:#ff0000;">为树形控件添加弹出式菜单,并跟踪所选择的项</span>   [cpp] view plaincopy   动态弹出式菜单   [cpp] view plaincopy    //获取当前右键的位置   CPoint pt;      GetCursorPos(&pt);      m_tree.ScreenToClien

基于对话框的MFC加菜单栏不成功

问题描述 基于对话框的MFC加菜单栏不成功 我想给对话框程序加菜单,在资源定义了自己的菜单ID为IDR_MENU1,然后给dlg类增加了CMenu类的成员变量m_Menu, 在OnInitDialog()函数增加菜单,代码如下: m_Menu->LoadMenu(IDR_MENU1); SetMenu(m_Menu) 可是为什么不成功

C++MFC编程笔记day02 MFC消息映射机制、菜单资源使用

机制3:MFC消息映射机制: 类内声明,类外定义宏,绑定消息处理函数派生自CCmdTarget类内声明宏:DECLARE_MESSAGE_MAP()类外添加实现宏:BEGIN_MESSAGE_MAP(类名,父类名)END_MESSAGE_MAP() //数据结构 struct AFX_MSGMAP_ENTRY {UINT nMessage;   // 消息IDUINT nCode;      // 通知码UINT nID;        // 控件ID或消息UINT nLastID;    //

MFC程序员WTL指南(3)WTL界面基类

对第二部分的介绍 好了,现在正式开始介绍WTL!在这一部分我讲的内容包括生成一个基本的主窗口和WTL提供的一些友好的改进,比如UI界面的更新(如菜单上的选择标记)和更好的消息映射机制.为了更好地掌握本章的内容,你应该安装WTL并将WTL库的头文件目录添加到VC的搜索目录中,还要将WTL的应用程序生成向导复制到正确的位置.WTL的发布版本中有文档具体介绍如何做这些设置,如果遇到困难可以查看这些文档. WTL 总体印象 WTL的类大致可以分为几种类型: 主框架窗口的实现- CFrameWindowI

串口通信-请高手帮忙回答,在龚建伟老师的串口调试中遇到了Serial串口类的问题

问题描述 请高手帮忙回答,在龚建伟老师的串口调试中遇到了Serial串口类的问题 点击打开串口按钮时,就会弹出以上图片的错误, 代码如下 // SerialPortTestDlg.h : header file // #include"SerialPort.h" #if !defined(AFX_SERIALPORTTESTDLG_H__37F6643D_1905_4655_883E_24AD7F141ED0__INCLUDED_) #define AFX_SERIALPORTTEST

CMenu菜单

菜单项属性说明:ID 标识菜单的唯一常量.Caption 菜单项标题,"&" 后面的字符为快捷键,在菜单项后的字符将加下划线.Separator 水平线,其它属性无效.Pop_up 有子菜单Grayed 无效,标题以灰色显示Inactive 无效,标题正常显示Checked 在标题前加一个对钩break 为None时,使它和它的兄弟们一行或一列显示.Help 只对最上层菜单项有效,使它及后面的最上层菜单移到窗口的右上角.Prompt 当鼠标指向它时的提示信息多文档应用程序除了生