【问题标题】:Using Modern IFileDialog Open/Save dialog with Delphi 7 apps under Win10/11在 Win10/11 下将 Modern IFileDialog 打开/保存对话框与 Delphi 7 应用程序一起使用
【发布时间】:2022-02-04 08:01:38
【问题描述】:

我想对我的 Delphi 7 应用程序的 GUI 进行现代化改造,我已经有了 .manifest 文件,它看起来很不错,但是 Fileopen 对话框很糟糕。如何让它们变得现代?

我目前正在使用此代码。 它需要使用什么,例如IFileOpenDialog 相反,如何为此编译标头,或对 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;

下面的IFileDialog示例代码不能用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;

【问题讨论】:

  • Delphi 7 不支持开箱即用的新对话框。如果您没有找到任何第 3 方控件,您可能需要自己实现所有需要的东西。您可以考虑升级您的 Delphi 版本。
  • 很容易修补 VCL 以便显示新对话框,即使使用基于 GetOpenFileName 的包装器也是如此。但是,最好使用 IFileDialog,因为它支持任意长度的多选对话框。
  • 我放弃了 Windows 对话,最终以自己的方式完成了一个表单,我可以在其中拥有用户可配置的快捷按钮和自动完成递归搜索。做起来并不难。
  • @SilverWarior:OP 可能在他们的ShellAPI.pas 中找不到IFileDialog。 IFileDialog 于 2007 年在 Windows Vista、IIRC 中引入。2007 年引入的接口声明在 2002 年的 Delphi 7 中很少可用。

标签: delphi delphi-7


【解决方案1】:

我用过这个,我用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;

【讨论】:

  • OP 专门询问如何使用 Vista+ 文件对话框,但这个答案解释了一种使用旧的、pre-Vista 文件对话框的方法。 更新: 我想即使你使用旧的 API,系统也会显示一个 Vista 对话框,对吧?如果是这样,您可能希望在这个(几乎只有代码的)答案中明确说明。
  • 是的,显示最近的对话框,用D7可以看到同时使用“OpenDialog”组件
  • 优秀的工作代码没有问题问你为什么不升级你的 D7 :D
【解决方案2】:

除了使用IFileDialog 界面,您还可以只修改Delphi 的7 Dialogs.pas 文件以显示“现代”对话框。 首先对Delphi安装目录下Source\VCL文件夹下的Dialogs.pas文件进行备份。然后在文件中搜索术语OFN_ENABLEHOOK。完整的行应该是Flags := OFN_ENABLEHOOK;。注释掉该行。在下面直接添加新行Flags := 0;。 现在搜索术语OFN_ENABLETEMPLATE。上面两行应该是if Template &lt;&gt; nil then 语句。注释掉这个声明和所有后续声明,直到 hWndOwner := Application.Handle; 并添加行 hWndOwner := Screen.ActiveForm.Handle;。

现在确保将Delphi安装目录下Lib和SLib目录下的预编译单元Dialogs.dcu替换为新编译的包含更改的Dialogs.dcu。在Lib 目录中存储一个没有调试信息的版本,而SLib 目录包含一个带有调试信息的版本。在替换文件之前制作文件的备份副本。

请注意,上面给出的说明仅适用于 Delphi 7。此外,该代码禁用了常见对话框组件的事件处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多