自定义卸载页面(不是MsgBox)

时间:2011-09-14 11:19:24

标签: inno-setup

我需要在安装期间询问用户密码,然后将其用作安装后运行的命令的一部分。我正在使用自定义页面执行此操作并且工作正常。

我还需要在卸载期间提出相同的问题,该问题用作卸载后运行的命令的一部分。

我已经检查了帮助,似乎没有适用于卸载的PageID,我可以在CreateInputQuery函数中使用它。我不特别介意,如果页面显示在卸载的开始,中间或结尾,只要它显示。

我不想使用MsgBox进行卸载,因为我想要标准页面的外观。

关于如何实现这一目标的任何提示?

4 个答案:

答案 0 :(得分:7)

您可以修改卸载表单,使其行为类似于安装表单(包含页面和下一页/后退按钮)。

InitializeUninstallProgressForm

  • 创建新页面并将其插入UninstallProgressForm.InnerNotebook(或.OuterNotebook)。
  • 实施“下一步”和“后退”按钮。
  • 您也可以使“取消”按钮有效。
  • 使用UninstallProgressForm.ShowModal运行表单的模态循环。
  • 仅在模态循环退出后,恢复表单的原始布局并继续卸载。
[Code]

var
  UninstallFirstPage: TNewNotebookPage;
  UninstallSecondPage: TNewNotebookPage;
  UninstallBackButton: TNewButton;
  UninstallNextButton: TNewButton;

procedure UpdateUninstallWizard;
begin
  if UninstallProgressForm.InnerNotebook.ActivePage = UninstallFirstPage then
  begin
    UninstallProgressForm.PageNameLabel.Caption := 'First uninstall wizard page';
    UninstallProgressForm.PageDescriptionLabel.Caption :=
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
  end
    else
  if UninstallProgressForm.InnerNotebook.ActivePage = UninstallSecondPage then
  begin
    UninstallProgressForm.PageNameLabel.Caption := 'Second uninstall wizard page';
    UninstallProgressForm.PageDescriptionLabel.Caption :=
      'Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.';
  end;

  UninstallBackButton.Visible :=
    (UninstallProgressForm.InnerNotebook.ActivePage <> UninstallFirstPage);

  if UninstallProgressForm.InnerNotebook.ActivePage <> UninstallSecondPage then
  begin
    UninstallNextButton.Caption := SetupMessage(msgButtonNext);
    UninstallNextButton.ModalResult := mrNone;
  end
    else
  begin
    UninstallNextButton.Caption := 'Uninstall';
    { Make the "Uninstall" button break the ShowModal loop }
    UninstallNextButton.ModalResult := mrOK;
  end;
end;  

procedure UninstallNextButtonClick(Sender: TObject);
begin
  if UninstallProgressForm.InnerNotebook.ActivePage = UninstallSecondPage then
  begin
    UninstallNextButton.Visible := False;
    UninstallBackButton.Visible := False;
  end
    else
  begin
    if UninstallProgressForm.InnerNotebook.ActivePage = UninstallFirstPage then
    begin
      UninstallProgressForm.InnerNotebook.ActivePage := UninstallSecondPage;
    end;
    UpdateUninstallWizard;
  end;
end;

procedure UninstallBackButtonClick(Sender: TObject);
begin
  if UninstallProgressForm.InnerNotebook.ActivePage = UninstallSecondPage then
  begin
    UninstallProgressForm.InnerNotebook.ActivePage := UninstallFirstPage;
  end;
  UpdateUninstallWizard;
end;

procedure InitializeUninstallProgressForm();
var
  PageText: TNewStaticText;
  PageNameLabel: string;
  PageDescriptionLabel: string;
  CancelButtonEnabled: Boolean;
  CancelButtonModalResult: Integer;
