MFC(五)(菜单)

C……app类和C……doc类都不是从cwnd类派生的,不能使用直接使用messagebox(),可以使用全局的MessageBox()或者用应用程序框架的函数AfxMessageBox()

 

响应菜单项命令的顺序依次是:视图类、文档类、框架类、应用程序类

 

Windows消息分类:

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

 

命令消息:来自菜单、加速键、工具栏按钮的消息。这类消息都以WM_COMMAND形式呈现,在MFC中通过菜单项的标识ID来区分不同的命令消息

 

通告消息:由控件产生的消息如按钮、列表框选择等产生这类消息,这类消息也是以WM_COMMAND形式呈现,从CCmdTarget派生的类都可以接受这类消息,CWnd类实际派生于CCmdTarget类

总结:从CCmdTarget派生的类都可以接受命令消息和通告消息。。 从cwnd派生的类可以接受以上三类消息

 

设置标记菜单:

//getmenu获取菜单栏对象,然后用getsubmenu获取楼号对应的菜单对象,check……设置标记菜单,同理可以用该函数通过设置不同的参数来去除菜单标记

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

 

设置默认菜单项:

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

 

注:分割栏在子菜单中是占据索引位置的

 

 

设置图形标记菜单:

 

//获取系统的一些参数,当实参指定值为SM_CXMENUSIZE,SM_CXMENUSIZE,SM_CYMENUSIZE时获取的是菜单项上标记图形的默认尺寸

 

         CString str;

         str.Format("x=%d,y=%d",::GetSystemMetrics(SM_CXMENUSIZE),::GetSystemMetrics(SM_CYMENUSIZE));

         MessageBox(str);

//两幅位图分别显示选中前和选中后显示的位图

         this->GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(3,MF_BYPOSITION,&bitmap1,&bitmap2);

 

禁用菜单项:

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

//MFC为菜单提供了一种命令更新机制,程序运行时根据此机制去判断哪个菜单能使用哪个不能使用,默认机制下菜单项的更新都是MFC的命令更新机制完成的,如果我们要自己更新菜单状态就要把m_bAutoMenuEnable =false;设置为false(一般写在构造函数中)

 

移除、装载菜单项:

 

//当参数为NULL时就是移除菜单项

         SetMenu(NULL);

 

         //加载菜单项

         CMenu menu;

         menu.LoadMenu(IDR_MAINFRAME);

         SetMenu(&menu);

 

//将菜单句柄和菜单项分离,同时也将菜单对象的所有权交给窗口对象

         Detach();

 

MFC中菜单项状态的维护依赖于CN_UPDATE_COMMAND_UI消息

因此可以在CN_UPDATE_COMMAND_UI响应函数中进行以上一些对于菜单的操作,如:

void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)

{

         // TODO: Add your command update UI handler code here

 

         if (ID_EDIT_CUT==pCmdUI->m_nID)

         {

                   pCmdUI->Enable(false);

         }

        

}

 

添加快捷菜单

Project菜单下的Add to project然后选择Components and Controls菜单项(注意应该在view类上添加该组件,view类覆盖了frame类)

 

 

 

动态添加菜单:

①  在菜单末尾添加

         CMenu menu1;

         menu1.CreateMenu();

//由于菜单类的句柄是HMENU类型因此要进行类型转换

         this->GetMenu()->AppendMenu(MF_STRING,(UINT)menu1.m_hMenu,"我是谁");

//菜单对象的所有权交给窗口对象

         menu1.Detach();

 

②  插入菜单

BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );

 

删除菜单:

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

 

动态添加菜单项的响应命令:

 

三个步骤:

①  在响应这个菜单项命令的程序类头文件中添加响应函数原型,添加的位置应该是在声明消息映射宏(DECLARE_MESSAGE_MAP)之上,两个AFX_MSG注释宏的后面,如:

afx_msg void OnHello()

②  在响应这个菜单项命令的程序类源文件消息映射表中添加消息映射,位置在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏之间,菜单命令消息的映射宏是ON_COMMAND宏,如ON_COMMAND(IDM_HELLO,OnHello)

③  实现菜单命令消息响应函数的定义体,如:

Void CMainFrame::OnHello()

{

MessageBox(“hello world”);

}

 

        

posted @ 2012-04-17 21:10  乌托邦.  阅读(1552)  评论(0编辑  收藏  举报