Inno Setup - 如何创建允许我找到要解压缩的文件的自定义表单?

Inno Setup - How to create a custom form that allows me to locate the files to decompress?

我正在尝试使用此代码创建一个自定义表单,使我能够找到要解压缩的文件:

var
  TNewDiskForm :TSetupForm;
  DiskBitmapImage: TBitmapImage;
  SelectDiskLabel,PathLabel: TLabel;
  PathEdit: TEdit;
  BrowseButton: TButton;
  OKButton: TButton;
  CancelButton: TButton;
  Filename: String;
  Path: String;
  Dir: String;
  ModalResult: Longint;


{ Пути поиска файла }
function GetSanitizedPath: String;
begin
  Result := Trim(PathEdit.Text);
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  Cancel :=True;
  Confirm :=False;
end;

{ Кнопки Обзор }
procedure BrowseButtonClick(Sender: TObject);
begin
  Dir := GetSanitizedPath;
  if BrowseForFolder(SetupMessage (msgSelectDirectoryLabel), Dir, False) then
    PathEdit.Text := Dir + '\';
  TNewDiskForm.Show;
end;

{ Форма зыкрытия (работает mrOK) }
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Path := PathEdit.Text;
  Filename:= ExpandConstant ('data.bin');

  case TNewDiskForm.ModalResult of
    mrOK:
    begin
      if (Path = '') or not FileExists(Path + Filename) then
      begin
        CanClose := false
        MsgBox(FmtMessage(SetupMessage(msgFileNotInDir2), [Filename, Path]), mbError, MB_OK);
      end;
    end;
    mrCancel:
    begin
      CanClose := True;
    end;
  end;
end;

{ запрос диска }
procedure SelectDisk(const DiskNumber: Integer; const Filename, Path: String);
var
  ExitFlag:Boolean;
