システム デバイス列挙子の使用
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
システム デバイス列挙子は、ユーザーのシステムに登録されているフィルターをカテゴリ別に一様に列挙する方法を提供します。 さらに、同じフィルターでサポートされている場合でも、個々のハードウェア デバイスを区別します。 これは、Windows ドライバー モデル (WDM) と KSProxy フィルターを使用するデバイスに特に役立ちます。 たとえば、ユーザーは複数の WDM ビデオ キャプチャ デバイスを持ち、すべて同じフィルターでサポートされている場合があります。 システム デバイス列挙子は、それらを個別のデバイス インスタンスとして扱います。
システム デバイス列挙子は、オーディオ キャプチャやビデオ圧縮など、特定のカテゴリの列挙子を作成することによって機能します。 カテゴリ列挙子は、カテゴリ内の各デバイスに対して一意のモニカーを返します。 カテゴリ列挙子には、カテゴリ内の関連するプラグ アンド プレイ デバイスが自動的に含まれます。 カテゴリの一覧については、「 カテゴリのフィルター処理」を参照してください。
システム デバイス列挙子を使用するには、次の操作を行います。
- CoCreateInstance を呼び出して、システム デバイス列挙子を作成します。 クラス識別子 (CLSID) がCLSID_SystemDeviceEnum。
- 目的のカテゴリの CLSID を使用して ICreateDevEnum::CreateClassEnumerator を呼び出して、カテゴリ列挙子を取得します。 このメソッドは、 IEnumMoniker インターフェイス ポインターを返します。 カテゴリが空の場合 (または存在しない場合)、メソッドはエラー コードではなくS_FALSEを返します。 その場合、返された IEnumMoniker ポインターは NULL であり、逆参照すると例外が発生します。 したがって、通常の SUCCEEDED マクロを呼び出す代わりに、CreateClassEnumerator を呼び出すときに、S_OKを明示的にテストします。
- 各モニカーを列挙するには、 IEnumMoniker::Next メソッドを使用します。 このメソッドは 、IMoniker インターフェイス ポインターを返します。 Next メソッドが列挙体の末尾に達すると、S_FALSEも返されるため、S_OKに対してもう一度チェック。
- デバイスのフレンドリ名 (ユーザー インターフェイスに表示するなど) を取得するには、 IMoniker::BindToStorage メソッドを呼び出します。
- デバイスを管理する DirectShow フィルターを作成して初期化するには、モニカーで IMoniker::BindToObject を呼び出します。 IFilterGraph::AddFilter を呼び出して、グラフにフィルターを追加します。
このプロセスを説明する図を次に示します。
次の例は、ユーザーのシステムにインストールされているビデオ コンプレッサーを列挙する方法を示しています。 簡潔にするために、この例では最小限のエラー チェックを実行します。
// Create the System Device Enumerator.
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr))
{
return hr;
}
// Obtain a class enumerator for the video compressor category.
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);
if (hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker = NULL;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if (SUCCEEDED(hr))
{
// To retrieve the filter's friendly name, do the following:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
// Display the name in your UI somehow.
}
VariantClear(&varName);
// To create an instance of the filter, do the following:
IBaseFilter *pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void**)&pFilter);
// Now add the filter to the graph.
//Remember to release pFilter later.
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
デバイス モニカー
デバイス モニカーの場合は、モニカーを IFilterGraph2::AddSourceFilterForMoniker メソッドに渡して、デバイスのキャプチャ フィルターを作成できます。 コード例については、そのメソッドのドキュメントを参照してください。
IMoniker::GetDisplayName メソッドはモニカーの表示名を返します。 表示名は読み取り可能ですが、通常はエンドユーザーに表示しません。 前に説明したように、代わりにプロパティ バッグからフレンドリ名を取得します。
IMoniker::P arseDisplayName メソッドまたは MkParseDisplayName 関数を使用して、特定のフィルター カテゴリの既定のデバイス モニカーを作成できます。 という形式 @device:*:{category-clsid}
で表示名を使用します。ここで category-clsid
、 はカテゴリ GUID の文字列表現です。 既定のモニカーは、そのカテゴリのデバイス列挙子によって返される最初のモニカーです。