ATL中的创建对象模型

本文给出了在ATL环境下创建对象型的方法,适用于VC6、VC8

首先,设定集合类为XCollection,子对象为XItem。

第一步:添加一个ATL Simple Objecct,起名为XItem。

第二步:修改IDL文件,添加IXCollection接口。接口声明如下:

 interface IXItem;  //向前声明
 [
  object,
  uuid(4807AD05-1CCF-4CFF-A134-8CB12AEA1655),
  dual,
  helpstring("IXCollection Interface"),
  pointer_default(unique)
 ]
 interface IXCollection : IDispatch
 {
  [id(1), helpstring("method Add")] HRESULT Add([out,retval] IXItem** ppVal);
  [id(2), helpstring("method Remove")] HRESULT Remove([in] long i, [out,retval] IXItem** ppVal);
  [propget] HRESULT Count([out, retval] long* pnCount);
  [id(DISPID_VALUE), propget, helpstring("property Item (1-based)")] HRESULT Item([in] long i, [out, retval] IXItem** ppItem);
  [id(DISPID_NEWENUM), propget] HRESULT _NewEnum([out, retval] IUnknown** ppEnum);
 };

......

......

[
  uuid(DF7F1C9F-ED81-41E3-8796-13A559B1DE0F),
  helpstring("XCollection Class"),
  noncreatable,
 ]
 coclass XCollection
 {
  [default] interface IXCollection;
 };

 

第三步:添加XCollection.h文件。文件如下:

#ifndef __XCOLLECTION_H_
#define __XCOLLECTION_H_

#include "resource.h"       // main symbols

 

#include "cltnadaptors.h"
#include <vector> //本例用vector实现
#include "XItem.h"

using namespace std;

 

typedef CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,
                        _CopyVariantFromAdaptItf<IXItem>,
                        vector < CAdapt< CComPtr<IXItem> > > >
        CComEnumVariantOnSTL;

 

typedef ICollectionOnSTLImpl<IDispatchImpl<IXCollection, &IID_IXCollection>,
                             vector< CAdapt< CComPtr<IXItem> > >,
                             IXItem*,
                             _CopyItfFromAdaptItf<IXItem>,
                             CComEnumVariantOnSTL>
        IXCollectionImpl;

 

 // CXCollection
class ATL_NO_VTABLE CXCollection :
 public CComObjectRootEx<CComSingleThreadModel>,
 public CComCoClass<CXCollection, &CLSID_XCollection>,
 public IXCollectionImpl
{
public:
 CXCollection()
 {
 }

DECLARE_NO_REGISTRY()

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CXCollection)
 COM_INTERFACE_ENTRY(IXCollection)
 COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// IXCollection
public:
 STDMETHOD(Add)(IXItem** ppVal)
 {

  HRESULT hr = CXItem::CreateInstance(ppVal);

  if(SUCCEEDED(hr))

  {

    CComPtr<IXItem> spXItem = *ppVal;
    m_coll.push_back(spXItem );

  }
  return hr;
 }
 STDMETHOD(Remove)(long Index, ** ppVal)
 {
  return S_OK;
 }
};

#endif //__XCOLLECTION_H_

 

第四步:添加头文件cltnadaptors.h,cltnadaptors.h代码如下:

#ifndef _CLTNADAPTORS_H
#define _CLTNADAPTORS_H

template <typename T>
struct _CopyVariantFromAdaptItf {
 static HRESULT copy(VARIANT* p1, const CAdapt< CComPtr<T> >* p2) {
    HRESULT hr = p2->m_T->QueryInterface(IID_IDispatch, (void**)&p1->pdispVal);
    if( SUCCEEDED(hr) ) {
      p1->vt = VT_DISPATCH;
    }
    else {
      hr = p2->m_T->QueryInterface(IID_IUnknown, (void**)&p1->punkVal);
      if( SUCCEEDED(hr) ) {
        p1->vt = VT_UNKNOWN;
      }
    }

    return hr;
  }
 
  static void init(VARIANT* p)    { VariantInit(p); }
  static void destroy(VARIANT* p) { VariantClear(p); }
};

template <typename T>
struct _CopyItfFromAdaptItf {
 static HRESULT copy(T** p1, const CAdapt< CComPtr<T> >* p2) {
    if( *p1 = p2->m_T ) return (*p1)->AddRef(), S_OK;
    return E_POINTER;
  }
 
  static void init(T** p)    {}
  static void destroy(T** p) { if( *p ) (*p)->Release(); }
};

#endif

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值