CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

如何动态使菜单项变得可用或不可用?

楼主herring666(herring)2006-03-07 09:14:02 在 VC/MFC / 基础类 提问

我创建了一个基于应用程序的项目。此项目有默认的菜单。  
  我现在想根据情况,把某个菜单项动态变得可用或不可用。  
  可我不会,请教高手,如何解决?可否给个小例子?  
  谢谢! 问题点数:20、回复次数:3Top

1 楼LongLongAgoImBoy(ThereIsAMe)回复于 2006-03-07 09:22:10 得分 15

如何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(...)));    
     
          在Paste菜单的情形中,你必须检查剪贴板是否有粘贴的内容,内容有可能是文本或图形,这里关键是在需要的时候决定菜单的状态,菜单更新代码被单独放在一个函数中-远离潜在的对象-替代了遍及所有对象的洒水式EnableMenuItem调用。      
          MFC使用CCmdUI和ON_UPDATE_COMMAND_UI来调整按钮、状态条窗格和菜单项的状态,并且你可以自己扩展其它的UI项目。例如,当用户点击下拉箭头时,你可以根据程序的状态调整组合框或列表框的内容。CCmdUI::Enable是个虚拟函数,在对于菜单项的操作当中,它变成了::EnableMenuItem。      
          在前面的例子中,我们讨论的UI处理是在CMainFrame中实现的,但你也能将这种处理放在框架,视图,文档,应用(派生于CWinApp)或任何其它类中,命令通过CCmdTarget::OnCmdMsg发送。如果MFC找不到特定菜单的ON_UPDATE_COMMAND_UI,它用以下的规则自动做enable或disable:      
          如果命令有一个处理器(ON_COMMAND),MFC   enable菜单项;否则,MFC   disable菜单项。你可以设置CFrameWnd::m_bAutoMenuEnable   =   FALSE重载这个行为,这样的话,所有菜单项都将被enable-不管有没有处理器。      
          所以,在MFC应用程序中,不要用EnableMenuItem来enable或disable菜单,而要使用ON_UPDATE_COMMAND_UI处理器来实现菜单的enable或disable。      
  Top

2 楼ysc918(白纸人生)回复于 2006-03-07 09:25:07 得分 5

CMenu*   mmenu   =   GetMenu();  
  CMenu*   submenu   =   mmenu->GetSubMenu(0);  
  submenu->EnableMenuItem(ID_FILE_NEW,   MF_BYCOMMAND   |   MF_DISABLED   |   MF_GRAYED);  
  Top

3 楼herring666(herring)回复于 2006-03-08 21:02:01 得分 0

LongLongAgoImBoy  
   
  给个具体的例子好不好?  
  你写的文档我看不太懂。  
  不好意思,我是新手。  
  谢谢!Top

相关问题

  • 如何在程序中动态控制菜单栏中的菜单项的可用与不可用
  • 动态添加菜单项后怎样处理是它可用?
  • 如何使某一菜单项不可用(变灰)?
  • 怎么让弹出菜单的某一个菜单项变灰(不可用)?
  • 动态建立菜单项
  • 动态添加菜单项
  • 如何动态生成菜单而且根据权限动态决定某菜单项是否可用呀?
  • 谁知道如何写出像某菜单项不可用的字体效果来???UP有分!!
  • 58分求小问题::::::为何下拉菜单项是灰色不可用的?代码:
  • 高难问题:A软件如何才能知道B软件的一级菜单项"搜索(S)"下面的二级菜单项"结束(E)"是处于可用还是不可用?

关键词

  • 函数
  • 用户界面
  • mfc
  • 应用程序
  • 用户
  • 文档
  • 内容
  • 菜单项
  • 菜单
  • 状态

得分解答快速导航

  • 帖主:herring666
  • LongLongAgoImBoy
  • ysc918

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo