ビデオ入力デバイス名を取得する
ここでは、ビデオカメラ(デスクトップカメラ、DVカメラなど)やTVチューナーデバイスの名前を取得する方法を説明したいと思います。 (注意)ここの例では、サンプルを簡潔にするためにエラー処理を書いていません。
とりあえず、コードを書いてみる
まず、何も考えずに以下のコードを書いてみましょう。 このコードは、発見したビデオ入力デバイスのFriendlyNameを一つずつ表示します。 例えば、一番最初に発見したビデオキャプチャデバイスがDVカメラであった場合、MessageBoxで「Microsoft DV Camera and VCR」と表示されます。
#include <stdio.h>
#include <dshow.h>
int
main()
{
// 補足情報)英単語の日本語訳
// Enumerate : 列挙、一覧
// Moniker : あだ名
ICreateDevEnum *pCreateDevEnum = NULL;
IEnumMoniker *pEnumMoniker = NULL;
IMoniker *pMoniker = NULL;
ULONG nFetched = 0;
// COMを初期化
CoInitialize(NULL);
// デバイスを列挙するためのCreateDevEnumを生成
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
// VideoInputDeviceを列挙するためのEnumMonikerを生成
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnumMoniker, 0);
if (pEnumMoniker == NULL) {
// 接続された映像入力デバイスが一つも無い場合にはこのif文に入ります
printf("no device\n");
return 0;
}
// EnumMonikerをResetする
// Resetすると、先頭から数えなおします
pEnumMoniker->Reset();
// 最初のMonikerを取得
while (pEnumMoniker->Next(1, &pMoniker, &nFetched) == S_OK) {
// get the device friendly name:
IPropertyBag *pPropertyBag;
TCHAR devname[128];
// IPropertyBagにbindする
pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropertyBag);
// Friendly nameを取得するための入れ物
VARIANT varFriendlyName;
varFriendlyName.vt = VT_BSTR;
// FriendlyNameを取得
pPropertyBag->Read(L"FriendlyName", &varFriendlyName, 0);
// 取得したFriendlyNameをコピー
#ifdef UNICODE
// 念のためUNICODEの時のコード
_tcscpy(devname, varFriendlyName.bstrVal);
#else
// 特に何もしなければ、UNICODEではなく、こちらになるはずです
WideCharToMultiByte(CP_ACP, 0,
varFriendlyName.bstrVal, -1, devname, sizeof(devname), 0, 0);
#endif
// 結果を表示
MessageBox(NULL, devname, "DEVICE NAME", MB_OK);
// 資源を解放
VariantClear(&varFriendlyName);
// 資源を解放
pMoniker->Release();
pPropertyBag->Release();
}
// 資源を解放
pEnumMoniker->Release();
pCreateDevEnum->Release();
// COM終了
CoUninitialize();
return 0;
}
このサンプルはデバイスのFriendlyNameだけを表示しています。 例えば、デスクトップカメラ、DVカメラ、TVチューナーデバイスなどが同時にある場合、それらを選択するUIを作りたいと思ったときなどに上記例を改造すると良いでしょう。