coclass
COM インターフェイスを実装できる COM オブジェクトを作成します。
[coclass]
解説
C++ 属性 coclass は、生成された .idl ファイルにコクラス コンストラクトを配置します。
コクラスを定義するときに、uuid、version、threading、vi_progid、progid の各属性も指定できます。これらの属性が指定されていない場合は、指定されていない属性が生成されます。
2 つのヘッダー ファイルに coclass 属性を持つクラスが含まれ、GUID が指定されていない場合、コンパイラは両方のクラスに対して同じ GUID を使用し、MIDL エラーの原因になります。したがって、coclass を使用する場合には、uuid 属性を使用する必要があります。
ATL プロジェクト
この属性が ATL プロジェクトのクラスまたは構造体定義の前にある場合は、以下の処理が行われます。
オブジェクトの自動登録をサポートするコードまたはデータが挿入されます。
オブジェクトの COM クラス ファクトリをサポートするコードまたはデータが挿入されます。
IUnknown を実装し、オブジェクトを COM で作成できるオブジェクトにするコードまたはデータが挿入されます。
具体的には、以下の基本クラスが適用先オブジェクトに追加されます。
CComCoClass クラスは、オブジェクトの既定のクラス ファクトリと集約モデルを提供します。
CComObjectRootEx クラスには、threading 属性で指定されるスレッド モデル クラスに基づくテンプレートがあります。threading 属性が指定されていない場合、既定のスレッド モデルはアパートメント モデルです。
IProvideClassInfo2Impl は、適用先オブジェクトに noncreatable 属性が指定されていない場合に追加されます。
最後に、埋め込みインターフェイス定義言語 (IDL: Interface Definition Language) を使用して定義されていないデュアル インターフェイスは、対応する IDispatchImpl クラスで置き換えられます。デュアル インターフェイスが埋め込み IDL で定義されている場合は、基本リスト内の特定のインターフェイスは変更されません。
また coclass 属性は、以下の関数を、挿入コードを介して、または GetObjectCLSID の場合は、基本クラス CComCoClass の静的メソッドとして使用できるようにします。
UpdateRegistry は、適用先クラスのクラス ファクトリを登録します。
登録に関連する GetObjectCLSID は、適用先クラスの CLSID の取得に使用できます。
既定では、GetObjectFriendlyName は "<target class name> Object" という書式の文字列を返します。この関数が既に存在する場合は追加されません。この関数を適用先クラスに追加して、自動的に生成された名前よりもわかりやすい名前を返します。
登録に関連する GetProgID は、progid 属性で指定された文字列を返します。
GetVersionIndependentProgID の機能は GetProgID と同じですが、GetVersionIndependentProgID は vi_progid で指定された文字列を返します。
COM マップに関連する以下の変更が適用先クラスに対して行われます。
COM マップは、適用先クラスの派生元のすべてのインターフェイスのエントリ、および COM インターフェイス エントリ ポイント属性で指定されたすべてのエントリまたは aggregates 属性で必要なすべてのエントリと共に追加されます。
OBJECT_ENTRY_AUTO マクロが COM マップに挿入されます。このマクロの機能は OBJECT_ENTRY と同様ですが、適用先クラスの COM マップの一部にする必要はありません。
そのクラスの .idl ファイル内に生成されるコクラスの名前は、そのクラスと同じ名前になります。たとえば、および以下のサンプルでは、コクラス CMyClass のクラス ID にアクセスするには、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 (挿入されたコードのマージ)」を参照してください。クラスに使用する基本クラスまたはインターフェイスは、挿入されたコードに表示されます。さらに、挿入されたコードにクラスが既定で組み込まれ、そのクラスがコクラスの基本クラスであると明示的に指定した場合、属性プロバイダはコードで指定されているフォームを使用します。
// 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);
}
};
必要条件
属性コンテキスト
対象 |
class、struct |
複数回の適用 |
不可 |
必要な属性 |
なし |
無効な属性 |
なし |
属性コンテキストの詳細については、「属性コンテキスト」を参照してください。