1 顶层菜单默认都是Pop-up,即弹出式菜单,不能响应命令。
2.
当对某菜单添加消息响应函数时,
4个类的消息响应优先次序分别是: 1.View;2.CDOC;3.CMainFrame.4.CWinAPP. 为什么?请参阅《深入浅出》
3.
消息分类:
a;
标准消息(以
WM_开头的消息,但不包括WM_COMMAND);从CWnd派生的类,可以接受这类消息。
b;
命令消息
ON_COMMAND(IDM_PHONE1, OnPhone1),菜单和工具栏的消息。从CCmdTarget派生的类,可以接受这类消息。
c.
通告消息:按钮,列表框发出的消息。
从CCmdTarget派生的类,可以接受这类消息。
CCmdTarget
只能接受命令消息和通告消息。而从
CCmdTarget派生的CWnd 可以能接受命令消息和通告消息,也可以接受标准消息。
4.
确定菜单的索引号,注意从
0开始, 分隔符也算数。
GetMenu() 获取一个菜单指针(菜单栏对象)
GetSubMenu()获取子菜单的指针
一个子菜单只能有一个缺省菜单(粗体字体显示)。
//GetMenu()->GetSubMenu(0)->SetDefaultItem(5,TRUE);
SetMunuItemBitmaps() 将指定位图与菜单项关联起来,即菜单项前面显示图形。
图形标记菜单项上显示的位图的大小是13x13
str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),
GetSystemMetrics(SM_CYMENUCHECK));//
获得系统的菜单的位图的大小。
EnableMenuItem() 禁用菜单项
SetMenu(NULL);//
移除当前菜单
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
SetMenu(&menu);
menu.Detach();//
增加菜单,此处 detach(),如果是局部变量。
5.UPDATE_COMMAND_UI消息响应设置菜单项的状态
void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)
{
if(2==pCmdUI->m_nIndex)
pCmdUI->Enable();//
当此菜单显示时,设为可用。
}
6.
右键弹出菜单功能的实现方法有两个:
a.Project->Add to Project->component and controls->
文件夹VC components->Popup Menu OK
b.
用
TrackPopupMenu()
实现。
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu *pPopup=menu.GetSubMenu(0);
ClientToScreen(&point);//客户区坐标转换成屏幕坐标
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
GetParent());//注意,
TrackPopupMenu的参数的x,y都是屏幕坐标。
7.
动态创建菜单的方法:
CMenu menu;
menu.CreatePopupMenu();
// GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,"WinSun");
GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,"WinSun");
menu.AppendMenu(MF_STRING,IDM_HELLO,"Hello");
menu.AppendMenu(MF_STRING,112,"Weixin");
menu.AppendMenu(MF_STRING,113,"Mybole");
menu.Detach();
GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,"Welcome");
GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,
MF_BYCOMMAND | MF_STRING,115,"
维新");
// GetMenu()->DeleteMenu(1,MF_BYPOSITION);
// GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);
8.
为动态创建的菜单增加消息响应的步骤
a.
在
resource.h
中增加#define IDM_HELLO 123
b.
在
MainFrm.h
中加入afx_msg void OnHello();
c.MainFrm.cpp
中加入ON_COMMAND(IDM_HELLO,OnHello)
d.
最后加入
void CMainFrame::OnHello()
{
MessageBox("Hello!");
}
9.
动态增加电话号码本步骤
a.
处理
WM_Char
消息。如果回车,则清空字符串,窗口重绘 invalidate,将人名加入到菜单中,将字符串保存集合类 CStringArray中, 用的是成员函数 Add方法。
b.
取出动态创建的菜单的数据的方法。
1
)创建一个弹出菜单,弹出菜单下面有 4个子菜单。将子菜单的ID号连续。
2
)在resource.h中添加 #define IDM_PHONE1 123....
3
)添加其消息响应函数。注意注释中的文字
BEGIN_MESSAGE_MAP(CMenu2View, CView)
//{{AFX_MSG_MAP(CMenu2View)
ON_WM_CHAR()
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)//
下面的4句代码原来在此处。
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(IDM_PHONE1, OnPhone1)//
一定要这 4句代码移到此处。
ON_COMMAND(IDM_PHONE2, OnPhone2)
ON_COMMAND(IDM_PHONE3, OnPhone3)
ON_COMMAND(IDM_PHONE4, OnPhone4)
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
4
)填写代码
10.
如何在
MainFrame
中拦截OnCommand消息?答,在它增加 OnCommand的消息处理函数即可。
11.
错误调试方法:
Missing ";" before "*"
CMenu2Doc* GetDocument();//
因为CMenu2Doc是个不认识的变量,将其头文件包含进即可。
12 在CMainFrame类中重绘菜单栏
DrawMenuBar();//重绘菜单栏