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,还是必须得理解其内部运行机理,在什么样的时机能干什么样的事情,知道这些是非常重要的。
暑期的时候写的那个“扫雷”程序就是典型的走弯路的例子。在它的资源文件中有如下的菜单资源:
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,还是必须得理解其内部运行机理,在什么样的时机能干什么样的事情,知道这些是非常重要的。
相关文章推荐
- 在MFC对话框中使用ON_UPDATE_COMMAND_UI更新菜单
- MFC菜单命令更新机制
- 在MFC对话框中使用ON_UPDATE_COMMAND_UI更新菜单
- MFC菜单的命令更新机制
- MFC 菜单名称修改后还是显示以前的--无法更新
- MFC菜单更新机制
- MFC对话框界面中使用CCmdUI对象更新菜单状态
- 孙鑫VC++深入详解:Lesson6 Part2 -- MFC菜单更新机制 用该机制实现 Enable or Disable MenuItem
- MFC菜单命令更新机制
- MFC-5动态更新窗体菜单1
- MFC---如何利用菜单更新机制动态更新菜单
- MFC笔记(2)菜单
- 网络爬虫更新策略和分布式抓取系统机构
- 【MFC】VS2013 动态创建快捷菜单(右键菜单)
- [MFC]Shapes程序(3):响应菜单命令、菜单项的跟新
- maven 快照 更新策略
- MFC通过获取菜单句柄,实现菜单的基本操作
- MFC实现弹出式快捷菜单/右键菜单
- 对话框中使用ON_UPDATE_COMMAND_UI更新菜单(转载)
- MFC学习笔记(4)—— 菜单