キャプチャ デバイスの選択

キャプチャ デバイスを選択するには、「System Device Enumerator の使い方」で説明しているように、System Device Enumerator を使う。このヘルパー オブジェクトは、フィルタ カテゴリにより選択されたデバイス モニカのコレクションを返す。 (モニカとは、別のオブジェクトに関する情報が入った COM オブジェクトである。アプリケーションでモニカを使うと、オブジェクト自体は作成せずにオブジェクトに関する情報を取得できる。後で、アプリケーションはモニカを使ってオブジェクトを作成できる。モニカの詳細については、Platform SDK の IMoniker のドキュメントを参照すること。)

キャプチャ デバイスには、次のカテゴリが関係する。

カテゴリ GUID 説明
CLSID_AudioInputDeviceCategory オーディオ キャプチャ デバイス
CLSID_VideoInputDeviceCategory ビデオ キャプチャ デバイス

1 つのデバイスは両方のカテゴリで現れることがある。次のコードは、ビデオ キャプチャ デバイスの列挙子を作成する。

ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;

// システム デバイス列挙子を作成する。
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
    CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, 
    reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr))
{
    // ビデオ キャプチャ カテゴリの列挙子を作成する。
    hr = pDevEnum->CreateClassEnumerator(
        CLSID_VideoInputDeviceCategory,
        &pEnum, 0);
}

IEnumMoniker インターフェイスは IMoniker インターフェイスの一覧を返す。それぞれはデバイス モニカを表す。通常、デバイスの一覧を表示し、ユーザーがいずれか 1 つを選択できるようにする。まず IMoniker::BindToStorage メソッドを呼び出す。このメソッドは IPropertyBag インターフェイス ポインタを返す。次に、IPropertyBag::Read を呼び出し、モニカからプロパティを読み取る。次のようなプロパティがある。

プロパティ 説明
FriendlyName デバイスの名前
Description デバイスの説明
DevicePath 一意の文字列
  • FriendlyName プロパティはすべてのデバイスで利用できる。人が読むことができるデバイス名が格納される。
  • Description プロパティは DV と D-VHS/MPEG のカムコーダ デバイスでのみ利用できる。詳細については、「MSDV ドライバ」と「MSTape ドライバ」を参照すること。利用できる場合、FriendlyName プロパティより詳しいデバイスの説明が格納される。通常、ベンダ名が入る。
  • DevicePath プロパティは人が読むことができる文字列ではないが、デバイスごとに一意であることが保証されている。このプロパティを使い、デバイスの同一モデルの複数インスタンスを区別できる。

次のサンプル コードは、リスト ボックスにデバイス名を入れる方法を示している。

HWND hList; // リスト ボックスへのハンドル。
IMoniker *pMoniker = NULL;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
    IPropertyBag *pPropBag;
    hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
        (void**)(&pPropBag));
    if (FAILED(hr))
    {
        pMoniker->Release();
        continue;  // 今回はスキップする。次は正しく動く可能性がある。
    } 
    // 説明またはフレンドリ名を検索する。
    VARIANT varName;
    VariantInit(&varName);
    hr = pPropBag->Read(L"Description", &varName, 0);
    if (FAILED(hr))
    {
        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
    }
    if (SUCCEEDED(hr))
    {
        // アプリケーションのリスト ボックスに追加する。
        USES_CONVERSION;
        (long)SendMessage(hList, LB_ADDSTRING, 0, 
            (LPARAM)OLE2T(varName.bstrVal));
        VariantClear(&varName); 
    }
    pPropBag->Release();
    pMoniker->Release();
}

ユーザーがデバイスを選択すると、モニカで IMoniker::BindToObject を呼び出して、デバイスのキャプチャ フィルタを作成する。次に、AddFilter を呼び出してフィルタ グラフにフィルタを追加する。

IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr))
{
    hr = m_pGraph->AddFilter(pCap, L"Capture Filter");
}