in microsoft.public.vc.atl发件人: "Townee" <[email protected]> 主题: About Collection 日期: 2003年5月21日 15:361.how to define a Collection Object in ATL/COM 2.How to add a property which is a Collection Object in ATL/COM发件人: "Vadim Melnik" <[email protected]> 主题: Re: About Collection 日期: 2003年5月21日 16:09Hi,> 1.how to define a Collection Object in ATL/COM > 2.How to add a property which is a Collection Object in ATL/COMPlease see "ATL Collections and Enumerators" topic in MSDN library:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcconATLCollectionsEnumerators.asp -- Best regards, Vadim Melnik _____________________ http://www.docsultant.com/
主题: About Collection
日期: 2003年5月21日 15:361.how to define a Collection Object in ATL/COM
2.How to add a property which is a Collection Object in ATL/COM发件人: "Vadim Melnik" <[email protected]>
主题: Re: About Collection
日期: 2003年5月21日 16:09Hi,> 1.how to define a Collection Object in ATL/COM
> 2.How to add a property which is a Collection Object in ATL/COMPlease see "ATL Collections and Enumerators" topic in MSDN library:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcconATLCollectionsEnumerators.asp
--
Best regards,
Vadim Melnik
_____________________
http://www.docsultant.com/
主题: 关于集合
日期: 2003年5月21日 15:181.在ATL/COM中如何定义一集合?
2.在ATL/COM中如何添加一集合属性?发件人: "Felix" <[email protected]>
主题: Re: 关于集合
日期: 2003年5月21日 19:53"Townee" <[email protected]> writes:> 1.在ATL/COM中如何定义一集合?
> 2.在ATL/COM中如何添加一集合属性?
>
>集合是一个COM对象,它必须支持Count(), Item(), _NewEnum()这几个方法。ATL有CComEnum,CComEnumOnSTL等Class来简化集合对象的编写。--
Felix发件人: "Black Ice" <[email protected]>
主题: Re: 关于集合
日期: 2003年5月22日 15:43enum or collection?--
Regards,
Leo Liu
"Townee" <[email protected]> wrote in message
news:[email protected]...
> 1.在ATL/COM中如何定义一集合?
> 2.在ATL/COM中如何添加一集合属性?
>
>发件人: "Townee" <[email protected]>
主题: Re: 关于集合
日期: 2003年5月22日 16:59collection.
在MSDN.NET上找到了一篇
实现基于 STL 的集合
有没有更简单的方法,比如现成的基类,或有精灵引导发件人: "Townee" <[email protected]>
主题: Re: 关于集合
日期: 2003年5月22日 16:59collection.
在MSDN.NET上找到了一篇
实现基于 STL 的集合
有没有更简单的方法,比如现成的基类,或有精灵引导发件人: "Townee" <[email protected]>
主题: Re: 关于集合
日期: 2003年5月22日 16:59collection.
在MSDN.NET上找到了一篇
实现基于 STL 的集合
有没有更简单的方法,比如现成的基类,或有精灵引导发件人: "Black Ice" <[email protected]>
主题: Re: 关于集合
日期: 2003年5月26日 12:16这是最简单的方法。--
Regards,
Leo Liu
"Townee" <[email protected]> wrote in message
news:[email protected]...
> collection.
> 在MSDN.NET上找到了一篇
> 实现基于 STL 的集合
> 有没有更简单的方法,比如现成的基类,或有精灵引导
>
>
ms-help://MS.VSCC/MS.MSDNVS.2052/vccore/html/vcconImplementingSTLBasedCollection.htm
是你的集合接口有一个属性,NewEnum,返回的对象支持IEnumVariant。
为生成的接口编辑 IDL 文件。
创建五个 typedef,它们描述集合项的存储方式,以及它们如何通过 COM 接口向客户端公开。
创建复制策略类的两个 typedef。
创建枚举数和集合实现的 typedef。
编辑向导生成的 C++ 代码以使用集合 typedef。
添加填充集合的代码。
生成新的简单对象
创建一个新项目,确保清除了“应用程序设置”下的“属性”框。使用 ATL“添加类”对话框和添加简单对象向导生成一个名为 Words 的简单对象。确保生成了一个名为 IWords 的双重接口。生成的类的对象将用于表示单词的集合(即字符串)。编辑 IDL 文件
现在,打开 IDL 文件并添加将 IWords 转变为只读集合接口所需的三个属性,如下所示: [
object,
uuid(0D44F689-B373-11D2-9A7F-50F653C10000),
dual, // (1)
pointer_default(unique),
nonextensible // (2)
]
interface IWords : IDispatch
{
[id(DISPID_NEWENUM), propget] // (3)
HRESULT _NewEnum([out, retval] IUnknown** ppUnk); [id(DISPID_VALUE), propget] // (4)
HRESULT Item(
[in] long Index,
[out, retval] BSTR* pVal); // (5) [id(0x00000001), propget] // (6)
HRESULT Count([out, retval] long* pVal);
};
这是在设计时考虑了自动化客户端的只读集合接口的标准形式。该接口定义中的编号注释对应于下面的注释: 集合接口通常是双重的,原因在于自动化客户端通过 IDispatch::Invoke 访问 _NewEnum 属性。但是,自动化客户端可以通过 vtable 访问其余的方法,因此双重接口优于调度接口。
如果双重接口或者调度接口在运行时不被扩展(即,您不会通过 IDispatch::Invoke 提供额外的方法或属性),则应该将 nonextensible 属性应用于您的定义。该属性使自动化客户端能够在编译时执行完全代码验证。在此情况下,接口不应扩展。
如果希望自动化客户端能够使用该属性,则正确的 DISPID 是很重要的。(注意在 DISPID_NEWENUM 中只有一个下划线)。
可以提供任何值作为 Item 属性的 DISPID。但是,Item 一般使用 DISPID_VALUE 以使它成为集合的默认属性。这使自动化客户端不用显式命名属性就可以引用它。
就 COM 客户端而言,用于 Item 属性的返回值的数据类型是集合中存储的项的类型。接口返回字符串,因此应使用标准的 COM 字符串类型 BSTR。在内部可以用另一种格式存储数据,就像很快就会看到的一样。
用于 Count 属性的 DISPID 的值完全是任意的。该属性没有标准的 DISPID。
创建存储和公开的 Typedef
定义了集合接口后,需要决定如何存储数据,以及如何通过枚举数公开数据。这些问题的答案可以以若干 typedef 的形式提供,在靠近新创建的类的头文件的开头可以添加这些 typedef: // Store the data in a vector of std::strings
typedef std::vector< std::string > ContainerType; // The collection interface exposes the data as BSTRs
typedef BSTR CollectionExposedType;
typedef IWords CollectionInterface; // Use IEnumVARIANT as the enumerator for VB compatibility
typedef VARIANT EnumeratorExposedType;
typedef IEnumVARIANT EnumeratorInterface;
这里,您将把数据存储为 std::string 的 std::vector。std::vector 是 STL 容器类,它的行为类似托管数组。std::string 是标准 C++ 库的字符串类。这些类使字符串集合的使用很容易。由于 Visual Basic 支持对于该接口的成功至关重要,因此 _NewEnum 属性所返回的枚举数必须支持 IEnumVARIANT 接口。这是 Visual Basic 识别的唯一枚举数接口。创建复制策略类的 Typedef
到目前为止所创建的 typedef 提供了创建进一步的 typedef(用于将由枚举数和集合使用的复制类)所需的全部信息。 // Typedef the copy classes using existing typedefs
typedef VCUE::GenericCopy<EnumeratorExposedType, ContainerType::value_type> EnumeratorCopyType;
typedef VCUE::GenericCopy<CollectionExposedType, ContainerType::value_type> CollectionCopyType;
在此示例中,可以使用在 VCUE_Copy.h 和 VCUE_CopyString.h(它们来自 ATLCollections 示例)中定义的自定义 GenericCopy 类。可以在其他代码中使用该类,但是可能需要定义进一步的 GenericCopy 专用化以支持在您自己的集合中使用的数据类型。有关更多信息,请参阅 ATL 复制策略类。创建枚举和集合的 Typedef
现在,已经以 typedef 的形式提供了针对这种情况专用化 CComEnumOnSTL 和 ICollectionOnSTLImpl 类所需的所有模板参数。若要简化专用化的使用,请再创建两个 typedef,如下所示: typedef CComEnumOnSTL< EnumeratorInterface, &__uuidof(EnumeratorInterface), EnumeratorExposedType, EnumeratorCopyType, ContainerType > EnumeratorType; typedef ICollectionOnSTLImpl< CollectionInterface, ContainerType, CollectionExposedType, CollectionCopyType, EnumeratorType > CollectionType;
现在,CollectionType 是 ICollectionOnSTLImpl(它实现以前定义的 IWords 接口,并提供支持 IEnumVARIANT 的枚举数)专用化的同义词。编辑向导生成的代码
现在,必须从 CollectionType typedef 而不是 IWords 所表示的接口实现派生 CWords,如下所示:class ATL_NO_VTABLE CWords :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CWords, &CLSID_Words>,
public IDispatchImpl<CollectionType, &IID_IWords, &LIBID_ATLCOLLECTIONSLib>
{
public:
DECLARE_REGISTRY_RESOURCEID(IDR_STRINGCOLLECTION)
DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CWords)
COM_INTERFACE_ENTRY(IWords)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()// IWords
public:
};
添加填充集合的代码
剩下的唯一一件事就是用数据填充向量。在此简单示例中,可以将几个单词添加到集合中类的构造函数中:CWords()
{
m_coll.push_back("this");
m_coll.push_back("is");
m_coll.push_back("a");
m_coll.push_back("test");
}
现在,可以用选择的客户端测试代码。
希望大家能给我讲一下!