• ベストアンサー

directshowのイベント処理

こんにちは。 現在「directshow」を使って動画再生プログラムを作っています。 再生、停止などはできています。 そこで質問があるのですが、ムービーを再生しているウィンドウで処理(マウスクリックやキー入力)を取得したいときはどうすればよろしいのでしょうか? ムービー再生中に画面上でクリック(もしくはキー入力)することでムービーを停止したいと思っているのですが、なかなかうまくいきません。 どなたかご教授いただければ幸いです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんにちは。  IVideoWindowのウィンドウハンドルを取って来て、サブクラス化するのが手っ取り早そうです。  後、「リサイズ等で画面が消えてしまう」と言った類の副次的な問題の対処は以下を参考に。  http://oshiete1.goo.ne.jp/qa4494380.html //ビデオウィンドウのフックプロシージャ LRESULT CALLBACK VideoWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { //GWL_USERDATAの方に以前のWNDPROCを入れておいたので、そっちから取る WNDPROC wndProcOrig = (WNDPROC)::GetWindowLong(hWnd, GWL_USERDATA); switch(iMsg) { case WM_LBUTTONDOWN: //ココで何かする break; case WM_KEYDOWN: //ココで何かする break; } //以前のプロシージャへ渡す return ::CallWindowProc(wndProcOrig, hWnd, iMsg, wParam, lParam); } //ビデオウィンドウのフック static BOOL VideoWndHook(HWND hWnd) { //ビデオウィンドウを取る HWND hWndVideo = ::GetWindow(hWnd, GW_CHILD); //失敗 if(hWndVideo == NULL) return FALSE; //ウィンドウプロシージャのすり替え const LONG lWndProcOld = ::SetWindowLong(hWndVideo, GWL_WNDPROC, (LONG)VideoWndProc); //古い方をGWL_USERDATAに代入しておく(後で取り出して使う) ::SetWindowLong(hWndVideo, GWL_USERDATA, lWndProcOld); return TRUE; } //使う時 +----------------------------------------------------------------------- //DirectShowの初期化をする //ビデオウィンドウのフックをする(少なくとも、IVideoWindowが出来上がっており、再生する前に) if(::VideoWndHook(hWnd) == FALSE) ::MessageBox(NULL, NULL, "IVideoWindowのフックに失敗した", IDOK); //再生をする pMediaControl->Run(); -----------------------------------------------------------------------+

bokutaka
質問者

お礼

なるほど、 何となく分かったような気がします。 ありがとうございました。

その他の回答 (1)

回答No.2

>なかなかうまくいきません。 ソースコードを載せるとか、なにがどう「うまくいかない」のかを具体的にどうぞ。 GUIなフォームエディタが付いているコンパイラでは、普通、以下のようにします。 キーでの操作は、フォーム上に再生ウィンドゥを載せ、フォームの方にキーボードフォーカスを当てておき、フォームに対するキー入力で処理します。 マウスでの操作の場合は、再生ウィンドゥの上に、透明で透過の「見えないウィンドゥ」を重ねて、その見えないウィンドゥに対して発生するマウスイベントを拾います。 再生ウィンドゥのメッセージループを上書きして処理する手もあるけど、見えないウィンドゥを最前面に置いてラップしちゃう方が簡単。 普通、GUIなフォームエディタが付いているコンパイラでは、メッセージループとかは自分で書かず、ウィンドゥやコントロールをペタッと貼って、プロパティシートでイベント発生時の処理を書き足すだけなので、上記の方法の方が楽です。 フォームエディタなどを使わず、1からゴリゴリと全部書いている場合は、メインプログラムのメッセージループとか、何から何まで全部自分で書けてる筈でしょうから、ANo.1のように、サブクラス化して再生ウィンドゥのメッセージループを上書きしましょう。

bokutaka
質問者

お礼

見えないウィンドウを出してそれに対応させるって言う手があったんですね! ありがとうございます。

関連するQ&A