WEB开发网
开发学院软件开发VC 编写可复用性更好的C++代码:Band对象和COMToys(7)... 阅读

编写可复用性更好的C++代码:Band对象和COMToys(7)

 2006-07-21 11:46:03 来源:WEB开发网   
核心提示: IMPLEMENT_IPersist(CMyComClass, CTPersist);产生的GetClassID方法便替代IPersistStream 和 IPersistFile中的GetClassID, 最后正是在这些方法中我不得不针对语言规范编写一些代码,编写可复用性更好的C++代码
IMPLEMENT_IPersist(CMyComClass, CTPersist);   

产生的GetClassID方法便替代IPersistStream 和 IPersistFile中的GetClassID。 最后正是在这些方法中我不得不针对语言规范编写一些代码。所幸的是它不算太麻烦。只是将前面用嵌套类实现的BandObj转换成本文中对应的CTXxx类,将必须的变量转换成数据成员并在构造函数中进行初始化。例如,CTPersist的代码如下:

class CTPersist {
public:
  const CLSID& m_clsid;
  CTPersist(const CLSID& clsid) : m_clsid(clsid) { }
  STDMETHODIMP GetClassID(LPCLSID pClassID) {
   return pClassID ?
    (*pClassID=m_clsid, S_OK) : E_UNEXPECTED;
  }
};   

CTPersist保存着类ID的引用,并不是类ID本身。此乃COMToys的一般原则:执行类不存储实际数据,只有外部对象的指针或引用。对于CTPersist,它无关紧要,因为一旦运行中的对象类ID改变,它便无所适从。但一般来说,数据是可以改变的,所以让父类拥有数据是明智的,这样它就可以自由的处理这些数据。CTPersistFile 和 CTPersistStream都有一个m_bModified修改标志,但它是对BOOL类型的一个引用,而不是BOOL类型。如果主类改变了实际的标志,执行类自动改变,不用自己去调用诸如SetModified之类的函数。作为一个一般的编程规则,对状态的操作最好是用按需方式进行(demand-pull),而不要用先入方式(supply-push),并且整个系统的每个状态变量自始至终只应该有一个拷贝。 CTMfcContextMenu的情况类似,它保存着对仅仅一个CMenu的引用,主类必须在构造时提供。

// 在COMToys.h文件中
class CTMfcContextMenu {
public:
  CCmdTarget* m_pCmdTarget;
  CMenu& m_ctxMenu;
  CTMfcContextMenu(CCmdTarget* pTarg, CMenu& menu)
   : m_pCmdTarget(pTarg), m_ctxMenu(menu) { }
  ……
};
// 在BandObj.cpp文件中
CBandObj::CBandObj(REFCLSID clsid) :
  CTMfcContextMenu(this, m_menu), ...
{
  ……
}   

因为CTMfcContextMenu::m_ctxMenu是个引用,CBandObj可以任何方式改变菜单,不必显式通知CTMfcContextMenu。CBandObj依赖这个特性,因为当用户右键单击Band时,它产生其浮动菜单。如图十二)。CTMfcContextMenu的实现基本上照搬前面代码中相应的部分。

图十二 CBandObj 上下文菜单 

当容器调用IContextMenu::QueryContextMenu获得菜单项时,CTMfcContextMenu用希望的CMenu项填写菜单,但不是在创建CcmdUI对象之前,并且通过CCmdTarget发送,从而ON_UPDATE_COMMAND_UI处理器都能挂上菜单。同样,当容器调用InvokeCommand,CTMfcContextMenu发送这个命令到ON_COMMAND处理器。CTMfcContextMenu甚至能通过查找串资源来处理提示串。简言之,CTMfcContextMenu将COM语言转换成MFC语言。剩下的事情只是给它一个菜单和命令目标(通常是COM类本身)。所有的命令处理与在MFC应用中处理一样,不用再次实现IContextMenu——用COMToys就能搞掂。(待续)

上一页  1 2 3 4 

Tags:编写 复用 更好

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接