VC++6.0でUSBカメラからの画像を取得しています。
そのプログラムをDLL化して、VBで表示できるようにしたいのですが、
新しいWindowが開いてしまいます。
VBのフォーム上に画像を表示させることはできないのでしょうか?
_declspec(dllexport) int preview()
{
IGraphBuilder *pGraphBuilder;
ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
IMediaControl *pMediaControl;
// 補足情報)英単語の日本語訳
// Enumerate : 列挙、一覧
// Moniker : あだ名
ICreateDevEnum *pCreateDevEnum = NULL;
IEnumMoniker *pEnumMoniker = NULL;
IMoniker *pMoniker = NULL;
ULONG nFetched = 0;
IBaseFilter *pDeviceFilter;
// COMを初期化
CoInitialize(NULL);
// FilterGraphを生成
CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC,
IID_IGraphBuilder,
(LPVOID *)&pGraphBuilder);
// CaptureGraphBuilder2というキャプチャ用GraphBuilderを生成する
CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2,
(LPVOID *)&pCaptureGraphBuilder2);
// FilterGraphをセットする
pCaptureGraphBuilder2->SetFiltergraph(pGraphBuilder);
// MediaControlインターフェース取得
pGraphBuilder->QueryInterface(IID_IMediaControl,
(LPVOID *)&pMediaControl);
// デバイスを列挙するための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を取得
pEnumMoniker->Next(1, &pMoniker, &nFetched);
// MonkierをFilterにBindする
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pDeviceFilter );
// FilterGraphにデバイスフィルタを追加する
pGraphBuilder->AddFilter(pDeviceFilter, L"Device Filter");
// この時点でMoniker系、Enumerate系は用済み
pMoniker->Release();
pEnumMoniker->Release();
pCreateDevEnum->Release();
// Graphを生成する
pCaptureGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW,
NULL, pDeviceFilter, NULL, NULL);
// 再生開始
pMediaControl->Run();
// 再生中にプログラムが終わってしまわないように
MessageBox(NULL,
"Block Execution",
"Block",
MB_OK);
// 資源を解放
pMediaControl->Release();
pCaptureGraphBuilder2->Release();
pGraphBuilder->Release();
// COM終了
CoUninitialize();
return 0;
}
表示したいVBのフォームのWindow Handleをどっかから(具体的な方法は知らん)取り出して
HWND hwnd = "フォームのハンドル";
IVideoWindow::put_Owner((OAHWND)hwnd);
IVideoWindow::put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
とかすれば、フォームに描画できるはずだが。
ボコノン教徒さん、返事が遅くなってすみません。
教えていただいた通りにやってみたのですが、Formに表示されませんでした。
VBのFormのハンドルは取れていると思うのですが・・・
下のプログラムでは実行されないのでしょうか?
よろしくお願いします。
pCaptureGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW,
NULL, pDeviceFilter, NULL, NULL);
struct HWND__ * hwnd;
hwnd=FindWindow(NULL,"Form1");
char buf[32];
sprintf(&buf[0], "%d", hwnd);
//ハンドルの表示
MessageBox(NULL,buf,"hwnd",MB_OK);
pGraphBuilder->QueryInterface(IID_IVideoWindow,
(LPVOID *)&pVideoWindow);
pVideoWindow->put_Owner((OAHWND)hwnd);
pVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);
// 再生開始
pMediaControl->Run();
put_Owner()、put_WindowStyle()の戻りはちゃんとチェックしてますね?
> // 再生中にプログラムが終わってしまわないように
> MessageBox(NULL,
> "Block Execution",
> "Block",
> MB_OK);
これではなく、
IMediaEvent *pEvent;
pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
.....
pMediaControl->Run(); // Run実行
.....
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);//終了を待つ
を使ってください。モーダルだと、Formの画面が更新されないかもしれない。
画面更新がうまくいかず、マウスで画面をつつくと描画開始されることもあります。
put_WindowStyle()で WS_CLIPCHILDRENも追加する必要があるかも。
Formがだめなら、PictureBoxをはりつけ、Formのハンドルの変わりに
PictureBoxのハンドルを使って試してみては。