begin
  if not UninstallSilent then
  begin
    { Create the first page and make it active }
    UninstallFirstPage := TNewNotebookPage.Create(UninstallProgressForm);
    UninstallFirstPage.Notebook := UninstallProgressForm.InnerNotebook;
    UninstallFirstPage.Parent := UninstallProgressForm.InnerNotebook;
    UninstallFirstPage.Align := alClient;

    PageText := TNewStaticText.Create(UninstallProgressForm);
    PageText.Parent := UninstallFirstPage;
    PageText.Top := UninstallProgressForm.StatusLabel.Top;
    PageText.Left := UninstallProgressForm.StatusLabel.Left;
    PageText.Width := UninstallProgressForm.StatusLabel.Width;
    PageText.Height := UninstallProgressForm.StatusLabel.Height;
    PageText.AutoSize := False;
    PageText.ShowAccelChar := False;
    PageText.Caption := 'Press Next to proceeed with uninstallation.';

    UninstallProgressForm.InnerNotebook.ActivePage := UninstallFirstPage;

    PageNameLabel := UninstallProgressForm.PageNameLabel.Caption;
    PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption;

    { Create the second page }

    UninstallSecondPage := TNewNotebookPage.Create(UninstallProgressForm);
    UninstallSecondPage.Notebook := UninstallProgressForm.InnerNotebook;
    UninstallSecondPage.Parent := UninstallProgressForm.InnerNotebook;
    UninstallSecondPage.Align := alClient;

    PageText := TNewStaticText.Create(UninstallProgressForm);
    PageText.Parent := UninstallSecondPage;
    PageText.Top := UninstallProgressForm.StatusLabel.Top;
    PageText.Left := UninstallProgressForm.StatusLabel.Left;
    PageText.Width := UninstallProgressForm.StatusLabel.Width;
    PageText.Height := UninstallProgressForm.StatusLabel.Height;
    PageText.AutoSize := False;
    PageText.ShowAccelChar := False;
    PageText.Caption := 'Press Uninstall to proceeed with uninstallation.';

    UninstallNextButton := TNewButton.Create(UninstallProgressForm);
    UninstallNextButton.Parent := UninstallProgressForm;
    UninstallNextButton.Left :=
      UninstallProgressForm.CancelButton.Left -
      UninstallProgressForm.CancelButton.Width -
      ScaleX(10);
    UninstallNextButton.Top := UninstallProgressForm.CancelButton.Top;
    UninstallNextButton.Width := UninstallProgressForm.CancelButton.Width;
    UninstallNextButton.Height := UninstallProgressForm.CancelButton.Height;
    UninstallNextButton.OnClick := @UninstallNextButtonClick;

    UninstallBackButton := TNewButton.Create(UninstallProgressForm);
    UninstallBackButton.Parent := UninstallProgressForm;
    UninstallBackButton.Left :=
      UninstallNextButton.Left - UninstallNextButton.Width -
      ScaleX(10);
    UninstallBackButton.Top := UninstallProgressForm.CancelButton.Top;
    UninstallBackButton.Width := UninstallProgressForm.CancelButton.Width;
    UninstallBackButton.Height := UninstallProgressForm.CancelButton.Height;
    UninstallBackButton.Caption := SetupMessage(msgButtonBack);
    UninstallBackButton.OnClick := @UninstallBackButtonClick;
    UninstallBackButton.TabOrder := UninstallProgressForm.CancelButton.TabOrder;

    UninstallNextButton.TabOrder := UninstallBackButton.TabOrder + 1;

    UninstallProgressForm.CancelButton.TabOrder := UninstallNextButton.TabOrder + 1;

    { Run our wizard pages } 
    UpdateUninstallWizard;
    CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled
    UninstallProgressForm.CancelButton.Enabled := True;
    CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult;
    UninstallProgressForm.CancelButton.ModalResult := mrCancel;

    if UninstallProgressForm.ShowModal = mrCancel then Abort;

    { Restore the standard page payout }
    UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled;
    UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult;

    UninstallProgressForm.PageNameLabel.Caption := PageNameLabel;
    UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel;

    UninstallProgressForm.InnerNotebook.ActivePage :=
      UninstallProgressForm.InstallingPage;
  end;
end;

First page

Second page

Uninstalling

另见Inno Setup - How to create a OuterNotebook/welcome page in the uninstaller?

答案 1 :(得分:5)

