COM オブジェクトから COM インターフェースを取得する方法
C++、COM、QueryInterface
本記事の前提条件は以下の通りです。
- 初心者向け
- とは言っても、何らかのプログラムはそれなりに書けるけど、C とか C++ はちょっと、という人向け
- ざっくり概要しか説明しないので細かいことは気にしないでいただきたい
- Visual Studio 2013 くらい~
- Windowsプログラム (CUI, GUI)
- コードの検証
- 開発環境: Visual Studio 2022, x64, Release ビルド
- 実行環境: Windows 10
- 本記事は上から順番に読む前提となっている
- 「Visual Studio 2013 くらい~」と書いてあるが、本記事の内容だと現在過去未来のどのバージョンでもほぼ同じ
はじめに
ミュージック・プレイヤー・コンポーネントを考えてみる。
下図のようなインターフェースを持っているとする。
また、ToneControl プラグインを追加することで下記インターフェースが使えるようになるとする。
再生するファイルを選択したり、オプション設定したり、その他の機能も必要と思われるが、それらについては割愛する。
なお、以降のサンプルコードではエラーチェックなどなにもしていないのでご了承いただきたい。(この状態での動作は確認している。COM サーバー側が想定通りであれば、だが)
また、COM システムの初期化・解放も別途必要なので留意。
COM オブジェクトの生成
CoCreateInstance
を使った場合、COM オブジェクトの生成と同時に、COM インターフェースも取得する。
ここでは MusicPlayer
オブジェクトを生成し、IPlayback
インターフェースを取得している。
IPlayback* pPlayback;
CoCreateInstance(CLSID_MusicPlayer,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPlayback,
(void**)&pPlayback);
pPlayback->Play();
pPlayback->Stop();
// COMインターフェースを使い終わったら必ずReleaseする。
pPlayback->Release();
別のインターフェースを取得する
COM インターフェースから QueryInterface
を使って別のインターフェースを取得する。
ここでは、IPlayback
インターフェースから IVolumeControl
インターフェースを取得している。
IPlayback* pPlayback;
CoCreateInstance(CLSID_MusicPlayer,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPlayback,
(void**)&pPlayback);
pPlayback->Play();
pPlayback->Stop();
IVolumeControl* pVolumeControl;
pPlayback->QueryInterface(IID_IVolumeControl, (void**)&pVolumeControl);
pVolumeControl->Up();
pVolumeControl->Down();
pVolumeControl->Release();
pPlayback->Release();
インターフェースが取得できない場合に対応
ToneControl プラグインがないと IToneControl
インターフェースは取得できない仕様なので、取得できたときだけ処理するようにする。
IPlayback* pPlayback;
CoCreateInstance(CLSID_MusicPlayer,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPlayback,
(void**)&pPlayback);
pPlayback->Play();
pPlayback->Stop();
IToneControl* pToneControl;
HRESULT hr = pPlayback->QueryInterface(IID_IToneControl, (void**)&pToneControl);
if (hr != E_NOINTERFACE)
{
pToneControl->Treble(80);
pToneControl->Bass(65);
pToneControl->Release();
}
pPlayback->Release();
以上。