ITPub博客

首页 > 应用开发 > IT综合 > mfc中的消息的应用 (转)

mfc中的消息的应用 (转)

原创 IT综合 作者:amyz 时间:2007-10-09 09:22:04 0 删除 编辑
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/10752019/viewspace-975338/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    3984
  • 访问量
    7334690