Inno Setup - How to create a custom form that allo

2019-04-14 09:25发布

问题:

i am trying to use this code 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;

This code works ok (it only starts when the file is not present, and if i indicate where it is and the process continues) in older version of inno setup (russian version) but i am trying to modified to work on the last version of inno setup (unknown identifier ´MODALRESULT´).

1) How to modify the code to work with the latest version of inno setup?

2) How to check more than one file at same time? (filename1, filename2, etc.)

回答1:

I have refactored your code and made it compatible with official Inno Setup and your requirements.

There's indeed no TForm.ModalResult. You have to test, what button was clicked to know what's the form "result" in OnCloseQuery handler.

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;

Use it like:

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;

And then use the Data1Path, Data2Path and Data3Path, when you need to refer to the respective files.


For problem with dialogs Z-order in this solution, see Inno Setup - Opening directory browse dialog from another dialog without hiding it.



标签: inno-setup