当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 如何enable/disable菜单项

VC++
用 auto_ptr 类模板帮助动态内存管理
走近 STL
一步一步学STL标准模板库
使用 <multimap> 库创建重复键关联容器
使用 <map> 库创建关联容器
用 vectors 改进内存的再分配
用函数模板实现和优化抽象操作
STL 字符串类与 UNICODE 及其它......
如何在Dll中导出STL类
再谈“在STL列表(Lists)中插入不同类型的对象”
使用::std::vector<>作为管理动态数组的优先选择
三种常见中文内码的转换方法
JNI 中文处理问题小结
构建 GB2312 汉字库的 unicode 码表
正则表达式简介
在非MFC程序中引用CString
UTF-8与GB2312之间的互换
宽字符标量L"xx"在VC6.0/7.0和GNU g++中的不同实现
用VC++设计语法编辑器
C语言中对时间和日期的处理

VC++ 中的 如何enable/disable菜单项


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 229 ::
收藏到网摘: n/a

如何enable/disable菜单项
VCKBASE
    这个问题在以前的知识库中出现过多次,许多人问及在MFC应用程序中enable或disable菜单的问题,在主菜单中调用 CMenu::EnableMenuItem不起作用......如何disable菜单项?
    根据以往的经验,要解决这种问题,似乎应该有一个象EnableMenuItem之类的API函数,它的功能就是enable或disable菜单项。Windows中确实有这样的函数-但不是在MFC的应用中。实际上,在MFC里enable或disable菜单项是通过使用ON_ UPDATE_COMMAND_UI实现的。首先让我解释一下为什么MFC的实现方法不同于标准的C和Windows API,以及MFC的实现方法的好处。
    一般情况下,用户界面的状态指的是按钮,状态格,菜单项等任何反映程序状态的东西。例如,如果程序处于只读模式,那么编辑(Edit)命令应该是disable的,并且在程序的某个地方可能有一个小指示器向用户提示这个状态。另一个例子是如果剪贴板没有内容(一种状态),那么菜单中的粘贴(Paste)命令应该是disable的。所以说通常的用户界面(UI)指的就是程序表现的状态,同时,程序状态的改变应该在程序的菜单中反映出来。
如何随时获得反映程序状态的用户界面呢?我自己的方法有两种:
    第一种是神经过敏型,也就是说无论何时只要程序状态改变,都不要忘记同时更新用户界面,如果用户调用只读模式命令,这个命令要disable所由编辑控制。同样,如果用户调用Cut或者Copy,处理器立刻enable Paste命令。在程序的任何地方对程序状态的任何改变,都必须要更新相应的UI。
    第二种方法是放松型,也就是说,不要试图去维护所有的状态信息,只根据需要更新用户界面。对于菜单来说,不用保持菜单的状态的更新,只在显示的时候进行更新。
    这个方法较容易,也十分简单。更重要的是,它使数据从用户界面中分离出来。每个对象只存储它自己的状态-例如,文档知道什么时候处于只读模式。UI能解释出现的各种状态,你不想低级对象调用类似EnableMenu的UI函数!MFC提供一个UI更新机制来实现后一种方法,详细的方法描述因为内容太多,将在另文中讨论,其基本思路是这样的:当用户调用一个菜单的时候,Windows发送一个WM_INITMENUPOPUP消息。MFC创建一个暂时的CCmdUI对象处理这个消息,为每一个菜单项做连续初始化并将它传递到应用程序中的对象。MFC为此调用ON_UPDATE_COMMAND_UI消息处理器更新用户界面:
ON_UPDATE_COMMAND_UI(ID_FOO, OnUpdateFoo)
    只要用户进入包含Foo的菜单项,MFC就会调用OnUpdateFoo函数。你不必担心必须调用::EnableMenuItem(第一种方法)的所有地方;要做的只是从程序状态确定菜单状态。典型的处理方法如下:
void CMainFrame::OnUpdateFoo(CCmdUI* pCmdUI) { pCmdUI->Enable(pObj->GetFoo()); } 
    GetFoo()是个假设的函数,它获得某个对象的foo状态-例如,m_pDocument->GetReadOnly()。可能有20函数来修改foo状态(自然是通过方法SetFoo),但更新菜单的地方只有一处。当然有可能是更复杂的情形,如:
pCmdUI->Enable(m_bFoo && (GetStatusX(...) || GetStatusY(...)));