mfc中的消息的应用 (转)

本文探讨MFC中消息机制相较于虚函数表的优势,包括节省内存、灵活的消息处理及自定义消息支持。通过具体实例对比不同实现方式,展示了MFC消息处理的灵活性与效率。
mfc中的消息的应用 (转)[@more@]

 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);
 }
 
 呼!总算完了。最后请大家多提意见!

 

 
 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-996715/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-996715/

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值