幸运的是,Inno Setup 提供了足够的能力来构建自己的表单,因此您可以在另一个模态表单上模仿卸载表单的任何页面。
以下是我成功创建的内容。该表单从
UninstallForm
中获取尺寸,包含一个
TNewNotebook
控件和用于跳转页面和取消对话框的按钮。
![demo](https://istack.dev59.com/RvNN6.gif)
const
ControlGap = 5;
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'));
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;
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'));
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;
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;
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';
Notebook.Align := alClient;
Pan := TPanel.Create(Result);
Pan.Parent := Notebook;
Pan.Caption := '';
Pan.Align := alBottom;
BtnNext := TNewButton.Create(Result);
with BtnNext do
begin
Parent := Pan;
Name := 'BtnNext';
Caption := SetupMessage(msgButtonNext);
OnClick := @BtnPageChangeClick;
ParentFont := True;
end;
BtnBack := TNewButton.Create(Result);
with BtnBack do
begin
Parent := Pan;
Caption := SetupMessage(msgButtonBack);
Name := 'BtnBack';
OnClick := @BtnPageChangeClick;
ParentFont := True;
end;
BtnCancel := TNewButton.Create(Result);
with BtnCancel do
begin
Parent := Pan;
Name := 'BtnCancel';
Caption := SetupMessage(msgButtonCancel);
ModalResult := mrCancel;
Cancel := True;
ParentFont := True;
end;
TmpLabel := TLabel.Create(Result);
with TmpLabel do
begin
Left := 0;
Top := 0;
Parent := Pan;
ParentFont := True;
Visible := False;
WordWrap := False;
Autosize := True;
end;
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';
if MaxWidth < TmpLabel.Width then
MaxWidth := TmpLabel.Width;
end;
TmpLabel.Caption := 'Yy';
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;
使用方式如下:
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;
TPanel
是否比将另一个表单放在UninstallProgressForm
上方更好呢?使用此代码,您难道不是拥有两个单独的(可移动的)表单吗? - TLama