ファイルの種類のプロパティ シート ハンドラーを登録して実装する方法

ユーザーがファイルの種類のメンバーを右クリックして Properties プロパティ シートを表示すると、シェルはファイルの種類に登録されているプロパティ シート ハンドラーを呼び出します。 各ハンドラーは、既定のプロパティ シートに 1 つのカスタム ページを追加できます。

知っておくべきこと

テクノロジ

  • Shell

前提条件

  • ショートカット メニューの理解

Instructions

手順 1: ファイルの種類のプロパティ シート ハンドラーを登録する

通常のコンポーネント オブジェクト モデル (COM) の登録に加えて、ファイルの種類に関連付けられているアプリケーションの ProgID キーの shellex サブキーに PropertySheetHandlers サブキーを追加します。 ハンドラーの名前を使用して PropertySheetHandlers のサブキーを作成し、既定値をプロパティ シート ハンドラーのクラス識別子 (CLSID) GUID の文字列形式に設定します。

プロパティ シートに複数のページを追加するには、ページごとにハンドラーを登録します。 プロパティ シートでサポートできるページの最大数は 32 です。 複数のハンドラーを登録するには、ハンドラーごとに shellex キーの下にキーを作成し、既定値をハンドラーの CLSID GUID に設定します。 ハンドラーごとに個別のオブジェクトを作成する必要はありません。つまり、複数のハンドラーがすべて同じ GUID 値を持つことができます。 ページは、そのキーが shellex の下に表示される順序で表示されます。

次の例は、.myp ファイルの種類の例に対して 2 つのプロパティ シート拡張ハンドラーを有効にするレジストリ エントリを示しています。 この例では、ページごとに個別のオブジェクトを使用しますが、両方に 1 つのオブジェクトを使用することもできます。

HKEY_CLASSES_ROOT
   .myp
      (Default) = MyProgram.1
   CLSID
      {Page 1 Property Sheet Handler CLSID GUID}
         InProcServer32
            (Default) = C:\MyDir\MyPropSheet1.dll
            ThreadingModel = Apartment
      {Page 2 Property Sheet Handler CLSID GUID}
         InProcServer32
            (Default) = C:\MyDir\MyPropSheet2.dll
            ThreadingModel = Apartment
   MyProgram.1
      (Default) = MyProgram Application
      shellex
         PropertySheetHandlers
            MyPropSheet1
               (Default) = {Page1 Property Sheet Handler CLSID GUID}
            MyPropSheet2
               (Default) = {Page2 Property Sheet Handler CLSID GUID}

手順 2: ファイルの種類のプロパティ シート ハンドラーを実装する

「プロパティ シート ハンドラーのしくみ」で説明されている一般的な実装に加えて、ファイルの種類のプロパティ シート ハンドラーにも、IShellPropSheetExt インターフェイスの適切な実装が必要です。 非トークン実装が必要なのは 、IShellPropSheetExt::AddPages メソッドだけです。 シェルは IShellPropSheetExt::ReplacePage を呼び出しません。

IShellPropSheetExt::AddPages メソッドを使用すると、プロパティ シート ハンドラーでプロパティ シートにページを追加できます。 メソッドには 2 つの入力パラメーターがあります。 1 つ目の lpfnAddPage は、ページをプロパティ シートに追加するために必要な情報をシェルに提供するために使用される AddPropSheetPageProc コールバック関数へのポインターです。 2 つ目の lParam は、ハンドラーによって処理されないシェル定義の値です。 コールバック関数が呼び出されると、単にシェルに返されます。

AddPages を実装するための一般的な手順は次のとおりです。

AddPages メソッドの実装

  1. PROPSHEETPAGE 構造体のメンバーに適切な値を割り当てます。 特に次の点に違いがあります。
    • ハンドラーの参照カウントを保持する変数を pcRefParent メンバーに割り当てます。 この方法では、プロパティ シートがまだ表示されている間、ハンドラー オブジェクトがアンロードされないようにします。
    • PropSheetPageProc コールバック関数を実装し、そのポインターを pfnCallback メンバーに割り当てることもできます。 この関数は、ページが作成され、破棄されるときに呼び出されます。
  2. PROPSHEETPAGE 構造体を CreatePropertySheetPage 関数に渡して、ページの HPAGE ハンドルを作成します。
  3. lpfnAddPage が指す関数を呼び出します。 最初のパラメーターを、前の手順で作成した HPAGE ハンドルに設定します。 その 2 番目のパラメーターを、シェルによって AddPages に渡された lParam 値に設定します。
  4. ページに関連付けられているすべてのメッセージは、PROPSHEETPAGE 構造体の pfnDlgProc メンバーに割り当てられたダイアログ ボックス プロシージャに渡されます。
  5. pfnCallbackPropSheetPageProc コールバック関数を割り当てた場合、ページが破棄されるときに呼び出されます。 ハンドラーは、保持されている参照の解放など、必要なクリーンアップ操作を実行できます。

次のコード サンプルは、単純な AddPages 実装を 示しています。

STDMETHODIMP CShellPropSheetExt::AddPages(LPFNADDPROPSHEETPAGE, lpfnAddPage, LPARAM lParam)
{
    PROPSHEETPAGE  psp;
    HPROPSHEETPAGE hPage;

    psp.dwSize        = sizeof(psp);
    psp.dwFlags       = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK;
    psp.hInstance     = g_hInst;
    psp.pszTemplate   = MAKEINTRESOURCE(IDD_PAGEDLG);
    psp.hIcon         = 0;
    psp.pszTitle      = TEXT("Extension Page");
    psp.pfnDlgProc    = (DLGPROC)PageDlgProc;
    psp.pcRefParent   = &g_DllRefCount;
    psp.pfnCallback   = PageCallbackProc;
    psp.lParam        = (LPARAM)this;

    hPage = CreatePropertySheetPage(&psp);
            
    if(hPage) 
    {
        if(lpfnAddPage(hPage, lParam))
        {
            this->AddRef();
            return S_OK;
        }
        else
        {
            DestroyPropertySheetPage(hPage);
        }
    }
    else
    {
        return E_OUTOFMEMORY;
    }
    return E_FAIL;
}

g_hInst変数は DLL へのインスタンス ハンドルであり、IDD_PAGEDLGはページのダイアログ ボックス テンプレートのリソース ID です。 PageDlgProc 関数は、ページのメッセージを処理するダイアログ ボックス プロシージャです。 g_DllRefCount変数は、オブジェクトの参照カウントを保持します。 AddPages メソッドは AddRef を呼び出してカウントをインクリメントします。 ただし、ページが破棄されようとしている場合、参照カウントはコールバック関数 PageCallbackProc によって解放されます。

解説

シェル拡張ハンドラーを登録する方法の一般的な説明については、「 シェル拡張ハンドラーの作成」を参照してください。

IShellPropSheetExt