VC菜单编程

菜单命令的路由

命令消息是由OnCommadn这个函数来处理的

当单击菜单项参数命令消息后。框架类会收到此条消息,然后框架类会把消息给视类。视类会查找自己是否对该消息作出响应,如果有,则进行相应的处理结束路由过程。没有则交给文档类,文档类也会查找是否对消息做出响应,作出了则结束,否则 又给视类,视类又给框架类,框架类又给应用程序类。


屏蔽菜单项,使之不能用 
(需要在CMainFrame::CMainFrame()中设置m_bAutoMenuEnable=FALSE;) 
GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION | MF_DISABLED | MF_GRAYED);

//GetMenu先获取菜单栏 然后GetSubMenu(0)获取第一个子菜单的指针,EnableMenuItem禁用菜单项第一个参数 的设置 取决于第二个参数的设置


添加UPDATE_COMMAND_UI对菜单操作 

如图所示


void CMainFrame::OnUpdatePhone1(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
if(pCmdUI->m_nID==IDM_PHONE1)
pCmdUI->Enable(false);
}


右键弹出菜单的创建 两种方式


动态添加菜单(子菜单数目变化)  
在MainFrame::OnCreate中试验如下  
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();  
       响应函数添加方法:  
1)  在resource.h中添加资源ID定义 
#define IDM_HELLO                                  111  
2)  在MainFrm.h中声明消息响应。DECLARE_MESSAGE_MAP()之前添加 afx_msg void OnHello(); 

3)  在MainFrm.cpp中END_MESSAGE_MAP()之前,添加 ON_COMMAND(IDM_HELLO,OnHello)

4)  在MainFrm.cpp中添加CMainFrame::OnHello()函数定义

给系统菜单添加/删除菜单项 
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);*/  
GetMenu()->DeleteMenu(       GetMenu()->GetSubMenu(1)->GetMenuItemID(0),MF_BYCOMMAND);  

动态添加系统菜单项  
电话本程序:键盘输入人名,空格之后电话号码。回车之后,把人名添加到菜单项。当点击菜单时,显示电话本信息。  
1,  给View添加private 的 
CString m_strLine;//存储输入的字符串 CMenu m_menu;//菜单 
int m_nIndex;//用于计数,是不是第一次  
2,  添加View的public成员 CStringArray m_strArray;  
3,  添加View的WM_CHAR消息响应函数  
4,  在View::OnChar中添加如下代码 CClientDC dc(this);  
if(0x0d==nChar)  {  
if(0==++m_nIndex)//如果是第一次,就创建菜单  {  
m_menu.CreatePopupMenu();  
GetParent()->GetMenu()->AppendMenu(MF_POPUP,

(UINT)m_menu.m_hMenu,"PhoneBook");  
GetParent()->DrawMenuBar();//立即显示菜单  }  
       
m_menu.AppendMenu(MF_STRING,IDM_PHONE1+m_nIndex,m_strLine.Left(m_strLine.Find(' ')));  
m_strArray.Add(m_strLine);  
m_strLine.Empty();  
Invalidate();//擦除先前的背景,防止重叠显示     }  else  {  
m_strLine+=nChar;  
dc.TextOut(0,0,m_strLine);  }

添加菜单的响应函数  
方法一:  
1)  在Toolbar上添加一个菜单,其弹出项为ID号为IDM_PHONE1, IDM_PHONE2, IDM_PHONE3。  
2)  在Rsource.h中添加  
#define IDM_PHONE1                                 201  
#define IDM_PHONE2                                 202 

#define IDM_PHONE3                                 203  

3)  利用ClassWizard给菜单项添加响应函数,并编辑函数  
4)  删除菜单项(其响应函数会依然存在,并且4步中利用了ID号,可以对应过去)  
方法二:  
视频没有提供,但我感觉应该有其他方法。方法一太死板  
6,  另:由框架类捕获菜单响应,而不是由View处理,可以节约代码  
1)  给MainFrame添加WM_COMMAND消息响应函数  可以LOWORD(wParam) wParam 的低序运行标识菜单项、控件或快捷键的命令ID
2)  在其中添加如下代码 
int MenuCmdId=LOWORD(wParam); 
CMenu2View *pView=(CMenu2View*)GetActiveView();  
if(MenuCmdId>=IDM_PHONE1 
&&MenuCmdId<IDM_PHONE1+pView->m_strArray.GetSize())  {  
CClientDC dc(pView);  
dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdId-IDM_PHONE1));  
return TRUE;    }  
第6点提供的方法,不能解决第5点提出方法的限制,响应菜单还是和事先编好的ID相对应,不能动态增加  
其他注意的地方:  
1,  弹出菜单(Pop-up)是不能用来作命令响应的。此项设置在菜单属性栏内。  
2,  将Toolbar的ID设为菜单的ID,二者即发生了关联。  
3,  在计算子菜单菜单项的索引的时候,分隔栏符也算索引。  
4,  消息影射函数 

Cpp文件中  
BEGIN_MESSAGE_MAP(CMenu2View, CView)  
//{{AFX_MSG_MAP(CMenu2View)  
//位置1  
//}}AFX_MSG_MAP  
位置2  
END_MESSAGE_MAP()  
头文件中  
       //{{AFX_MSG(CMenu2View)  
       位置3  
       //}}AFX_MSG  
位置4  
DECLARE_MESSAGE_MAP()  
消息映射在位置1和位置2不一样,可以调用Classwizard看到修改结果  
位置3和位置4的函数声明,随便放1或2都可以,没有影响

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值