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

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

 2006-07-21 11:46:03 来源:WEB开发网   
核心提示:第一部分:Band 对象介绍第二部分:BandObj的类层次和MyBands服务程序的注册第三部分:深入Band内部,揭开Band的面纱第四部分:Band对象使用中遇到的一些问题第五部分:建立自己的COM编程平台ComToys第六部分:设计和构造COMToys第七部分 类的实现类的混合实现到目前为止,编写可复用性更好的

第一部分:Band 对象介绍

第二部分:BandObj的类层次和MyBands服务程序的注册

第三部分:深入Band内部,揭开Band的面纱

第四部分:Band对象使用中遇到的一些问题

第五部分:建立自己的COM编程平台ComToys

第六部分:设计和构造COMToys

第七部分 类的实现

类的混合实现

到目前为止,我介绍了一种用多继承代替嵌套类在MFC中实现COM对象的方法。基本思路是忽略MFC宏和接口映射,并调用GetInterfaceHook来返回接口指针。很明显,这已经使编程容易了许多,但可复用性体现在哪呢?开发COMToys的主要目的是让它具备可复用性特点来实现普通的COM接口。为此,COMToys使用了混合类。

混合类被设计成利用多继承特性与其它类混合。通常混合类与主类的关系是直交的,也就是说它提供与类层次的无关性来避免菱形派生树(请原谅我的矛盾修饰法),不用怀疑,CBandObj比我在前面四个部分中讨论的要复杂一些,其新版本的代码如下:

//更新的 CBandObj
/////////////////////////////////////////
// CBandObj —— 典型的实现多接口的 COM 类
// 头文件.h :
class CBandObj : public CWnd,
  // interfaces
// public IOleWindow,   // 从IDeskBand继承
// public IDockingWindow, // 从IDeskBand继承
  public IDeskBand,
  public IObjectWithSite,
  public IInputObject,
// public IPersist,    // 从IPersistStream继承
  public IPersistStream,
  public IContextMenu,
  // 使用ComToys实现
  public CTOleWindow,
  public CTDockingWindow,
  public CTPersist,
  public CTPersistStream,
  public CTInputObject,
  public CTInputObjectSite,
  public CTContextMenu
{
public:
  CBandObj(REFCLSID clsid);
  virtual ~CBandObj();
  // 改写以便实现 QueryInterface
  virtual LPUNKNOWN GetInterfaceHook(const void* iid);
  // 用ComToys实现的接口
  DECLARE_IUnknown();
  DECLARE_IOleWindow();
  DECLARE_IDockingWindow();
  DECLARE_IInputObject();
  DECLARE_IPersist();
  DECLARE_IPersistStream();
  DECLARE_IContextMenu();
  DECLARE_IObjectWithSite();
  // IDeskBand
  STDMETHOD (GetBandInfo) (DWORD, DWORD, DESKBANDINFO*);
};
// 实现文件 .cpp :
CBandObj::CBandObj(REFCLSID clsid) :
  // 初始化所有实现类
  CTMfcComObj(this),
  CTOleWindow(this),
  CTDockingWindow(this),
  CTPersist(clsid),
  CTPersistStream(),
  CTInputObject(this),
  CTContextMenu(this, CTMfcComObjFactory::GetFactory(clsid)->GetResourceID())
{
  ......
}
//////////////////////////////////
// 这些宏用ComToys实现了所有接口
//
IMPLEMENT_IUnknown     (CBandObj, CTMfcComObj);
IMPLEMENT_IOleWindow    (CBandObj, CTOleWindow);
IMPLEMENT_IDockingWindow  (CBandObj, CTDockingWindow);
IMPLEMENT_IPersist     (CBandObj, CTPersist);
IMPLEMENT_IContextMenu   (CBandObj, CTContextMenu);
IMPLEMENT_IPersistStream  (CBandObj, CTPersistStream);
IMPLEMENT_IInputObject   (CBandObj, CTInputObject);
/////////////////////////////////////////////////////////////////////
// 改写后旁路掉MFC在CCmdTarget::InternalQueryInterface中的接口映射
//
LPUNKNOWN CBandObj::GetInterfaceHook(const void* piid)
{
  REFIID iid = *((IID*)piid);
  if (iid==IID_IUnknown)
    return (IDeskBand*)this;
#define IF_INTERFACE(iid, iface)              \
  if (iid==IID_##iface)                  \
    return (iface*)this;                 \
  IF_INTERFACE(iid, IOleWindow);
  IF_INTERFACE(iid, IDockingWindow);
  IF_INTERFACE(iid, IObjectWithSite);
  IF_INTERFACE(iid, IInputObject);
  IF_INTERFACE(iid, IPersist);
  IF_INTERFACE(iid, IPersistStream);
  IF_INTERFACE(iid, IContextMenu);
  IF_INTERFACE(iid, IDeskBand);
  return NULL;
} 

乍一看这些类与ATL如此类似!且看下文的分析。

1 2 3 4  下一页

Tags:编写 复用 更好

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