现在的位置: 首页 > 综合 > 正文

六.菜单

2014年09月05日 ⁄ 综合 ⁄ 共 3538字 ⁄ 字号 评论关闭

1.响应菜单命令顺序

视类-文档类-框架类-应用程序类

2.windows消息分类

标准消息

WM_COMMAND之外,所有以WM_开头的消息都是标准消息。从Cwnd派生的类,都可以接收到这类消息。

命令消息

来自菜单、加速键或工具栏按钮的消息。这类消息都可以WM_COMMAND形式吃不呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;SDK中,通过消息的wParam参数识别。从CcmdTarget派生的类,都可以接收到这类消息。

通告消息

由控件产生的消息,例如按钮的单击、列表框的选择等都会产生这类消息,目的是为了向其父窗口(通常对话框)通知事件的发生。这类消息也可以是WM_COMMAND形式呈现的。从CcmdTarge派生的类,都可以接收到这类消息。

3.菜单命令的路由

当点击某个菜单项时,最先接收到这个菜单命令消息是框架类。框架类交给视类,视类首先根据命令消息映射机制查找自身是否对此消息进行了响应,如果响应了调用相应函数处理,消息路由过程结束;如果没有响应交给文档类,如果没有响应交还给视类,视类在交给框架类,如果没有响应最后交给应用程序类。

4.标记菜单

GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_CHECKED|MF_BYPOSITION);

首先获取指向菜单栏的指针,在获取子菜单,在跟据索引或ID获取菜单项MF_BYPOSITION跟据索引获取 MF_BYCOMAND跟据ID获取第一个参数是索引或ID号。

5.默认菜单选项

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

同样第一个参数要跟据第二个参数来,如果第二个参数是FALSE,第一个参数是菜单项标识,否则是菜单项索引。

一个菜单只能有一个默认项,分隔栏也要占有索引位置。

6.图形标记菜单

bitmap.LoadBitmap(IDB_BITMAP1);

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

下面是获取标记菜单上,标记图形的尺寸。

      CString str;

  str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK));

  MessageBox(str);

7禁用菜单项

一旦在CmainFrame类的构造函数中把成员变量m_bAutoMenuEnable设置成FALSE后,就不需要对ON_UPDATE_COMMAND_UION_COMMAND消息进行响应处理了,CmenuEnableMenuItem函数将能够正常工作。

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

8.菜单的移除

SetMenu(NULL);

  cmenu.LoadMenu(IDR_MAINFRAME);

  SetMenu(&cmenu);

cmenu是局部对象的时候在窗口重绘时会出现问题,一个方式是将cmenu声明类的成员变量,一种是取消它的所有权.

menu.Detach();

这样当局部菜单对象生命周期结束时,它不会去销毁一个它不再具有拥有权的菜单。

 

9.MFC菜单命令更新机制

利用MFC编程,菜单项状态的维护依赖于CN_UPDATE_COMMAND_UI消息。我们可以通过手工,或利用ClassWizard在消息映射中ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。

 

当为菜单项添加一个UPDATE_COMMANG_UI消息响应函数,MFC在后台所做的工作是:当要显示菜单时,操作系统发出WM_INITMENUPOPUP消息,然后由程序窗口的基类如CframeWnd接管。它会创建一个CcmdUI对象,并与程序的第一个菜单项关联,调用该对象的一个成员函数DoUpdate()。这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息带有一个指向CcmdUI对象的指针。这时,系统会判断是否存在一个ON_UPDATE_COMMAND_UI宏去捕获这个菜单项消息。如果找到一个这样的宏,就调用相应的消息响应函数进行处理,在这个函数中,可以利用传递过来的CcmdUI对象去调用相应的函数,使该菜单项可以使用,或禁用该菜单项。当更新完第一个菜单项后,同一个CcmdUI对象就设置为与第二个菜单项相关联,依此顺序进行,直到完成所有菜单项的处理。这就是MFC采用的命令更新机制

因为工具栏和菜单栏的索引不一样,所以为保证二者状态一致,最好采用菜单项标识或工具栏按钮标识的方式来进行设置。

9.快捷菜单

右键显示菜单 称为快捷菜单,或上下文菜单。

VC++界面中选择Project菜单下的Add To Project然后从它的下拉菜单中选择[Com….]菜单项。

Pop-up Menu组件作用就是给一个派生CWnd类的窗口添加一个左键菜单。

      CMenu cmenu;

  cmenu.LoadMenu(IDR_MENU1);

  CMenu *popUp =cmenu.GetSubMenu(0);

  ClientToScreen(&point);

  popUp->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,GetParent());

10.添加菜单

BOOL AppendMenu(UNIT nFlags,UNIT_PTR nIDNEWITEM=0,LPCTSTR lpszNewItem=NULL);

GetMenu()->AppendMenu(MF_POPUP,(UINT)cmenu.m_hMenu,"Test");

关于AppendMenu

nFlags

指定新添加的菜单项目的状太息息,有多种多样的状态标志。

nIDNewItem

取决于第一个参数。如果第一个参数的值是MF_POPUP,那么nIDNewItem就是一个顶层菜单的句柄;否则就是要添加的新菜单项的命令ID.如果第一个参数的值是MF_SEPARATOR,那么nIDNewItem的值 将被忽略。

lpszNewItem

取值同样取决于第一个参数。如果第一个参数的值是MF_STRING,lpszNewItem就是指向要添加的这个菜单项目的文本的指针。如果第一个参数的值是MF_OWNERDRAW,则lpszNewItem就是指向该菜单项目的一个附加数据的指针.如果第一个参数的值是MF_SEPARATOR,lpszNewItem的值将被忽略。

11.插入菜单项目

GetMenu()->InsertMenu(0,MF_BYPOSITION|MF_POPUP,(UINT)cmenu.m_hMenu,"Test");

在指定位置前插入新菜单。

12.添加菜单项

  cmenu.AppendMenu(MF_STRING,111,"HELLO");

  cmenu.AppendMenu(MF_STRING,222,"bye");

  cmenu.AppendMenu(MF_STRING,113,"Mybloe");

13.删除菜单

GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);

14.动态添加菜单的命令响应

Resource.h

#define IDM_HELLO                  111

cmenu.AppendMenu(MF_STRING,IDM_HELLO,"HELLO");
1.
在响应这个菜单命令的程序类头文件中添加响应函数原型。添加的位置应该是在声明消息映射宏之上。两个AFX_MSG注释宏的后面。

afx_msg void OnHello();

2.在响应这个菜单项命令程序的类的源文件中的消息映射表中添加消息的映射。添加的位置应该是在BEGIN_MESSAGE_MAPEND_MESSAGE_MMAP宏之间,两个AFX_MSG_MAP注释宏之后。菜单命令的映射宏是ON_COMMAND宏。

3.实现菜单函数的定义体。

15.菜单栏的重绘

m_menu.CreatePopupMenu();

        GetParent()->GetMenu()->AppendMenu(MF_POPUP,(UINT)m_menu.m_hMenu,"PhoneBook");

GetParent()->DrawMenuBar();

抱歉!评论已关闭.