是否可以在 Inno Setup 中以列表形式显示安装操作?

问题描述 投票:0回答:2

是否可以像其他安装程序一样列出进度?

enter image description here

installation inno-setup
2个回答
5
投票

您可以监控

WizardForm.StatusLabel
WizardForm.FilenameLabel
中的更改,并将它们添加到自定义列表框进度视图中。

const
  GWL_WNDPROC = -4;
  SB_VERT = 1;
  SB_BOTTOM = 7;
  WM_VSCROLL = $0115;
  WM_ERASEBKGND = $0014;

type
  WPARAM = UINT_PTR;
  LPARAM = LongInt;
  LRESULT = LongInt;

var
  OldStatusLabelWndProc: LongInt;
  OldFilenameLabelWndProc: LongInt;
  OldProgressListBoxWndProc: LongInt;
  ProgressListBox: TNewListBox;
  PrevStatus: string;
  PrevFileName: string;

function CallWindowProc(
  lpPrevWndFunc: LongInt; hWnd: HWND; Msg: UINT; wParam: WPARAM;
  lParam: LPARAM): LRESULT; external '[email protected] stdcall';  
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: LongInt): LongInt;
  external '[email protected] stdcall';

procedure AddProgress(S: string);
begin
  if S <> '' then
  begin
    ProgressListBox.Items.Add(S);
    ProgressListBox.ItemIndex := ProgressListBox.Items.Count;
    SendMessage(ProgressListBox.Handle, WM_VSCROLL, SB_BOTTOM, 0);
  end;
end;

