coclass
coclass
coclass C++ 特性在生成的 .idl 文件放置在 coclass 構造。
當定義 coclass 時,還可以指定 uuid、版本、線程處理、 vi_progid和 progid 屬性。如果將其中的任何一個未指定,則將生成。
創建 COM 對象,可以實現 COM 介面。
[coclass]
coclass C++ 特性在生成的 .idl 文件放置在 coclass 構造。
當定義 coclass 時,還可以指定 uuid、版本、線程處理、 vi_progid和 progid 屬性。如果將其中的任何一個未指定,則將生成。
如果兩個頭文件包含與 coclass 屬性的類,而不指定 GUID,編譯器為兩個類都將使用相同的 GUID,並且,這會導致的錯誤。因此,那麼,當您使用 coclass時,應使用 uuid 屬性。
當此特性前面在 ATL 項目的類或結構定義,則:
插入代碼或數據支持對象的自動註冊。
插入代碼或數據支持對象的一個 COM 類工廠。
插入代碼或數據實現 IUnknown 並將對象 COMcreatable 對象。
具體而言,以下基類添加到目標對象:
CComCoClass 類 為對象提供默認類工廠和摘要模型。
CComObjectRootEx 類 具有基於線程模型類的一個模板以指定由 線程處理 屬性。如果 線程處理 未指定屬性,默認線程模型是單元。
IProvideClassInfo2Impl 添加 不可創建 屬性是否沒有為目標對象指定。
最後,未定義使用嵌入 IDL 的所有雙重介面用相應的 IDispatchImpl 類來替換。如果雙重介面在嵌入的 IDL 中定義,在基礎的特定介面列表不會被修改。
coclass 屬性還使以下功能可通過注入的代碼,但如果 GetObjectCLSID,用作靜態方法在基類 CComCoClass:
該 目標的類工廠類的UpdateRegistry 註冊。
默認情況下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
#include
#include
#include
#include
#include
#include
[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);
}
};