Pārlūkot izejas kodu

Split main form and main functions+vars.

Martijn Laan 1 gadu atpakaļ
vecāks
revīzija
c745379b5f

+ 1 - 0
Projects/Setup.dpr

@@ -20,6 +20,7 @@ uses
   Shared.CommonFunc.Vcl in 'Src\Shared.CommonFunc.Vcl.pas',
   Shared.CommonFunc.Vcl in 'Src\Shared.CommonFunc.Vcl.pas',
   Shared.CommonFunc in 'Src\Shared.CommonFunc.pas',
   Shared.CommonFunc in 'Src\Shared.CommonFunc.pas',
   Setup.MainForm in 'Src\Setup.MainForm.pas' {MainForm},
   Setup.MainForm in 'Src\Setup.MainForm.pas' {MainForm},
+  Setup.MainFunc in 'Src\Setup.MainFunc.pas',
   Setup.Install in 'Src\Setup.Install.pas',
   Setup.Install in 'Src\Setup.Install.pas',
   SetupLdrAndSetup.Messages in 'Src\SetupLdrAndSetup.Messages.pas',
   SetupLdrAndSetup.Messages in 'Src\SetupLdrAndSetup.Messages.pas',
   Shared.SetupMessageIDs in 'Src\Shared.SetupMessageIDs.pas',
   Shared.SetupMessageIDs in 'Src\Shared.SetupMessageIDs.pas',

+ 1 - 0
Projects/Setup.dproj

@@ -81,6 +81,7 @@
         <DCCReference Include="Src\Setup.MainForm.pas">
         <DCCReference Include="Src\Setup.MainForm.pas">
             <Form>MainForm</Form>
             <Form>MainForm</Form>
         </DCCReference>
         </DCCReference>
+        <DCCReference Include="Src\Setup.MainFunc.pas"/>
         <DCCReference Include="Src\Setup.Install.pas"/>
         <DCCReference Include="Src\Setup.Install.pas"/>
         <DCCReference Include="Src\SetupLdrAndSetup.Messages.pas"/>
         <DCCReference Include="Src\SetupLdrAndSetup.Messages.pas"/>
         <DCCReference Include="Src\Shared.SetupMessageIDs.pas"/>
         <DCCReference Include="Src\Shared.SetupMessageIDs.pas"/>

+ 1 - 1
Projects/Src/Setup.DebugClient.pas

@@ -36,7 +36,7 @@ procedure SetDebugServerWnd(Wnd: HWND; WantCodeText: Boolean);
 implementation
 implementation
 
 
 uses
 uses
-  Forms, Classes, Shared.CommonFunc, Shared.Struct, Setup.InstFunc, Setup.MainForm;
+  Forms, Classes, Shared.CommonFunc, Shared.Struct, Setup.InstFunc, Setup.MainFunc;
 
 
 type
 type
   TDummyClass = class
   TDummyClass = class

+ 1 - 1
Projects/Src/Setup.FileExtractor.pas

@@ -50,7 +50,7 @@ procedure FreeFileExtractor;
 implementation
 implementation
 
 
 uses
 uses
-  PathFunc, Shared.CommonFunc, Setup.MainForm, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
+  PathFunc, Shared.CommonFunc, Setup.MainFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
   Setup.InstFunc, Compression.Zlib, Compression.bzlib,
   Setup.InstFunc, Compression.Zlib, Compression.bzlib,
   Compression.LZMADecompressor, SHA1, Setup.LoggingFunc, Setup.NewDiskForm;
   Compression.LZMADecompressor, SHA1, Setup.LoggingFunc, Setup.NewDiskForm;
 
 

+ 1 - 1
Projects/Src/Setup.Helper.pas

@@ -31,7 +31,7 @@ implementation
 {x$DEFINE HELPERDEBUG}
 {x$DEFINE HELPERDEBUG}
 
 
 uses
 uses
-  Forms, Shared.Int64Em, Shared.CommonFunc.Vcl, Shared.CommonFunc, PathFunc, Setup.MainForm, Setup.InstFunc,
+  Forms, Shared.Int64Em, Shared.CommonFunc.Vcl, Shared.CommonFunc, PathFunc, Setup.MainFunc, Setup.InstFunc,
   Setup.LoggingFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs;
   Setup.LoggingFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs;
 
 
 const
 const

+ 1 - 1
Projects/Src/Setup.InstFunc.Ole.pas

@@ -23,7 +23,7 @@ function UnpinShellLink(const Filename: String): Boolean;
 implementation
 implementation
 
 
 uses
 uses
-  Windows, SysUtils, PathFunc, Shared.CommonFunc, Setup.InstFunc, Setup.MainForm,
+  Windows, SysUtils, PathFunc, Shared.CommonFunc, Setup.InstFunc, Setup.MainFunc,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
   ActiveX, ComObj, PropSys, ShellAPI, ShlObj;
   ActiveX, ComObj, PropSys, ShellAPI, ShlObj;
 
 

+ 1 - 1
Projects/Src/Setup.Install.pas

@@ -30,7 +30,7 @@ implementation
 uses
 uses
   Windows, SysUtils, Messages, Classes, Forms, ShlObj, Shared.Struct, Setup.UninstallLog, Shared.SetupTypes,
   Windows, SysUtils, Messages, Classes, Forms, ShlObj, Shared.Struct, Setup.UninstallLog, Shared.SetupTypes,
   SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, Setup.SecurityFunc, SetupLdrAndSetup.Messages,
   SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, Setup.SecurityFunc, SetupLdrAndSetup.Messages,
-  Setup.MainForm, Setup.LoggingFunc, Setup.FileExtractor, Shared.FileClass,
+  Setup.MainFunc, Setup.LoggingFunc, Setup.FileExtractor, Shared.FileClass,
   Compression.Base, SHA1, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, SetupLdrAndSetup.RedirFunc, Shared.Int64Em, Shared.SetupMessageIDs,
   Compression.Base, SHA1, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, SetupLdrAndSetup.RedirFunc, Shared.Int64Em, Shared.SetupMessageIDs,
   Setup.WizardForm, Shared.DebugStruct, Setup.DebugClient, Shared.VerInfoFunc, Setup.ScriptRunner, Setup.RegDLL, Setup.Helper,
   Setup.WizardForm, Shared.DebugStruct, Setup.DebugClient, Shared.VerInfoFunc, Setup.ScriptRunner, Setup.RegDLL, Setup.Helper,
   Shared.ResUpdateFunc, Setup.DotNetFunc, TaskbarProgressFunc, NewProgressBar, RestartManager,
   Shared.ResUpdateFunc, Setup.DotNetFunc, TaskbarProgressFunc, NewProgressBar, RestartManager,

+ 767 - 0
Projects/Src/Setup.MainForm.pas