begin
  repeat
    TNewDiskForm:= CreateCustomForm();
    TNewDiskForm.SetBounds(ScaleX(0), ScaleY(0), ScaleX(377), ScaleY(200));
    TNewDiskForm.CenterInsideControl(WizardForm, False);
    TNewDiskForm.Caption:=SetupMessage(msgChangeDiskTitle);
    TNewDiskForm.Font.Color:= clWindowText
    TNewDiskForm.Font.Height:= -11
    TNewDiskForm.Font.Name:= 'MS Sans Serif'
    TNewDiskForm.Font.Style:= []
    TNewDiskForm.OnCloseQuery:=@FormCloseQuery;

    SelectDiskLabel:=TLabel.Create(TNewDiskForm)
    SelectDiskLabel.SetBounds(ScaleX(72),ScaleY(8), ScaleX(297), ScaleY(72));
    SelectDiskLabel.AutoSize:=False
    SelectDiskLabel.WordWrap:=True
    SelectDiskLabel.Transparent:=True
    SelectDiskLabel.Font.Color:=clBlack
    SelectDiskLabel.Font.Size:=8
    SelectDiskLabel.Caption:=FmtMessage(SetupMessage(msgSelectDiskLabel2), [IntToStr(DiskNumber)]);
    SelectDiskLabel.Parent:=TNewDiskForm
    SelectDiskLabel.ShowAccelChar:= False

    PathEdit:=TEdit.Create(TNewDiskForm)
    PathEdit.SetBounds(ScaleX(8), ScaleY(96), ScaleX(281), ScaleY(21));
    PathEdit.TabOrder:=2
    PathEdit.Text := ExpandConstant('{src}\');
    PathEdit.Parent := TNewDiskForm;

    PathLabel:= TLabel.Create(TNewDiskForm);
    PathLabel.SetBounds(ScaleX(8),ScaleY(80), ScaleX(5), ScaleY(14));
    PathLabel.Font.Color:=clBlack
    PathLabel.FocusControl:= PathEdit
    PathLabel.Caption := SetupMessage(msgPathLabel);
    PathLabel.Parent:=TNewDiskForm

    BrowseButton := TNewButton.Create(TNewDiskForm);
    BrowseButton.SetBounds(ScaleX(296), ScaleY(95), ScaleX(73), ScaleY(23));
    BrowseButton.Parent := TNewDiskForm;
    BrowseButton.OnClick:=@BrowseButtonClick;
    BrowseButton.Caption := SetupMessage(msgButtonBrowse);

    CancelButton := TNewButton.Create(TNewDiskForm);
    CancelButton.SetBounds(ScaleX(296), ScaleY(137), ScaleX(73), ScaleY(23));
    CancelButton.ModalResult := mrCancel;
    CancelButton.Parent := TNewDiskForm;
    CancelButton.Caption := SetupMessage (msgButtonCancel);

    OkButton := TNewButton.Create(TNewDiskForm);
    OkButton.SetBounds(ScaleX(216), ScaleY(137), ScaleX(73), ScaleY(23));
    OkButton.ModalResult := mrOk;
    OkButton.Parent := TNewDiskForm;
    OKButton.Caption := SetupMessage(msgButtonOK);

    TNewDiskForm.ShowModal;

    { закрытие формы (работает mrCancel) }
    case TNewDiskForm.ModalResult of
      mrCancel:
      begin

        TNewDiskForm.Free;
        ExitFlag := ExitSetupMsgBox;

        case ExitFlag of
          True: WizardForm.Close;
          False: SelectDisk (DiskNumber,Filename,Path);
          True: TNewDiskForm.free;
        end;
    end;
  end;
  until ((TNewDiskForm.ModalResult=mrOk) or (TNewDiskForm.ModalResult = mrCancel));
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  { Запуск формы распаковки            № диска          место поиска }
  {                                       |                |         }
  if not (FileExists('data.bin')) then  
  if CurStep = ssInstall then  SelectDisk (2, 'Filename','{src}');
end;

此代码在旧版本的 Inno Setup(俄语版)中工作正常(它仅在文件不存在时启动,并且如果我指出它的位置并且该过程继续)。但我正在尝试修改它以适用于最新版本的 Inno Setup(未知标识符 MODALRESULT)。

  1. 如何修改代码以使用最新版本的 Inno Setup?

  2. 如何同时查看多个文件? (文件名 1、文件名 2 等)

我已经重构了您的代码并使其与官方 Inno Setup 和您的要求兼容。

确实没有TForm.ModalResult。您必须测试,单击哪个按钮才能知道 OnCloseQuery 处理程序中的 "result" 形式是什么。

var
  SelectFilePathEdit: TEdit;
  SelectFileFileName: string;
  SelectFileDialogCanClose: Boolean;
  WizardCancelled: Boolean;

function GetSelectFilePath: string;
begin
  Result := AddBackslash(Trim(SelectFilePathEdit.Text));
end;

procedure SelectFileBrowseButtonClick(Sender: TObject);
var
  Dir: string;
begin
  Dir := GetSelectFilePath;
  if BrowseForFolder(SetupMessage(msgSelectDirectoryLabel), Dir, False) then
  begin
    SelectFilePathEdit.Text := AddBackslash(Dir);
  end;
end;

procedure SelectFileOKButtonClick(Sender: TObject);
begin
  if not FileExists(GetSelectFilePath + SelectFileFileName) then
  begin
    MsgBox(
      FmtMessage(SetupMessage(msgFileNotInDir2), [SelectFileFileName, GetSelectFilePath]),
      mbError, MB_OK);
  end
    else
  begin
    SelectFileDialogCanClose := True;
  end;
end;

procedure SelectFileCancelButtonClick(Sender: TObject);
begin
  SelectFileDialogCanClose := ExitSetupMsgBox();
  Log(Format('SelectFileCancelButtonClick %d', [SelectFileDialogCanClose]));
end;

procedure SelectFileFormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Log(Format('SelectFileFormCloseQuery %d', [SelectFileDialogCanClose]));
  CanClose := SelectFileDialogCanClose;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  Confirm := not WizardCancelled;
end;

function ValidateFile(FileName: string; DefaultPath: string; var Path: string): Boolean;
var
  OKButton: TButton;
  CancelButton: TButton;
  SelectFileForm: TSetupForm;
  SelectFileLabel, PathLabel: TNewStaticText;
  BrowseButton: TButton;
begin
  Path := AddBackslash(DefaultPath) + FileName;

  if FileExists(Path) then
  begin
    Result := True;
  end
    else
  begin
    SelectFileFileName := FileName;

    SelectFileForm := CreateCustomForm();
    try
      SelectFileForm.Width := ScaleX(377);
      SelectFileForm.Position := poScreenCenter;
      SelectFileForm.Caption := Format('Setup needs %s', [FileName]);
      SelectFileForm.OnCloseQuery := @SelectFileFormCloseQuery;

      SelectFileLabel := TNewStaticText.Create(SelectFileForm);
      SelectFileLabel.Left := ScaleX(8);
      SelectFileLabel.Top := ScaleY(8);
      SelectFileLabel.Width :=
        SelectFileForm.ClientWidth - SelectFileLabel.Left - ScaleX(8);
      SelectFileLabel.AutoSize := False;
      SelectFileLabel.WordWrap := True;
      SelectFileLabel.Caption :=
        Format('Select folder with file %s and click OK.', [FileName]);
      SelectFileLabel.Parent := SelectFileForm;
      SelectFileLabel.ShowAccelChar := False;
      WizardForm.AdjustLabelHeight(SelectFileLabel);

      PathLabel := TNewStaticText.Create(SelectFileForm);
      PathLabel.Left := ScaleX(8);
      PathLabel.Top := SelectFileLabel.Top + SelectFileLabel.Height + ScaleX(8);
      PathLabel.Caption := SetupMessage(msgPathLabel);
      PathLabel.Parent := SelectFileForm;

      SelectFilePathEdit := TEdit.Create(SelectFileForm);
      SelectFilePathEdit.Left := PathLabel.Left;
      SelectFilePathEdit.Top := PathLabel.Top + PathLabel.Height + ScaleY(4);
      SelectFilePathEdit.Text := AddBackslash(DefaultPath);
      SelectFilePathEdit.Parent := SelectFileForm;

      PathLabel.FocusControl := SelectFilePathEdit;

      BrowseButton := TNewButton.Create(SelectFileForm);
      BrowseButton.Width := ScaleX(75);
      BrowseButton.Left := SelectFileForm.ClientWidth - BrowseButton.Width - ScaleX(8);
      BrowseButton.Height := ScaleY(23);
      BrowseButton.Top :=
        SelectFilePathEdit.Top -
        ((BrowseButton.Height - SelectFilePathEdit.Height) div 2);
      BrowseButton.Parent := SelectFileForm;
      BrowseButton.OnClick := @SelectFileBrowseButtonClick;
      BrowseButton.Caption := SetupMessage(msgButtonBrowse);

      SelectFilePathEdit.Width :=
        SelectFileForm.ClientWidth - SelectFilePathEdit.Left -
        (SelectFileForm.ClientWidth - BrowseButton.Left) - ScaleX(8);

      OkButton := TNewButton.Create(SelectFileForm);
      OkButton.Width := BrowseButton.Width;
      OkButton.Left :=
        SelectFileForm.ClientWidth - 2 * OkButton.Width - ScaleX(8) - ScaleX(8);
      OkButton.Top := SelectFilePathEdit.Top + SelectFilePathEdit.Height + ScaleY(8);
      OkButton.Height := BrowseButton.Height;
      OkButton.ModalResult := mrOk;
      OkButton.Parent := SelectFileForm;
      OKButton.Caption := SetupMessage(msgButtonOK);
      OKButton.Default := True;
      OKButton.OnClick := @SelectFileOKButtonClick; 

      CancelButton := TNewButton.Create(SelectFileForm);
      CancelButton.Width := OkButton.Width;
      CancelButton.Left := OkButton.Left + OkButton.Width + ScaleX(8);
      CancelButton.Top := OkButton.Top;
      CancelButton.Height := OkButton.Height;
      CancelButton.ModalResult := mrCancel;
      CancelButton.Parent := SelectFileForm;
      CancelButton.Caption := SetupMessage(msgButtonCancel);
      CancelButton.Cancel := True;
      CancelButton.OnClick := @SelectFileCancelButtonClick;

      SelectFileForm.ClientHeight := CancelButton.Top + CancelButton.Height + ScaleY(8);

      SelectFileDialogCanClose := False;

      Result := (SelectFileForm.ShowModal() = mrOK);
      if Result then 
      begin
        Path := GetSelectFilePath;
      end
        else
      begin
        WizardCancelled := True;
        WizardForm.Close;
      end;
    finally
      SelectFileForm.Free;
    end;
  end;
end;

像这样使用它:

var
  Data1Path: string;
  Data2Path: string;
  Data3Path: string;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then 
  begin
       { Start looking in installer folder }
    if ValidateFile('data1.bin', ExpandConstant('{src}'), Data1Path) and
       { But if user selects a different folder, use that for the following files }
       ValidateFile('data2.bin', ExtractFilePath(Data1Path), Data2Path) and
       ValidateFile('data3.bin', ExtractFilePath(Data2Path), Data3Path) then
    begin
      { Process file here }
    end;
  end;
end;

然后使用Data1PathData2PathData3Path,当你需要引用各自的文件时。


有关此解决方案中对话框 Z 顺序的问题,请参阅