中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > MFC或CPP
mfc中的消息的应用
作者:realfly 时间:2001-10-06 09:58 出处:互联网 责编:chinaitpower
              摘要:mfc中的消息的应用

 mfc中的消息莫是相对于虚函数表来说到底有什么优势?有人说是空间上面有好处。既可以省下长长的虚函数表的内存。比如:
 用虚函数的话,window的基类会是
 class window
 {
  virtual OnSize() = 0;
  virtual OnMove() = 0;
  virtual OnContextMenu() = 0;
  ……等等
 }
 可想而知,每个由此继承而来的子类将会负担多么大的虚函数表,光是windows自带的就有数十个之多。当然不可取。
 
 可是除此之外,似乎有一种观点是如果机器够快的话就可以采用虚函数的方法了,哪只不不过是ms在当年的无奈之举。嗬嗬,真的是这样吗?非也!
 其一、如果有自定义的消息怎么办?修改基类?
 其二、其实在窗口间互相传递消息可以看成是互相的请求服务,此服务被请求窗体可以响应,也可以不响应。这种灵活性是虚函数方法所无法取得的——如果不支持的话,嗬嗬,对不起,编译时便会报错了。请求方对于被请求方的所有要求仅仅是其是CCmdTarget的子类即可。怎么样,正所谓便宜实惠量又足啊。可就是不太好理解,所以ms提供了许多宏来做这件事情。 
 
 下面看一个具体的例子。这是一个关于treectrl操作的例子。这是一棵表示公司组织的树,上面的节点有
 公司
    ----人事科
          -----张三
          -----李四 
    ----采购 
            -----王二
            -----麻子
 
 即三类节点,公司、科室、员工
 
 当客户右击鼠标时,对于不同的节点弹出的菜单当然是不同的。 
 做法1、判断三种节点的图标,(假定用不同的图标显示不同节点)然后针对不同的情况弹出菜单。这种方法对于显然不妥,有点像经典的
 if ( obj.typeid == ...)
  do something
 else if ( obj.typeid == .. )
  do somthine else ...
 结果就是在treectrl的代码中充满了这样的判断代码
 
 做法2、有class Company, class office, class person,均从CCmdTarget继承。当insert treeitem的时候,产生对象,将其指针和插入的item联系起来,方法可以采用SetItemData(对象的指针),这样的话,处理弹出菜单的方法就变为
 treectrl::OnContextMenu(...)
 {
  CCmdTarget* p = GetItemData(hSelItem);
  p->sendcommand(wm_contextmenu, point)
 }
 这样就ok了。但是有一个缺点,占用太多的内存了!每个item都有多出sizeof(CCmdTarget),有点过分。
 再改进——做法3
 class Company, office, person不变,
 但增加他们的工厂类
 
 class treeitemor
 {
  virtual CCmdTarget* CreateItem() = 0;
 }
 class Companyor
 {
  long m_ID;
  virtual CmdTarget* CreateItem(); //产生Company类
 }
 class office和person同上
 
 弹出菜单变为
 treectrl::OnContextMenu(...)
 {
  treeItemor* ItemCreator = GetItemData(hSelItem);
  CCmdTarget *pCmd = ItemCreator->CreateItem();
  pCmd->SendCommand(WM_CONTEXTMENU, POINT);
 }
 
 呼!总算完了。最后请大家多提意见!

 

  
 

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有