coclass簡介
創建 COM 對象,可以實現 COM 接口。
[coclass]
coclass C++ 特性在生成的 .idl 檔案放置在 coclass 構造。
當定義 coclass 時,還可以指定 uuid、 版本、 執行緒處理、 vi_progid和 progid 屬性。 如果將其中的任何一個未指定,則將生成。
如果兩個頭檔案包含與 coclass 屬性的類,而不指定 GUID,編譯器為兩個類都將使用相同的 GUID,並且,這會導致的錯誤。 因此,那么,當您使用 coclass時,應使用 uuid 屬性。
ATL 項目
當此特性前面在 ATL 項目的類或結構定義,則:
插入代碼或數據支持對象的自動註冊。
插入代碼或數據支持對象的一個 COM 類工廠。
插入代碼或數據實現 IUnknown 並將對象 COMcreatable 對象。
具體而言,以下基類添加到目標對象:
CComCoClass 類 為對象提供默認類工廠和摘要模型。
CComObjectRootEx 類 具有基於執行緒模型類的一個模板以指定由 執行緒處理 屬性。 如果 執行緒處理 未指定屬性,默認執行緒模型是單元。
IProvideClassInfo2Impl 添加 不可創建 屬性是否沒有為目標對象指定。
最後,未定義使用嵌入 IDL 的所有雙重接口用相應的 IDispatchImpl 類來替換。 如果雙重接口在嵌入的 IDL 中定義,在基礎的特定接口列表不會被修改。
coclass 屬性還使以下功能可通過注入的代碼,但如果 GetObjectCLSID,用作靜態方法在基類 CComCoClass:
該 目標的類工廠類的UpdateRegistry 註冊。
GetObjectCLSID,與註冊相關,還可用於獲取目標類的 CLSID。
默認情況下GetObjectFriendlyName 返回該格式 “AMP_LTtarget類 nameAMP_GTObject”的字元串。 如果此功能已存在,不會添加。 比自動生成的控制項將此功能添加到目標類返回一個更友好的名稱。
GetProgID,與註冊相關,返回字元串指定與 progid 屬性。
GetVersionIndependentProgID 具有與 GetProgID相同,但是,它返回字元串指定與 vi_progid。
以下更改,與 COM 映射相關,對目標類:
COM 映射添加與目標類派生自的任何接口的項,並且所有項。 COM 接口的入口點 屬性指定了或那些由 聚合 屬性要求。
OBJECT_ENTRY_AUTO 宏插入到 COM 映射。 此宏類似於 OBJECT_ENTRY 基於功能,但不必是目標類的 COM 映射的一部分。
在類的 .idl 檔案中生成的 coclass 的名稱將與類相同。 例如,並參考以下示例,訪問的類 ID 在客戶端的 coclass CMyClass,通過使用 MIDL 生成的頭檔案,使用 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);
}
};