幸运的是Inno Setup提供了足够的能力来构建自己的表单,因此您可以在另一个模态表单上模仿卸载表单的任何页面。 这是我设法创造的。表单从UninstallForm获取尺寸,包含TNewNotebook控件和按钮以在页面之间跳转并取消对话框。

demo

const
  ControlGap = 5; // determined empirically

// Set Back/Next buttons state according to current selected notebook page
procedure UpdateButtonsState(Form: TSetupForm);
var
  Notebook: TNewNotebook;
  BtnBack, BtnNext: TButton;
begin
  Notebook := TNewNotebook(Form.FindComponent('Notebook'));
  BtnBack := TButton(Form.FindComponent('BtnBack'));
  BtnNext := TButton(Form.FindComponent('BtnNext'));

  // Update buttons state
  BtnBack.Enabled := (Notebook.ActivePage <> Notebook.Pages[0]);
  if Notebook.ActivePage <> Notebook.Pages[Notebook.PageCount - 1] then
  begin
    BtnNext.Caption := SetupMessage(msgButtonNext)
    BtnNext.ModalResult := mrNone;
  end
  else
  begin
    BtnNext.Caption := SetupMessage(msgButtonFinish);
    BtnNext.ModalResult := mrYes;
  end;
end;

// Change notebook page
procedure BtnPageChangeClick(Sender: TObject);
var
  NextPage: TNewNotebookPage;
  Notebook: TNewNotebook;
  Form: TWinControl;
  Button, BtnBack, BtnNext: TButton;
begin
  Button := TButton(Sender);
  Form := Button;
  while not (Form is TSetupForm) do
    Form := Form.Parent;
  Notebook := TNewNotebook(Form.FindComponent('Notebook'));
  BtnBack := TButton(Form.FindComponent('BtnBack'));
  BtnNext := TButton(Form.FindComponent('BtnNext'));

  // Avoid cycled style of Notebook's page looping
  if (Button = BtnBack) and (Notebook.ActivePage = Notebook.Pages[0]) then
    NextPage := nil
  else
  if (Button = BtnNext) and (Notebook.ActivePage = Notebook.Pages[Notebook.PageCount - 1]) then
    NextPage := nil
  else
    NextPage := Notebook.FindNextPage(Notebook.ActivePage, Button = BtnNext);
  Notebook.ActivePage := NextPage;

  UpdateButtonsState(TSetupForm(Form));
end;

// Add a new page to notebook and return it
function AddPage(NotebookForm: TSetupForm): TNewNotebookPage;
var
  Notebook: TNewNotebook;
begin
  Notebook := TNewNotebook(NotebookForm.FindComponent('Notebook'));
  Result := TNewNotebookPage.Create(Notebook);
  Result.Notebook:=Notebook;
  Result.Parent:=Notebook;
  Result.Align := alClient;
  if Notebook.ActivePage = nil then 
    Notebook.ActivePage := Result;
  UpdateButtonsState(NotebookForm);
end;

// Create a form with notebook and 3 buttons: Back, Next, Cancel
function CreateNotebookForm: TSetupForm;
var
  Notebook: TNewNotebook;
  NotebookPage: TNewNotebookPage;
  Pan: TPanel;
  TmpLabel: TLabel;
  MaxWidth, i: Integer;
  BtnBack, BtnNext, BtnCancel: TButton;
  BtnLabelMsgIDs: array of TSetupMessageID;
