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; 
}

怎样使用CMenu类的更多相关文章

  1. VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)

    鸡啄米在上一节中讲的是VS2010的菜单资源,本节主要讲菜单及CMenu类的使用. CMenu类的主要成员函数 MFC为菜单的操作提供了CMenu类,下面鸡啄米就常用的几个成员函数进行简单的介绍. B ...

  2. 菜单及CMenu类的使用

    CMenu类的主要成员函数 BOOL LoadMenu(UINT nIDResource); 加载菜单资源,并将其附加到CMenu对象上.参数nIDResource指定了要加载的菜单资源的ID.如果菜 ...

  3. VS2010-MFC(菜单:菜单及CMenu类的使用)

    转自:http://www.jizhuomi.com/software/212.html 上一节讲的是VS2010的菜单资源,本节主要讲菜单及CMenu类的使用. CMenu类的主要成员函数 MFC为 ...

  4. CMenu类中禁用/变灰某一项

    CMenu::EnableMenuItem   启用. 禁用,或变暗的菜单项.   UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable); 参数 ...

  5. 建立CMenu菜单项,实现选中菜单项点击左键响应事件

    这里我只是根据自己的项目做了一些总结,实现点击右键弹出菜单项,点左键选择菜单项: CMenu menu; VERIFY(menu.CreatePopupMenu());//新建一个cmenu菜单项 m ...

  6. Visual C++中最常用的类与API函数

    这篇文章能让初学者快速了解visual C++ MFC中常见的核心的类与函数,虽然全部看下来有点枯燥,但对初学者快速了解MFC的框架结构很有好处. 常用类 CArchive类:用于二进制保存档案 CB ...

  7. VS2010/MFC编程入门之三十六(工具栏:工具栏资源及CToolBar类)

    上一节中鸡啄米讲了菜单及CMenu类的使用,这一节讲与菜单有密切联系的工具栏. 工具栏简介 工具栏一般位于主框架窗口的上部,菜单栏的下方,由一些带图片的按钮组成.当用户用鼠标单击工具栏上某个按钮时,程 ...

  8. VS2010-MFC(工具栏:工具栏资源及CToolBar类)

    转自:http://www.jizhuomi.com/software/215.html 上一节讲了菜单及CMenu类的使用,这一节讲与菜单有密切联系的工具栏. 工具栏简介 工具栏一般位于主框架窗口的 ...

  9. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

随机推荐

  1. 基于visual Studio2013解决C语言竞赛题之0414特殊平方数

       题目 解决代码及点评 这道题依旧是通过for循环,遍历所有四位数,然后根据题目要求判断数的性质即可 /**************************************** ...

  2. 上证A股股指跌破1900

    上证A股股指跌破1900 有钱的同学赶紧买哦,机会难得哈哈!

  3. 面向对象(类,实例变量,方法定义,方法重载,构造方法,this,string类)

    面向对象 类是由属性和方法组成 类是所有创建对象的模板 实例变量有默认值 实例变量至少在本类范围中有效 实例变量与局部变量冲突时,局部变量优先 类中方法定义类似于函数定义 修饰符 返回值类型 方法名( ...

  4. 浅谈HTML之模仿人人网登陆界面(新手必学)

    为方便大家对web相关知识的了解,现谈谈新手如何从HTML css  Javascript到以后后台的发展.首先,让大家看看HTML仿人人登陆界面: <!doctype html> < ...

  5. 网站实战 从效果图开始CSS+DIV 布局华为网站

    经过我们的前面css的学习,我们已经分模块的掌握的CSS的技术,但是,要是完整的做一个页面,我们还没有接触过,这次呢,小强老师来和大家完整的利用CSS+DIV做一个网站案例,我们来模仿下华为的网站. ...

  6. Integral Promotions整数提升和符号扩展(char,unsigned char,signed char)

    以下来自msdn: Objects of an integral type can be converted to another wider integral type (that is, a ty ...

  7. TCP拥塞控制算法内核实现剖析(十)

    内核版本:3.2.12 主要源文件:linux-3.2.12/ net/ ipv4/ tcp_veno.c 主要内容:Veno的原理和实现 Author:zhangskd @ csdn blog 概要 ...

  8. ADO.NET 2SqlDataAdapter、DataSet 的基本用法

    数据集完全独立于数据源,可以与数据源链接或者完全断开,其基本作用是为存储在内存缓存中的的数据提供关系视图 如果只是想读取和显示数据,则值需要使用数据读取器,尤其是处理大量数据的时候 如果需要处理数据, ...

  9. 幻世(OurDream)2D图形引擎使用教程8——处理操作输入(2)

    声明:本教程版权归Lizcst Software Lab所有,欢迎转载,但是转载必须保留本段声明文字,并注明文章来源:http://blog.csdn.net/kflizcst 谢谢合作! 今天的教程 ...

  10. gdi+ 高速绘制透明窗体

    gdi+ 高速绘制透明窗体: 方法一: 1.用Iamge对象载入png资源, 2.调用drawimage函数讲图片绘制出了 3.UpdateLayeredWindow对窗体进行布局 方法二: 1.用B ...