coclass
创建可实现 COM 接口的 COM 对象。
语法
[coclass]
备注
coclass C++ 特性将 coclass 构造放置在生成的 .idl 文件中。
定义 coclass 时,还可以指定 uuid、version、threading、vi_progid 和 progid 特性。 如果未指定其中任何一个,系统会生成它。
如果两个头文件包含具有 coclass 特性的类且未指定 GUID,则编译器将为这两个类使用相同的 GUID,这会导致 MIDL 错误。 因此,在使用 coclass 时,应使用 uuid
特性。
ATL 项目
当此特性位于 ATL 项目中的类或结构定义之前时,它会执行以下操作:
注入代码或数据以支持对象的自动注册。
注入代码或数据以支持对象的 COM 类工厂。
注入代码或数据以实现
IUnknown
,并使此对象成为可通过 COM 创建的对象。
具体而言,以下基类将添加到目标对象:
CComCoClass 类为对象提供默认类工厂和聚合模型。
CComObjectRootEx 类具有一个基于线程模型类(通过 threading 特性指定)的模板。 如果未指定
threading
特性,则默认线程模型为单元。如果未为目标对象指定 noncreatable 特性,则会添加 IProvideClassInfo2Impl。
最后,未使用嵌入式 IDL 定义的任何双接口都会被替换为相应的 IDispatchImpl 类。 如果在嵌入式 IDL 中定义了双接口,则基列表中的特定接口不会进行修改。
coclass 特性还通过注入的代码提供以下函数,或在使用 GetObjectCLSID
的情况下,将以下函数作为基类 CComCoClass
中的静态方法提供:
UpdateRegistry
注册目标类的类工厂。GetObjectCLSID
与注册相关,还可用于获取目标类的 CLSID。GetObjectFriendlyName
默认返回格式为“<目标类名>Object
”的字符串。 如果此函数已存在,则不会添加它。 将此函数添加到目标类,以返回比自动生成的名称更易记的名称。与注册相关的
GetProgID
返回使用 progid 特性指定的字符串。GetVersionIndependentProgID
具有与GetProgID
相同的功能,但返回使用 vi_progid 指定的字符串。
以下与 COM 映射相关的更改是针对目标类进行的:
添加 COM 映射时,会使用目标类派生自的所有接口的条目,以及 COM 接口入口点特性指定的所有条目,或 aggregates 属性所需的条目。
OBJECT_ENTRY_AUTO 宏插入到 COM 映射中。
类的 .idl 文件中生成的 coclass 的名称将与类的名称相同。 如果需要示例,尤其是需要参阅以下示例,以便在客户端中通过 MIDL 生成的头文件来访问 coclass CMyClass
的类 ID,请使用 CLSID_CMyClass
。
示例
以下代码显示了如何使用 coclass 特性:
// cpp_attr_ref_coclass1.cpp
// compile with: /LD
#include "unknwn.h"
[module(name="MyLib")];
[ object, uuid("00000000-0000-0000-0000-000000000001") ]
__interface I {
HRESULT func();
};
[coclass, progid("MyCoClass.coclass.1"), vi_progid("MyCoClass.coclass"),
appobject, uuid("9E66A294-4365-11D2-A997-00C04FA37DDB")]
class CMyClass : public I {};
以下示例演示如何重写由 coclass 特性注入的代码中显示的函数的默认实现。 有关查看插入的代码的详细信息,请参阅 /Fx 。 用于类的任何基类或接口将显示在注入的代码中。 此外,如果注入代码中默认包含类,而你显式指定该类作为 coclass 的基类,则属性提供程序将使用代码中指定的形式。
// cpp_attr_ref_coclass2.cpp
// compile with: /LD
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
#include <atlplus.h>
[module(name="MyLib")];
[object, uuid("00000000-0000-0000-0000-000000000000")]
__interface bb {};
[coclass, uuid("00000000-0000-0000-0000-000000000001")]
class CMyClass : public bb {
public:
// by adding the definition of UpdateRegistry to your code, // the function will not be included in the injected code
static HRESULT WINAPI UpdateRegistry(BOOL bRegister) {
// you can add to the default implementation
CRegistryVirtualMachine rvm;
HRESULT hr;
if (FAILED(hr = rvm.AddStandardReplacements()))
return hr;
rvm.AddReplacement(_T("FriendlyName"), GetObjectFriendlyName());
return rvm.VMUpdateRegistry(GetOpCodes(), GetOpcodeStringVals(), GetOpcodeDWORDVals(), GetOpcodeBinaryVals(), bRegister);
}
};
要求
特性上下文 | 值 |
---|---|
适用于 | %> |
可重复 | 否 |
必需的特性 | 无 |
无效的特性 | 无 |
有关特性上下文的详细信息,请参见 特性上下文。