(ウィザードなし)手動COM
オブジェクトを作成するために、以下のステップが必要とされる:
- に延びる、ターゲットクラスを実装
IClassFactory
- を拡張ファクトリを実装
DllGetClassObject
& DllCanUnloadNow
- を実装
IUknown
- を登録するレジストリ内の
- [オプション]
DllRegisterServe
r & DllUnregisterServer
を実装して、レジストリを簡単にします。
を実装いるDllGetClassObject &のDllCanUnloadNow
それらのみDLL関数に輸出されている:
STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID * ppObject)
STDAPI DllCanUnloadNow(void)
いるDllGetClassObject、提供rclsid
はTargetClassCLSID
とriid
が `FactoryCLSIDである場合、それFactoryオブジェクトを作成して返します。
DLLが使用されている場合(S_OK
)、ユーザー/クライアントがDLL(S_FALSE
)をアンロードする可能性がある場合は、DllCanUnloadNowが返します。
問題は、この定義ではVSを「必須」にするMicrosoft monopol指示におそらく__declspec(dllexport)
が追加されないことです。
#pragma comment(linker, "/export:DllGetClassObject,PRIVATE")
#pragma comment(linker, "/export:DllCanUnloadNow,PRIVATE")
//TODO: make this cross-compiler compatible?
直前に追加し、それらをエクスポートするには工場
を実装
はAddRef
とRelease
を実装します:彼らは、クライアント/ユーザーは、現在このファクトリオブジェクトを使用しているどのように多くの維持します。 AddRefは1だけインクリメントし、Releaseは1だけインクリメントします。数字が0になるとすぐにRelease
が自動的に削除されます。
実装QueryInterface
riid
がFactoryCLSIDの場合に戻ってきます。
RIIDの試合が対象のクラスを再度
を実装
をTargetClassCLSID場合、我々はのAddRef、リリースとQueryInterfaceをを実装する必要がありますが、最終的にクラスのため、この対象物体のインスタンスを返すCreateInstance
を実装時間。
私の場合、このTargetクラスはIShellIconOverlayIdentifierを拡張します。
、DLLを生成した後、OSのレジストリ
にいくつかのレジストリをCOMオブジェクトを登録するには、設定する必要があります。それらのいくつかはリンクされているので、自動的に別のリンクを追加することがあります。追加するコンテンツ
HKEY_CLASS_ROOT::CLSID::<Add Here>
HKEY_CLASS_ROOT::Wow6432Node::CLSID::<Add Here>
HKEY_LOCAL_MACHINE::SOFTWARE::Classes::CLSID::<Add Here>
HKEY_LOCAL_MACHINE::SOFTWARE::Classes::Wow6432Node::CLSID::<Add Here>
HKEY_LOCAL_MACHINE::SOFTWARE::Wow6432Node::Classes::CLSID::<Add Here>
です:
- は、キーを作成します。名前=
{TargetClassCLSID}
、値= <Any app name>
- は、サブキーを作成します。名前=
InProcServer32
、値を= <link to your dll>
- の作成InProcServer32のサブストリング:name =
ThreadingModel
、値= Apartment
// TODO:おそらく、その意味を理解するために、他の選択肢があります。 <TargetClassCLSID>
新しいエントリがある=名前= <Any app name>
、値:オーバーレイエントリはキーがある
HKEY_LOCAL_MACHINE::SOFTWARE::Microsoft::Windows::CurrentVersion::Explorer::ShellIconOverlayIdentifier::<Overlay here>
HKEY_LOCAL_MACHINE::SOFTWARE::Microsoft::Windows::CurrentVersion::ShellExtensions::Aproved::<new entry here>
:私の場合は
は、私はIconHandlerのためのいくつかのより多くのレジスタを登録しなければなりませんでした文字列値その名= <TargetClassCLSID>
と値= Any app name
これらの値は、であることも必要です
HKEY_LOCAL_MACHINE::SOFTWARE::Wow6432Node::Microsoft::Windows....
ここをクリックしてください。 http://stackoverflow.com/a/5665927/3747990; COM dllが正しく構築されていれば 'regsvr32'を使ってオブジェクトを登録することができます。 – Niall
@Niall: "DllRegisterServerが見つかりません"とは、 "指定されたDLL名は.dllまたは.ocxファイルではありません。たとえば、regsvr32 wjview.exeと入力すると、このエラーメッセージが表示されます。私はMSVC2015を仮定しています。64ビットdllはサポートされていません。 –
いいえ、それらはすべてサポートされています。 DLLから 'DllRegisterServer'という名前の関数をエクスポートしますか?エラーが発生した場合、少なくとも適切ではありません。 VS2015でウィザードを使用して "ATL COMオブジェクト"プロジェクトを生成するのが最も簡単です。すべてのボイラープレートコードを配置します。次に、「COMオブジェクト」をプロジェクトに追加します(メニューまたはプロジェクトを右クリックしてそこから追加します)。 – Niall