菜单基本操作(二)
本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6285902.html
利用MFC编程时,菜单项状态的维护依赖于CN_UPDATE_COMMAND_UI消息,我们可以手工或利用ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来捕获CN_UPDATE_COMMAND_UI消息。
如图示,接下来,我们使Edit子菜单下的Cut菜单项变为可用状态。
打开类向导对话框,在框架类中添加如下函数,选择对象ID为ID_EDIT_CUT,Message列表框中选择UPDATE_COMMAND_UI消息,单击Add Handler添加消息响应函数,Edit Code。
这样,在框架类文件中添加了如下信息,
头文件中信息:
afx_msg void OnUpdateEditCut(CCmdUI *pCmdUI);
源文件信息一:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
…
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, &CMainFrame::OnUpdateEditCut)
END_MESSAGE_MAP()
源文件信息二:
void CMainFrame::OnUpdateEditCut(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
}
备注:UI即用户接口(User Interface),UPDATE_COMMAND_UI消息只能应用于菜单项,不能应用于永久显示的顶级菜单(即弹出式菜单)项目。
利用CCmdUI类的Enable函数实现菜单项的可用或禁用功能,代码如下:
void CMainFrame::OnUpdateEditCut(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI ->Enable();//默认为可用
// pCmdUI ->Enable(false);//false为不可用
}
运行可以看到工具栏和菜单项中的剪切功能都可用了。那么二者是如何关联的呢?通过分别查看Resource View下的Menu和Toolbar可以知道,菜单栏和工具栏下的剪切功能ID都是ID_EDIT_CUT,由此可知,如果要把工具栏上的一个工具按钮和菜单栏中的某个菜单项相关联,只要将它们的ID设为一致即可。
以禁用【文件】子菜单下的【新建】菜单项为例:
利用菜单项标识访问菜单项进行状态设置:
添加UPDATE_COMMAND_UI消息响应函数,具体代码如下:
void CMainFrame::OnUpdateFileNew(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI ->Enable(false);
}
运行可发现【新建】菜单项已经被禁用。
CCmdUI类有一个成员变量m_nID用于保存当前菜单项、工具栏按钮、或者是其他由CCmdUI对象表示的UI对象的标识。我们可以利用其进行判断是哪一个菜单项,当然实际应用时无需判断。
void CMainFrame::OnUpdateFileNew(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
if(ID_FILE_NEW == pCmdUI ->m_nID)
pCmdUI ->Enable(false);
}
CCmdUI类还有一个成员变量m_nIndex用于保存当前菜单项的位置索引。
if(2 == pCmdUI -> m_nIndex) //利用位置索引进行判断
注意:计算菜单项索引时必须把分隔栏菜单项计算在内。
在【剪切】菜单项的UI命令中利用位置索引进行判断时,会发现工具栏上的按钮状态并没有改变,这是因为菜单项和工具栏按钮的位置索引计算方式不同,它们都是从0计数,但可能位置索引不是一一对应的,因此为了保证二者状态的一致性,最好采用菜单项标识或工具栏按钮标识(二者一致)的方式来进行设置。
MFC采用的命令更新机制:
我们可以用类向导添加UPDATE_COMMAND_UI消息响应函数,而MFC在后台所做的工作是:当要显示菜单时,操作系统发出WM_INITMENUPOPUP消息,然后由程序窗口的基类如CFrameWnd接管。它会创建一个CCmdUI对象,并与程序的第一个菜单项相关联,调用该对象的一个成员函数DoUpdate(),这个函数发出CN_UPDATE_COMMAND_UI消息,这个消息带有一个指向CCmdUI对象的指针。这时系统会判断是否存在一个ON_UPDATE_COMMAND_UI宏去捕获这个菜单项消息。如果有则调用相应的消息响应函数进行处理,在这个函数中可以利用传递的CCmdUI对象去调用相应的函数来修改菜单状态。当更新完第一个菜单项后,同一个CCmdUI对象就设置为与第二个菜单项相关联,依此顺序进行,直到完成所有菜单项的处理。
总结:如果要在程序中设置某个菜单项的状态,首先通过ClassWizard为这个菜单项添加UPDATE_COMMAND_UI消息响应函数,然后在这个函数中进行状态的设置即可。
如果有疑问,可以联系giserdev@163.com,更多内容请参考:http://www.cnblogs.com/mxbs/,技术交流请加QQ群:586571286。