@@ -0,0 +1,767 @@
+unit Setup.MainForm;
+
+{
+  Inno Setup
+  Copyright (C) 1997-2024 Jordan Russell
+  Portions by Martijn Laan
+  For conditions of distribution and use, see LICENSE.TXT.
+
+  Background form
+}
+
+interface
+
+uses
+  Windows, Messages, SysUtils, Classes,
+  Shared.Struct, Setup.MainFunc, Setup.SetupForm, Shared.SetupTypes;
+
+type
+  TMainForm = class(TSetupForm)
+    procedure FormResize(Sender: TObject);
+    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+    procedure FormPaint(Sender: TObject);
+    procedure FormKeyDown(Sender: TObject; var Key: Word;
+      Shift: TShiftState);
+  private
+    IsMinimized, HideWizard: Boolean;
+    function MainWindowHook(var Message: TMessage): Boolean;
+    procedure UpdateWizardFormVisibility;
+    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
+    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
+    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
+    procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
+  public
+    CurStep: TSetupStep;
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure Finish(const FromPreparingPage: Boolean);
+    procedure InitializeWizard;
+    function Install: Boolean;
+    procedure SetStep(const AStep: TSetupStep; const HandleExceptions: Boolean);
+    class procedure ShowException(Sender: TObject; E: Exception);
+    class procedure ShowExceptionMsg(const S: String);
+    procedure ShowAboutBox;
+  end;
+
+var
+  MainForm: TMainForm;
+
+implementation
+
+uses
+  Forms, Graphics, ShlObj, MD5, RestartManager,
+  Shared.CommonFunc, Shared.CommonFunc.Vcl, Shared.SetupMessageIDs,
+  SetupLdrAndSetup.Messages, SetupLdrAndSetup.RedirFunc, Setup.Install,
+  Setup.InstFunc, Setup.WizardForm, Setup.LoggingFunc;
+
+{$R *.DFM}
+
+constructor TMainForm.Create(AOwner: TComponent);
+var
+  SystemMenu: HMenu;
+begin
+  inherited;
+
+  InitializeFont;
+
+  if shWindowVisible in SetupHeader.Options then begin
+    { Should the main window not be sizable? }
+    if not(shWindowShowCaption in SetupHeader.Options) then
+      BorderStyle := bsNone
+    else
+    if not(shWindowResizable in SetupHeader.Options) then
+      BorderStyle := bsSingle;
+
+    { Make the main window full-screen. If the window is resizable, limit it
+      to just the work area because full-screen resizable windows don't cover
+      over the taskbar. }
+    BoundsRect := GetRectOfPrimaryMonitor(BorderStyle = bsSizeable);
+    { Before maximizing the window, ensure Handle is created now so the correct
+      'restored' position is saved properly }
+    HandleNeeded;
+
+    { Maximize the window so that the taskbar is still accessible }
+    if shWindowStartMaximized in SetupHeader.Options then
+      WindowState := wsMaximized;
+  end
+  else begin
+    Application.ShowMainForm := False;
+  end;
+
+  if shDisableWelcomePage in SetupHeader.Options then
+    Caption := FmtSetupMessage1(msgSetupWindowTitle, ExpandedAppVerName)
+  else
+    Caption := FmtSetupMessage1(msgSetupWindowTitle, ExpandedAppName);
+
+  { Append the 'About Setup' item to the system menu }
+  SystemMenu := GetSystemMenu(Handle, False);
+  AppendMenu(SystemMenu, MF_SEPARATOR, 0, nil);
+  AppendMenu(SystemMenu, MF_STRING, 9999, PChar(SetupMessages[msgAboutSetupMenuItem]));
+
+  Application.HookMainWindow(MainWindowHook);
+
+  if Application.ShowMainForm then
+    { Show this form now, so that the focus stays on the wizard form that
+      InitializeWizard (called in the .dpr) shows }
+    Visible := True;
+end;
+
+destructor TMainForm.Destroy;
+begin
+  Application.UnhookMainWindow(MainWindowHook);
+  inherited;
+end;
+
+procedure TMainForm.WMSysCommand(var Message: TWMSysCommand);
+begin
+  if Message.CmdType = 9999 then
+    ShowAboutBox
+  else
+    inherited;
+end;
+
+procedure TMainForm.WMEraseBkgnd(var Message: TWMEraseBkgnd);
+begin
+  { Since the form paints its entire client area in FormPaint, there is
+    no need for the VCL to ever erase the client area with the brush color.
+    Doing so only slows it down, so this message handler disables that default
+    behavior. }
+  Message.Result := 0;
+end;
+
+procedure TMainForm.FormPaint(Sender: TObject);
+
+  function BlendRGB(const Color1, Color2: TColor; const Blend: Integer): TColor;
+  { Blends Color1 and Color2. Blend must be between 0 and 255; 0 = all Color1,
+    255 = all Color2. }
+  type
+    TColorBytes = array[0..3] of Byte;
+  var
+    I: Integer;
+  begin
+    Result := 0;
+    for I := 0 to 2 do
+      TColorBytes(Result)[I] := Integer(TColorBytes(Color1)[I] +
+        ((TColorBytes(Color2)[I] - TColorBytes(Color1)[I]) * Blend) div 255);
+  end;
+
+var
+  C1, C2: TColor;
+  CS: TPoint;
+  Z: Integer;
+  DrawTextFlags: UINT;
+  R, R2: TRect;
+begin
+  with Canvas do begin
+    { Draw the blue background }
+    if SetupHeader.BackColor = SetupHeader.BackColor2 then begin
+      Brush.Color := SetupHeader.BackColor;
+      FillRect(ClientRect);
+    end
+    else begin
+      C1 := ColorToRGB(SetupHeader.BackColor);
+      C2 := ColorToRGB(SetupHeader.BackColor2);
+      CS := ClientRect.BottomRight;
+      for Z := 0 to 255 do begin
+        Brush.Color := BlendRGB(C1, C2, Z);
+        if not(shBackColorHorizontal in SetupHeader.Options) then
+          FillRect(Rect(0, MulDiv(CS.Y, Z, 255), CS.X, MulDiv(CS.Y, Z+1, 255)))
+        else
+          FillRect(Rect(MulDiv(CS.X, Z, 255), 0, MulDiv(CS.X, Z+1, 255), CS.Y));
+      end;
+    end;
+
+    { Draw the application name and copyright }
+    SetBkMode(Handle, TRANSPARENT);
+
+    DrawTextFlags := DT_WORDBREAK or DT_NOPREFIX or DT_NOCLIP;
+    if RightToLeft then
+      DrawTextFlags := DrawTextFlags or (DT_RIGHT or DT_RTLREADING);
+    SetFontNameSize(Font, LangOptions.TitleFontName,
+      LangOptions.TitleFontSize, 'Arial', 29);
+    if IsMultiByteString(AnsiString(ExpandedAppName)) then
+      { Don't use italics on Japanese characters }
+      Font.Style := [fsBold]
+    else
+      Font.Style := [fsBold, fsItalic];
+    R := ClientRect;
+    InflateRect(R, -8, -8);
+    R2 := R;
+    if RightToLeft then
+      OffsetRect(R2, -4, 4)
+    else
+      OffsetRect(R2, 4, 4);
+    Font.Color := clBlack;
+    DrawText(Handle, PChar(ExpandedAppName), -1, R2, DrawTextFlags);
+    Font.Color := clWhite;
+    DrawText(Handle, PChar(ExpandedAppName), -1, R, DrawTextFlags);
+
+    DrawTextFlags := DrawTextFlags xor DT_RIGHT;
+    SetFontNameSize(Font, LangOptions.CopyrightFontName,
+      LangOptions.CopyrightFontSize, 'Arial', 8);
+    Font.Style := [];
+    R := ClientRect;
+    InflateRect(R, -6, -6);
+    R2 := R;
+    DrawText(Handle, PChar(ExpandedAppCopyright), -1, R2, DrawTextFlags or
+      DT_CALCRECT);
+    R.Top := R.Bottom - (R2.Bottom - R2.Top);
+    R2 := R;
+    if RightToLeft then
+      OffsetRect(R2, -1, 1)
+    else
+      OffsetRect(R2, 1, 1);
+    Font.Color := clBlack;
+    DrawText(Handle, PChar(ExpandedAppCopyright), -1, R2, DrawTextFlags);
+    Font.Color := clWhite;
+    DrawText(Handle, PChar(ExpandedAppCopyright), -1, R, DrawTextFlags);
+  end;
+end;
+
+procedure TMainForm.FormResize(Sender: TObject);
+begin
+  { Needs to redraw the background whenever the form is resized }
+  Repaint;
+end;
+
+procedure TMainForm.ShowAboutBox;
+var
+  S: String;
+begin
+  { Removing the About box or modifying any existing text inside it is a
+    violation of the Inno Setup license agreement; see LICENSE.TXT.
+    However, adding additional lines to the end of the About box is
+    permitted. }
+  S := SetupTitle + ' version ' + SetupVersion + SNewLine;
+  if SetupTitle <> 'Inno Setup' then
+    S := S + (SNewLine + 'Based on Inno Setup' + SNewLine);
+  S := S + ('Copyright (C) 1997-2024 Jordan Russell' + SNewLine +
+    'Portions Copyright (C) 2000-2024 Martijn Laan' + SNewLine +
+    'All rights reserved.' + SNewLine2 +
+    'Inno Setup home page:' + SNewLine +
+    'https://www.innosetup.com/');
+  S := S + SNewLine2 + 'RemObjects Pascal Script home page:' + SNewLine +
+    'https://www.remobjects.com/ps';
+  if SetupMessages[msgAboutSetupNote] <> '' then
+    S := S + SNewLine2 + SetupMessages[msgAboutSetupNote];
+  if SetupMessages[msgTranslatorNote] <> '' then
+    S := S + SNewLine2 + SetupMessages[msgTranslatorNote];
+  StringChangeEx(S, '(C)', #$00A9, True);
+  LoggedMsgBox(S, SetupMessages[msgAboutSetupTitle], mbInformation, MB_OK, False, 0);
+end;
+
+class procedure TMainForm.ShowExceptionMsg(const S: String);
+begin
+  Log('Exception message:');
+  LoggedAppMessageBox(PChar(S), PChar(Application.Title), MB_OK or MB_ICONSTOP, True, IDOK);
+end;
+
+class procedure TMainForm.ShowException(Sender: TObject; E: Exception);
+begin
+  ShowExceptionMsg(AddPeriod(E.Message));
+end;
+
+procedure TMainForm.SetStep(const AStep: TSetupStep; const HandleExceptions: Boolean);
+begin
+  CurStep := AStep;
+  if CodeRunner <> nil then begin
+    try
+      CodeRunner.RunProcedures('CurStepChanged', [Ord(CurStep)], False);
+    except
+      if HandleExceptions then begin
+        Log('CurStepChanged raised an exception.');
+        Application.HandleException(Self);
+      end
+      else begin
+        Log('CurStepChanged raised an exception (fatal).');
+        raise;
+      end;
+    end;
+  end;
+end;
+
+procedure TMainForm.InitializeWizard;
+begin
+  WizardForm := TWizardForm.Create(Application);
+  if CodeRunner <> nil then begin
+    try
+      CodeRunner.RunProcedures('InitializeWizard', [''], False);
+    except
+      Log('InitializeWizard raised an exception (fatal).');
+      raise;
+    end;
+  end;
+  WizardForm.FlipSizeAndCenterIfNeeded(shWindowVisible in SetupHeader.Options, MainForm, True);
+  WizardForm.SetCurPage(wpWelcome);
+  if InstallMode = imNormal then begin
+    WizardForm.ClickToStartPage; { this won't go past wpReady  }
+    SetActiveWindow(Application.Handle);  { ensure taskbar button is selected }
+    WizardForm.Show;
+  end
+  else
+    WizardForm.ClickThroughPages;
+end;
+
+procedure TerminateApp;
+begin
+  { Work around shell32 bug: Don't use PostQuitMessage/Application.Terminate
+    here.
+    When ShellExecute is called with the name of a folder, it internally
+    creates a window used for DDE communication with Windows Explorer. After
+    ShellExecute returns, this window eventually receives a posted WM_DDE_ACK
+    message back from the DDE server (Windows Explorer), and in response, it
+    tries to flush the queue of DDE messages by using a PeekMessage loop.
+    Problem is, PeekMessage will return WM_QUIT messages posted with
+    PostQuitMessage regardless of the message range specified, and the loop was
+    not written with this in mind.
+    In previous IS versions, this was causing our WM_QUIT message to be eaten
+    if Application.Terminate was called very shortly after a shellexec [Run]
+    entry was processed (e.g. if DisableFinishedPage=yes).
+    A WM_QUIT message posted with PostMessage instead of PostQuitMessage will
+    not be returned by a GetMessage/PeekMessage call with a message range that
+    does not include WM_QUIT. }
+  PostMessage(0, WM_QUIT, 0, 0);
+end;
+
+function TMainForm.Install: Boolean;
+
+  procedure ProcessRunEntries;
+  var
+    CheckIfRestartNeeded: Boolean;
+    ChecksumBefore, ChecksumAfter: TMD5Digest;
+    WindowDisabler: TWindowDisabler;
+    I: Integer;
+    RunEntry: PSetupRunEntry;
+  begin
+    if Entries[seRun].Count <> 0 then begin
+      CheckIfRestartNeeded := (shRestartIfNeededByRun in SetupHeader.Options) and
+        not NeedsRestart;
+      if CheckIfRestartNeeded then
+        ChecksumBefore := MakePendingFileRenameOperationsChecksum;
+      WindowDisabler := nil;
+      try
+        for I := 0 to Entries[seRun].Count-1 do begin
+          RunEntry := PSetupRunEntry(Entries[seRun][I]);
+          if not(roPostInstall in RunEntry.Options) and
+             ShouldProcessRunEntry(WizardComponents, WizardTasks, RunEntry) then begin
+            { Disable windows during execution of [Run] entries so that a nice
+              "beep" is produced if the user tries clicking on WizardForm }
+            if WindowDisabler = nil then
+              WindowDisabler := TWindowDisabler.Create;
+            if RunEntry.StatusMsg <> '' then begin
+              try
+                WizardForm.StatusLabel.Caption := ExpandConst(RunEntry.StatusMsg);
+              except
+                { Don't die if the expansion fails with an exception. Just
+                  display the exception message, and proceed with the default
+                  status message. }
+                Application.HandleException(Self);
+                WizardForm.StatusLabel.Caption := SetupMessages[msgStatusRunProgram];
+              end;
+            end
+            else
+              WizardForm.StatusLabel.Caption := SetupMessages[msgStatusRunProgram];
+            WizardForm.StatusLabel.Update;
+            if roHideWizard in RunEntry.Options then begin
+              if WizardForm.Visible and not HideWizard then begin
+                HideWizard := True;
+                UpdateWizardFormVisibility;
+              end;
+            end
+            else begin
+              if HideWizard then begin
+                HideWizard := False;
+                UpdateWizardFormVisibility;
+              end;
+            end;
+            DebugNotifyEntry(seRun, I);
+            NotifyBeforeInstallEntry(RunEntry.BeforeInstall);
+            ProcessRunEntry(RunEntry);
+            NotifyAfterInstallEntry(RunEntry.AfterInstall);
+          end;
+        end;
+      finally
+        if HideWizard then begin
+          HideWizard := False;
+          UpdateWizardFormVisibility;
+        end;
+        WindowDisabler.Free;
+        if CheckIfRestartNeeded then begin
+          ChecksumAfter := MakePendingFileRenameOperationsChecksum;
+          if not MD5DigestsEqual(ChecksumBefore, ChecksumAfter) then
+            NeedsRestart := True;
+        end;
+      end;
+      Application.BringToFront;
+    end;
+  end;
+
+  procedure RestartApplications;
+  const
+    ERROR_FAIL_RESTART = 353;
+  var
+    Error: DWORD;
+    WindowDisabler: TWindowDisabler;
+  begin
+    if not NeedsRestart then begin
+      WizardForm.StatusLabel.Caption := SetupMessages[msgStatusRestartingApplications];
+      WizardForm.StatusLabel.Update;
+
+      Log('Attempting to restart applications.');
+
+      { Disable windows during application restart so that a nice
+        "beep" is produced if the user tries clicking on WizardForm }
+      WindowDisabler := TWindowDisabler.Create;
+      try
+        Error := RmRestart(RmSessionHandle, 0, nil);
+      finally
+        WindowDisabler.Free;
+      end;
+      Application.BringToFront;
+
+      if Error = ERROR_FAIL_RESTART then
+        Log('One or more applications could not be restarted.')
+      else if Error <> ERROR_SUCCESS then begin
+        RmEndSession(RmSessionHandle);
+        RmSessionStarted := False;
+        LogFmt('RmRestart returned an error: %d', [Error]);
+      end;
+    end else
+      Log('Need to restart Windows, not attempting to restart applications');
+  end;
+
+var
+  Succeeded, ChangesEnvironment, ChangesAssociations: Boolean;
+  S: String;
+begin
+  Result := False;
+  try
+    if not WizardForm.ValidateDirEdit then
+      Abort;
+    WizardDirValue := WizardForm.DirEdit.Text;
+    if not WizardForm.ValidateGroupEdit then
+      Abort;
+    WizardGroupValue := WizardForm.GroupEdit.Text;
+    WizardNoIcons := WizardForm.NoIconsCheck.Checked;
+    WizardSetupType := WizardForm.GetSetupType();
+    WizardForm.GetComponents(WizardComponents, WizardDeselectedComponents);
+    WizardForm.GetTasks(WizardTasks, WizardDeselectedTasks);
+    WizardPreparingYesRadio := WizardForm.PreparingYesRadio.Checked;
+    if InitSaveInf <> '' then
+      SaveInf(InitSaveInf);
+
+    Application.Restore;
+    Update;
+    if InstallMode = imSilent then begin
+      SetActiveWindow(Application.Handle);  { ensure taskbar button is selected }
+      WizardForm.Show;
+    end;
+    WizardForm.Update;
+
+    SetStep(ssInstall, False);
+    
+    ChangesEnvironment := EvalDirectiveCheck(SetupHeader.ChangesEnvironment);
+    ChangesAssociations := EvalDirectiveCheck(SetupHeader.ChangesAssociations);
+
+    PerformInstall(Succeeded, ChangesEnvironment, ChangesAssociations);
+    if not Succeeded then begin
+      { The user canceled the install or there was a fatal error }
+      TerminateApp;
+      Exit;
+    end;
+    { Can't cancel at any point after PerformInstall, so disable the button }
+    WizardForm.CancelButton.Enabled := False;
+
+    ProcessRunEntries;
+
+    if RmDoRestart and
+       (InitRestartApplications or
+        ((shRestartApplications in SetupHeader.Options) and not InitNoRestartApplications)) then
+      RestartApplications;
+
+    SetStep(ssPostInstall, True);
+
+    { Notify Windows of assocations/environment changes *after* ssPostInstall
+      since user might set more stuff there }
+    if ChangesAssociations then
+      SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
+    if ChangesEnvironment then
+      RefreshEnvironment;
+
+    if InstallMode <> imNormal then
+      WizardForm.Hide;
+
+    LogFmt('Need to restart Windows? %s', [SYesNo[NeedsRestart]]);
+    if NeedsRestart and not InitNoRestart then begin
+      with WizardForm do begin
+        ChangeFinishedLabel(ExpandSetupMessage(msgFinishedRestartLabel));
+        YesRadio.Visible := True;
+        NoRadio.Visible := True;
+      end;
+    end else begin
+      if CreatedIcon then
+        S := ExpandSetupMessage(msgFinishedLabel)
+      else
+        S := ExpandSetupMessage(msgFinishedLabelNoIcons);
+      with WizardForm do begin
+        ChangeFinishedLabel(S + SNewLine2 + SetupMessages[msgClickFinish]);
+        if not NeedsRestart then begin
+          UpdateRunList(WizardComponents, WizardTasks);
+          RunList.Visible := RunList.Items.Count > 0;
+        end;
+      end;
+    end;
+
+    if InstallMode = imNormal then begin
+      Application.Restore;
+      Update;
+    end;
+
+    Result := True;
+  except
+    { If an exception was raised, display the message, then terminate }
+    Application.HandleException(Self);
+    SetupExitCode := ecNextStepError;
+    TerminateApp;
+  end;
+end;
+
+procedure ProcessMessagesProc; far;
+begin
+  Application.ProcessMessages;
+end;
+
+procedure TMainForm.Finish(const FromPreparingPage: Boolean);
+
+  procedure WaitForForegroundLoss;
+
+    function IsForegroundProcess: Boolean;
+    var
+      W: HWND;
+      PID: DWORD;
+    begin
+      W := GetForegroundWindow;
+      Result := False;
+      if (W <> 0) and (GetWindowThreadProcessId(W, @PID) <> 0) then
+        Result := (PID = GetCurrentProcessId);
+    end;
+
+  var
+    StartTick: DWORD;
+  begin
+    StartTick := GetTickCount;
+    while IsForegroundProcess do begin
+      { Stop if it's taking too long (e.g. if the spawned process never
+        displays a window) }
+      if Cardinal(GetTickCount - StartTick) >= Cardinal(1000) then
+        Break;
+      ProcessMessagesProc;
+      WaitMessageWithTimeout(10);
+      ProcessMessagesProc;
+    end;
+  end;
+
+  procedure ProcessPostInstallRunEntries;
+  var
+    WindowDisabler: TWindowDisabler;
+    ProcessedNoWait: Boolean;
+    I: Integer;
+    RunEntry: PSetupRunEntry;
+  begin
+    WindowDisabler := nil;
+    try
+      ProcessedNoWait := False;
+      with WizardForm do begin
+        for I := 0 to RunList.Items.Count-1 do begin
+          if RunList.Checked[I] then begin
+            { Disable windows before processing the first entry }
+            if WindowDisabler = nil then
+              WindowDisabler := TWindowDisabler.Create;
+            RunEntry := PSetupRunEntry(Entries[seRun][Integer(RunList.ItemObject[I])]);
+            DebugNotifyEntry(seRun, Integer(RunList.ItemObject[I]));
+            NotifyBeforeInstallEntry(RunEntry.BeforeInstall);
+            ProcessRunEntry(RunEntry);
+            NotifyAfterInstallEntry(RunEntry.AfterInstall);
+            if RunEntry.Wait = rwNoWait then
+              ProcessedNoWait := True;
+          end;
+        end;
+      end;
+      { Give nowait processes some time to bring themselves to the
+        foreground before Setup exits. Without this delay, the application
+        underneath Setup can end up coming to the foreground instead.
+        (Note: Windows are already disabled at this point.) }
+      if ProcessedNoWait then
+        WaitForForegroundLoss;
+    finally
+      WindowDisabler.Free;
+    end;
+  end;
+
+var
+  S: String;
+begin
+  try
+    { Deactivate WizardForm so another application doesn't come to the
+      foreground when Hide is called. (Needed by WaitForForegroundLoss.) }
+    if GetForegroundWindow = WizardForm.Handle then
+      SetActiveWindow(Application.Handle);
+    WizardForm.Hide;
+
+    if not FromPreparingPage and not NeedsRestart then begin
+      ProcessPostInstallRunEntries;
+    end else begin
+      if FromPreparingPage then
+        SetupExitCode := ecPrepareToInstallFailedRestartNeeded
+      else if InitRestartExitCode <> 0 then
+        SetupExitCode := InitRestartExitCode;
+
+      if InitNoRestart then
+        RestartSystem := False
+      else begin
+        case InstallMode of
+          imNormal:
+            if FromPreparingPage then
+              RestartSystem := WizardForm.PreparingYesRadio.Checked
+            else
+              RestartSystem := WizardForm.YesRadio.Checked;
+          imSilent:
+            begin
+              if FromPreparingPage then
+                S := WizardForm.PrepareToInstallFailureMessage + SNewLine +
+                  SNewLine + SNewLine + ExpandSetupMessage(msgPrepareToInstallNeedsRestart)
+              else
+                S := ExpandSetupMessage(msgFinishedRestartMessage);
+              RestartSystem :=
+                LoggedMsgBox(S, '', mbConfirmation, MB_YESNO, True, IDYES) = IDYES;
+            end;
+          imVerySilent:
+            RestartSystem := True;
+        end;
+      end;
+      if not RestartSystem then
+        Log('Will not restart Windows automatically.');
+    end;
+
+    SetStep(ssDone, True);
+  except
+    Application.HandleException(Self);
+    SetupExitCode := ecNextStepError;
+  end;
+  TerminateApp;
+end;
+
+procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+
+  function ConfirmCancel(const DefaultConfirm: Boolean): Boolean;
+  var
+    Cancel, Confirm: Boolean;
+  begin
+    Cancel := True;
+    Confirm := DefaultConfirm;
+    WizardForm.CallCancelButtonClick(Cancel, Confirm);
+    Result := Cancel and (not Confirm or ExitSetupMsgBox);
+  end;
+
+begin
+  { Note: Setting CanClose to True causes Application.Terminate to be called;
+    we don't want that. }
+  CanClose := False;
+  if Assigned(WizardForm) and WizardForm.HandleAllocated and
+     IsWindowVisible(WizardForm.Handle) and IsWindowEnabled(WizardForm.Handle) and
+     WizardForm.CancelButton.CanFocus then begin
+    case CurStep of
+      ssPreInstall:
+        if ConfirmCancel((WizardForm.CurPageID <> wpPreparing) or (WizardForm.PrepareToInstallFailureMessage = '')) then begin
+          if WizardForm.CurPageID = wpPreparing then
+            SetupExitCode := ecPrepareToInstallFailed
+          else
+            SetupExitCode := ecCancelledBeforeInstall;
+          TerminateApp;
+        end;
+      ssInstall:
+        if (shAllowCancelDuringInstall in SetupHeader.Options) and not InitNoCancel then
+          if ConfirmCancel(True) then
+            NeedToAbortInstall := True;
+    end;
+  end;
+end;
+
+procedure TMainForm.WMGetDlgCode(var Message: TWMGetDlgCode);
+begin
+  Message.Result := Message.Result or DLGC_WANTTAB;
+end;
+
+function EWP(Wnd: HWND; Param: LPARAM): BOOL; stdcall;
+begin
+  { Note: GetParent is not used here because the other windows are not
+    actually child windows since they don't have WS_CHILD set. }
+  if GetWindowLong(Wnd, GWL_HWNDPARENT) <> Param then
+    Result := True
+  else begin
+    Result := False;
+    BringWindowToTop(Wnd);
+  end;
+end;
+
+procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
+  Shift: TShiftState);
+begin
+  { If, for some reason, the user doesn't have a mouse and the main form was
+    activated, there would normally be no way to reactivate the child form.
+    But this reactivates the form if the user hits a key on the keyboard }
+  if not(ssAlt in Shift) then begin
+    Key := 0;
+    EnumThreadWindows(GetCurrentThreadId, @EWP, Handle);
+  end;
+end;
+
+procedure TMainForm.UpdateWizardFormVisibility;
+var
+  ShouldShow: Boolean;
+begin
+  { Note: We don't adjust WizardForm.Visible because on Delphi 3+, if all forms
+    have Visible set to False, the application taskbar button disappears. }
+  if Assigned(WizardForm) and WizardForm.HandleAllocated then begin
+    ShouldShow := WizardForm.Showing and not HideWizard and
+      not IsIconic(Application.Handle);
+    if (GetWindowLong(WizardForm.Handle, GWL_STYLE) and WS_VISIBLE <> 0) <> ShouldShow then begin
+      if ShouldShow then
+        ShowWindow(WizardForm.Handle, SW_SHOW)
+      else
+        ShowWindow(WizardForm.Handle, SW_HIDE);
+    end;
+  end;
+end;
+
+function TMainForm.MainWindowHook(var Message: TMessage): Boolean;
+var
+  IsIcon: Boolean;
+begin
+  Result := False;
+  case Message.Msg of
+    WM_WINDOWPOSCHANGED: begin
+        { When the application window is minimized or restored, also hide or
+          show WizardForm.
+          Note: MainForm is hidden/shown automatically because its owner
+          window is Application.Handle. }
+        IsIcon := IsIconic(Application.Handle);
+        if IsMinimized <> IsIcon then begin
+          IsMinimized := IsIcon;
+          UpdateWizardFormVisibility;
+        end;
+      end;
+  end;
+end;
+
+procedure TMainForm.WMShowWindow(var Message: TWMShowWindow);
+begin
+  inherited;
+  { When showing, ensure WizardForm is the active window, not MainForm }
+  if Message.Show and (GetActiveWindow = Handle) and
+     Assigned(WizardForm) and WizardForm.HandleAllocated and
+     IsWindowVisible(WizardForm.Handle) then
+    SetActiveWindow(WizardForm.Handle);
+end;
+
+end.

+ 9 - 747
Projects/Src/Setup.MainFunc.pas

@@ -1,4 +1,4 @@
-unit Setup.MainForm;
+unit Setup.MainFunc;
 
 
 {
 {
   Inno Setup
   Inno Setup
@@ -13,39 +13,10 @@ interface
 
 
 uses
 uses
   Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs,
   Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs,
-  Setup.SetupForm, StdCtrls, Shared.Struct, Shared.DebugStruct, Shared.Int64Em, Shared.CommonFunc.Vcl, Shared.CommonFunc,
-  Shared.SetupTypes, Setup.ScriptRunner, BidiUtils, RestartManager;
+  StdCtrls, Shared.Struct, Shared.DebugStruct, Shared.Int64Em, Shared.CommonFunc.Vcl, Shared.CommonFunc,
+  Shared.SetupTypes, Setup.ScriptRunner, RestartManager;
 
 
 type
 type
-  TMainForm = class(TSetupForm)
-    procedure FormResize(Sender: TObject);
-    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
-    procedure FormPaint(Sender: TObject);
-    procedure FormKeyDown(Sender: TObject; var Key: Word;
-      Shift: TShiftState);
-  private
-    { Private declarations }
-    IsMinimized, HideWizard: Boolean;
-    function MainWindowHook(var Message: TMessage): Boolean;
-    procedure UpdateWizardFormVisibility;
-    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
-    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
-    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
-    procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
-  public
-    { Public declarations }
-    CurStep: TSetupStep;
-    constructor Create(AOwner: TComponent); override;
-    destructor Destroy; override;
-    procedure Finish(const FromPreparingPage: Boolean);
-    procedure InitializeWizard;
-    function Install: Boolean;
-    procedure SetStep(const AStep: TSetupStep; const HandleExceptions: Boolean);
-    class procedure ShowException(Sender: TObject; E: Exception);
-    class procedure ShowExceptionMsg(const S: String);
-    procedure ShowAboutBox;
-  end;
-
   TEntryType = (seLanguage, seCustomMessage, sePermission, seType, seComponent,
   TEntryType = (seLanguage, seCustomMessage, sePermission, seType, seComponent,
     seTask, seDir, seFile, seFileLocation, seIcon, seIni, seRegistry,
     seTask, seDir, seFile, seFileLocation, seIcon, seIni, seRegistry,
     seInstallDelete, seUninstallDelete, seRun, seUninstallRun);
     seInstallDelete, seUninstallDelete, seRun, seUninstallRun);
@@ -94,8 +65,6 @@ const
   CodeRunnerNamingAttribute = 'Event';
   CodeRunnerNamingAttribute = 'Event';
 
 
 var
 var
-  MainForm: TMainForm;
-
   { Variables for command line parameters }
   { Variables for command line parameters }
   SetupLdrMode: Boolean;
   SetupLdrMode: Boolean;
   SetupLdrOriginalFilename: String;
   SetupLdrOriginalFilename: String;
@@ -240,12 +209,14 @@ function PreviousInstallCompleted(const WizardComponents, WizardTasks: TStringLi
 function CodeRegisterExtraCloseApplicationsResource(const DisableFsRedir: Boolean; const AFilename: String): Boolean;
 function CodeRegisterExtraCloseApplicationsResource(const DisableFsRedir: Boolean; const AFilename: String): Boolean;
 procedure RegisterResourcesWithRestartManager(const WizardComponents, WizardTasks: TStringList);
 procedure RegisterResourcesWithRestartManager(const WizardComponents, WizardTasks: TStringList);
 procedure RemoveTempInstallDir;
 procedure RemoveTempInstallDir;
+procedure SaveInf(const FileName: String);
 procedure SaveResourceToTempFile(const ResName, Filename: String);
 procedure SaveResourceToTempFile(const ResName, Filename: String);
 procedure SetActiveLanguage(const I: Integer);
 procedure SetActiveLanguage(const I: Integer);
 procedure SetTaskbarButtonVisibility(const AVisible: Boolean);
 procedure SetTaskbarButtonVisibility(const AVisible: Boolean);
 procedure ShellExecuteAsOriginalUser(hWnd: HWND; Operation, FileName, Parameters, Directory: LPWSTR; ShowCmd: Integer); stdcall;
 procedure ShellExecuteAsOriginalUser(hWnd: HWND; Operation, FileName, Parameters, Directory: LPWSTR; ShowCmd: Integer); stdcall;
 function ShouldDisableFsRedirForFileEntry(const FileEntry: PSetupFileEntry): Boolean;
 function ShouldDisableFsRedirForFileEntry(const FileEntry: PSetupFileEntry): Boolean;
 function ShouldDisableFsRedirForRunEntry(const RunEntry: PSetupRunEntry): Boolean;
 function ShouldDisableFsRedirForRunEntry(const RunEntry: PSetupRunEntry): Boolean;
+procedure ProcessRunEntry(const RunEntry: PSetupRunEntry);
 function EvalArchitectureIdentifier(const Name: String): Boolean;
 function EvalArchitectureIdentifier(const Name: String): Boolean;
 function EvalDirectiveCheck(const Expression: String): Boolean;
 function EvalDirectiveCheck(const Expression: String): Boolean;
 function ShouldProcessEntry(const WizardComponents, WizardTasks: TStringList;
 function ShouldProcessEntry(const WizardComponents, WizardTasks: TStringList;
@@ -268,16 +239,13 @@ implementation
 uses
 uses
   ShellAPI, ShlObj, StrUtils,
   ShellAPI, ShlObj, StrUtils,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.Install, SetupLdrAndSetup.InstFunc,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.Install, SetupLdrAndSetup.InstFunc,
-  Setup.InstFunc, Setup.InstFunc.Ole, SetupLdrAndSetup.RedirFunc, PathFunc,
+  Setup.InstFunc, SetupLdrAndSetup.RedirFunc, PathFunc,
   Compression.Base, Compression.Zlib, Compression.bzlib, Compression.LZMADecompressor,
   Compression.Base, Compression.Zlib, Compression.bzlib, Compression.LZMADecompressor,
   Shared.ArcFour, Shared.SetupEntFunc, Setup.SelectLanguageForm,
   Shared.ArcFour, Shared.SetupEntFunc, Setup.SelectLanguageForm,
   Setup.WizardForm, Setup.DebugClient, Shared.VerInfoFunc, Setup.FileExtractor,
   Setup.WizardForm, Setup.DebugClient, Shared.VerInfoFunc, Setup.FileExtractor,
-  Shared.FileClass, Setup.LoggingFunc, MD5, SHA1, ActiveX,
+  Shared.FileClass, Setup.LoggingFunc, SHA1, ActiveX,
   SimpleExpression, Setup.Helper, Setup.SpawnClient, Setup.SpawnServer,
   SimpleExpression, Setup.Helper, Setup.SpawnClient, Setup.SpawnServer,
-  Setup.DotNetFunc, BitmapImage,
-  Shared.TaskDialogFunc, RegStr;
-
-{$R *.DFM}
+  Setup.DotNetFunc, Shared.TaskDialogFunc, RegStr, Setup.MainForm;
 
 
 var
 var
   ShellFolders: array[Boolean, TShellFolderID] of String;
   ShellFolders: array[Boolean, TShellFolderID] of String;
@@ -531,7 +499,7 @@ end;
 class function TDummyClass.EvalArchitectureIdentifier(Sender: TSimpleExpression;
 class function TDummyClass.EvalArchitectureIdentifier(Sender: TSimpleExpression;
   const Name: String; const Parameters: array of const): Boolean;
   const Name: String; const Parameters: array of const): Boolean;
 begin
 begin
-  Result := Setup.MainForm.EvalArchitectureIdentifier(Name);
+  Result := Setup.MainFunc.EvalArchitectureIdentifier(Name);
 end;
 end;
 
 
 class function TDummyClass.EvalComponentOrTaskIdentifier(Sender: TSimpleExpression;
 class function TDummyClass.EvalComponentOrTaskIdentifier(Sender: TSimpleExpression;
@@ -3591,240 +3559,12 @@ begin
   end;
   end;
 end;
 end;
 
 
-function BlendRGB(const Color1, Color2: TColor; const Blend: Integer): TColor;
-{ Blends Color1 and Color2. Blend must be between 0 and 255; 0 = all Color1,
-  255 = all Color2. }
-type
-  TColorBytes = array[0..3] of Byte;
-var
-  I: Integer;
-begin
-  Result := 0;
-  for I := 0 to 2 do
-    TColorBytes(Result)[I] := Integer(TColorBytes(Color1)[I] +
-      ((TColorBytes(Color2)[I] - TColorBytes(Color1)[I]) * Blend) div 255);
-end;
-
 function ExitSetupMsgBox: Boolean;
 function ExitSetupMsgBox: Boolean;
 begin
 begin
   Result := LoggedMsgBox(SetupMessages[msgExitSetupMessage], SetupMessages[msgExitSetupTitle],
   Result := LoggedMsgBox(SetupMessages[msgExitSetupMessage], SetupMessages[msgExitSetupTitle],
     mbConfirmation, MB_YESNO or MB_DEFBUTTON2, False, 0) = IDYES;
     mbConfirmation, MB_YESNO or MB_DEFBUTTON2, False, 0) = IDYES;
 end;
 end;
 
 
-procedure TerminateApp;
-begin
-  { Work around shell32 bug: Don't use PostQuitMessage/Application.Terminate
-    here.
-    When ShellExecute is called with the name of a folder, it internally
-    creates a window used for DDE communication with Windows Explorer. After
-    ShellExecute returns, this window eventually receives a posted WM_DDE_ACK
-    message back from the DDE server (Windows Explorer), and in response, it
-    tries to flush the queue of DDE messages by using a PeekMessage loop.
-    Problem is, PeekMessage will return WM_QUIT messages posted with
-    PostQuitMessage regardless of the message range specified, and the loop was
-    not written with this in mind.
-    In previous IS versions, this was causing our WM_QUIT message to be eaten
-    if Application.Terminate was called very shortly after a shellexec [Run]
-    entry was processed (e.g. if DisableFinishedPage=yes).
-    A WM_QUIT message posted with PostMessage instead of PostQuitMessage will
-    not be returned by a GetMessage/PeekMessage call with a message range that
-    does not include WM_QUIT. }
-  PostMessage(0, WM_QUIT, 0, 0);
-end;
-
-
-{ TMainForm }
-
-constructor TMainForm.Create(AOwner: TComponent);
-var
-  SystemMenu: HMenu;
-begin
-  inherited;
-
-  InitializeFont;
-
-  if shWindowVisible in SetupHeader.Options then begin
-    { Should the main window not be sizable? }
-    if not(shWindowShowCaption in SetupHeader.Options) then
-      BorderStyle := bsNone
-    else
-    if not(shWindowResizable in SetupHeader.Options) then
-      BorderStyle := bsSingle;
-
-    { Make the main window full-screen. If the window is resizable, limit it
-      to just the work area because full-screen resizable windows don't cover
-      over the taskbar. }
-    BoundsRect := GetRectOfPrimaryMonitor(BorderStyle = bsSizeable);
-    { Before maximizing the window, ensure Handle is created now so the correct
-      'restored' position is saved properly }
-    HandleNeeded;
-
-    { Maximize the window so that the taskbar is still accessible }
-    if shWindowStartMaximized in SetupHeader.Options then
-      WindowState := wsMaximized;
-  end
-  else begin
-    Application.ShowMainForm := False;
-  end;
-
-  if shDisableWelcomePage in SetupHeader.Options then
-    Caption := FmtSetupMessage1(msgSetupWindowTitle, ExpandedAppVerName)
-  else
-    Caption := FmtSetupMessage1(msgSetupWindowTitle, ExpandedAppName);
-
-  { Append the 'About Setup' item to the system menu }
-  SystemMenu := GetSystemMenu(Handle, False);
-  AppendMenu(SystemMenu, MF_SEPARATOR, 0, nil);
-  AppendMenu(SystemMenu, MF_STRING, 9999, PChar(SetupMessages[msgAboutSetupMenuItem]));
-
-  Application.HookMainWindow(MainWindowHook);
-
-  if Application.ShowMainForm then
-    { Show this form now, so that the focus stays on the wizard form that
-      InitializeWizard (called in the .dpr) shows }
-    Visible := True;
-end;
-
-destructor TMainForm.Destroy;
-begin
-  Application.UnhookMainWindow(MainWindowHook);
-  inherited;
-end;
-
-procedure TMainForm.WMSysCommand(var Message: TWMSysCommand);
-begin
-  if Message.CmdType = 9999 then
-    ShowAboutBox
-  else
-    inherited;
-end;
-
-procedure TMainForm.WMEraseBkgnd(var Message: TWMEraseBkgnd);
-begin
-  { Since the form paints its entire client area in FormPaint, there is
-    no need for the VCL to ever erase the client area with the brush color.
-    Doing so only slows it down, so this message handler disables that default
-    behavior. }
-  Message.Result := 0;
-end;
-
-procedure TMainForm.FormPaint(Sender: TObject);
-var
-  C1, C2: TColor;
-  CS: TPoint;
-  Z: Integer;
-  DrawTextFlags: UINT;
-  R, R2: TRect;
-begin
-  with Canvas do begin
-    { Draw the blue background }
-    if SetupHeader.BackColor = SetupHeader.BackColor2 then begin
-      Brush.Color := SetupHeader.BackColor;
-      FillRect(ClientRect);
-    end
-    else begin
-      C1 := ColorToRGB(SetupHeader.BackColor);
-      C2 := ColorToRGB(SetupHeader.BackColor2);
-      CS := ClientRect.BottomRight;
-      for Z := 0 to 255 do begin
-        Brush.Color := BlendRGB(C1, C2, Z);
-        if not(shBackColorHorizontal in SetupHeader.Options) then
-          FillRect(Rect(0, MulDiv(CS.Y, Z, 255), CS.X, MulDiv(CS.Y, Z+1, 255)))
-        else
-          FillRect(Rect(MulDiv(CS.X, Z, 255), 0, MulDiv(CS.X, Z+1, 255), CS.Y));
-      end;
-    end;
-
-    { Draw the application name and copyright }
-    SetBkMode(Handle, TRANSPARENT);
-
-    DrawTextFlags := DT_WORDBREAK or DT_NOPREFIX or DT_NOCLIP;
-    if RightToLeft then
-      DrawTextFlags := DrawTextFlags or (DT_RIGHT or DT_RTLREADING);
-    SetFontNameSize(Font, LangOptions.TitleFontName,
-      LangOptions.TitleFontSize, 'Arial', 29);
-    if IsMultiByteString(AnsiString(ExpandedAppName)) then
-      { Don't use italics on Japanese characters }
-      Font.Style := [fsBold]
-    else
-      Font.Style := [fsBold, fsItalic];
-    R := ClientRect;
-    InflateRect(R, -8, -8);
-    R2 := R;
-    if RightToLeft then
-      OffsetRect(R2, -4, 4)
-    else
-      OffsetRect(R2, 4, 4);
-    Font.Color := clBlack;
-    DrawText(Handle, PChar(ExpandedAppName), -1, R2, DrawTextFlags);
-    Font.Color := clWhite;
-    DrawText(Handle, PChar(ExpandedAppName), -1, R, DrawTextFlags);
-
-    DrawTextFlags := DrawTextFlags xor DT_RIGHT;
-    SetFontNameSize(Font, LangOptions.CopyrightFontName,
-      LangOptions.CopyrightFontSize, 'Arial', 8);
-    Font.Style := [];
-    R := ClientRect;
-    InflateRect(R, -6, -6);
-    R2 := R;
-    DrawText(Handle, PChar(ExpandedAppCopyright), -1, R2, DrawTextFlags or
-      DT_CALCRECT);
-    R.Top := R.Bottom - (R2.Bottom - R2.Top);
-    R2 := R;
-    if RightToLeft then
-      OffsetRect(R2, -1, 1)
-    else
-      OffsetRect(R2, 1, 1);
-    Font.Color := clBlack;
-    DrawText(Handle, PChar(ExpandedAppCopyright), -1, R2, DrawTextFlags);
-    Font.Color := clWhite;
-    DrawText(Handle, PChar(ExpandedAppCopyright), -1, R, DrawTextFlags);
-  end;
-end;
-
-procedure TMainForm.FormResize(Sender: TObject);
-begin
-  { Needs to redraw the background whenever the form is resized }
-  Repaint;
-end;
-
-procedure TMainForm.ShowAboutBox;
-var
-  S: String;
-begin
-  { Removing the About box or modifying any existing text inside it is a
-    violation of the Inno Setup license agreement; see LICENSE.TXT.
-    However, adding additional lines to the end of the About box is
-    permitted. }
-  S := SetupTitle + ' version ' + SetupVersion + SNewLine;
-  if SetupTitle <> 'Inno Setup' then
-    S := S + (SNewLine + 'Based on Inno Setup' + SNewLine);
-  S := S + ('Copyright (C) 1997-2024 Jordan Russell' + SNewLine +
-    'Portions Copyright (C) 2000-2024 Martijn Laan' + SNewLine +
-    'All rights reserved.' + SNewLine2 +
-    'Inno Setup home page:' + SNewLine +
-    'https://www.innosetup.com/');
-  S := S + SNewLine2 + 'RemObjects Pascal Script home page:' + SNewLine +
-    'https://www.remobjects.com/ps';
-  if SetupMessages[msgAboutSetupNote] <> '' then
-    S := S + SNewLine2 + SetupMessages[msgAboutSetupNote];
-  if SetupMessages[msgTranslatorNote] <> '' then
-    S := S + SNewLine2 + SetupMessages[msgTranslatorNote];
-  StringChangeEx(S, '(C)', #$00A9, True);
-  LoggedMsgBox(S, SetupMessages[msgAboutSetupTitle], mbInformation, MB_OK, False, 0);
-end;
-
-class procedure TMainForm.ShowExceptionMsg(const S: String);
-begin
-  Log('Exception message:');
-  LoggedAppMessageBox(PChar(S), PChar(Application.Title), MB_OK or MB_ICONSTOP, True, IDOK);
-end;
-
-class procedure TMainForm.ShowException(Sender: TObject; E: Exception);
-begin
-  ShowExceptionMsg(AddPeriod(E.Message));
-end;
-
 procedure ProcessMessagesProc; far;
 procedure ProcessMessagesProc; far;
 begin
 begin
   Application.ProcessMessages;
   Application.ProcessMessages;
@@ -3837,47 +3577,6 @@ begin
   Log(S);
   Log(S);
 end;
 end;
 
 
-procedure TMainForm.SetStep(const AStep: TSetupStep; const HandleExceptions: Boolean);
-begin
-  CurStep := AStep;
-  if CodeRunner <> nil then begin
-    try
-      CodeRunner.RunProcedures('CurStepChanged', [Ord(CurStep)], False);
-    except
-      if HandleExceptions then begin
-        Log('CurStepChanged raised an exception.');
-        Application.HandleException(Self);
-      end
-      else begin
-        Log('CurStepChanged raised an exception (fatal).');
-        raise;
-      end;
-    end;
-  end;
-end;
-
-procedure TMainForm.InitializeWizard;
-begin
-  WizardForm := TWizardForm.Create(Application);
-  if CodeRunner <> nil then begin
-    try
-      CodeRunner.RunProcedures('InitializeWizard', [''], False);
-    except
-      Log('InitializeWizard raised an exception (fatal).');
-      raise;
-    end;
-  end;
-  WizardForm.FlipSizeAndCenterIfNeeded(shWindowVisible in SetupHeader.Options, MainForm, True);
-  WizardForm.SetCurPage(wpWelcome);
-  if InstallMode = imNormal then begin
-    WizardForm.ClickToStartPage; { this won't go past wpReady  }
-    SetActiveWindow(Application.Handle);  { ensure taskbar button is selected }
-    WizardForm.Show;
-  end
-  else
-    WizardForm.ClickThroughPages;
-end;
-
 function ShouldDisableFsRedirForRunEntry(const RunEntry: PSetupRunEntry): Boolean;
 function ShouldDisableFsRedirForRunEntry(const RunEntry: PSetupRunEntry): Boolean;
 begin
 begin
   Result := InstallDefaultDisableFsRedir;
   Result := InstallDefaultDisableFsRedir;
@@ -3968,443 +3667,6 @@ begin
   InstShellExecEx(True, Operation, Filename, Parameters, Directory, ewNoWait, ShowCmd, ProcessMessagesProc, ErrorCode);
   InstShellExecEx(True, Operation, Filename, Parameters, Directory, ewNoWait, ShowCmd, ProcessMessagesProc, ErrorCode);
 end;
 end;
 
 
-function TMainForm.Install: Boolean;
-
-  procedure ProcessRunEntries;
-  var
-    CheckIfRestartNeeded: Boolean;
-    ChecksumBefore, ChecksumAfter: TMD5Digest;
-    WindowDisabler: TWindowDisabler;
-    I: Integer;
-    RunEntry: PSetupRunEntry;
-  begin
-    if Entries[seRun].Count <> 0 then begin
-      CheckIfRestartNeeded := (shRestartIfNeededByRun in SetupHeader.Options) and
-        not NeedsRestart;
-      if CheckIfRestartNeeded then
-        ChecksumBefore := MakePendingFileRenameOperationsChecksum;
-      WindowDisabler := nil;
-      try
-        for I := 0 to Entries[seRun].Count-1 do begin
-          RunEntry := PSetupRunEntry(Entries[seRun][I]);
-          if not(roPostInstall in RunEntry.Options) and
-             ShouldProcessRunEntry(WizardComponents, WizardTasks, RunEntry) then begin
-            { Disable windows during execution of [Run] entries so that a nice
-              "beep" is produced if the user tries clicking on WizardForm }
-            if WindowDisabler = nil then
-              WindowDisabler := TWindowDisabler.Create;
-            if RunEntry.StatusMsg <> '' then begin
-              try
-                WizardForm.StatusLabel.Caption := ExpandConst(RunEntry.StatusMsg);
-              except
-                { Don't die if the expansion fails with an exception. Just
-                  display the exception message, and proceed with the default
-                  status message. }
-                Application.HandleException(Self);
-                WizardForm.StatusLabel.Caption := SetupMessages[msgStatusRunProgram];
-              end;
-            end
-            else
-              WizardForm.StatusLabel.Caption := SetupMessages[msgStatusRunProgram];
-            WizardForm.StatusLabel.Update;
-            if roHideWizard in RunEntry.Options then begin
-              if WizardForm.Visible and not HideWizard then begin
-                HideWizard := True;
-                UpdateWizardFormVisibility;
-              end;
-            end
-            else begin
-              if HideWizard then begin
-                HideWizard := False;
-                UpdateWizardFormVisibility;
-              end;
-            end;
-            DebugNotifyEntry(seRun, I);
-            NotifyBeforeInstallEntry(RunEntry.BeforeInstall);
-            ProcessRunEntry(RunEntry);
-            NotifyAfterInstallEntry(RunEntry.AfterInstall);
-          end;
-        end;
-      finally
-        if HideWizard then begin
-          HideWizard := False;
-          UpdateWizardFormVisibility;
-        end;
-        WindowDisabler.Free;
-        if CheckIfRestartNeeded then begin
-          ChecksumAfter := MakePendingFileRenameOperationsChecksum;
-          if not MD5DigestsEqual(ChecksumBefore, ChecksumAfter) then
-            NeedsRestart := True;
-        end;
-      end;
-      Application.BringToFront;
-    end;
-  end;
-
-  procedure RestartApplications;
-  const
-    ERROR_FAIL_RESTART = 353;
-  var
-    Error: DWORD;
-    WindowDisabler: TWindowDisabler;
-  begin
-    if not NeedsRestart then begin
-      WizardForm.StatusLabel.Caption := SetupMessages[msgStatusRestartingApplications];
-      WizardForm.StatusLabel.Update;
-
-      Log('Attempting to restart applications.');
-
-      { Disable windows during application restart so that a nice
-        "beep" is produced if the user tries clicking on WizardForm }
-      WindowDisabler := TWindowDisabler.Create;
-      try
-        Error := RmRestart(RmSessionHandle, 0, nil);
-      finally
-        WindowDisabler.Free;
-      end;
-      Application.BringToFront;
-
-      if Error = ERROR_FAIL_RESTART then
-        Log('One or more applications could not be restarted.')
-      else if Error <> ERROR_SUCCESS then begin
-        RmEndSession(RmSessionHandle);
-        RmSessionStarted := False;
-        LogFmt('RmRestart returned an error: %d', [Error]);
-      end;
-    end else
-      Log('Need to restart Windows, not attempting to restart applications');
-  end;
-
-var
-  Succeeded, ChangesEnvironment, ChangesAssociations: Boolean;
-  S: String;
-begin
-  Result := False;
-  try
-    if not WizardForm.ValidateDirEdit then
-      Abort;
-    WizardDirValue := WizardForm.DirEdit.Text;
-    if not WizardForm.ValidateGroupEdit then
-      Abort;
-    WizardGroupValue := WizardForm.GroupEdit.Text;
-    WizardNoIcons := WizardForm.NoIconsCheck.Checked;
-    WizardSetupType := WizardForm.GetSetupType();
-    WizardForm.GetComponents(WizardComponents, WizardDeselectedComponents);
-    WizardForm.GetTasks(WizardTasks, WizardDeselectedTasks);
-    WizardPreparingYesRadio := WizardForm.PreparingYesRadio.Checked;
-    if InitSaveInf <> '' then
-      SaveInf(InitSaveInf);
-
-    Application.Restore;
-    Update;
-    if InstallMode = imSilent then begin
-      SetActiveWindow(Application.Handle);  { ensure taskbar button is selected }
-      WizardForm.Show;
-    end;
-    WizardForm.Update;
-
-    SetStep(ssInstall, False);
-    
-    ChangesEnvironment := EvalDirectiveCheck(SetupHeader.ChangesEnvironment);
-    ChangesAssociations := EvalDirectiveCheck(SetupHeader.ChangesAssociations);
-
-    PerformInstall(Succeeded, ChangesEnvironment, ChangesAssociations);
-    if not Succeeded then begin
-      { The user canceled the install or there was a fatal error }
-      TerminateApp;
-      Exit;
-    end;
-    { Can't cancel at any point after PerformInstall, so disable the button }
-    WizardForm.CancelButton.Enabled := False;
-
-    ProcessRunEntries;
-
-    if RmDoRestart and
-       (InitRestartApplications or
-        ((shRestartApplications in SetupHeader.Options) and not InitNoRestartApplications)) then
-      RestartApplications;
-
-    SetStep(ssPostInstall, True);
-
-    { Notify Windows of assocations/environment changes *after* ssPostInstall
-      since user might set more stuff there }
-    if ChangesAssociations then
-      SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
-    if ChangesEnvironment then
-      RefreshEnvironment;
-
-    if InstallMode <> imNormal then
-      WizardForm.Hide;
-
-    LogFmt('Need to restart Windows? %s', [SYesNo[NeedsRestart]]);
-    if NeedsRestart and not InitNoRestart then begin
-      with WizardForm do begin
-        ChangeFinishedLabel(ExpandSetupMessage(msgFinishedRestartLabel));
-        YesRadio.Visible := True;
-        NoRadio.Visible := True;
-      end;
-    end else begin
-      if CreatedIcon then
-        S := ExpandSetupMessage(msgFinishedLabel)
-      else
-        S := ExpandSetupMessage(msgFinishedLabelNoIcons);
-      with WizardForm do begin
-        ChangeFinishedLabel(S + SNewLine2 + SetupMessages[msgClickFinish]);
-        if not NeedsRestart then begin
-          UpdateRunList(WizardComponents, WizardTasks);
-          RunList.Visible := RunList.Items.Count > 0;
-        end;
-      end;
-    end;
-
-    if InstallMode = imNormal then begin
-      Application.Restore;
-      Update;
-    end;
-
-    Result := True;
-  except
-    { If an exception was raised, display the message, then terminate }
-    Application.HandleException(Self);
-    SetupExitCode := ecNextStepError;
-    TerminateApp;
-  end;
-end;
-
-procedure TMainForm.Finish(const FromPreparingPage: Boolean);
-
-  procedure WaitForForegroundLoss;
-
-    function IsForegroundProcess: Boolean;
-    var
-      W: HWND;
-      PID: DWORD;
-    begin
-      W := GetForegroundWindow;
-      Result := False;
-      if (W <> 0) and (GetWindowThreadProcessId(W, @PID) <> 0) then
-        Result := (PID = GetCurrentProcessId);
-    end;
-
-  var
-    StartTick: DWORD;
-  begin
-    StartTick := GetTickCount;
-    while IsForegroundProcess do begin
-      { Stop if it's taking too long (e.g. if the spawned process never
-        displays a window) }
-      if Cardinal(GetTickCount - StartTick) >= Cardinal(1000) then
-        Break;
-      ProcessMessagesProc;
-      WaitMessageWithTimeout(10);
-      ProcessMessagesProc;
-    end;
-  end;
-
-  procedure ProcessPostInstallRunEntries;
-  var
-    WindowDisabler: TWindowDisabler;
-    ProcessedNoWait: Boolean;
-    I: Integer;
-    RunEntry: PSetupRunEntry;
-  begin
-    WindowDisabler := nil;
-    try
-      ProcessedNoWait := False;
-      with WizardForm do begin
-        for I := 0 to RunList.Items.Count-1 do begin
-          if RunList.Checked[I] then begin
-            { Disable windows before processing the first entry }
-            if WindowDisabler = nil then
-              WindowDisabler := TWindowDisabler.Create;
-            RunEntry := PSetupRunEntry(Entries[seRun][Integer(RunList.ItemObject[I])]);
-            DebugNotifyEntry(seRun, Integer(RunList.ItemObject[I]));
-            NotifyBeforeInstallEntry(RunEntry.BeforeInstall);
-            ProcessRunEntry(RunEntry);
-            NotifyAfterInstallEntry(RunEntry.AfterInstall);
-            if RunEntry.Wait = rwNoWait then
-              ProcessedNoWait := True;
-          end;
-        end;
-      end;
-      { Give nowait processes some time to bring themselves to the
-        foreground before Setup exits. Without this delay, the application
-        underneath Setup can end up coming to the foreground instead.
-        (Note: Windows are already disabled at this point.) }
-      if ProcessedNoWait then
-        WaitForForegroundLoss;
-    finally
-      WindowDisabler.Free;
-    end;
-  end;
-
-var
-  S: String;
-begin
-  try
-    { Deactivate WizardForm so another application doesn't come to the
-      foreground when Hide is called. (Needed by WaitForForegroundLoss.) }
-    if GetForegroundWindow = WizardForm.Handle then
-      SetActiveWindow(Application.Handle);
-    WizardForm.Hide;
-
-    if not FromPreparingPage and not NeedsRestart then begin
-      ProcessPostInstallRunEntries;
-    end else begin
-      if FromPreparingPage then
-        SetupExitCode := ecPrepareToInstallFailedRestartNeeded
-      else if InitRestartExitCode <> 0 then
-        SetupExitCode := InitRestartExitCode;
-
-      if InitNoRestart then
-        RestartSystem := False
-      else begin
-        case InstallMode of
-          imNormal:
-            if FromPreparingPage then
-              RestartSystem := WizardForm.PreparingYesRadio.Checked
-            else
-              RestartSystem := WizardForm.YesRadio.Checked;
-          imSilent:
-            begin
-              if FromPreparingPage then
-                S := WizardForm.PrepareToInstallFailureMessage + SNewLine +
-                  SNewLine + SNewLine + ExpandSetupMessage(msgPrepareToInstallNeedsRestart)
-              else
-                S := ExpandSetupMessage(msgFinishedRestartMessage);
-              RestartSystem :=
-                LoggedMsgBox(S, '', mbConfirmation, MB_YESNO, True, IDYES) = IDYES;
-            end;
-          imVerySilent:
-            RestartSystem := True;
-        end;
-      end;
-      if not RestartSystem then
-        Log('Will not restart Windows automatically.');
-    end;
-
-    SetStep(ssDone, True);
-  except
-    Application.HandleException(Self);
-    SetupExitCode := ecNextStepError;
-  end;
-  TerminateApp;
-end;
-
-procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
-
-  function ConfirmCancel(const DefaultConfirm: Boolean): Boolean;
-  var
-    Cancel, Confirm: Boolean;
-  begin
-    Cancel := True;
-    Confirm := DefaultConfirm;
-    WizardForm.CallCancelButtonClick(Cancel, Confirm);
-    Result := Cancel and (not Confirm or ExitSetupMsgBox);
-  end;
-
-begin
-  { Note: Setting CanClose to True causes Application.Terminate to be called;
-    we don't want that. }
-  CanClose := False;
-  if Assigned(WizardForm) and WizardForm.HandleAllocated and
-     IsWindowVisible(WizardForm.Handle) and IsWindowEnabled(WizardForm.Handle) and
-     WizardForm.CancelButton.CanFocus then begin
-    case CurStep of
-      ssPreInstall:
-        if ConfirmCancel((WizardForm.CurPageID <> wpPreparing) or (WizardForm.PrepareToInstallFailureMessage = '')) then begin
-          if WizardForm.CurPageID = wpPreparing then
-            SetupExitCode := ecPrepareToInstallFailed
-          else
-            SetupExitCode := ecCancelledBeforeInstall;
-          TerminateApp;
-        end;
-      ssInstall:
-        if (shAllowCancelDuringInstall in SetupHeader.Options) and not InitNoCancel then
-          if ConfirmCancel(True) then
-            NeedToAbortInstall := True;
-    end;
-  end;
-end;
-
-procedure TMainForm.WMGetDlgCode(var Message: TWMGetDlgCode);
-begin
-  Message.Result := Message.Result or DLGC_WANTTAB;
-end;
-
-function EWP(Wnd: HWND; Param: LPARAM): BOOL; stdcall;
-begin
-  { Note: GetParent is not used here because the other windows are not
-    actually child windows since they don't have WS_CHILD set. }
-  if GetWindowLong(Wnd, GWL_HWNDPARENT) <> Param then
-    Result := True
-  else begin
-    Result := False;
-    BringWindowToTop(Wnd);
-  end;
-end;
-
-procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
-  Shift: TShiftState);
-begin
-  { If, for some reason, the user doesn't have a mouse and the main form was
-    activated, there would normally be no way to reactivate the child form.
-    But this reactivates the form if the user hits a key on the keyboard }
-  if not(ssAlt in Shift) then begin
-    Key := 0;
-    EnumThreadWindows(GetCurrentThreadId, @EWP, Handle);
-  end;
-end;
-
-procedure TMainForm.UpdateWizardFormVisibility;
-var
-  ShouldShow: Boolean;
-begin
-  { Note: We don't adjust WizardForm.Visible because on Delphi 3+, if all forms
-    have Visible set to False, the application taskbar button disappears. }
-  if Assigned(WizardForm) and WizardForm.HandleAllocated then begin
-    ShouldShow := WizardForm.Showing and not HideWizard and
-      not IsIconic(Application.Handle);
-    if (GetWindowLong(WizardForm.Handle, GWL_STYLE) and WS_VISIBLE <> 0) <> ShouldShow then begin
-      if ShouldShow then
-        ShowWindow(WizardForm.Handle, SW_SHOW)
-      else
-        ShowWindow(WizardForm.Handle, SW_HIDE);
-    end;
-  end;
-end;
-
-function TMainForm.MainWindowHook(var Message: TMessage): Boolean;
-var
-  IsIcon: Boolean;
-begin
-  Result := False;
-  case Message.Msg of
-    WM_WINDOWPOSCHANGED: begin
-        { When the application window is minimized or restored, also hide or
-          show WizardForm.
-          Note: MainForm is hidden/shown automatically because its owner
-          window is Application.Handle. }
-        IsIcon := IsIconic(Application.Handle);
-        if IsMinimized <> IsIcon then begin
-          IsMinimized := IsIcon;
-          UpdateWizardFormVisibility;
-        end;
-      end;
-  end;
-end;
-
-procedure TMainForm.WMShowWindow(var Message: TWMShowWindow);
-begin
-  inherited;
-  { When showing, ensure WizardForm is the active window, not MainForm }
-  if Message.Show and (GetActiveWindow = Handle) and
-     Assigned(WizardForm) and WizardForm.HandleAllocated and
-     IsWindowVisible(WizardForm.Handle) then
-    SetActiveWindow(WizardForm.Handle);
-end;
-
-
 procedure InitIsWin64AndProcessorArchitectureAndMachineTypesSupportedBySystem;
 procedure InitIsWin64AndProcessorArchitectureAndMachineTypesSupportedBySystem;
 const
 const
   PROCESSOR_ARCHITECTURE_ARM64 = 12;
   PROCESSOR_ARCHITECTURE_ARM64 = 12;

+ 1 - 1
Projects/Src/Setup.NewDiskForm.pas

@@ -41,7 +41,7 @@ implementation
 
 
 uses
 uses
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, BrowseFunc,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, BrowseFunc,
-  Setup.MainForm, Setup.WizardForm;
+  Setup.MainFunc, Setup.WizardForm;
 
 
 {$R *.DFM}
 {$R *.DFM}
 
 

+ 1 - 1
Projects/Src/Setup.RegDLL.pas

@@ -21,7 +21,7 @@ implementation
 
 
 uses
 uses
   SysUtils, Forms, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, Setup.InstFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
   SysUtils, Forms, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, Setup.InstFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs,
-  Setup.LoggingFunc, SetupLdrAndSetup.RedirFunc, Setup.MainForm;
+  Setup.LoggingFunc, SetupLdrAndSetup.RedirFunc, Setup.MainFunc;
 
 
 function WaitForAndCloseProcessHandle(var AProcessHandle: THandle): DWORD;
 function WaitForAndCloseProcessHandle(var AProcessHandle: THandle): DWORD;
 var
 var

+ 1 - 1
Projects/Src/Setup.RegSvr.pas

@@ -17,7 +17,7 @@ implementation
 
 
 uses
 uses
   Windows, SysUtils, Classes, Forms, PathFunc, Shared.CommonFunc, Setup.InstFunc, Setup.InstFunc.Ole,
   Windows, SysUtils, Classes, Forms, PathFunc, Shared.CommonFunc, Setup.InstFunc, Setup.InstFunc.Ole,
-  Shared.FileClass, Shared.CommonFunc.Vcl, Shared.Struct, Setup.MainForm,
+  Shared.FileClass, Shared.CommonFunc.Vcl, Shared.Struct, Setup.MainFunc,
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.RegDLL, Setup.Helper;
   SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.RegDLL, Setup.Helper;
 
 
 procedure DeleteOldTempFiles(const Path: String);
 procedure DeleteOldTempFiles(const Path: String);

+ 1 - 1
Projects/Src/Setup.ScriptDlg.pas

@@ -201,7 +201,7 @@ implementation
 
 
 uses
 uses
   StrUtils,
   StrUtils,
-  Shared.Struct, Setup.MainForm, Setup.SelectFolderForm, SetupLdrAndSetup.Messages,
+  Shared.Struct, Setup.MainFunc, Setup.SelectFolderForm, SetupLdrAndSetup.Messages,
   Shared.SetupMessageIDs, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
   Shared.SetupMessageIDs, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
   BrowseFunc, Setup.LoggingFunc, Setup.InstFunc;
   BrowseFunc, Setup.LoggingFunc, Setup.InstFunc;
 
 

+ 1 - 1
Projects/Src/Setup.ScriptFunc.pas

@@ -21,7 +21,7 @@ implementation
 uses
 uses
   Windows, Shared.ScriptFunc,
   Windows, Shared.ScriptFunc,
   Forms, uPSUtils, SysUtils, Classes, Graphics, Controls, TypInfo, ActiveX,
   Forms, uPSUtils, SysUtils, Classes, Graphics, Controls, TypInfo, ActiveX,
-  Shared.Struct, Setup.ScriptDlg, Setup.MainForm, PathFunc, Shared.CommonFunc.Vcl,
+  Shared.Struct, Setup.ScriptDlg, Setup.MainForm, Setup.MainFunc, PathFunc, Shared.CommonFunc.Vcl,
   Shared.CommonFunc, Shared.FileClass, SetupLdrAndSetup.RedirFunc,
   Shared.CommonFunc, Shared.FileClass, SetupLdrAndSetup.RedirFunc,
   Setup.Install, SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, SetupLdrAndSetup.Messages,
   Setup.Install, SetupLdrAndSetup.InstFunc, Setup.InstFunc, Setup.InstFunc.Ole, SetupLdrAndSetup.Messages,
   Shared.SetupMessageIDs, Setup.NewDiskForm, BrowseFunc, Setup.WizardForm, Shared.VerInfoFunc,
   Shared.SetupMessageIDs, Setup.NewDiskForm, BrowseFunc, Setup.WizardForm, Shared.VerInfoFunc,

+ 1 - 1
Projects/Src/Setup.SelectFolderForm.pas

@@ -42,7 +42,7 @@ function ShowSelectFolderDialog(const StartMenu, AppendDir: Boolean;
 implementation
 implementation
 
 
 uses
 uses
-  PathFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.MainForm,
+  PathFunc, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.MainFunc,
   Shared.SetupTypes, Setup.WizardForm, Shared.CommonFunc;
   Shared.SetupTypes, Setup.WizardForm, Shared.CommonFunc;
 
 
 {$R *.DFM}
 {$R *.DFM}

+ 1 - 1
Projects/Src/Setup.SelectLanguageForm.pas

@@ -36,7 +36,7 @@ function AskForLanguage: Boolean;
 implementation
 implementation
 
 
 uses
 uses
-  Shared.Struct, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.MainForm;
+  Shared.Struct, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.MainFunc;
 
 
 {$R *.DFM}
 {$R *.DFM}
 
 

+ 1 - 1
Projects/Src/Setup.SetupForm.pas

@@ -74,7 +74,7 @@ implementation
 
 
 uses
 uses
   Generics.Collections, UITypes,
   Generics.Collections, UITypes,
-  Shared.CommonFunc, Setup.MainForm, SetupLdrAndSetup.Messages, BidiUtils;
+  Shared.CommonFunc, Setup.MainFunc, SetupLdrAndSetup.Messages, BidiUtils;
 
 
 var
 var
   WM_QueryCancelAutoPlay: UINT;
   WM_QueryCancelAutoPlay: UINT;

+ 1 - 1
Projects/Src/Setup.Uninstall.pas

@@ -22,7 +22,7 @@ uses
   Shared.SetupMessageIDs, SetupLdrAndSetup.InstFunc, Setup.InstFunc, Shared.Struct,
   Shared.SetupMessageIDs, SetupLdrAndSetup.InstFunc, Setup.InstFunc, Shared.Struct,
   Shared.SetupEntFunc, Setup.UninstallProgressForm, Setup.UninstallSharedFileForm,
   Shared.SetupEntFunc, Setup.UninstallProgressForm, Setup.UninstallSharedFileForm,
   Shared.FileClass, Setup.ScriptRunner, Setup.DebugClient, Shared.SetupTypes,
   Shared.FileClass, Setup.ScriptRunner, Setup.DebugClient, Shared.SetupTypes,
-  Setup.LoggingFunc, Setup.MainForm, Setup.SpawnServer;
+  Setup.LoggingFunc, Setup.MainFunc, Setup.SpawnServer;
 
 
 type
 type
   TExtUninstallLog = class(TUninstallLog)
   TExtUninstallLog = class(TUninstallLog)

+ 1 - 1
Projects/Src/Setup.WizardForm.pas

@@ -342,7 +342,7 @@ function ValidateCustomDirEdit(const AEdit: TEdit;
 implementation
 implementation
 
 
 uses
 uses
-  ShellApi, ShlObj, Types, SetupLdrAndSetup.Messages, Setup.MainForm, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
+  ShellApi, ShlObj, Types, SetupLdrAndSetup.Messages, Setup.MainForm, Setup.MainFunc, PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc,
   MD5, Setup.InstFunc, Setup.SelectFolderForm, Setup.FileExtractor, Setup.LoggingFunc, RestartManager, Setup.ScriptRunner;
   MD5, Setup.InstFunc, Setup.SelectFolderForm, Setup.FileExtractor, Setup.LoggingFunc, RestartManager, Setup.ScriptRunner;
 
 
 {$R *.DFM}
 {$R *.DFM}