begin
  Result := CreateCustomForm;
  Result.SetBounds(0, 0, UninstallProgressForm.Width, UninstallProgressForm.Height);
  Result.Position := poOwnerFormCenter;

  Notebook := TNewNotebook.Create(Result);
  Notebook.Parent := Result;
  Notebook.Name := 'Notebook';  // will be used for searching
  Notebook.Align := alClient;

  Pan := TPanel.Create(Result);
  Pan.Parent := Notebook;
  Pan.Caption := '';
  Pan.Align := alBottom;

  // Create buttons

  BtnNext := TNewButton.Create(Result);
  with BtnNext do
  begin
    Parent := Pan;
    Name := 'BtnNext';  // will be used for searching
    Caption := SetupMessage(msgButtonNext);
    OnClick := @BtnPageChangeClick;
    ParentFont := True;
  end;

  BtnBack := TNewButton.Create(Result);
  with BtnBack do
  begin
    Parent := Pan;
    Caption := SetupMessage(msgButtonBack);
    Name := 'BtnBack';  // will be used for searching
    OnClick := @BtnPageChangeClick;
    ParentFont := True;
  end;

  BtnCancel := TNewButton.Create(Result);
  with BtnCancel do
  begin
    Parent := Pan;
    Name := 'BtnCancel';  // will be used for searching
    Caption := SetupMessage(msgButtonCancel);
    ModalResult := mrCancel;
    Cancel := True;
    ParentFont := True;
  end;

  // Determine dimensions of buttons. Should use TCanvas.TextWidth here
  // but it doesn't allow Font property assignment :(

  TmpLabel := TLabel.Create(Result);
  with TmpLabel do
  begin
    Left := 0;
    Top := 0;
    Parent := Pan;
    ParentFont := True;
    Visible := False;
    WordWrap := False;
    Autosize := True;
  end;

  // Determine max label width among these labels: Back, Next, Cancel, Finish
  SetArrayLength(BtnLabelMsgIDs, 4);
  BtnLabelMsgIDs[0] := msgButtonBack;
  BtnLabelMsgIDs[1] := msgButtonNext;
  BtnLabelMsgIDs[2] := msgButtonCancel;
  BtnLabelMsgIDs[3] := msgButtonFinish;
  MaxWidth := 0;
  for i := Low(BtnLabelMsgIDs) to High(BtnLabelMsgIDs) do
  begin
    TmpLabel.Caption := SetupMessage(BtnLabelMsgIDs[i]) + 'WWW';  // Add letters for surrounding spaces 
    if MaxWidth < TmpLabel.Width then
      MaxWidth := TmpLabel.Width;
  end;

  TmpLabel.Caption := 'Yy';  // Determine height

  // Assign sizes and positions
  Pan.ClientHeight := TmpLabel.Height*4;

  with BtnBack do
  begin
    Width := MaxWidth;
    Height := TmpLabel.Height*2;
    Left := Parent.ClientWidth - 3*(MaxWidth + ScaleX(ControlGap));
    Top := (Parent.ClientHeight - Height) div 2;
  end;
  with BtnNext do
  begin
    Width := MaxWidth;
    Height := TmpLabel.Height*2;
    Left := Parent.ClientWidth - 2*(MaxWidth + ScaleX(ControlGap));
    Top := (Parent.ClientHeight - Height) div 2;
  end;
  with BtnCancel do
  begin
    Width := MaxWidth;
    Height := TmpLabel.Height*2;
    Left := Parent.ClientWidth - 1*(MaxWidth + ScaleX(ControlGap));
    Top := (Parent.ClientHeight - Height) div 2;
  end;
end;

用法就像

// UninstallProgressForm is about to be shown
// Show modal dialog which allows to select additional components to uninstall
procedure InitializeUninstallProgressForm;
var
  Form: TSetupForm;
  i: Integer;
  NotebookPage: TNewNotebookPage;
  ModResult: Integer;
begin
  Form := CreateNotebookForm;
  for i := 1 to 4 do
  begin
    NotebookPage := AddPage(Form);
    with NotebookPage do
    begin
      Color := clWindow;
      with TLabel.Create(Form) do
      begin
        Parent := NotebookPage;
        SetBounds(0, 0, 50, 30);
        Autosize := true;
        Font.Size := 14;
        Caption := 'Label ' + IntToStr(i);
      end;
    end;
  end;

  ModResult := Form.ShowModal;
  if ModResult = mrYes then
    MsgBox('Continuing uninstall', mbInformation, MB_OK)
  else
  begin
    MsgBox('Cancelled', mbInformation, MB_OK);
    Abort;
  end;

  ...
end;

答案 2 :(得分:2)

我正在使用InnoSetup 5.4.2,在文档中有几个Uninstall Event Functions,包括: 过程CurUninstallStepChanged(CurUninstallStep:TUninstallStep);

您应该能够在[code]部分中创建输入页面。

答案 3 :(得分:2)

Inno目前在卸载期间不支持向导页面。您将需要使用Forms。