您的位置:首页 > 其它

MFC中复选菜单的更新策略

2009-12-02 03:05 274 查看
对于“菜单”,一向认为是没有什么太多技巧可言的,就是一些很普通的操作而已。直到现在为止也依旧这样认为,不过不同的是越来越觉得自己对于MFC里的机制了解得太少,在以前的程序中走了很多愚蠢的路而不自知。
暑期的时候写的那个“扫雷”程序就是典型的走弯路的例子。在它的资源文件中有如下的菜单资源:



minemenu
其中“初级”–“中级”–“高级”–“自定义”几个是唯一勾选的。当时对此的解决方案是每当用户点击它们其中一个菜单项,就采用选中当前点击项,而对其它几个取消选中的方式,例如当用户点击“初级”时,其消息响应函数中对菜单项的相关处理代码为:
GetParent()->GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_GAME_PRIMARY,
MF_BYCOMMAND | MF_CHECKED);
GetParent()->GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_GAME_INTERMEDIATE,
MF_BYCOMMAND | MF_UNCHECKED);
GetParent()->GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_GAME_EXCLUSIVE,
MF_BYCOMMAND | MF_UNCHECKED);
GetParent()->GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_GAME_CUSTOM,
MF_BYCOMMAND | MF_UNCHECKED);
(那时把消息处理函数是放在View中。)
可见这种方式是相当的繁琐,即要在代码中要出现四处几乎完全相同的代码,冗余量太大了,而且当程序的其它地方要获知当前某菜单项处于哪种状态时,也比较复杂,当时采用的是如下方式:
if (8 == GetParent()->GetMenu()->GetSubMenu(0)->
GetMenuState(ID_GAME_MARK, MF_BYCOMMAND))
虽然也可以完成功能,但是这种实现方式说实话连自己也不敢恭维。
今天在跟着ZJ老师的课件做一个小绘图程序时,又学会了另外一种巧妙地利用了消息机制的菜单更新处理方式。
在程序中用到的菜单资源与扫雷程序中的基本一样:



colormenu
也是在四个子菜单项中只能唯一地选中一个。
这种处理方式简单描述为:设置一个变量记录当前菜单项的状态,然后在每次将要显示菜单前,每个菜单项会自动发送UPDATE_COMMAND_UI消息(由MFC自动完成),这时即可趁机对菜单项的属性进行必要的更新,修改完属性后,再绘制菜单。
利用这种机制,我们可以有机会在菜单绘制前对菜单进行处理。比如今天用到的程序中在doc类中添加了一个COLORREF m_Color;变量来记录菜单状态,然后为每个菜单项添加ON_COMMAND和UPDATE_COMMAND_UI消息响应,每个菜单项的消息响应函数均如:
void CSketcherDoc::OnRed()
{
// TODO: Add your command handler code here
this->m_Color = RED;
}
void CSketcherDoc::OnUpdateRed(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(this->m_Color == RED);
}
的形式即可,廖廖数行,即解决了这个问题,而且到时获取菜单项状态时直接获取m_Color值即可,比以前采用的方式更加简洁,准确有效。
看来学习MFC,还是必须得理解其内部运行机理,在什么样的时机能干什么样的事情,知道这些是非常重要的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: