WEB开发网
开发学院软件开发VC 组件对象模型与ATL实现 阅读

组件对象模型与ATL实现

 2010-09-04 20:48:02 来源:WEB开发网   
核心提示:三 实现集合对象下面增加具体的实现代码,以把Layers和Shapes变成集合类(Collection),组件对象模型与ATL实现(6),第一步 把下面的代码添加到stdafx.h中// stdafx.h : 标准系统包含文件的包含文件,// 或是经常使用但不常更改的// 特定于项目的包含文件(原有内容不动)// 后添

三 实现集合对象

下面增加具体的实现代码,以把Layers和Shapes变成集合类(Collection)。

第一步 把下面的代码添加到stdafx.h中

// stdafx.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(); }
};

第二步 把Layers变成集合对象

把下面的代码添加到Layers.h中,添加后的Layers.h为:

// Layers.h : CLayers 的声明

#pragma once
#include "resource.h" // 主符号

#include "MapLib.h"

#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全DCOM 支持的Windows Mobile 平台)上无法正确支持单线程COM 对象。定义_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制ATL 支持创建单线程COM 对象实现并允许使用其单线程COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非DCOM Windows CE 平台支持的唯一线程模型。"
#endif

// 下面加粗的文字是我添加的代码
#include "Layer.h"

typedef CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT,
_CopyVariantFromAdaptItf<ILayer>,
list< CAdapt< CComPtr<ILayer> > > >
CComEnumVariantOnListOfLayers;

typedef ICollectionOnSTLImpl<IDispatchImpl<ILayers, &IID_ILayers>,
list< CAdapt< CComPtr<ILayer> > >,
ILayer*,
_CopyItfFromAdaptItf<ILayer>,
CComEnumVariantOnListOfLayers>
ILayerCollImpl;

// CLayers

class ATL_NO_VTABLE CLayers :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CLayers>, // non-createable,去掉注册表项
    public ISupportErrorInfo,
    public ILayerCollImpl
{
public:
    CLayers()
    {
    }

//DECLARE_REGISTRY_RESOURCEID(IDR_LAYERS)
DECLARE_NO_REGISTRY()   // non-createable,去掉注册表项

// 原来的代码被我注释掉
// CHEUNGMINE:
// CHEUNGMINE: // CLayers

// CHEUNGMINE: class ATL_NO_VTABLE CLayers :
// CHEUNGMINE:     public CComObjectRootEx<CComSingleThreadModel>,
// CHEUNGMINE:     public CComCoClass<CLayers, &CLSID_Layers>,
// CHEUNGMINE:     public ISupportErrorInfo,
// CHEUNGMINE:     public IDispatchImpl<ILayers, &IID_ILayers, &LIBID_MapLibLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
// CHEUNGMINE: {
// CHEUNGMINE: public:
// CHEUNGMINE:     CLayers()
// CHEUNGMINE:     {
// CHEUNGMINE:     }

// CHEUNGMINE: DECLARE_REGISTRY_RESOURCEID(IDR_LAYERS)

BEGIN_COM_MAP(CLayers)
     COM_INTERFACE_ENTRY(ILayers)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()

// ISupportsErrorInfo
     STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);

     DECLARE_PROTECT_FINAL_CONSTRUCT()

     HRESULT FinalConstruct()
     {
         return S_OK;
     }

     void FinalRelease()
     {
     }

public:

};

OBJECT_ENTRY_AUTO(__uuidof(Layers), CLayers)

然后编译,出现一堆的错误。首先在文件“stdafx.h”中的适当位置加入使用STL的语句,如下:

// Standard C++ STL supports
#include <stack>
#include <vector>
#include <list>
#include <map>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;

然后,重新编译,全部OK。接下来,修改“MapLib.idl”文件的ILayers部分,使其如下所示:

interface ILayers : IDispatch{
     [propget,helpstring("Layer元素数目")] HRESULT Count([out,retval] long *nItems);
    [id(DISPID_VALUE),propget,helpstring("取得指定索引的Layer元素。索引以为基数")]
HRESULT Item([in] long index, [out,retval] ILayer** ppRef);
    [id(DISPID_NEWENUM),propget,hidden] HRESULT _NewEnum([out,retval] IUnknown** ppEnum);
//   [id(1),helpstring("向集合增加一个元素,返回引用")] HRESULT Add([out,retval] ILayer** ppRef);
};

上一页  1 2 3 4 5 6 7 8 9 10 11  下一页

Tags:组件 对象 模型

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