2

[開く] ボタンに [開く] オプションと [読み取り専用で開く] オプションを含む [共通ファイルを開く] ダイアログを表示します。

私はの例に従いました...

IFileDialogCustomize PushButton イベントを追加する

(以下に再現されたコードのほとんどは、Remy Lebeau の回答からのものです)

... および ... の MSDN 情報

http://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx#OnFileOk

ダイアログは機能しますが、ユーザーが選択したドロップダウンを開く方法を特定する方法が見つかりません。

    (* this is skeleton implementation of the interfaces *)
    type
      TMyFileDialogEvents = class(TInterfacedObject, IFileDialogEvents, IFileDialogControlEvents)
      public
        { IFileDialogEvents }
        function OnFileOk(const pfd: IFileDialog): HResult; stdcall;
        function OnFolderChanging(const pfd: IFileDialog; const psiFolder: IShellItem): HResult; stdcall;
        function OnFolderChange(const pfd: IFileDialog): HResult; stdcall;
        function OnSelectionChange(const pfd: IFileDialog): HResult; stdcall;
        function OnShareViolation(const pfd: IFileDialog; const psi: IShellItem;  out pResponse: DWORD): HResult; stdcall;
        function OnTypeChange(const pfd: IFileDialog): HResult; stdcall;
        function OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; out pResponse: DWORD): HResult; stdcall;
        { IFileDialogControlEvents }
        function OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; dwIDItem: DWORD): HResult; stdcall;
        function OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult; stdcall;
        function OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; bChecked: BOOL): HResult; stdcall;
        function OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult; stdcall;
      end;

    const
      dwVisualGroup1ID: DWORD = 1900;

    implementation

    function TMyFileDialogEvents.OnFileOk(const pfd: IFileDialog): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnFolderChange(const pfd: IFileDialog): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnFolderChanging(const pfd: IFileDialog;
      const psiFolder: IShellItem): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnOverwrite(const pfd: IFileDialog;
      const psi: IShellItem; out pResponse: DWORD): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnSelectionChange(const pfd: IFileDialog): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnShareViolation(const pfd: IFileDialog;
      const psi: IShellItem; out pResponse: DWORD): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnTypeChange(const pfd: IFileDialog): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; dwIDItem: DWORD): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult;
    begin
      if dwIDCtl = dwVisualGroup1ID then begin
        // ...
        Result := S_OK;
      end else begin
        Result := E_NOTIMPL;
      end;
    end;

    function TMyFileDialogEvents.OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; bChecked: BOOL): HResult;
    begin
      Result := E_NOTIMPL;
    end;

    function TMyFileDialogEvents.OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult;
    begin
      Result := E_NOTIMPL;
    end;
    end.

すべてのメソッドにブレークポイントを設定し、ユーザーが [読み取り専用で開く] を選択すると、FileOpenOK メソッド呼び出ししか表示されません。

    (* This is the test code hooking up the dialog *)
    procedure TForm1.Button1Click(Sender: TObject);
    var       Ok: Boolean;
    begin
         FileDialog := nil;
         MyEvents := nil;
         MyEventsCookie := 0;
         try
            Ok := FileOpenDialog1.Execute;
         finally
            if (FileDialog <> nil) and (MyEventsCookie <> 0)
             then FileDialog.Unadvise(MyEventsCookie);
            FileDialog := nil;
            MyEvents := nil;
            MyEventsCookie := 0;
         end;
         if OK
          then ; // open the file
    end;

    procedure TForm1.FileOpenDialog1Execute(Sender: TObject);
    var       c: IFileDialogCustomize;
              d: IFileDialogEvents;
              cookie: DWORD;
    begin
         if Supports(FileOpenDialog1.Dialog, IFileDialogCustomize, c)
          then begin
               c.EnableOpenDropDown(0);
               c.AddControlItem(0,0,'&Open');
               c.AddControlItem(0,1,'Open &read-only');
               d:= TMyFileDialogEvents.Create;
               if Succeeded(FileOpenDialog1.Dialog.Advise(d, cookie))
                then begin
                     FileDialog := FileOpenDialog1.Dialog;
                     MyEvents := d;
                     MyEventsCookie := cookie;
                end;
        end;
    end;

私が特に気に入っている (気に入っていない) のは、MSDN の例で ComboBox と同じメカニズムを使用する方法が提案されていることです。ComboBox の例では、そのコードが省略されており、「完全な」サンプルのどちらにも EnableOpenDropDown が含まれていません! ;)

4

1 に答える 1

1

のプロトタイプを見てくださいEnableOpenDropDown:

HRESULT EnableOpenDropDown(
  [in]  DWORD dwIDCtl
);

渡すパラメーターは、ドロップダウン ボタンの ID です。次に、アイテムを追加するときにその ID を再利用します。

HRESULT AddControlItem(
  [in]  DWORD dwIDCtl,
  [in]  DWORD dwIDItem,
  [in]  LPCWSTR pszLabel
);

したがって、あなたの場合、を呼び出したときに0forを渡しました。次に、2 つの項目を追加したときに、最初のパラメーターと同じ値を使用しました。2 つのアイテムの ID はとです。dwIDCtlEnableOpenDropDownAddControlItem01

ダイアログが閉じられたときにどれが選択されているかを調べるには、 を呼び出しますGetSelectedControlItem

HRESULT GetSelectedControlItem(
  [in]   DWORD dwIDCtl,
  [out]  DWORD *pdwIDItem
);

ドロップダウンを識別するために0forを渡す必要があります。dwIDCtl選択したコントロール項目は、 経由で戻りpdwIDItemます。

IFileDialogCustomizefromの宣言を使用していると仮定するとWinapi.ShlObj、コードは次のようになります。

var
  fdc: IFileDialogCustomize;
  dwIDItem: DWORD;
....
// this code executes after the call to IFileDialog.Show returns
OleCheck(fdc.GetSelectedControlItem(0, dwIDItem));
// dwIDItem will be 0 for Open and 1 for Open read-only

魔法のリテラル値に依存するのではなく、これらの ID に対していくつかの定数を宣言することを検討することをお勧めします。

ダイアログを表示する前に選択したドロップダウン項目を設定する必要がある場合は、 を使用しますSetSelectedControlItem

于 2013-11-04T11:17:18.150 に答える