From 974b25887e96be1ae6c3e75a4a71ef97c5838a4c Mon Sep 17 00:00:00 2001 From: Jordan Russell Date: Thu, 2 Jan 2025 03:46:28 -0600 Subject: [PATCH] Add AppCreateForm wrapper function. --- Projects/Setup.dpr | 3 +-- Projects/Src/Setup.MainForm.pas | 1 + Projects/Src/Setup.SelectLanguageForm.pas | 7 ++++--- Projects/Src/Setup.Uninstall.pas | 4 ++-- Projects/Src/Shared.CommonFunc.Vcl.pas | 19 ++++++++++++++++++- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Projects/Setup.dpr b/Projects/Setup.dpr index f6e36dbc..8994bd90 100644 --- a/Projects/Setup.dpr +++ b/Projects/Setup.dpr @@ -2,7 +2,7 @@ program Setup; { Inno Setup - Copyright (C) 1997-2024 Jordan Russell + Copyright (C) 1997-2025 Jordan Russell Portions by Martijn Laan For conditions of distribution and use, see LICENSE.TXT. @@ -300,7 +300,6 @@ begin Application.MainFormOnTaskBar := True; InitializeSetup; MainForm := TMainForm.Create(Application); - Application.CreateForm(TWizardForm, WizardForm); MainForm.InitializeWizard; except { Halt on any exception } diff --git a/Projects/Src/Setup.MainForm.pas b/Projects/Src/Setup.MainForm.pas index d18f5b3a..6755207d 100644 --- a/Projects/Src/Setup.MainForm.pas +++ b/Projects/Src/Setup.MainForm.pas @@ -107,6 +107,7 @@ procedure TMainForm.SetStep(const AStep: TSetupStep; const HandleExceptions: Boo procedure TMainForm.InitializeWizard; begin + WizardForm := AppCreateForm(TWizardForm) as TWizardForm; if CodeRunner <> nil then begin try CodeRunner.RunProcedures('InitializeWizard', [''], False); diff --git a/Projects/Src/Setup.SelectLanguageForm.pas b/Projects/Src/Setup.SelectLanguageForm.pas index e3e4a836..cc0f5e65 100644 --- a/Projects/Src/Setup.SelectLanguageForm.pas +++ b/Projects/Src/Setup.SelectLanguageForm.pas @@ -2,7 +2,7 @@ { Inno Setup - Copyright (C) 1997-2019 Jordan Russell + Copyright (C) 1997-2025 Jordan Russell Portions by Martijn Laan For conditions of distribution and use, see LICENSE.TXT. @@ -36,7 +36,8 @@ function AskForLanguage: Boolean; implementation uses - Shared.Struct, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, Setup.MainFunc; + Shared.Struct, SetupLdrAndSetup.Messages, Shared.SetupMessageIDs, + Setup.MainFunc, Shared.CommonFunc.Vcl; {$R *.DFM} @@ -48,7 +49,7 @@ function AskForLanguage: Boolean; I, J: Integer; LangEntry: PSetupLanguageEntry; begin - Application.CreateForm(TSelectLanguageForm, LangForm); + LangForm := AppCreateForm(TSelectLanguageForm) as TSelectLanguageForm; try for I := 0 to Entries[seLanguage].Count-1 do begin LangEntry := Entries[seLanguage][I]; diff --git a/Projects/Src/Setup.Uninstall.pas b/Projects/Src/Setup.Uninstall.pas index a01ad046..c24ec474 100644 --- a/Projects/Src/Setup.Uninstall.pas +++ b/Projects/Src/Setup.Uninstall.pas @@ -2,7 +2,7 @@ { Inno Setup - Copyright (C) 1997-2024 Jordan Russell + Copyright (C) 1997-2025 Jordan Russell Portions by Martijn Laan For conditions of distribution and use, see LICENSE.TXT. @@ -91,7 +91,7 @@ function TExtUninstallLog.ShouldRemoveSharedFile(const Filename: String): Boolea procedure InitializeUninstallProgressForm; begin - Application.CreateForm(TUninstallProgressForm, UninstallProgressForm); + UninstallProgressForm := AppCreateForm(TUninstallProgressForm) as TUninstallProgressForm; UninstallProgressForm.Initialize(Title, UninstLog.AppName, ufModernStyle in UninstLog.Flags); if CodeRunner <> nil then begin try diff --git a/Projects/Src/Shared.CommonFunc.Vcl.pas b/Projects/Src/Shared.CommonFunc.Vcl.pas index 5e7269f6..ac9c5cd2 100644 --- a/Projects/Src/Shared.CommonFunc.Vcl.pas +++ b/Projects/Src/Shared.CommonFunc.Vcl.pas @@ -2,7 +2,7 @@ { Inno Setup - Copyright (C) 1997-2024 Jordan Russell + Copyright (C) 1997-2025 Jordan Russell Portions by Martijn Laan For conditions of distribution and use, see LICENSE.TXT. @@ -37,6 +37,7 @@ TWindowDisabler = class const EnableColor: array[Boolean] of TColor = (clBtnFace, clWindow); +function AppCreateForm(const AClass: TCustomFormClass): TCustomForm; procedure UpdateHorizontalExtent(const ListBox: TCustomListBox); function MinimizePathName(const Filename: String; const Font: TFont; MaxLen: Integer): String; @@ -68,6 +69,22 @@ implementation MessageBoxCallbackParam: LongInt; MessageBoxCallbackActive: Boolean; +function AppCreateForm(const AClass: TCustomFormClass): TCustomForm; +{ Creates a form, making it the main form if there isn't one already. + Usage: AppCreateForm(TMyForm) as TMyForm + This is a wrapper around Application.CreateForm, but with these advantages: + - Safety: Returns a typed value instead of writing to an untyped parameter. + - Safety: When used in an assignment statement: MyForm := AppCreateForm(...) + the variable isn't modified until the form is fully constructed and the + function exits. Application.CreateForm writes to its parameter, making the + value public, before the form's constructor is executed, which could allow + code outside the form to access the form before it's fully constructed. + - When the result is casted with "as", it works with type inference. + - When used in the .dpr, the Delphi IDE will never touch it. } +begin + Application.CreateForm(AClass, Result); +end; + type TListBoxAccess = class(TCustomListBox);