Microsoft DirectX 8.0

フィルタのプロパティ ページの表示

プロパティ ページは、ユーザーが設定可能なプロパティをサポートするための 1 つの方法である。ここでは、アプリケーションでフィルタのプロパティ ページを表示する方法を解説し、コンソール アプリケーションのサンプルを示す。このサンプル アプリケーションは、ファイル再生グラフを構築し、グラフ内のフィルタが定義したプロパティ ページを表示してから、ファイルを再生する。

以下の項で構成される。

プロパティ ページの詳細については、Platform SDK のドキュメントを参照すること。

プロパティ ページの表示法

プロパティ ページを持つフィルタは、ISpecifyPropertyPages インターフェイスを公開する。フィルタがプロパティ ページを定義しているかどうかを判断するには、QueryInterface を使ってフィルタにこのインターフェイスを照会し、SUCCEEDED マクロを使って戻り値を検査する。以下の例に処理の概要を示す。

IBaseFilter *pFilter;
// フィルタの IBaseFilter インターフェイスを取得する (表示されない)。

ISpecifyPropertyPages *pSpecify;
HRESULT hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpecify);
if (SUCCEEDED(hr)) {
    // ページを表示する。
}

フィルタのインスタンスを (CoCreateInstance を呼び出して) 直接生成した場合は、フィルタへのポインタを既に持っている。そうでない場合は、以下のいずれかの操作を行う。

ISpecifyPropertyPages インターフェイス ポインタが得られれば、ISpecifyPropertyPages::GetPages メソッドを呼び出してフィルタのプロパティ ページを取り出すことができる。このメソッドは、グローバル一意識別子 (GUID) のカウント配列に各プロパティ ページのクラス識別子 (CLSID) を書き込む。カウント配列は CAUUID 構造体で定義される。この構造体は割り当てなければならないが、初期化する必要はない。配列自体はこのメソッドによって割り当てられ、CAUUID 構造体の pElems メンバに格納される。

CAUUID caGUID;
pSpecify->GetPages(&caGUID);
pSpecify->Release();

以下のコードに示すように、OleCreatePropertyFrame 関数によって、モーダル ダイアログ ボックスにプロパティ ページを簡単に表示する手段が提供される。

OleCreatePropertyFrame(
    NULL,                   // 親ウィンドウ
    0,                      // x (予約済み)
    0,                      // y (予約済み)
    FilterInfo.achName,     // ダイアログ ボックスのキャプション
    1,                      // フィルタの数
    (IUnknown **)&pFilter,  // フィルタへのポインタ
    caGUID.cElems,          // プロパティ ページの数
    caGUID.pElems,          // プロパティ ページの CLSID へのポインタ
    0,                      // ロケール識別子
    0,                      // 予約済み
    NULL                    // 予約済み
);

サンプル コードでは、ダイアログ ボックスのキャプションにフィルタの名前を使っている。名前は、フィルタの IBaseFilter::QueryFilterInfo メソッドを呼び出して取得する。詳細については、以下のサンプル コードを参照すること。処理が終わったら、必ず CoTaskMemFree 関数を呼び出して GUID 配列を解放する。

CoTaskMemFree(caGUID.pElems);

サンプル コード

以下のサンプル コードは、コンソール アプリケーションである。これは、コマンドライン引数としてファイル名を受け取り、ファイルを再生するグラフを構築し、グラフ内のフィルタが定義するプロパティ ページを表示し、ファイルを再生する。

#include <dshow.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    HRESULT  hr;
    WCHAR    wPath[MAX_PATH];
    IGraphBuilder *pGraph = NULL;

    if (argc < 2) {
        printf("Usage: %s movie.ext\n", argv[0]);
        exit(0);
    }    
    CoInitialize(NULL);
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (LPVOID *)&pGraph);

    // ファイル名をワイド文字列に変換する。
    MultiByteToWideChar(CP_ACP, 0, argv[1], -1, wPath, MAX_PATH);    
    hr = pGraph->RenderFile(wPath, NULL);
    if (FAILED(hr)) {
        printf("Error: Could not open file named %s.\n", argv[1]);
        pGraph->Release();
        CoUninitialize();
        exit(1);
    }

    // フィルタを列挙し、それらのプロパティ ページを表示する。
    IEnumFilters *pEnum;
    IBaseFilter *pFilter = NULL;

    pGraph->EnumFilters(&pEnum);
    while(pEnum->Next(1, &pFilter, NULL) == S_OK)
    {
        ISpecifyPropertyPages *pSpecify;
        hr = pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpecify);
        if (SUCCEEDED(hr)) {
            FILTER_INFO FilterInfo;
            pFilter->QueryFilterInfo(&FilterInfo);

            CAUUID caGUID;
            pSpecify->GetPages(&caGUID);
            pSpecify->Release();
            
            OleCreatePropertyFrame(
                NULL,                   // 親ウィンドウ
                0,                      // x (予約済み)
                0,                      // y (予約済み)
                FilterInfo.achName,     // ダイアログ ボックスのキャプション
                1,                      // フィルタの数
                (IUnknown **)&pFilter,  // フィルタへのポインタ
                caGUID.cElems,          // プロパティ ページの数
                caGUID.pElems,          // プロパティ ページ CLSID へのポインタ
                0,                      // ロケール識別子
                0,                      // 予約済み
                NULL                    // 予約済み
            );
            CoTaskMemFree(caGUID.pElems);
            FilterInfo.pGraph->Release(); 
        }
        pFilter->Release();
    }
    pEnum->Release();

// グラフを実行する。
    IMediaControl *pMediaControl = NULL;
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pMediaControl->Run();
    MessageBox(NULL, "Click to end playback.", "DirectShow", MB_OK);

    pMediaControl->Release();
    pGraph->Release();
    CoUninitialize();
    return 0;
}