Search code examples
delphi

Add a IFileDialogCustomize PushButton Event


I can create a Pushbutton with FileSaveDialog1.Dialog.QueryInterface as shown below. How do you setup and handle the OnPushButton click event so I can respond to the button click?

procedure TForm1.FileSaveDialog1Execute(Sender: TObject);
const
  dwVisualGroup1ID: DWORD = 1900;
var
  c: IFileDialogCustomize;
  d: IFileDialogControlEvents;
begin
  if FileSaveDialog1.Dialog.QueryInterface(IFileDialogCustomize, c) = S_OK then
  begin
    // Add a Advanced Button
    c.AddPushButton(dwVisualGroup1ID, 'Advanced');
    c.MakeProminent(dwVisualGroup1ID);
    // Setup the PushButton Click event?

  end;

Solution

  • The following works fine for me in XE2:

    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; 
    
    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;
    

    .

    var
      FileDialog: IFileDialog = nil;
      MyEvents: IFileDialogEvents = nil; 
      MyEventsCookie: DWORD = 0;
    
    procedure TForm1.FileSaveDialog1Execute(Sender: TObject); 
    var 
      c: IFileDialogCustomize; 
      d: IFileDialogEvents; 
      cookie: DWORD;
    begin 
      if Supports(FileSaveDialog1.Dialog, IFileDialogCustomize, c) then 
      begin 
        // Add a Advanced Button 
        c.AddPushButton(dwVisualGroup1ID, 'Advanced'); 
        c.MakeProminent(dwVisualGroup1ID); 
    
        // Setup the PushButton Click event 
        d := TMyFileDialogEvents.Create; 
        if Succeeded(FileSaveDialog1.Dialog.Advise(d, cookie)) then
        begin
          FileDialog := FileSaveDialog1.Dialog
          MyEvents := d;
          MyEventsCookie := cookie;
        end;
      end; 
    end;
    
    procedure TForm1.Button1Click(Sender: TObject); 
    var
      Ok: Boolean;
    begin
      FileDialog := nil;
      MyEvents := nil; 
      MyEventsCookie := 0;
    
      try
        Ok := FileSaveDialog1.Execute;
      finally
        if (FileDialog <> nil) and (MyEventsCookie <> 0) then
          FileDialog.Unadvise(MyEventsCookie);
        FileDialog := nil;
        MyEvents := nil; 
        MyEventsCookie := 0;
      end;
    
      if Ok then ...
    end;