function StatusLabelWndProc(
  hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
  Result := CallWindowProc(OldStatusLabelWndProc, hwnd, uMsg, wParam, lParam);
  if PrevStatus <> WizardForm.StatusLabel.Caption then
  begin
    AddProgress(WizardForm.StatusLabel.Caption);
    PrevStatus := WizardForm.StatusLabel.Caption;
  end;
end;

function FilenameLabelWndProc(
  hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
  Result := CallWindowProc(OldFilenameLabelWndProc, hwnd, uMsg, wParam, lParam);
  if PrevFileName <> WizardForm.FilenameLabel.Caption then
  begin
    AddProgress(WizardForm.FilenameLabel.Caption);
    PrevFileName := WizardForm.FilenameLabel.Caption;
  end;
end;

function ProgressListBoxWndProc(
  hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
  // reduce flicker
  if uMsg = WM_ERASEBKGND then
  begin
    Result := 1;
  end
    else
  begin
    Result :=
      CallWindowProc(OldProgressListBoxWndProc, hwnd, uMsg, wParam, lParam);
  end;
end;

procedure InitializeWizard();
begin
  OldStatusLabelWndProc :=
    SetWindowLong(WizardForm.StatusLabel.Handle, GWL_WNDPROC,
      CreateCallback(@StatusLabelWndProc));
  OldFilenameLabelWndProc :=
    SetWindowLong(WizardForm.FilenameLabel.Handle, GWL_WNDPROC,
      CreateCallback(@FilenameLabelWndProc));

  WizardForm.ProgressGauge.Top := WizardForm.FilenameLabel.Top;

  ProgressListBox := TNewListBox.Create(WizardForm);
  ProgressListBox.Parent := WizardForm.ProgressGauge.Parent;
  ProgressListBox.Top :=
    WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + ScaleY(8);
  ProgressListBox.Width := WizardForm.FilenameLabel.Width;
  ProgressListBox.Height :=
    ProgressListBox.Parent.ClientHeight - ProgressListBox.Top - ScaleY(16);
  ProgressListBox.Anchors := [akLeft, akTop, akRight, akBottom];
  OldProgressListBoxWndProc :=
    SetWindowLong(ProgressListBox.Handle, GWL_WNDPROC,
      CreateCallback(@ProgressListBoxWndProc));
  // Lame way to shrink width of labels to client width of the list box,
  // so that particularly when the file paths in FilenameLabel are shortened
  // to fit to the label, they actually fit even to the list box.
  WizardForm.StatusLabel.Width := WizardForm.StatusLabel.Width - ScaleY(24);
  WizardForm.FilenameLabel.Width := WizardForm.FilenameLabel.Width - ScaleY(24);
end;

procedure DeinitializeSetup();
begin
  // In case you are using VCL styles or similar, this needs to be done before
  // you unload the style.
  SetWindowLong(
    WizardForm.StatusLabel.Handle, GWL_WNDPROC, OldStatusLabelWndProc);
  SetWindowLong(
    WizardForm.FilenameLabel.Handle, GWL_WNDPROC, OldFilenameLabelWndProc);
  SetWindowLong(
    ProgressListBox.Handle, GWL_WNDPROC, OldProgressListBoxWndProc);
end;

enter image description here


0
投票

不为我工作

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "My Program"
#define MyAppVersion "1.5"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{07292470-E419-4162-A4A0-717FBEF10626}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[Languages]
Name: "default"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

[Files]

[Icons]
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Code]
const
  GWL_WNDPROC = -4;
  SB_VERT = 1;
  SB_BOTTOM = 7;
  WM_VSCROLL = $0115;
  WM_ERASEBKGND = $0014;

type
  WPARAM = UINT_PTR;
  LPARAM = LongInt;
  LRESULT = LongInt;

var
  OldStatusLabelWndProc: LongInt;
  OldFilenameLabelWndProc: LongInt;
  OldProgressListBoxWndProc: LongInt;
  ProgressListBox: TNewListBox;
  PrevStatus: string;
  PrevFileName: string;

function CallWindowProc(
  lpPrevWndFunc: LongInt; hWnd: HWND; Msg: UINT; wParam: WPARAM;
  lParam: LPARAM): LRESULT; external '[email protected] stdcall';
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: LongInt): LongInt;
  external '[email protected] stdcall';

procedure AddProgress(S: string);
begin
  if S <> '' then
  begin
    ProgressListBox.Items.Add(S);
    ProgressListBox.ItemIndex := ProgressListBox.Items.Count;
    SendMessage(ProgressListBox.Handle, WM_VSCROLL, SB_BOTTOM, 0);
  end;
end;

function StatusLabelWndProc(
  hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
  Result := CallWindowProc(OldStatusLabelWndProc, hwnd, uMsg, wParam, lParam);
  if PrevStatus <> WizardForm.StatusLabel.Caption then
  begin
    AddProgress(WizardForm.StatusLabel.Caption);
    PrevStatus := WizardForm.StatusLabel.Caption;
  end;
end;

function FilenameLabelWndProc(
  hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
  Result := CallWindowProc(OldFilenameLabelWndProc, hwnd, uMsg, wParam, lParam);
  if PrevFileName <> WizardForm.FilenameLabel.Caption then
  begin
    AddProgress(WizardForm.FilenameLabel.Caption);
    PrevFileName := WizardForm.FilenameLabel.Caption;
  end;
end;

function ProgressListBoxWndProc(
  hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
begin
  // reduce flicker
  if uMsg = WM_ERASEBKGND then
  begin
    Result := 1;
  end
    else
  begin
    Result :=
      CallWindowProc(OldProgressListBoxWndProc, hwnd, uMsg, wParam, lParam);
  end;
end;

procedure InitializeWizard();
begin
  OldStatusLabelWndProc :=
    SetWindowLong(WizardForm.StatusLabel.Handle, GWL_WNDPROC,
      CreateCallback(@StatusLabelWndProc));
  OldFilenameLabelWndProc :=
    SetWindowLong(WizardForm.FilenameLabel.Handle, GWL_WNDPROC,
      CreateCallback(@FilenameLabelWndProc));

  WizardForm.ProgressGauge.Top := WizardForm.FilenameLabel.Top;

  ProgressListBox := TNewListBox.Create(WizardForm);
  ProgressListBox.Parent := WizardForm.ProgressGauge.Parent;
  ProgressListBox.Top :=
    WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + ScaleY(8);
  ProgressListBox.Width := WizardForm.FilenameLabel.Width;
  ProgressListBox.Height :=
    ProgressListBox.Parent.ClientHeight - ProgressListBox.Top - ScaleY(16);
  ProgressListBox.Anchors := [akLeft, akTop, akRight, akBottom];
  OldProgressListBoxWndProc :=
    SetWindowLong(ProgressListBox.Handle, GWL_WNDPROC,
      CreateCallback(@ProgressListBoxWndProc));
  // Lame way to shrink width of labels to client width of the list box,
  // so that particularly when the file paths in FilenameLabel are shortened
  // to fit to the label, they actually fit even to the list box.
  WizardForm.StatusLabel.Width := WizardForm.StatusLabel.Width - ScaleY(24);
  WizardForm.FilenameLabel.Width := WizardForm.FilenameLabel.Width - ScaleY(24);
end;

procedure DeinitializeSetup();
begin
  // In case you are using VCL styles or similar, this needs to be done before
  // you unload the style.
  SetWindowLong(
    WizardForm.StatusLabel.Handle, GWL_WNDPROC, OldStatusLabelWndProc);
  SetWindowLong(
    WizardForm.FilenameLabel.Handle, GWL_WNDPROC, OldFilenameLabelWndProc);
  SetWindowLong(
    ProgressListBox.Handle, GWL_WNDPROC, OldProgressListBoxWndProc);
end;
© www.soinside.com 2019 - 2024. All rights reserved.