IMediaEvent
COMIDispatch (デュアル)comobj 経由でメソッド名による遅延バインド呼び出しができます(vtableインデックス不要)。公式ドキュメント
IMediaEvent インターフェイスには、イベント通知を取得するためのメソッドと、Filter Graph Manager によるイベントの既定の処理をオーバーライドするためのメソッドが含まれています。
メソッド 6
vtbl = vtable インデックス(0始まり)。IDispatch 実装のため HSP ではメソッド名でも呼べます(上記)。低レベルの index 呼び出し用に vtbl も掲載。0〜2 は IUnknown。
GetEventHandle メソッドは、キューにイベント通知が存在する間はシグナル状態を維持する、手動リセット イベントのハンドルを取得します。
| hEvent | INT_PTR* | out | イベント ハンドルを受け取る変数へのポインター。 |
戻り値
S_OK を返します。
解説(Remarks)
Filter Graph Manager は、イベント キューの状態を反映する手動リセット イベントを保持しています。キューにイベント通知が含まれている場合、この手動リセット イベントはシグナル状態になります。キューが空の場合、IMediaEvent::GetEvent メソッドがイベントをリセットします。
アプリケーションは、このイベントを使用してキューの状態を判断できます。まず GetEventHandle を呼び出してイベントのハンドルを取得します。次に WaitForSingleObject などの関数を使用して、イベントがシグナル状態になるのを待ちます。イベントがシグナル状態になったら、IMediaEvent::GetEvent メソッドを呼び出してキューから次のイベント通知を取得します。Filter Graph Manager は、キューが空になるまでイベントをシグナル状態に保ち、空になった時点でイベントをリセットします。
このメソッドが返すイベント ハンドルは、フィルター グラフが内部的に使用しているため、閉じないでください。また、Filter Graph Manager を解放した後にこのハンドルを使用しないでください。Filter Graph Manager が破棄された後は、ハンドルが無効になるためです。(このエラーを回避するには、DuplicateHandle を呼び出してハンドルを複製し、元のハンドルの代わりに複製を使用することをお勧めします。使用が終わったら複製したハンドルを閉じてください。)
オートメーションとの互換性のため、このメソッドは OAEVENT 型へのポインターを受け取ります。C++ では、次のように HANDLE 型の変数を宣言し、それを OAEVENT ポインターにキャストします。
HANDLE hEvent;
GetEventHandle( (OAEVENT*) &hEvent );
アプリケーションがイベント キューを監視するもう一つの方法として、IMediaEventEx::SetNotifyWindow メソッドを呼び出す方法があります。
GetEvent メソッドは、イベント キューから次のイベント通知を取得します。
| lEventCode | INT* | out | イベント コードを受け取る変数へのポインター。 |
| lParam1 | INT_PTR* | out | 1 番目のイベント パラメーターを受け取る変数へのポインター。 |
| lParam2 | INT_PTR* | out | 2 番目のイベント パラメーターを受け取る変数へのポインター。 |
| msTimeout | INT | in | タイムアウト間隔(ミリ秒単位)。イベントが発生するまでブロックするには INFINITE を使用します。 |
戻り値
解説(Remarks)
キューにイベントが存在しない場合、このメソッドはイベントが到着するまで最大 msTimeout ミリ秒待機します。GetEvent で待機している間はスレッドがメッセージを処理できなくなるため、タイムアウト間隔に INFINITE を使用することは避けてください。Windows メッセージを処理するスレッドと同じスレッドから GetEvent を呼び出す場合は、ユーザー入力に対する応答性を保つため、待機時間を小さな値のみに指定してください。
GetEvent を呼び出した後は、IMediaEvent::FreeEventParams メソッドを呼び出して、イベント パラメーターに割り当てられたリソースを解放してください。
通知コードとイベント パラメーター値の一覧については、Event Notification Codes を参照してください。
このメソッドはフィルター グラフのイベント キューからイベントを削除するため、複数のクライアントが同じグラフのイベントを監視する方法はありません。
WaitForCompletion メソッドは、フィルター グラフが利用可能なすべてのデータをレンダリングするのを待ちます。フィルター グラフが実行中でなければ、このメソッドは失敗します。
| msTimeout | INT | in | タイムアウト間隔(ミリ秒単位)。すぐに戻るにはゼロを渡します。無期限にブロックするには INFINITE を渡します。 |
| pEvCode | INT* | out | イベント コードを受け取る変数へのポインター。詳細については「解説」を参照してください。 |
戻り値
HRESULT 値を返します。取り得る値には次のものが含まれます。
| 戻り値 | 説明 |
|---|---|
| 成功しました。 | |
| タイムアウトが経過しました。 | |
| フィルター グラフが実行されていません。 |
解説(Remarks)
このメソッドは、タイムアウトが経過するか、次のいずれかのイベントが発生するまでブロックします。
待機中、このメソッドは他のすべてのイベント通知を破棄します。戻り値が S_OK の場合、pEvCode パラメーターは待機を終了させたイベント コードを受け取ります。メソッドが戻った時点でも、フィルター グラフはまだ実行中です。アプリケーションは、必要に応じてグラフを一時停止または停止できます。
CancelDefaultHandling メソッドは、指定したイベントに対する Filter Graph Manager の既定の処理をキャンセルします。イベント通知はアプリケーションに渡されます。
| lEvCode | INT | in | 既定の処理をキャンセルする対象のイベント コード。 |
戻り値
HRESULT 値を返します。取り得る値には、次の表に示すものが含まれます。
| 戻り値 | 説明 |
|---|---|
| 成功しました。 | |
| このイベントには既定の処理がありません。 |
解説(Remarks)
イベントの既定の処理を復元するには、そのイベント コードを指定して IMediaEvent::RestoreDefaultHandling メソッドを呼び出します。
RestoreDefaultHandling メソッドは、指定したイベントに対する Filter Graph Manager の既定の処理を復元します。
| lEvCode | INT | in | 既定の処理を復元する対象のイベント コード。 |
戻り値
HRESULT 値を返します。取り得る値には次のものが含まれます。
| 戻り値 | 説明 |
|---|---|
| 成功しました。 | |
| このイベントには既定の処理がありません。 |
解説(Remarks)
既定では、Filter Graph Manager は一部のイベント(EC_REPAINT など)を、アプリケーションに渡さずに処理します。IMediaEvent::CancelDefaultHandling メソッドを呼び出してイベントの既定の処理をオーバーライドした場合、同じイベント コードを指定して RestoreDefaultHandling を呼び出すことで既定の動作を復元できます。
FreeEventParams メソッドは、イベントのパラメーターに関連付けられたリソースを解放します。
| lEvCode | INT | in | イベント コード。 |
| lParam1 | INT_PTR | in | 1 番目のイベント パラメーター。 |
| lParam2 | INT_PTR | in | 2 番目のイベント パラメーター。 |
戻り値
S_OK を返します。
解説(Remarks)
IMediaEvent::GetEvent メソッドを呼び出してイベント通知を取得した後は、FreeEventParams を呼び出す必要があります。このメソッドは、イベント パラメーターに割り当てられたリソースを解放します。GetEvent の呼び出しで使用したものと同じ変数を渡してください。
例
hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0);
// イベントを処理します(コードは省略)。
hr = pEvent->FreeEventParams(evCode, param1, param2);
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMediaEvent "{56A868B6-0AD4-11CE-B03A-0020AF0BA770}" #usecom global IMediaEvent IID_IMediaEvent "{}" #comfunc global IMediaEvent_GetEventHandle 7 var #comfunc global IMediaEvent_GetEvent 8 var,var,var,int #comfunc global IMediaEvent_WaitForCompletion 9 int,var #comfunc global IMediaEvent_CancelDefaultHandling 10 int #comfunc global IMediaEvent_RestoreDefaultHandling 11 int #comfunc global IMediaEvent_FreeEventParams 12 int,sptr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。 ; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。#define global IID_IMediaEvent "{56A868B6-0AD4-11CE-B03A-0020AF0BA770}" #usecom global IMediaEvent IID_IMediaEvent "{}" #comfunc global IMediaEvent_GetEventHandle 7 sptr #comfunc global IMediaEvent_GetEvent 8 sptr,sptr,sptr,int #comfunc global IMediaEvent_WaitForCompletion 9 int,sptr #comfunc global IMediaEvent_CancelDefaultHandling 10 int #comfunc global IMediaEvent_RestoreDefaultHandling 11 int #comfunc global IMediaEvent_FreeEventParams 12 int,sptr,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。 ; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。