diff --git a/Components/BrowseFunc.pas b/Components/BrowseFunc.pas
index ed01ea520..bbedebbaf 100644
--- a/Components/BrowseFunc.pas
+++ b/Components/BrowseFunc.pas
@@ -86,16 +86,13 @@ function BrowseForFolder(const Prompt: String; var Directory: String;
Pointer(lParam) := PChar(InitialDir);
end;
ActiveWindow := GetActiveWindow;
- WindowList := DisableTaskWindows(0);
+ WindowList := DisableTaskWindows(ParentWnd);
CoInitialize(nil);
try
IDList := SHBrowseForFolder(BrowseInfo);
finally
CoUninitialize();
EnableTaskWindows(WindowList);
- { SetActiveWindow(Application.Handle) is needed or else the focus doesn't
- properly return to ActiveWindow }
- SetActiveWindow(Application.Handle);
SetActiveWindow(ActiveWindow);
end;
try
@@ -169,7 +166,7 @@ function NewGetOpenOrSaveFileName(const Prompt: String; var FileName: String;
ofn.lpstrDefExt := Pointer(DefaultExtension);
ActiveWindow := GetActiveWindow;
- WindowList := DisableTaskWindows(0);
+ WindowList := DisableTaskWindows(ParentWnd);
try
asm
// Avoid FPU control word change in NETRAP.dll, NETAPI32.dll, etc
@@ -198,9 +195,6 @@ function NewGetOpenOrSaveFileName(const Prompt: String; var FileName: String;
end;
finally
EnableTaskWindows(WindowList);
- { SetActiveWindow(Application.Handle) is needed or else the focus doesn't
- properly return to ActiveWindow }
- SetActiveWindow(Application.Handle);
SetActiveWindow(ActiveWindow);
end;
end;
diff --git a/Components/TaskbarProgressFunc.pas b/Components/TaskbarProgressFunc.pas
index cb988d79f..3de90c54a 100644
--- a/Components/TaskbarProgressFunc.pas
+++ b/Components/TaskbarProgressFunc.pas
@@ -48,14 +48,16 @@ procedure SetAppTaskbarProgressState(const State: TTaskbarProgressState);
StateFlags: array[TTaskbarProgressState] of Integer = (
TBPF_NOPROGRESS, TBPF_INDETERMINATE, TBPF_NORMAL, TBPF_ERROR, TBPF_PAUSED);
begin
- if InitializeTaskbarList then
- TaskbarListInterface.SetProgressState(Application.Handle, StateFlags[State]);
+ if InitializeTaskbarList and Assigned(Application.MainForm) and
+ Application.MainForm.HandleAllocated then
+ TaskbarListInterface.SetProgressState(Application.MainForm.Handle, StateFlags[State]);
end;
procedure SetAppTaskbarProgressValue(const Completed, Total: Cardinal);
begin
- if InitializeTaskbarList then
- TaskbarListInterface.SetProgressValue(Application.Handle, Completed, Total);
+ if InitializeTaskbarList and Assigned(Application.MainForm) and
+ Application.MainForm.HandleAllocated then
+ TaskbarListInterface.SetProgressValue(Application.MainForm.Handle, Completed, Total);
end;
end.
diff --git a/ISHelp/ISHelpGen/UIsxclassesParser.pas b/ISHelp/ISHelpGen/UIsxclassesParser.pas
index 0421b8a35..be797a8d2 100644
--- a/ISHelp/ISHelpGen/UIsxclassesParser.pas
+++ b/ISHelp/ISHelpGen/UIsxclassesParser.pas
@@ -248,7 +248,6 @@ procedure TIsxclassesParser.SaveXML(const HeaderFileName, HeaderFileName2, Foote
end;
end;
end;
- WriteLn(F, '');
WriteLn(F, '');
WriteLn(F, '');
finally
diff --git a/ISHelp/isetup.xml b/ISHelp/isetup.xml
index a7268c747..57e8c74d4 100644
--- a/ISHelp/isetup.xml
+++ b/ISHelp/isetup.xml
@@ -1124,18 +1124,10 @@ DefaultGroupName=My Program
AppCopyright
-
BackColor
-
BackColor2
-
BackColorDirection
-
BackSolid
FlatComponentsList
SetupIconFile
ShowComponentSizes
ShowTasksTreeLines
-
WindowShowCaption
-
WindowStartMaximized
-
WindowResizable
-
WindowVisible
WizardImageAlphaFormat
WizardImageFile
WizardImageStretch
@@ -1151,12 +1143,20 @@ DefaultGroupName=My Program
AlwaysCreateUninstallIcon
+
BackColor
+
BackColor2
+
BackColorDirection
+
BackSolid
DisableAppendDir
DontMergeDuplicateFiles
MessagesFile
UninstallIconFile
UninstallIconName
UninstallStyle
+
WindowResizable
+
WindowShowCaption
+
WindowStartMaximized
+
WindowVisible
WizardImageBackColor
WizardSmallImageBackColor
@@ -4032,41 +4032,6 @@ Keep the default set of selected tasks, but deselect the "desktopicon" task:
-
-
-A value in the form of $bbggrr, where rr, gg, and bb specify the two-digit intensities (in hexadecimal) for red, green, and blue respectively. Or it may be one of the following predefined color names: clBlack, clMaroon, clGreen, clOlive, clNavy, clPurple, clTeal, clGray, clSilver, clRed, clLime, clYellow, clBlue, clFuchsia, clAqua, clWhite.
-clBlue for BackColor, clBlack for BackColor2
-
-
The BackColor directive specifies the color to use at the top (or left, if BackColorDirection=lefttoright) of the setup window's gradient background. BackColor2 specifies the color to use at the bottom (or right).
-
The setting of BackColor2 is ignored if BackSolid=yes.
This determines the direction of the gradient background on the setup window. If BackColorDirection is toptobottom, it is drawn from top to bottom; if it is lefttoright, it is drawn from left to right.
-
-
-
-
-yes or no
-no
-
-
This specifies whether to use a solid or gradient background on the setup window. If this is yes, the background is a solid color (the color specified by BackColor; BackColor2 is ignored).
-
-
-
This required directive specifies the name of the application being installed. Do not include the version number, as that is defined by the AppVersion and/or AppVerName directives. AppName is displayed throughout the Setup program and uninstaller in window titles, wizard pages, and dialog boxes. The value may include constants.
Specifies a copyright message that Setup will display in the bottom-right corner of Setup's background window when WindowVisible is yes.
-
The value of this directive is also used as the default value for the VersionInfoCopyright directive if it is not specified.
+
The value of this directive is used as the default value for the VersionInfoCopyright directive if it is not specified.
AppCopyright=Copyright (C) 1997-2005 My Company, Inc.
@@ -5084,39 +5048,16 @@ DiskSliceSize=1457664
-
-yes or no
-yes
-
-
If set to no, Setup will be truly "full screen" -- it won't have a caption bar or border, and it will be on top of the taskbar.
-
This directive has no effect if WindowVisible is not set to yes.
-
-
-
-
-yes or no
-yes
-
-
If set to yes, the Setup program's background window will initially be displayed in a maximized state, where it won't cover over the taskbar.
-
This directive has no effect if WindowVisible is not set to yes.
-
-
-
-
-yes or no
-yes
-
-
If set to no, the user won't be able to resize the Setup program's background window when it's not maximized.
-
This directive has no effect if WindowVisible is not set to yes.
-
-
-
-
-yes or no
-no
+
+
+
+
+
+
+
+
-
If set to yes, there will be a gradient background window displayed behind the wizard.
-
Note that this is considered a legacy feature; it likely will be removed at some point in the future.
+
Obsolete in 6.4. These directives are no longer supported. In past versions, they were used to configure a 1990s-style gradient background behind the wizard window. This long-deprecated feature has been removed.
Returns the UninstallProgressForm support object, or raises an internal error if the object has not yet been created.
UninstallProgressForm
-
- GetMainForm
- function GetMainForm: TMainForm;
-
Returns the MainForm support object, or raises an internal error if the object has not yet been created.
-
MainForm
-
diff --git a/Projects/Setup.dpr b/Projects/Setup.dpr
index 5f44135f8..975427014 100644
--- a/Projects/Setup.dpr
+++ b/Projects/Setup.dpr
@@ -179,29 +179,6 @@ begin
AcceptedQueryEndSessionInProgress := False;
Result := True;
end;
- WM_STYLECHANGING: begin
- { On Delphi 2009, we must suppress some of the VCL's manipulation of
- the application window styles in order to prevent the taskbar button
- from re-appearing after SetTaskbarButtonVisibility(False) was used
- to hide it.
- - The VCL tries to clear WS_EX_TOOLWINDOW whenever a form handle is
- created (see TCustomForm.CreateParams). Since
- SetTaskbarButtonVisibility uses the WS_EX_TOOLWINDOW style
- internally to hide the taskbar button, we can't allow that.
- - The VCL tries to set WS_EX_APPWINDOW on the application window
- after the main form is created (see ChangeAppWindow in Forms).
- The WS_EX_APPWINDOW style forces the window to show a taskbar
- button, overriding WS_EX_TOOLWINDOW, so don't allow that either.
- (It appears to be redundant anyway.) }
- if Integer(Message.WParam) = GWL_EXSTYLE then begin
- { SetTaskbarButtonVisibility sets TaskbarButtonHidden }
- if TaskbarButtonHidden then
- PStyleStruct(Message.LParam).styleNew :=
- PStyleStruct(Message.LParam).styleNew or WS_EX_TOOLWINDOW;
- PStyleStruct(Message.LParam).styleNew :=
- PStyleStruct(Message.LParam).styleNew and not WS_EX_APPWINDOW;
- end;
- end;
end;
end;
@@ -277,17 +254,34 @@ begin
end;
begin
- { Delphi 2009 initially sets WS_EX_TOOLWINDOW on the application window.
- That will prevent our ShowWindow(Application.Handle, SW_SHOW) calls from
- actually displaying the taskbar button as intended, so clear it. }
- SetWindowLong(Application.Handle, GWL_EXSTYLE,
- GetWindowLong(Application.Handle, GWL_EXSTYLE) and not WS_EX_TOOLWINDOW);
-
try
SetErrorMode(SEM_FAILCRITICALERRORS);
DisableWindowGhosting;
Application.HookMainWindow(TDummyClass.AntiShutdownHook);
TRichEditViewer.CustomShellExecute := ShellExecuteAsOriginalUser;
+
+ { Don't respect the show command passed by the parent process.
+ "Maximized" makes no sense as our windows don't have maximize/restore
+ buttons, and "Minimized" is problematic as the VCL doesn't realize the
+ app is minimized (Application.Restore has no effect because
+ FAppIconic=False).
+ If the parent process is SetupLdr, then there shouldn't be a non-normal
+ show command because SetupLdr doesn't specify a show command when
+ starting Setup. So this should really only matter when UseSetupLdr=no.
+ First, overwrite the System.CmdShow variable to ensure that
+ Application.Run (if called) doesn't mess with the main form's
+ WindowState.
+ Second, because ShowWindow overrides the value of nCmdShow on the first
+ call if it's SW_SHOWNORMAL, SW_SHOW, or SW_SHOWDEFAULT (which isn't
+ specifically documented; I tested each value), make a first call to
+ ShowWindow here that doesn't actually do anything (the app window is
+ already hidden at this point, and SW_HIDE is not one of the values that
+ get overridden), so that when we show our first form, it will be the
+ second call to ShowWindow and won't have its SW_SHOWNORMAL nCmdShow
+ value overridden. }
+ CmdShow := SW_SHOWNORMAL;
+ ShowWindow(Application.Handle, SW_HIDE);
+
SelectMode; { Only returns if we should run as Setup }
except
{ Halt on any exception }
@@ -299,17 +293,15 @@ begin
Note: There's no need to localize the following line since it's changed in
InitializeSetup }
Application.Title := 'Setup';
- { On Delphi 3+, the application window by default isn't visible until a form
- is shown. Force it visible like Delphi 2. Note that due to the way
- TApplication.UpdateVisible is coded, this should be permanent; if a form
- is shown and hidden, the application window should still be visible. }
- ShowWindow(Application.Handle, SW_SHOW);
+ Application.ShowMainForm := False;
Application.OnException := TMainForm.ShowException;
try
Application.Initialize;
+ Application.MainFormOnTaskBar := True;
InitializeSetup;
- Application.CreateForm(TMainForm, MainForm);
- MainForm.InitializeWizard;
+ MainForm := TMainForm.Create(Application);
+ Application.CreateForm(TWizardForm, WizardForm);
+ MainForm.InitializeWizard;
except
{ Halt on any exception }
ShowExceptionMsg;
diff --git a/Projects/Src/Compiler.ScriptClasses.pas b/Projects/Src/Compiler.ScriptClasses.pas
index f5895a89c..1fca3380a 100644
--- a/Projects/Src/Compiler.ScriptClasses.pas
+++ b/Projects/Src/Compiler.ScriptClasses.pas
@@ -311,14 +311,6 @@ procedure RegisterSetupForm_C(Cl: TPSPascalCompiler);
end;
end;
-procedure RegisterMainForm_C(Cl: TPSPascalCompiler);
-begin
- with CL.AddClassN(CL.FindClass('TSetupForm'), 'TMainForm') do
- begin
- RegisterMethod('procedure ShowAboutBox');
- end;
-end;
-
procedure RegisterWizardForm_C(Cl: TPSPascalCompiler);
begin
with Cl.AddClassN(Cl.FindClass('TSetupForm'), 'TWizardForm') do
@@ -675,7 +667,6 @@ procedure ScriptClassesLibraryRegister_C(Cl: TPSPascalCompiler);
RegisterUIStateForm_C(Cl);
RegisterSetupForm_C(Cl);
- RegisterMainForm_C(Cl);
RegisterWizardForm_C(Cl);
RegisterUninstallProgressForm_C(Cl);
@@ -694,7 +685,6 @@ procedure ScriptClassesLibraryRegister_C(Cl: TPSPascalCompiler);
RegisterHandCursor_C(Cl);
AddImportedClassVariable(Cl, 'WizardForm', 'TWizardForm');
- AddImportedClassVariable(Cl, 'MainForm', 'TMainForm');
AddImportedClassVariable(Cl, 'UninstallProgressForm', 'TUninstallProgressForm');
end;
diff --git a/Projects/Src/Compiler.SetupCompiler.pas b/Projects/Src/Compiler.SetupCompiler.pas
index d8f0b586f..fded69d51 100644
--- a/Projects/Src/Compiler.SetupCompiler.pas
+++ b/Projects/Src/Compiler.SetupCompiler.pas
@@ -123,7 +123,7 @@ TSetupCompiler = class
SetupHeader: TSetupHeader;
SetupDirectiveLines: array[TSetupSectionDirective] of Integer;
- UseSetupLdr, DiskSpanning, BackSolid, TerminalServicesAware, DEPCompatible, ASLRCompatible: Boolean;
+ UseSetupLdr, DiskSpanning, TerminalServicesAware, DEPCompatible, ASLRCompatible: Boolean;
DiskSliceSize, DiskClusterSize, SlicesPerDisk, ReserveBytes: Longint;
LicenseFile, InfoBeforeFile, InfoAfterFile, WizardImageFile: String;
WizardSmallImageFile: String;
@@ -1653,8 +1653,8 @@ function TSetupCompiler.CheckConst(const S: String; const MinVersion: TSetupVers
const
UserConsts: array[0..0] of String = (
'username');
- Consts: array[0..42] of String = (
- 'src', 'srcexe', 'tmp', 'app', 'win', 'sys', 'sd', 'groupname', 'commonfonts', 'hwnd',
+ Consts: array[0..41] of String = (
+ 'src', 'srcexe', 'tmp', 'app', 'win', 'sys', 'sd', 'groupname', 'commonfonts',
'commonpf', 'commonpf32', 'commonpf64', 'commoncf', 'commoncf32', 'commoncf64',
'autopf', 'autopf32', 'autopf64', 'autocf', 'autocf32', 'autocf64',
'computername', 'dao', 'cmd', 'wizardhwnd', 'sysuserinfoname', 'sysuserinfoorg',
@@ -2579,30 +2579,11 @@ procedure TSetupCompiler.EnumSetupProc(const Line: PChar; const Ext: Integer);
ssASLRCompatible: begin
ASLRCompatible := StrToBool(Value);
end;
- ssBackColor: begin
- try
- SetupHeader.BackColor := StringToColor(Value);
- except
- Invalid;
- end;
- end;
- ssBackColor2: begin
- try
- SetupHeader.BackColor2 := StringToColor(Value);
- except
- Invalid;
- end;
- end;
- ssBackColorDirection: begin
- if CompareText(Value, 'toptobottom') = 0 then
- Exclude(SetupHeader.Options, shBackColorHorizontal)
- else if CompareText(Value, 'lefttoright') = 0 then
- Include(SetupHeader.Options, shBackColorHorizontal)
- else
- Invalid;
- end;
+ ssBackColor,
+ ssBackColor2,
+ ssBackColorDirection,
ssBackSolid: begin
- BackSolid := StrToBool(Value);
+ WarningsList.Add(Format(SCompilerEntryObsolete, ['Setup', KeyName]));
end;
ssChangesAssociations: begin
SetupHeader.ChangesAssociations := Value;
@@ -3153,17 +3134,11 @@ procedure TSetupCompiler.EnumSetupProc(const Line: PChar; const Ext: Integer);
if not StrToVersionNumbers(Value, VersionInfoVersion) then
Invalid;
end;
- ssWindowResizable: begin
- SetSetupHeaderOption(shWindowResizable);
- end;
- ssWindowShowCaption: begin
- SetSetupHeaderOption(shWindowShowCaption);
- end;
- ssWindowStartMaximized: begin
- SetSetupHeaderOption(shWindowStartMaximized);
- end;
+ ssWindowResizable,
+ ssWindowShowCaption,
+ ssWindowStartMaximized,
ssWindowVisible: begin
- SetSetupHeaderOption(shWindowVisible);
+ WarningsList.Add(Format(SCompilerEntryObsolete, ['Setup', KeyName]));
end;
ssWizardImageAlphaFormat: begin
if CompareText(Value, 'none') = 0 then
@@ -7385,7 +7360,6 @@ procedure TSetupCompiler.Compile;
SetupHeader.MinVersion.NTVersion := $06010000;
SetupHeader.MinVersion.NTServicePack := $100;
SetupHeader.Options := [shDisableStartupPrompt, shCreateAppDir,
- shWindowStartMaximized, shWindowShowCaption, shWindowResizable,
shUsePreviousAppDir, shUsePreviousGroup,
shUsePreviousSetupType, shAlwaysShowComponentsList, shFlatComponentsList,
shShowComponentSizes, shUsePreviousTasks, shUpdateUninstallLogAppName,
@@ -7398,15 +7372,12 @@ procedure TSetupCompiler.Compile;
SetupHeader.UninstallFilesDir := '{app}';
SetupHeader.DefaultUserInfoName := '{sysuserinfoname}';
SetupHeader.DefaultUserInfoOrg := '{sysuserinfoorg}';
- SetupHeader.BackColor := clBlue;
- SetupHeader.BackColor2 := clBlack;
SetupHeader.DisableDirPage := dpAuto;
SetupHeader.DisableProgramGroupPage := dpAuto;
SetupHeader.CreateUninstallRegKey := 'yes';
SetupHeader.Uninstallable := 'yes';
SetupHeader.ChangesEnvironment := 'no';
SetupHeader.ChangesAssociations := 'no';
- BackSolid := False;
DefaultDialogFontName := 'Tahoma';
SignToolRetryCount := 2;
SignToolRetryDelay := 500;
@@ -7505,8 +7476,6 @@ procedure TSetupCompiler.Compile;
CheckConst(SetupHeader.DefaultUserInfoOrg, SetupHeader.MinVersion, []);
LineNumber := SetupDirectiveLines[ssDefaultUserInfoSerial];
CheckConst(SetupHeader.DefaultUserInfoSerial, SetupHeader.MinVersion, []);
- if BackSolid then
- SetupHeader.BackColor2 := SetupHeader.BackColor;
if not DiskSpanning then begin
DiskSliceSize := MaxDiskSliceSize;
DiskClusterSize := 1;
diff --git a/Projects/Src/Setup.MainForm.pas b/Projects/Src/Setup.MainForm.pas
index af8137551..8d5677c2e 100644
--- a/Projects/Src/Setup.MainForm.pas
+++ b/Projects/Src/Setup.MainForm.pas
@@ -13,32 +13,19 @@ interface
uses
Windows, Messages, SysUtils, Classes,
- Shared.Struct, Setup.MainFunc, Setup.SetupForm, Shared.SetupSteps;
+ Shared.Struct, Setup.MainFunc, Shared.SetupSteps;
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);
+ TMainForm = class(TComponent)
private
- IsMinimized, HideWizard: Boolean;
class procedure AppOnGetActiveFormHandle(var AHandle: HWND);
- function MainWindowHook(var Message: TMessage): Boolean;
- procedure UpdateWizardFormVisibility(const IgnoreMinimizedState: Boolean = False);
- 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 Close;
procedure Finish(const FromPreparingPage: Boolean);
procedure InitializeWizard;
function Install: Boolean;
- procedure RestoreApp;
procedure SetStep(const AStep: TSetupStep; const HandleExceptions: Boolean);
class procedure ShowException(Sender: TObject; E: Exception);
class procedure ShowExceptionMsg(const S: String);
@@ -56,176 +43,12 @@ implementation
SetupLdrAndSetup.Messages, SetupLdrAndSetup.RedirFunc, Setup.Install,
Setup.InstFunc, Setup.WizardForm, Setup.LoggingFunc, Shared.SetupTypes;
-{$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);
+ MainForm := nil; { just to detect use-after-free }
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;
@@ -284,7 +107,6 @@ procedure TMainForm.SetStep(const AStep: TSetupStep; const HandleExceptions: Boo
procedure TMainForm.InitializeWizard;
begin
- WizardForm := TWizardForm.Create(Application);
if CodeRunner <> nil then begin
try
CodeRunner.RunProcedures('InitializeWizard', [''], False);
@@ -293,12 +115,11 @@ procedure TMainForm.InitializeWizard;
raise;
end;
end;
- WizardForm.FlipSizeAndCenterIfNeeded(shWindowVisible in SetupHeader.Options, MainForm, True);
+ WizardForm.FlipSizeAndCenterIfNeeded(False, nil, False);
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;
+ WizardForm.Visible := True;
end
else
WizardForm.ClickThroughPages;
@@ -340,6 +161,7 @@ function TMainForm.Install: Boolean;
not NeedsRestart;
if CheckIfRestartNeeded then
ChecksumBefore := MakePendingFileRenameOperationsChecksum;
+ var WizardWasHidden := False;
WindowDisabler := nil;
try
for I := 0 to Entries[seRun].Count-1 do begin
@@ -365,15 +187,15 @@ function TMainForm.Install: Boolean;
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;
+ if WizardForm.Visible and not WizardWasHidden then begin
+ WizardWasHidden := True;
+ WizardForm.Hide;
end;
end
else begin
- if HideWizard then begin
- HideWizard := False;
- UpdateWizardFormVisibility;
+ if WizardWasHidden then begin
+ WizardWasHidden := False;
+ WizardForm.Visible := True;
end;
end;
DebugNotifyEntry(seRun, I);
@@ -383,10 +205,8 @@ function TMainForm.Install: Boolean;
end;
end;
finally
- if HideWizard then begin
- HideWizard := False;
- UpdateWizardFormVisibility;
- end;
+ if WizardWasHidden then
+ WizardForm.Visible := True;
WindowDisabler.Free;
if CheckIfRestartNeeded then begin
ChecksumAfter := MakePendingFileRenameOperationsChecksum;
@@ -394,7 +214,8 @@ function TMainForm.Install: Boolean;
NeedsRestart := True;
end;
end;
- Application.BringToFront;
+ if WizardForm.WindowState <> wsMinimized then { VCL bug workaround }
+ Application.BringToFront;
end;
end;
@@ -419,7 +240,8 @@ function TMainForm.Install: Boolean;
finally
WindowDisabler.Free;
end;
- Application.BringToFront;
+ if WizardForm.WindowState <> wsMinimized then { VCL bug workaround }
+ Application.BringToFront;
if Error = ERROR_FAIL_RESTART then
Log('One or more applications could not be restarted.')
@@ -453,11 +275,8 @@ function TMainForm.Install: Boolean;
SaveInf(InitSaveInf);
Application.Restore;
- Update;
- if InstallMode = imSilent then begin
- SetActiveWindow(Application.Handle); { ensure taskbar button is selected }
- WizardForm.Show;
- end;
+ if InstallMode = imSilent then
+ WizardForm.Visible := True;
WizardForm.Update;
SetStep(ssInstall, False);
@@ -514,10 +333,8 @@ function TMainForm.Install: Boolean;
end;
end;
- if InstallMode = imNormal then begin
+ if InstallMode = imNormal then
Application.Restore;
- Update;
- end;
Result := True;
except
@@ -653,7 +470,7 @@ procedure TMainForm.Finish(const FromPreparingPage: Boolean);
TerminateApp;
end;
-procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+procedure TMainForm.Close;
function ConfirmCancel(const DefaultConfirm: Boolean): Boolean;
var
@@ -666,9 +483,6 @@ procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
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
@@ -689,109 +503,6 @@ procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
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(
- const IgnoreMinimizedState: Boolean = False);
-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
- (IgnoreMinimizedState or 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 TMainForm.RestoreApp;
-{ Restores the app if it is currently minimized, and tries to make its taskbar
- button blink (by attempting to bring it to the foreground, which Windows
- normally blocks). This should be called before displaying any dialogs that
- aren't user-initiated (like NewDiskForm). }
-begin
- if IsIconic(Application.Handle) then begin
- { If called alone, Application.Restore annoyingly brings WizardForm to the
- foreground even if you're actively clicking/typing in the foreground
- app. Evidently the SW_RESTORE command used by Application.Restore
- bypasses Windows' usual foreground-stealing protections. However, if
- we show WizardForm in advance (and leave the application window still
- minimized), then SW_RESTORE doesn't bring WizardForm to the foreground
- (not sure why).
- Calling ShowWindow(Application.Handle, SW_SHOWNOACTIVATE) before
- Application.Restore also works, but I worry that's relying on an
- implementation detail: Application.Restore could be a no-op if it finds
- the application window isn't minimized. (In fact, it used to be, until
- the Forms unit added that fake IsIconic function.) }
- UpdateWizardFormVisibility(True);
- Application.Restore;
- end;
- Application.BringToFront;
-end;
-
class procedure TMainForm.AppOnGetActiveFormHandle(var AHandle: HWND);
begin
{ IDE's TMainForm has this too; see comments there }
diff --git a/Projects/Src/Setup.MainFunc.pas b/Projects/Src/Setup.MainFunc.pas
index 8aa3ce64e..c30616ada 100644
--- a/Projects/Src/Setup.MainFunc.pas
+++ b/Projects/Src/Setup.MainFunc.pas
@@ -153,7 +153,6 @@ interface
SetupExitCode: Integer;
CreatedIcon: Boolean;
RestartInitiatedByThisProcess, DownloadTemporaryFileOrExtract7ZipArchiveProcessMessages: Boolean;
- TaskbarButtonHidden: Boolean;
InstallModeRootKey: HKEY;
CodeRunner: TScriptRunner;
@@ -212,7 +211,6 @@ procedure RemoveTempInstallDir;
procedure SaveInf(const FileName: String);
procedure SaveResourceToTempFile(const ResName, Filename: String);
procedure SetActiveLanguage(const I: Integer);
-procedure SetTaskbarButtonVisibility(const AVisible: Boolean);
procedure ShellExecuteAsOriginalUser(hWnd: HWND; Operation, FileName, Parameters, Directory: LPWSTR; ShowCmd: Integer); stdcall;
function ShouldDisableFsRedirForFileEntry(const FileEntry: PSetupFileEntry): Boolean;
function ShouldDisableFsRedirForRunEntry(const RunEntry: PSetupRunEntry): Boolean;
@@ -1179,12 +1177,6 @@ function ExpandIndividualConst(Cnst: String;
else
Result := PSetupLanguageEntry(Entries[seLanguage][ActiveLanguage]).Name
end
- else if Cnst = 'hwnd' then begin
- if Assigned(MainForm) then
- Result := IntToStr(MainForm.Handle)
- else
- Result := '0';
- end
else if Cnst = 'wizardhwnd' then begin
if Assigned(WizardForm) then
Result := IntToStr(WizardForm.Handle)
@@ -2235,33 +2227,6 @@ procedure ActivateDefaultLanguage;
SetActiveLanguage(I);
end;
-procedure SetTaskbarButtonVisibility(const AVisible: Boolean);
-var
- ExStyle: Longint;
-begin
- { The taskbar button is hidden by setting the WS_EX_TOOLWINDOW style on the
- application window. We can't simply hide the window because on D3+ the VCL
- would just show it again in TApplication.UpdateVisible when the first form
- is shown. }
- TaskbarButtonHidden := not AVisible; { see WM_STYLECHANGING hook in Setup.dpr }
- if (GetWindowLong(Application.Handle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW = 0) <> AVisible then begin
- SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
- SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
- ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
- if AVisible then
- ExStyle := ExStyle and not WS_EX_TOOLWINDOW
- else
- ExStyle := ExStyle or WS_EX_TOOLWINDOW;
- SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
- if AVisible then
- { Show and activate when becoming visible }
- ShowWindow(Application.Handle, SW_SHOW)
- else
- SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
- SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_SHOWWINDOW);
- end;
-end;
-
procedure LogCompatibilityMode;
var
S: String;
@@ -2424,14 +2389,6 @@ procedure RestartComputerFromThisProcess;
RestartInitiatedByThisProcess := True;
{ Note: Depending on the OS, RestartComputer may not return if successful }
if not RestartComputer then begin
- { Hack for when called from RespawnSetupElevated: re-show the
- application's taskbar button }
- ShowWindow(Application.Handle, SW_SHOW);
- { If another app denied the shutdown, we probably lost the foreground;
- try to take it back. (Note: Application.BringToFront can't be used
- because we have no visible forms, and MB_SETFOREGROUND doesn't make
- the app's taskbar button blink.) }
- SetForegroundWindow(Application.Handle);
LoggedMsgBox(SetupMessages[msgErrorRestartingComputer], '', mbError,
MB_OK, True, IDOK);
end;
@@ -2450,9 +2407,6 @@ procedure RespawnSetupElevated(const AParams: String);
NotifyNewLanguage: Integer;
end;
begin
- { Hide the taskbar button }
- SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
- SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
Cancelled := False;
try
Server := TSpawnServer.Create;
@@ -2473,11 +2427,8 @@ procedure RespawnSetupElevated(const AParams: String);
{ If the user clicked Cancel on the dialog, halt with special exit code }
if ExceptObject is EAbort then
Cancelled := True
- else begin
- { Otherwise, re-show the taskbar button and re-raise }
- ShowWindow(Application.Handle, SW_SHOW);
+ else
raise;
- end;
end;
if Cancelled then
Halt(ecCancelledBeforeInstall);
@@ -2496,7 +2447,6 @@ procedure RespawnSetupElevated(const AParams: String);
except
{ In the unlikely event that something above raises an exception, handle
it here so the right exit code will still be returned below }
- ShowWindow(Application.Handle, SW_SHOW);
Application.HandleException(nil);
end;
end;
@@ -2711,14 +2661,6 @@ procedure InitializeSetup;
InstallMode := imVerySilent
else if InitSilent then
InstallMode := imSilent;
-
- if InstallMode <> imNormal then begin
- if InstallMode = imVerySilent then begin
- Application.ShowMainForm := False;
- SetTaskbarButtonVisibility(False);
- end;
- SetupHeader.Options := SetupHeader.Options - [shWindowVisible];
- end;
end;
function RecurseExternalGetSizeOfFiles(const DisableFsRedir: Boolean;
diff --git a/Projects/Src/Setup.NewDiskForm.pas b/Projects/Src/Setup.NewDiskForm.pas
index a979af0bc..79c473d8f 100644
--- a/Projects/Src/Setup.NewDiskForm.pas
+++ b/Projects/Src/Setup.NewDiskForm.pas
@@ -48,7 +48,8 @@ implementation
function SelectDisk(const DiskNumber: Integer; const AFilename: String;
var Path: String): Boolean;
begin
- MainForm.RestoreApp;
+ Application.Restore; { see comments in AppMessageBox }
+ Application.BringToFront; { usually just makes taskbar button blink }
with TNewDiskForm.Create(Application) do
try
diff --git a/Projects/Src/Setup.RegSvr.pas b/Projects/Src/Setup.RegSvr.pas
index ed1559057..a2e41f491 100644
--- a/Projects/Src/Setup.RegSvr.pas
+++ b/Projects/Src/Setup.RegSvr.pas
@@ -119,9 +119,7 @@ procedure RunRegSvr;
{ Set default title; it's set again below after the messages are read }
Application.Title := 'Setup';
- { This is needed for D3+: Must force the application window visible since
- we aren't displaying any forms }
- ShowWindow(Application.Handle, SW_SHOW);
+ Application.MainFormOnTaskBar := True;
InitializeCommonVars;
@@ -133,7 +131,6 @@ procedure RunRegSvr;
registry entries be in an incomplete/inconsistent state? I'm not sure, so
a mutex is used here to ensure registrations are serialized. }
Mutex := Windows.CreateMutex(nil, False, 'Inno-Setup-RegSvr-Mutex');
- ShowWindow(Application.Handle, SW_HIDE); { hide taskbar button while waiting }
if Mutex <> 0 then begin
{ Even though we have no visible windows, process messages while waiting
so Windows doesn't think we're hung }
@@ -142,7 +139,6 @@ procedure RunRegSvr;
until MsgWaitForMultipleObjects(1, Mutex, False, INFINITE,
QS_ALLINPUT) <> WAIT_OBJECT_0+1;
end;
- ShowWindow(Application.Handle, SW_SHOW);
try
MsgFilename := PathChangeExt(NewParamStr(0), '.msg');
ListFilename := PathChangeExt(NewParamStr(0), '.lst');
diff --git a/Projects/Src/Setup.ScriptClasses.pas b/Projects/Src/Setup.ScriptClasses.pas
index 187a85ff1..2421ee1af 100644
--- a/Projects/Src/Setup.ScriptClasses.pas
+++ b/Projects/Src/Setup.ScriptClasses.pas
@@ -202,14 +202,6 @@ procedure RegisterSetupForm_R(Cl: TPSRuntimeClassImporter);
end;
end;
-procedure RegisterMainForm_R(Cl: TPSRuntimeClassImporter);
-begin
- with CL.Add(TMainForm) do
- begin
- RegisterMethod(@TMainForm.ShowAboutBox, 'ShowAboutBox');
- end;
-end;
-
procedure RegisterWizardForm_R(Cl: TPSRuntimeClassImporter);
begin
with Cl.Add(TWizardForm) do
@@ -444,7 +436,6 @@ function ScriptClassesLibraryRegister_R(ScriptInterpreter: TPSExec): TPSRuntimeC
RegisterUIStateForm_R(Cl);
RegisterSetupForm_R(Cl);
- RegisterMainForm_R(Cl);
RegisterWizardForm_R(Cl);
RegisterUninstallProgressForm_R(Cl);
@@ -474,7 +465,6 @@ function ScriptClassesLibraryRegister_R(ScriptInterpreter: TPSExec): TPSRuntimeC
procedure ScriptClassesLibraryUpdateVars(ScriptInterpreter: TIFPSExec);
begin
SetVariantToClass(ScriptInterpreter.GetVarNo(ScriptInterpreter.GetVar('WIZARDFORM')), WizardForm);
- SetVariantToClass(ScriptInterpreter.GetVarNo(ScriptInterpreter.GetVar('MAINFORM')), MainForm);
SetVariantToClass(ScriptInterpreter.GetVarNo(ScriptInterpreter.GetVar('UNINSTALLPROGRESSFORM')), UninstallProgressForm);
end;
diff --git a/Projects/Src/Setup.ScriptFunc.HelperFunc.pas b/Projects/Src/Setup.ScriptFunc.HelperFunc.pas
index 9e6eb68d4..1fc27a0f8 100644
--- a/Projects/Src/Setup.ScriptFunc.HelperFunc.pas
+++ b/Projects/Src/Setup.ScriptFunc.HelperFunc.pas
@@ -53,7 +53,6 @@ procedure NoUninstallFuncError(const C: AnsiString); overload;
procedure OnlyUninstallFuncError(const C: AnsiString); overload;
function GetMainForm: TMainForm;
function GetWizardForm: TWizardForm;
-function GetWizardFormHandle: HWND;
function GetUninstallProgressForm: TUninstallProgressForm;
function GetMsgBoxCaption: String;
procedure InitializeScaleBaseUnits;
@@ -125,14 +124,6 @@ function GetWizardForm: TWizardForm;
InternalError('An attempt was made to access WizardForm before it has been created');
end;
-function GetWizardFormHandle: HWND;
-begin
- if Assigned(WizardForm) then
- Result := WizardForm.Handle
- else
- Result := 0;
-end;
-
function GetUninstallProgressForm: TUninstallProgressForm;
begin
Result := UninstallProgressForm;
diff --git a/Projects/Src/Setup.ScriptFunc.pas b/Projects/Src/Setup.ScriptFunc.pas
index 2b668af14..f0622a95f 100644
--- a/Projects/Src/Setup.ScriptFunc.pas
+++ b/Projects/Src/Setup.ScriptFunc.pas
@@ -317,23 +317,23 @@ procedure ScriptFuncLibraryRegister_R(ScriptInterpreter: TPSExec);
RegisterScriptFunc('BROWSEFORFOLDER', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
var S := Stack.GetString(PStart-2);
- Stack.SetBool(PStart, BrowseForFolder(Stack.GetString(PStart-1), S, GetWizardFormHandle, Stack.GetBool(PStart-3)));
+ Stack.SetBool(PStart, BrowseForFolder(Stack.GetString(PStart-1), S, GetOwnerWndForMessageBox, Stack.GetBool(PStart-3)));
Stack.SetString(PStart-2, S);
end);
RegisterScriptFunc('GETOPENFILENAME', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
var S := Stack.GetString(PStart-2);
- Stack.SetBool(PStart, NewGetOpenFileName(Stack.GetString(PStart-1), S, Stack.GetString(PStart-3), Stack.GetString(PStart-4), Stack.GetString(PStart-5), GetWizardFormHandle));
+ Stack.SetBool(PStart, NewGetOpenFileName(Stack.GetString(PStart-1), S, Stack.GetString(PStart-3), Stack.GetString(PStart-4), Stack.GetString(PStart-5), GetOwnerWndForMessageBox));
Stack.SetString(PStart-2, S);
end);
RegisterScriptFunc('GETOPENFILENAMEMULTI', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
- Stack.SetBool(PStart, NewGetOpenFileNameMulti(Stack.GetString(PStart-1), TStrings(Stack.GetClass(PStart-2)), Stack.GetString(PStart-3), Stack.GetString(PStart-4), Stack.GetString(PStart-5), GetWizardFormHandle));
+ Stack.SetBool(PStart, NewGetOpenFileNameMulti(Stack.GetString(PStart-1), TStrings(Stack.GetClass(PStart-2)), Stack.GetString(PStart-3), Stack.GetString(PStart-4), Stack.GetString(PStart-5), GetOwnerWndForMessageBox));
end);
RegisterScriptFunc('GETSAVEFILENAME', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
var S := Stack.GetString(PStart-2);
- Stack.SetBool(PStart, NewGetSaveFileName(Stack.GetString(PStart-1), S, Stack.GetString(PStart-3), Stack.GetString(PStart-4), Stack.GetString(PStart-5), GetWizardFormHandle));
+ Stack.SetBool(PStart, NewGetSaveFileName(Stack.GetString(PStart-1), S, Stack.GetString(PStart-3), Stack.GetString(PStart-4), Stack.GetString(PStart-5), GetOwnerWndForMessageBox));
Stack.SetString(PStart-2, S);
end);
end;
@@ -1175,10 +1175,6 @@ procedure ScriptFuncLibraryRegister_R(ScriptInterpreter: TPSExec);
begin
Stack.SetBool(PStart, CodeRegisterExtraCloseApplicationsResource(Stack.GetBool(PStart-1), Stack.GetString(PStart-2)));
end);
- RegisterScriptFunc('GETMAINFORM', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
- begin
- Stack.SetClass(PStart, GetMainForm);
- end);
RegisterScriptFunc('GETWIZARDFORM', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
Stack.SetClass(PStart, GetWizardForm);
@@ -1591,8 +1587,9 @@ procedure ScriptFuncLibraryRegister_R(ScriptInterpreter: TPSExec);
begin
RegisterScriptFunc('BRINGTOFRONTANDRESTORE', procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
- Application.BringToFront;
+ { Must be in this order to work around VCL bug }
Application.Restore;
+ Application.BringToFront;
end);
RegisterScriptFunc('WizardDirValue', sfNoUninstall, procedure(const Caller: TPSExec; const OrgName: AnsiString; const Stack: TPSStack; const PStart: Cardinal)
begin
diff --git a/Projects/Src/Setup.SelectLanguageForm.pas b/Projects/Src/Setup.SelectLanguageForm.pas
index 1acdc22b2..e3e4a8365 100644
--- a/Projects/Src/Setup.SelectLanguageForm.pas
+++ b/Projects/Src/Setup.SelectLanguageForm.pas
@@ -48,7 +48,7 @@ function AskForLanguage: Boolean;
I, J: Integer;
LangEntry: PSetupLanguageEntry;
begin
- LangForm := TSelectLanguageForm.Create(Application);
+ Application.CreateForm(TSelectLanguageForm, LangForm);
try
for I := 0 to Entries[seLanguage].Count-1 do begin
LangEntry := Entries[seLanguage][I];
diff --git a/Projects/Src/Setup.SetupForm.pas b/Projects/Src/Setup.SetupForm.pas
index 0b8746d88..f3691055c 100644
--- a/Projects/Src/Setup.SetupForm.pas
+++ b/Projects/Src/Setup.SetupForm.pas
@@ -331,6 +331,13 @@ procedure TSetupForm.CenterInsideControl(const Ctl: TWinControl;
var
R: TRect;
begin
+ const CtlForm = GetParentForm(Ctl);
+ if (CtlForm = nil) or not IsWindowVisible(CtlForm.Handle) or
+ IsIconic(CtlForm.Handle) then begin
+ Center;
+ Exit;
+ end;
+
if not InsideClientArea then begin
if GetWindowRect(Ctl.Handle, R) then
CenterInsideRect(R);
diff --git a/Projects/Src/Setup.Uninstall.pas b/Projects/Src/Setup.Uninstall.pas
index 8897367df..a01ad0462 100644
--- a/Projects/Src/Setup.Uninstall.pas
+++ b/Projects/Src/Setup.Uninstall.pas
@@ -91,7 +91,7 @@ function TExtUninstallLog.ShouldRemoveSharedFile(const Filename: String): Boolea
procedure InitializeUninstallProgressForm;
begin
- UninstallProgressForm := TUninstallProgressForm.Create(nil);
+ Application.CreateForm(TUninstallProgressForm, UninstallProgressForm);
UninstallProgressForm.Initialize(Title, UninstLog.AppName, ufModernStyle in UninstLog.Flags);
if CodeRunner <> nil then begin
try
@@ -349,19 +349,9 @@ function RespawnFirstPhaseIfNeeded: Boolean;
RequireAdmin := (ufAdminInstalled in Flags) or (ufPowerUserInstalled in Flags);
if NeedToRespawnSelfElevated(RequireAdmin, False) then begin
- { Hide the taskbar button }
- SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
- SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
- try
- RespawnSelfElevated(UninstExeFilename,
- Format('/INITPROCWND=$%x ', [Application.Handle]) + GetCmdTail,
- UninstallExitCode);
- except
- { Re-show the taskbar button and re-raise }
- if not(ExceptObject is EAbort) then
- ShowWindow(Application.Handle, SW_SHOW);
- raise;
- end;
+ RespawnSelfElevated(UninstExeFilename,
+ Format('/INITPROCWND=$%x ', [Application.Handle]) + GetCmdTail,
+ UninstallExitCode);
Result := True;
end;
end;
@@ -402,11 +392,6 @@ procedure RunFirstPhase;
Longint(OldWindowProc) := SetWindowLong(Wnd, GWL_WNDPROC,
Longint(@FirstPhaseWindowProc));
try
- { Hide the application window so that we don't end up with two taskbar
- buttons once the second phase starts }
- SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
- SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
-
{ Execute the copy of itself ("second phase") }
ProcessHandle := Exec(TempFile, Format('/SECONDPHASE="%s" /FIRSTPHASEWND=$%x ',
[NewParamStr(0), Wnd]) + GetCmdTail);
@@ -485,9 +470,6 @@ procedure RunSecondPhase;
Res, RemovedAll, UninstallNeedsRestart: Boolean;
StartTime: DWORD;
begin
- if VerySilent then
- SetTaskbarButtonVisibility(False);
-
RestartSystem := False;
AllowUninstallerShutdown := True;
@@ -736,11 +718,6 @@ procedure RunSecondPhase;
Log('Restarting Windows.');
RestartInitiatedByThisProcess := True;
if not RestartComputer then begin
- { If another app denied the shutdown, we probably lost the foreground;
- try to take it back. (Note: Application.BringToFront can't be used
- because we have no visible forms, and MB_SETFOREGROUND doesn't make
- the app's taskbar button blink.) }
- SetForegroundWindow(Application.Handle);
LoggedAppMessageBox(PChar(SetupMessages[msgErrorRestartingComputer]),
PChar(SetupMessages[msgErrorTitle]), MB_OK or MB_ICONEXCLAMATION,
True, IDOK);
@@ -758,9 +735,7 @@ procedure RunUninstaller;
begin
{ Set default title; it's set again below after the messages are read }
Application.Title := 'Uninstall';
- { This is needed for D3+: Must force the application window visible since
- we aren't displaying any forms }
- ShowWindow(Application.Handle, SW_SHOW);
+ Application.MainFormOnTaskBar := True;
try
InitializeCommonVars;
diff --git a/Projects/Src/Setup.WizardForm.dfm b/Projects/Src/Setup.WizardForm.dfm
index b9b8a4acb..4cccae5ad 100644
--- a/Projects/Src/Setup.WizardForm.dfm
+++ b/Projects/Src/Setup.WizardForm.dfm
@@ -1,8 +1,8 @@
object WizardForm: TWizardForm
Left = 191
Top = 139
- BorderIcons = [biSystemMenu]
- BorderStyle = bsDialog
+ BorderIcons = [biSystemMenu, biMinimize]
+ BorderStyle = bsSingle
Caption = 'WizardForm'
ClientHeight = 360
ClientWidth = 497
@@ -12,14 +12,12 @@ object WizardForm: TWizardForm
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
- OldCreateOrder = True
Scaled = False
OnClose = FormClose
OnResize = FormResize
DesignSize = (
497
360)
- PixelsPerInch = 96
TextHeight = 13
object FBevel: TBevel
Left = 0
diff --git a/Projects/Src/Setup.WizardForm.pas b/Projects/Src/Setup.WizardForm.pas
index ed10c37c7..e4e1d8fb5 100644
--- a/Projects/Src/Setup.WizardForm.pas
+++ b/Projects/Src/Setup.WizardForm.pas
@@ -211,8 +211,7 @@ TWizardForm = class(TSetupForm)
procedure UpdatePage(const PageID: Integer);
procedure UpdateSelectTasksPage;
procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
- protected
- procedure CreateParams(var Params: TCreateParams); override;
+ procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
public
{ Public declarations }
PrepareToInstallFailureMessage: String;
@@ -761,10 +760,9 @@ constructor TWizardForm.Create(AOwner: TComponent);
SystemMenu: HMENU;
P: String;
I, DefaultSetupTypeIndex: Integer;
- DfmDefault, IgnoreInitComponents: Boolean;
+ IgnoreInitComponents: Boolean;
TypeEntry: PSetupTypeEntry;
ComponentEntry: PSetupComponentEntry;
- SaveClientWidth, SaveClientHeight: Integer;
begin
inherited;
@@ -793,34 +791,17 @@ constructor TWizardForm.Create(AOwner: TComponent);
WelcomeLabel1.Font.Style := [fsBold];
PageNameLabel.Font.Style := [fsBold];
- if shWindowVisible in SetupHeader.Options then
- Caption := SetupMessages[msgSetupAppTitle]
- else if shDisableWelcomePage in SetupHeader.Options then
+ if shDisableWelcomePage in SetupHeader.Options then
Caption := FmtSetupMessage1(msgSetupWindowTitle, ExpandedAppVerName)
else
Caption := FmtSetupMessage1(msgSetupWindowTitle, ExpandedAppName);
- { Set BorderStyle and BorderIcons:
- -WindowVisible + WizardResizable = sizeable
- -not WindowVisible + WizardResizable = sizeable + minimize
- -WindowVisible + not WizardResizable = dialog = .dfm default = do nothing
- -not WindowVisible + not WizardResizable = single + minimize }
- DfmDefault := (shWindowVisible in SetupHeader.Options) and not (shWizardResizable in SetupHeader.Options);
- if not DfmDefault then begin
- { Save ClientWidth/ClientHeight and restore them after changing BorderStyle. }
- SaveClientWidth := ClientWidth;
- SaveClientHeight := ClientHeight;
- if not(shWindowVisible in SetupHeader.Options) then
- BorderIcons := BorderIcons + [biMinimize];
- if not(shWizardResizable in SetupHeader.Options) then
- BorderStyle := bsSingle
- else
- BorderStyle := bsSizeable;
+ if shWizardResizable in SetupHeader.Options then begin
+ const SaveClientWidth = ClientWidth;
+ const SaveClientHeight = ClientHeight;
+ BorderStyle := bsSizeable;
ClientWidth := SaveClientWidth;
ClientHeight := SaveClientHeight;
- end;
-
- if shWizardResizable in SetupHeader.Options then begin
EnableAnchorOuterPagesOnResize := True;
{ Do not allow user to resize it smaller than 100% nor larger than 150%. }
Constraints.MinHeight := Height;
@@ -1347,14 +1328,6 @@ destructor TWizardForm.Destroy;
inherited;
end;
-procedure TWizardForm.CreateParams(var Params: TCreateParams);
-begin
- inherited;
- { Ensure the form is *always* on top of MainForm by making MainForm
- the "parent" of the form. }
- Params.WndParent := MainForm.Handle;
-end;
-
function TWizardForm.PageIndexFromID(const ID: Integer): Integer;
{ Given a page ID, returns the index of the page in FPageList. An exception is
raised if a page with the specified ID is not found. }
@@ -1865,10 +1838,8 @@ function TWizardForm.PrepareToInstall(const WizardComponents, WizardTasks: TStri
BackButton.Visible := False;
NextButton.Visible := False;
CancelButton.Enabled := False;
- if InstallMode = imSilent then begin
- SetActiveWindow(Application.Handle); { ensure taskbar button is selected }
- WizardForm.Show;
- end;
+ if InstallMode = imSilent then
+ WizardForm.Visible := True;
WizardForm.Update;
try
DownloadTemporaryFileOrExtract7ZipArchiveProcessMessages := True;
@@ -1879,7 +1850,8 @@ function TWizardForm.PrepareToInstall(const WizardComponents, WizardTasks: TStri
DownloadTemporaryFileOrExtract7ZipArchiveProcessMessages := False;
UpdateCurPageButtonState;
end;
- Application.BringToFront;
+ if WindowState <> wsMinimized then { VCL bug workaround }
+ Application.BringToFront;
end;
if Result <> '' then begin
if PrepareToInstallNeedsRestart then
@@ -2559,10 +2531,8 @@ procedure TWizardForm.NextButtonClick(Sender: TObject);
SetCurPage(wpPreparing); { controls are already hidden by PrepareToInstall }
BackButton.Visible := False;
NextButton.Visible := False;
- if InstallMode = imSilent then begin
- SetActiveWindow(Application.Handle); { ensure taskbar button is selected }
- WizardForm.Show;
- end;
+ if InstallMode = imSilent then
+ WizardForm.Visible := True;
try
WizardForm.Update;
RmFoundApplications := QueryRestartManager(WizardComponents, WizardTasks) <> '';
@@ -2709,18 +2679,28 @@ procedure TWizardForm.NoIconsCheckClick(Sender: TObject);
procedure TWizardForm.WMSysCommand(var Message: TWMSysCommand);
begin
- if Message.CmdType and $FFF0 = SC_MINIMIZE then
- { A minimize button is shown on the wizard form when (shWindowVisible in
- SetupHeader.Options). When it is clicked we want to minimize the whole
- application. }
- Application.Minimize
- else
if Message.CmdType = 9999 then
MainForm.ShowAboutBox
else
inherited;
end;
+procedure TWizardForm.WMWindowPosChanging(var Message: TWMWindowPosChanging);
+begin
+ { Work around a VCL issue (Delphi 11.3) when MainFormOnTaskBar=True:
+ If Application.Restore is called while the main form is hidden
+ (Visible=False), the window can become visible because of the SW_RESTORE
+ command it uses, which both unminimizes and shows a window. Reproducer:
+ Application.Minimize;
+ Hide;
+ Application.Restore;
+ This blocks any attempt to show the window while Visible=False.
+ (SW_RESTORE will still unminimize the window; it just cannot show it.) }
+ inherited;
+ if not Visible then
+ Message.WindowPos.flags := Message.WindowPos.flags and not SWP_SHOWWINDOW;
+end;
+
procedure TWizardForm.LicenseAcceptedRadioClick(Sender: TObject);
begin
if CurPageID = wpLicense then
@@ -3040,14 +3020,10 @@ procedure TWizardForm.ClickThroughPages;
{ After installation, we can't abort since e.g. a restart might be
needed. Instead, to avoid getting stuck in a loop, show the wizard
(even though this is a silent install) and let the user deal with the
- problem on their own.
- The taskbar button will be hidden at this point on very silent
- installs (see SetupInstallMode); re-show it. }
+ problem on their own. }
Log('Failed to proceed to next wizard page; showing wizard.');
- SetTaskbarButtonVisibility(True);
+ WizardForm.Visible := True;
Application.Restore;
- SetActiveWindow(Application.Handle); { ensure taskbar button is selected }
- WizardForm.Show;
Break;
end;
end;
diff --git a/Projects/Src/Shared.CommonFunc.Vcl.pas b/Projects/Src/Shared.CommonFunc.Vcl.pas
index e0f7a65d8..1f3679d96 100644
--- a/Projects/Src/Shared.CommonFunc.Vcl.pas
+++ b/Projects/Src/Shared.CommonFunc.Vcl.pas
@@ -54,6 +54,7 @@ procedure SetMessageBoxRightToLeft(const ARightToLeft: Boolean);
function GetMessageBoxRightToLeft: Boolean;
procedure SetMessageBoxCallbackFunc(const AFunc: TMsgBoxCallbackFunc; const AParam: LongInt);
procedure TriggerMessageBoxCallbackFunc(const Flags: LongInt; const After: Boolean);
+function GetOwnerWndForMessageBox: HWND;
implementation
@@ -207,11 +208,42 @@ procedure TriggerMessageBoxCallbackFunc(const Flags: LongInt; const After: Boole
end;
end;
+function GetOwnerWndForMessageBox: HWND;
+{ Returns window handle that Application.MessageBox, if called immediately
+ after this function, would use as the owner window for the message box.
+ Exception: If the window that would be returned is not shown on the taskbar,
+ or is a minimized Application.Handle window, then 0 is returned instead.
+ See comments in AppMessageBox. }
+begin
+ { This is what Application.MessageBox does (Delphi 11.3) }
+ Result := Application.ActiveFormHandle;
+ if Result = 0 then { shouldn't be possible, but they have this check }
+ Result := Application.Handle;
+
+ { Now our override }
+ if ((Result = Application.Handle) and IsIconic(Result)) or
+ (GetWindowLong(Result, GWL_STYLE) and WS_VISIBLE = 0) or
+ (GetWindowLong(Result, GWL_EXSTYLE) and WS_EX_TOOLWINDOW <> 0) then
+ Result := 0;
+end;
+
function AppMessageBox(const Text, Caption: PChar; Flags: Longint): Integer;
var
ActiveWindow: HWND;
WindowList: Pointer;
begin
+ { Always restore the app first if it's minimized. This makes sense from a
+ usability perspective (e.g., it may be unclear which app generated the
+ message box if it's shown by itself), but it's also a VCL bug mitigation
+ (seen on Delphi 11.3):
+ Without this, when Application.MainFormOnTaskBar=True, showing a window
+ like a message box causes a WM_ACTIVATEAPP message to be sent to
+ Application.Handle, and the VCL strangely responds by setting FAppIconic
+ to False -- even though the main form is still iconic (minimized). If we
+ later try to call Application.Restore, nothing happens because it sees
+ FAppIconic=False. }
+ Application.Restore;
+
{ Always try to bring the message box to the foreground. Task dialogs appear
to do that by default.
Without this, if the main form is minimized and then closed via the
@@ -266,13 +298,7 @@ function AppMessageBox(const Text, Caption: PChar; Flags: Longint): Integer;
(This problem doesn't occur when Application.MainFormOnTaskBar=True
because the main form retains its WS_VISIBLE style while minimized.)
}
- var ActWnd := Application.ActiveFormHandle;
- if ActWnd = 0 then { shouldn't be possible, but they have this check }
- ActWnd := Application.Handle;
- if (ActWnd = Application.Handle) and
- (IsIconic(Application.Handle) or
- (GetWindowLong(Application.Handle, GWL_STYLE) and WS_VISIBLE = 0) or
- (GetWindowLong(Application.Handle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW <> 0)) then begin
+ if GetOwnerWndForMessageBox = 0 then begin
ActiveWindow := GetActiveWindow;
WindowList := DisableTaskWindows(0);
try
diff --git a/Projects/Src/Shared.ScriptFunc.pas b/Projects/Src/Shared.ScriptFunc.pas
index 506dcaee3..359bc9cc1 100644
--- a/Projects/Src/Shared.ScriptFunc.pas
+++ b/Projects/Src/Shared.ScriptFunc.pas
@@ -400,8 +400,6 @@ initialization
'function CustomMessage(const MsgName: String): String;',
'function RmSessionStarted: Boolean;',
'function RegisterExtraCloseApplicationsResource(const DisableFsRedir: Boolean; const AFilename: String): Boolean;',
- { Actually access MainForm.pas }
- 'function GetMainForm: TMainForm;',
{ Actually access WizardForm.pas }
'function GetWizardForm: TWizardForm;',
'function WizardIsComponentSelected(const Components: String): Boolean;',
diff --git a/Projects/Src/Shared.Struct.pas b/Projects/Src/Shared.Struct.pas
index d10232f24..fa19f4aaa 100644
--- a/Projects/Src/Shared.Struct.pas
+++ b/Projects/Src/Shared.Struct.pas
@@ -33,7 +33,7 @@ interface
this file it's recommended you change SetupID. Any change will do (like
changing the letters or numbers), as long as your format is
unrecognizable by the standard Inno Setup. }
- SetupID: TSetupID = 'Inno Setup Setup Data (6.4.0)';
+ SetupID: TSetupID = 'Inno Setup Setup Data (6.4.0.1)';
UninstallLogID: array[Boolean] of TUninstallLogID =
('Inno Setup Uninstall Log (b)', 'Inno Setup Uninstall Log (b) 64-bit');
MessagesHdrID: TMessagesHdrID = 'Inno Setup Messages (6.4.0) (u)';
@@ -51,10 +51,9 @@ interface
end;
TSetupHeaderOption = (shDisableStartupPrompt, shCreateAppDir,
shAllowNoIcons, shAlwaysRestart, shAlwaysUsePersonalGroup,
- shWindowVisible, shWindowShowCaption, shWindowResizable,
- shWindowStartMaximized, shEnableDirDoesntExistWarning,
+ shEnableDirDoesntExistWarning,
shPassword, shAllowRootDirectory, shDisableFinishedPage, shUsePreviousAppDir,
- shBackColorHorizontal, shUsePreviousGroup, shUpdateUninstallLogAppName,
+ shUsePreviousGroup, shUpdateUninstallLogAppName,
shUsePreviousSetupType, shDisableReadyMemo, shAlwaysShowComponentsList,
shFlatComponentsList, shShowComponentSizes, shUsePreviousTasks,
shDisableReadyPage, shAlwaysShowDirOnReadyPage, shAlwaysShowGroupOnReadyPage,
@@ -106,7 +105,6 @@ TSetupEncryptionNonce = record
NumRegistryEntries, NumInstallDeleteEntries, NumUninstallDeleteEntries,
NumRunEntries, NumUninstallRunEntries: Integer;
MinVersion, OnlyBelowVersion: TSetupVersionData;
- BackColor, BackColor2: Longint;
WizardStyle: TSetupWizardStyle;
WizardSizePercentX, WizardSizePercentY: Integer;
WizardImageAlphaFormat: (afIgnored, afDefined, afPremultiplied); // Must be same as Graphics.TAlphaFormat
diff --git a/Projects/Src/Shared.TaskDialogFunc.pas b/Projects/Src/Shared.TaskDialogFunc.pas
index d4cf1b2e3..f22c4b323 100644
--- a/Projects/Src/Shared.TaskDialogFunc.pas
+++ b/Projects/Src/Shared.TaskDialogFunc.pas
@@ -49,15 +49,8 @@ function DoTaskDialog(const hWnd: HWND; const Instruction, Text, Caption, Icon:
Config.cbSize := SizeOf(Config);
if RightToLeft then
Config.dwFlags := Config.dwFlags or TDF_RTL_LAYOUT;
- { If the application window isn't currently visible, show the task dialog
- with no owner window so it'll get a taskbar button }
Config.hInstance := HInstance;
- if IsIconic(Application.Handle) or
- (GetWindowLong(Application.Handle, GWL_STYLE) and WS_VISIBLE = 0) or
- (GetWindowLong(Application.Handle, GWL_EXSTYLE) and WS_EX_TOOLWINDOW <> 0) then
- Config.hWndParent := 0
- else
- Config.hwndParent := hWnd;
+ Config.hwndParent := hWnd;
Config.dwCommonButtons := CommonButtons;
Config.pszWindowTitle := Caption;
Config.pszMainIcon := Icon;
@@ -85,7 +78,7 @@ function DoTaskDialog(const hWnd: HWND; const Instruction, Text, Caption, Icon:
end;
TriggerMessageBoxCallbackFunc(TriggerMessageBoxCallbackFuncFlags, False);
ActiveWindow := GetActiveWindow;
- WindowList := DisableTaskWindows(0);
+ WindowList := DisableTaskWindows(Config.hwndParent);
try
Result := TaskDialogIndirectFunc(Config, @ModalResult, nil, pfVerificationFlagChecked) = S_OK;
finally
@@ -116,6 +109,7 @@ function TaskDialogMsgBox(const Icon, Instruction, Text, Caption: String; const
NButtonLabelsAvailable: Integer;
ButtonIDs: array of Integer;
begin
+ Application.Restore; { See comments in AppMessageBox }
if Icon <> '' then
IconP := PChar(Icon)
else begin
@@ -177,7 +171,7 @@ function TaskDialogMsgBox(const Icon, Instruction, Text, Caption: String; const
end;
if Length(ButtonIDs) <> NButtonLabelsAvailable then
DoInternalError('TaskDialogMsgBox: Invalid ButtonLabels');
- if not DoTaskDialog(Application.Handle, PChar(Instruction), PChar(Text),
+ if not DoTaskDialog(GetOwnerWndForMessageBox, PChar(Instruction), PChar(Text),
GetMessageBoxCaption(PChar(Caption), Typ), IconP, TDCommonButtons, ButtonLabels, ButtonIDs, ShieldButton,
GetMessageBoxRightToLeft, IfThen(Typ in [mbError, mbCriticalError], MB_ICONSTOP, 0), Result, PChar(VerificationText), pfVerificationFlagChecked) then //note that MB_ICONEXCLAMATION (used by mbError) includes MB_ICONSTOP (used by mbCriticalError)
Result := 0;
diff --git a/whatsnew.htm b/whatsnew.htm
index 20d2231f0..7b9793c8b 100644
--- a/whatsnew.htm
+++ b/whatsnew.htm
@@ -91,6 +91,7 @@
Updated the encryption algorithm and key derivation function used by Inno Setup to XChaCha20 and PBKDF2-HMAC-SHA256 respectively, increasing security. This code is built-in: the separate ISCrypt.dll "encryption module" is no longer used and will be automatically deleted when you update.
Added [Setup] section directive EncryptionKeyDerivation to change the number of PBKDF2-HMAC-SHA256 iterations to use from the default of 200000 to another value.
Replaced all remaining use of MD5 and SHA-1 hashes with SHA-256 hashes, without removing the MD5 and SHA-1 Pascal Scripting and ISPP support functions.
+
At long last, Setup's wizard window now shows a thumbnail image on its taskbar button, and animates correctly when minimized and restored. As part of this work, support for the long-deprecated [Setup] section directive WindowVisible, which was used to enable a 1990s-style blue gradient background behind the wizard window, has been dropped.
The aspect ratio of Setup's large and small wizard images (as specified by WizardImageFile and WizardSmallImageFile) is now maintained when the window is scaled. Previously, depending on the font and font size used, they could have appeared horizontally stretched or squished.
The New Script Wizard now sets UninstallDisplayIcon when an .exe is chosen as the main executable file.
Merged the Inno Setup Preprocessor documentation into the main documentation instead of being separate.