Search code examples
delphidelphi-7

Using Modern IFileDialog Open/Save dialog with Delphi 7 apps under Win10/11


I would like to modernize the GUI of my Delphi 7 App, I have already .manifest file and it looks quite good, but the Fileopen dialogs are terrible. How the make them modern?

I am using this code at the moment. What would it require to use e.g. IFileOpenDialog instead, how to compile the header for that, or any tweaks to dialogs.pas ?

FileOpenDialog := TOpenDialog.create(parent);
FileOpenDialog.DefaultExt := '*.x';
FileOpenDialog.Filter := 'my|*.x|Text File (CSV)|*.csv'; 
FileOpenDialog.options := [ofHideReadOnly,ofFileMustExist  ,ofNoChangeDir,ofPathMustExist   ];
if FileOpenDialog.Execute then begin
    // do my tricks with FileOpenDialog.filename
    FormUpdate;
end;

The following example code of IFileDialog cannot be compiled with D7:

var
  FolderDialog : IFileDialog;
  hr: HRESULT;
  IResult: IShellItem;
  FileName: PChar;
  Settings: DWORD;
begin
  if Win32MajorVersion >= 6 then
    begin
      hr := CoCreateInstance(CLSID_FileOpenDialog,
                   nil,
                   CLSCTX_INPROC_SERVER,
                   IFileDialog,
                   FolderDialog);

      if hr = S_OK then
        begin
          FolderDialog.SetOkButtonLabel(PChar('Select'));
          FolderDialog.SetTitle(PChar('Select a Directory'));

          hr := FolderDialog.Show(Handle);
          if hr = S_OK then
            begin
              hr := FolderDialog.GetResult(IResult);

              if hr = S_OK then
                begin
                  IResult.GetDisplayName(SIGDN_FILESYSPATH,FileName);
                  ConfigPathEdit.Text := FileName;
                end;
            end;
        end;
    end;

Solution

  • I used this one, I tested it with D7.

    // uses commdlg
    function OpenSaveFileDialog(      Parent: TWinControl;
                                const DefExt,Filter,InitialDir,Title: string;
                                  var FileName: string;
                                      MustExist,OverwritePrompt,NoChangeDir,DoOpen: Boolean): Boolean;
         var ofn: TOpenFileName;
             szFile: array[0..MAX_PATH] of Char;
       begin
             Result := False;
             FillChar(ofn, SizeOf(TOpenFileName), 0);
             with ofn do
               begin
               lStructSize := SizeOf(TOpenFileName);
               hwndOwner := Parent.Handle;
               lpstrFile := szFile;
               nMaxFile := SizeOf(szFile);
    
               if (Title <> '') then
                  lpstrTitle := PChar(Title);
    
               if (InitialDir <> '') then
                  lpstrInitialDir := PChar(InitialDir);
    
               StrPCopy(lpstrFile, FileName);
               lpstrFilter := PChar(StringReplace(Filter, '|', #0,[rfReplaceAll, rfIgnoreCase])+#0#0);
    
               if DefExt <> '' then
                  lpstrDefExt := PChar(DefExt);
               end;
    
             if MustExist then
                ofn.Flags := ofn.Flags or OFN_FILEMUSTEXIST;
    
             if OverwritePrompt then
                ofn.Flags := ofn.Flags or OFN_OVERWRITEPROMPT;
    
             if NoChangeDir then
                ofn.Flags := ofn.Flags or OFN_NOCHANGEDIR;
    
             if DoOpen
                then begin
                     if GetOpenFileName(ofn) then
                        begin
                        Result := True;
                        FileName := StrPas(szFile);
                        end;
                     end
                else begin
                     if GetSaveFileName(ofn) then
                        begin
                        Result := True;
                        FileName := StrPas(szFile);
                        end;
                     end;
        end;
    
    procedure TForm1.Button1Click(Sender: TObject);
          VAR FilSelez : String;
        begin
              If OpenSaveFileDialog(Form1,'','*.*','c:\windows','',FilSelez,False,False,True,True) Then
                 Edit1.Text := FilSelez;
        end;