Procházet zdrojové kódy

Merge branch 'darker'

Martijn Laan před 2 měsíci
rodič
revize
5f28313043

+ 7 - 2
Components/BrowseFunc.pas

@@ -2,7 +2,7 @@ unit BrowseFunc;
 
 {
   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.
 
@@ -29,7 +29,7 @@ function NewGetSaveFileName(const Prompt: String; var FileName: String;
 implementation
 
 uses
-  CommDlg, ShlObj, ActiveX,
+  CommDlg, ShlObj, ActiveX, Themes,
   PathFunc;
 
 function BrowseCallback(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer; stdcall;
@@ -167,6 +167,10 @@ begin
 
   ActiveWindow := GetActiveWindow;
   WindowList := DisableTaskWindows(ParentWnd);
+  { Temporarily clear SystemHooks to make it support dark mode if Windows is in dark mode.
+    Taken from Vcl.Dialogs' TCustomFileDialog.Execute. }
+  const SaveHooks = TStyleManager.SystemHooks;
+  TStyleManager.SystemHooks := [];
   try
     asm
       // Avoid FPU control word change in NETRAP.dll, NETAPI32.dll, etc
@@ -194,6 +198,7 @@ begin
       end;
     end;
   finally
+    TStyleManager.SystemHooks := SaveHooks;
     EnableTaskWindows(WindowList);
     SetActiveWindow(ActiveWindow);
   end;

+ 5 - 2
Components/ModernColors.pas

@@ -2,7 +2,7 @@ unit ModernColors;
 
 {
   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.
 
@@ -43,7 +43,10 @@ const
 
   DFore = $D6D6D6;           { VSCode Modern Dark, 2 tints lightened using color-hex.com }
   DBack = $1F1F1F;           { VSCode Modern Dark }
-  DToolBack = $413E40;       { Monokai Pro }
+  { If you combine this unit with a dark VCL Style then the following color should match the style's
+    window background color. Value can be found using BitmapStyleDesigner.exe from BDS\Bin. Open the
+    style .vsf file, go to the Colors section and then to the Window color. }
+  DToolBack = $2B2B2B;       { VCL Style 'Windows11 Dark 1.0' }
   DSelBack = $764F1D;        { VSCode Modern Dark }
   //DSelInactiveBack = $51504F;{ VSCode Modern Dark }
   DIntelliBack = $202020;    { VSCode Modern Dark }

+ 61 - 7
Components/NewCheckListBox.pas

@@ -205,7 +205,7 @@ procedure Register;
 implementation
 
 uses
-  NewUxTheme.TmSchema, PathFunc, ActiveX, BidiUtils, Types;
+  Themes, NewUxTheme.TmSchema, PathFunc, ActiveX, BidiUtils, UITypes, Types;
 
 const
   sRadioCantHaveDisabledChildren = 'Radio item cannot have disabled child items';
@@ -720,6 +720,13 @@ const
     (CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED),
     (CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED)
   );
+  FontColorStates: array[Boolean] of TStyleFont = (sfListItemTextDisabled, sfListItemTextNormal);
+  CheckListItemStates: array[Boolean] of TThemedCheckListBox = (tclListItemDisabled, tclListItemNormal);
+  CheckBoxCheckedStates: array[Boolean] of TThemedButton = (tbCheckBoxCheckedDisabled, tbCheckBoxCheckedNormal);
+  CheckBoxUncheckedStates: array[Boolean] of TThemedButton = (tbCheckBoxUncheckedDisabled, tbCheckBoxUncheckedNormal);
+  CheckBoxMixedStates: array[Boolean] of TThemedButton = (tbCheckBoxMixedDisabled, tbCheckBoxMixedNormal);
+  RadioButtonCheckedStates: array[Boolean] of TThemedButton = (tbRadioButtonCheckedDisabled, tbRadioButtonCheckedNormal);
+  RadioButtonUncheckedStates: array[Boolean] of TThemedButton = (tbRadioButtonUncheckedDisabled, tbRadioButtonUncheckedNormal);
 var
   SavedClientRect: TRect;
 
@@ -773,17 +780,39 @@ begin
   ItemState := ItemStates[Index];
   UIState := SendMessage(Handle, WM_QUERYUISTATE, 0, 0);
   Disabled := not Enabled or not ItemState.Enabled;
+
+  { Style code below is based on Vcl.StdCtrls' TCustomListBox.CNDrawItem and Vcl.CheckLst's
+    TCustomCheckListBox.DrawItem and .DrawCheck }
+  var LStyle := StyleServices(Self);
+  if not LStyle.Enabled or LStyle.IsSystemStyle then
+    LStyle := nil;
+
   with Canvas do begin
+    { Initialize colors }
     if not FWantTabs and (odSelected in State) and Focused then begin
-      Brush.Color := clHighlight;
       NewTextColor := clHighlightText;
-    end
-    else begin
-      Brush.Color := Self.Color;
+      if (LStyle <> nil) and (seClient in StyleElements) then begin
+        Brush.Color := LStyle.GetSystemColor(clHighlight);
+        if seFont in StyleElements then
+          NewTextColor := LStyle.GetStyleFontColor(sfListItemTextSelected);
+      end else
+        Brush.Color := clHighlight;
+    end else begin
       if Disabled then
         NewTextColor := clGrayText
       else
         NewTextColor := Self.Font.Color;
+      if (LStyle <> nil) and (seClient in StyleElements) then begin
+        Brush.Color := LStyle.GetStyleColor(scListBox);
+        if seFont in StyleElements then begin
+          NewTextColor := LStyle.GetStyleFontColor(FontColorStates[not Disabled]);
+          const Details = LStyle.GetElementDetails(CheckListItemStates[Enabled]);
+          var LColor: TColor;
+          if LStyle.GetElementColor(Details, ecTextColor, LColor) and (LColor <> clNone) then
+            NewTextColor := LColor;
+        end;
+      end else
+        Brush.Color := Self.Color;
     end;
     { Draw threads }
     if FShowLines then begin
@@ -810,7 +839,32 @@ begin
         Rect.Top + ((Rect.Bottom - Rect.Top - FCheckHeight) div 2),
         FCheckWidth, FCheckHeight);
       FlipRect(CheckRect, SavedClientRect, FUseRightToLeft);
-      if FThemeData = 0 then begin
+      if LStyle <> nil then begin
+        var Detail: TThemedButton;
+        if ItemState.State <> cbGrayed then begin
+          if ItemState.ItemType = itCheck then begin
+            if ItemState.State = cbChecked then
+              Detail := CheckBoxCheckedStates[not Disabled]
+            else
+              Detail := CheckBoxUncheckedStates[not Disabled];
+          end else begin
+            if ItemState.State = cbChecked then
+              Detail := RadioButtonCheckedStates[not Disabled]
+            else
+              Detail := RadioButtonUncheckedStates[not Disabled];
+          end;
+        end else
+          Detail := CheckBoxMixedStates[not Disabled];
+        const ElementDetails = LStyle.GetElementDetails(Detail);
+        const SaveColor = Brush.Color;
+        const SaveIndex = SaveDC(Handle);
+        try
+          LStyle.DrawElement(Handle, ElementDetails, CheckRect, nil, CurrentPPI);
+        finally
+          RestoreDC(Handle, SaveIndex);
+        end;
+        Brush.Color := SaveColor;
+      end else if FThemeData = 0 then begin
         case ItemState.State of
           cbChecked: uState := ButtonStates[ItemState.ItemType] or DFCS_CHECKED;
           cbUnchecked: uState := ButtonStates[ItemState.ItemType];
@@ -897,7 +951,7 @@ begin
       lines are drawn -- and we mustn't draw too many. }
     InternalDrawText(Items[Index], Rect, DrawTextFormat or DT_CALCRECT, False);
     FlipRect(Rect, SavedClientRect, FUseRightToLeft);
-    InternalDrawText(Items[Index], Rect, DrawTextFormat, FWantTabs and Disabled);
+    InternalDrawText(Items[Index], Rect, DrawTextFormat, FWantTabs and Disabled and (LStyle = nil));
     { Draw focus rectangle }
     if FWantTabs and not Disabled and (odSelected in State) and Focused and
       (UIState and UISF_HIDEFOCUS = 0) then

+ 53 - 2
Components/NewStaticText.pas

@@ -35,6 +35,8 @@ type
     procedure Loaded; override;
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     procedure SetAutoSize(Value: Boolean); override;
+    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
+    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
   public
     constructor Create(AOwner: TComponent); override;
     function AdjustHeight: Integer;
@@ -58,6 +60,8 @@ type
     property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar
       default True;
     property ShowHint;
+    property StyleElements;
+    property StyleName;
     property TabOrder;
     property TabStop;
     property Visible;
@@ -78,6 +82,7 @@ procedure Register;
 implementation
 
 uses
+  Graphics, Themes, Types,
   BidiUtils;
 
 procedure Register;
@@ -87,11 +92,55 @@ end;
 
 { TNewStaticText }
 
+procedure TNewStaticText.WMEraseBkgnd(var Message: TWMEraseBkgnd);
+begin;
+  if IsCustomStyleActive and (seClient in StyleElements) then
+    Message.Result := 1
+  else
+    inherited;
+end;
+
+procedure TNewStaticText.WMPaint(var Message: TWMPaint);
+const
+  CStates: array[Boolean] of TThemedTextLabel = (ttlTextLabelDisabled, ttlTextLabelNormal);
+begin
+  { Based on Vcl.StdCtrl's TCustomLabel.DoDrawThemeTextEx and its callers. Only the
+    DrawParentBackground call is new compared to it.  }
+  if IsCustomStyleActive and (seClient in StyleElements) then begin
+    const LStyle = StyleServices(Self);
+    var DC := Message.DC;
+    var PS: TPaintStruct;
+    if DC = 0 then
+      DC := BeginPaint(Handle, PS);
+    try
+      var R := ClientRect;
+      const Details = LStyle.GetElementDetails(CStates[Enabled]);
+      LStyle.DrawParentBackground(Handle, DC, Details, False, @R);
+      var Text: String := Caption;
+      if (Text = '') or (FShowAccelChar and (Text[1] = '&') and (Length(Text) = 1)) then
+        Text := Text + ' ';
+      const TextFlags = GetDrawTextFlags;
+      const OldFont = SelectObject(DC, Font.Handle);
+      try
+        LStyle.DrawText(DC, Details, Text, R, TTextFormat(TextFlags), Font.Color);
+      finally
+        SelectObject(DC, OldFont);
+      end;
+    finally
+      if Message.DC = 0 then
+        EndPaint(Handle, PS);
+    end;
+  end else
+    inherited;
+end;
+
 constructor TNewStaticText.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   ControlStyle := [csCaptureMouse, csClickEvents, csSetCaption,
-    csOpaque, csReplicatable, csDoubleClicks];
+    csReplicatable, csDoubleClicks];
+  if not (StyleServices.Enabled and not StyleServices.IsSystemStyle) then
+    ControlStyle := ControlStyle + [csOpaque];
   Width := 65;
   Height := 17;
   FAutoSize := True;
@@ -132,12 +181,14 @@ end;
 procedure TNewStaticText.CMFontChanged(var Message: TMessage);
 begin
   inherited;
+  Invalidate;
   AdjustBounds;
 end;
 
 procedure TNewStaticText.CMParentFontChanged(var Message: TMessage);
 begin
   inherited;
+  Invalidate;
   { What we're really trapping here is changes to Parent. Recalculate size
     if the new Parent's RTL setting is different. }
   if IsParentRightToLeft(Self) <> FLastAdjustBoundsRTL then
@@ -186,7 +237,7 @@ begin
   if R.Right > 0 then Dec(R.Right);
 
   S := Caption;
-  if (S = '') or (FShowAccelChar and (S[1] = '&') and (S[2] = #0)) then
+  if (S = '') or (FShowAccelChar and (S[1] = '&') and (Length(S) = 1)) then
     S := S + ' ';
 
   DC := GetDC(0);

+ 9 - 1
Projects/Compil32.dpr

@@ -72,7 +72,9 @@ uses
   IDE.ImagesModule in 'Src\IDE.ImagesModule.pas' {ImagesModule: TDataModule},
   ECDSA in '..\Components\ECDSA.pas',
   ISSigFunc in '..\Components\ISSigFunc.pas',
-  StringScanner in '..\Components\StringScanner.pas';
+  StringScanner in '..\Components\StringScanner.pas',
+  VCL.Styles,
+  VCL.Themes;
 
 {$SETPEOSVERSION 6.1}
 {$SETPESUBSYSVERSION 6.1}
@@ -81,6 +83,7 @@ uses
 {$R Res\Compil32.docicon.res}
 {$R Res\Compil32.manifest.res}
 {$R Res\Compil32.versionandicon.res}
+{$R Res\Compil32.darkstyle.res}
 
 procedure SetAppUserModelID;
 var
@@ -252,6 +255,11 @@ begin
       Title := SCompilerFormCaption;
   end;
 
+  if Assigned(FlushMenuThemes) then begin
+    { We don't need VCL Styles for dark menus. This keeps shDialogs and shTooltips. }
+    TStyleManager.SystemHooks := TStyleManager.SystemHooks - [shMenus];
+  end;
+
   Application.CreateForm(TImagesModule, ImagesModule);
   Application.CreateForm(TMainForm, MainForm);
   Application.Run;

+ 2 - 0
Projects/Res/Compil32.darkstyle.rc

@@ -0,0 +1,2 @@
+// The name below doesn't matter except that it must be a name and not just an index
+MYSTYLE1 VCLSTYLE Compil32.darkstyle.vsf

binární
Projects/Res/Compil32.darkstyle.res


+ 10 - 0
Projects/Res/Compil32.darkstyle.vsf.txt

@@ -0,0 +1,10 @@
+Compil32.darkstyle.vsf should any VCL Style File with its name changed to Dark using
+Bitmap Style Designer (BDS\Bin\BitmapStyleDesigner.exe)
+
+Currently equals VCL Style 'Windows11 Dark 1.0' by Embarcadero from GetIt
+
+For easier testing, you could instead use VCL Style 'Stellar 2.0' by Embarcadero
+from GetIt, in either variant. This style features a colored (blue) background with
+a white foreground. This combination is very rare, if not unique, among all available
+styles. Other styles with a colored background use a black foreground, but since things
+are black by default, those are not useful for testing.

+ 1 - 0
Projects/Src/IDE.FilesDesignerForm.pas

@@ -50,6 +50,7 @@ uses
 procedure TFilesDesignerForm.FormCreate(Sender: TObject);
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
 
   FFilesHelper := TWizardFormFilesHelper.Create(Self,
     NotCreateAppDirCheck, AppFilesListBox, AppFilesAddButton, AppFilesAddDirButton,

+ 32 - 39
Projects/Src/IDE.HelperFunc.pas

@@ -13,7 +13,7 @@ interface
 
 uses
   Windows,
-  Classes, Forms, Dialogs, Menus, Controls, StdCtrls,
+  Classes, Forms, Dialogs, Menus, Controls, StdCtrls, Graphics,
   ScintEdit, IDE.IDEScintEdit, ModernColors;
 
 const
@@ -26,8 +26,10 @@ type
 
 procedure InitFormFont(Form: TForm);
 procedure SetControlWindowTheme(const WinControl: TWinControl; const Dark: Boolean);
-procedure InitFormThemeInit(const ATheme: TTheme);
-procedure InitFormTheme(Form: TForm);
+procedure InitFormThemeInit(const Theme: TTheme);
+function InitFormTheme(const Form: TForm): Boolean;
+function InitFormThemeGetBkColor(const WindowColor: Boolean): TColor;
+function InitFormThemeIsDark: Boolean;
 function GetDisplayFilename(const Filename: String): String;
 function GetFileTitle(const Filename: String): String;
 function GetCleanFileNameOfFile(const Filename: String): String;
@@ -85,7 +87,7 @@ implementation
 uses
   ActiveX, ShlObj, ShellApi, CommDlg, SysUtils, IOUtils, StrUtils, ExtCtrls,
   Messages, DwmApi, Consts,
-  Shared.CommonFunc, Shared.CommonFunc.Vcl, PathFunc, Shared.FileClass, NewUxTheme,
+  Shared.CommonFunc, Shared.CommonFunc.Vcl, PathFunc, Shared.FileClass, NewUxTheme, NewNotebook,
   IDE.MainForm, IDE.Messages, Shared.ConfigIniFile;
 
 procedure InitFormFont(Form: TForm);
@@ -108,8 +110,10 @@ begin
 end;
 
 procedure SetControlWindowTheme(const WinControl: TWinControl; const Dark: Boolean);
+{ Can be used for memos and listboxes to switch them to (or from) a native dark scrollbar }
 begin
   if UseThemes then begin
+    WinControl.StyleName := 'Windows';
     if Dark then
       SetWindowTheme(WinControl.Handle, 'DarkMode_Explorer', nil)
     else
@@ -120,56 +124,45 @@ end;
 var
   FormTheme: TTheme;
 
-procedure InitFormThemeInit(const ATheme: TTheme);
+procedure InitFormThemeInit(const Theme: TTheme);
 begin
-  FormTheme := ATheme;
+  FormTheme := Theme;
 end;
 
-procedure InitFormTheme(Form: TForm);
-
-  procedure InitListBoxDarkTheme(const ListBox: TListBox);
-  begin
-    ListBox.Font.Color := FormTheme.Colors[tcFore];
-    ListBox.Color := FormTheme.Colors[tcBack];
-    ListBox.Invalidate;
-    SetControlWindowTheme(ListBox, FormTheme.Dark);
-  end;
-
-  procedure InitWinControlTheme(const ParentControl: TWinControl);
-  begin
-    for var I := 0 to ParentControl.ControlCount-1 do begin
-      var Control := ParentControl.Controls[I];
-      if Control is TListBox then
-        InitListBoxDarkTheme(Control as TListBox)
-      else if (Control is TButton) or (Control is TRadioButton) or (Control is TCheckBox) then begin
-        { Not actually used at the moment since only TMainForm calls InitFormTheme and it doesn't
-          have any of these controls. If it would be used: it works fully for buttons but for
-          radiobuttons and checkboxes it only updates the glyph and not the text color. }
-        SetControlWindowTheme(Control as TWinControl, FormTheme.Dark);
-      end;
-
-      if Control is TWinControl then
-        InitWinControlTheme(Control as TWinControl);
-    end;
-  end;
-
+function InitFormTheme(const Form: TForm): Boolean;
+{ Assumes forms other then MainForm call this function only once during creation, and assumes they
+  don't need any styling if the theme is non dark. Always styles MainForm. Returns True if it did
+  style, False otherwise. }
 begin
-  if (Form = MainForm) or FormTheme.Dark then begin
-    Form.Color := FormTheme.Colors[tcBack];
-  
+  Result := (Form = MainForm) or FormTheme.Dark;
+  if Result then begin
+    Form.Color := InitFormThemeGetBkColor(Form = MainForm);
+
     { Based on https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes
       Unlike this article we check for Windows 10 Version 2004 because that's the first version
       that introduced DWMWA_USE_IMMERSIVE_DARK_MODE as 20 (the now documented value) instead of 19 }
     if WindowsVersionAtLeast(10, 0, 19041) then begin
+      Form.StyleElements := Form.StyleElements - [seBorder];
       const DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
       var value: BOOL := FormTheme.Dark;
       DwmSetWindowAttribute(Form.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE, @value, SizeOf(value));
     end;
-  
-    InitWinControlTheme(Form);
   end;
 end;
 
+function InitFormThemeGetBkColor(const WindowColor: Boolean): TColor;
+begin
+  if WindowColor then
+    Result := FormTheme.Colors[tcBack] { This is white/window if not dark mode }
+  else
+    Result := FormTheme.Colors[tcToolBack]; { This is gray/btnface if not dark mode }
+end;
+
+function InitFormThemeIsDark: Boolean;
+begin
+  Result := FormTheme.Dark;
+end;
+
 function GetDisplayFilename(const Filename: String): String;
 var
   Buf: array[0..MAX_PATH-1] of Char;

+ 1 - 0
Projects/Src/IDE.InputQueryComboForm.pas

@@ -63,6 +63,7 @@ end;
 procedure TInputQueryComboForm.FormCreate(Sender: TObject);
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
 end;
 
 function TInputQueryComboForm.GetValue: String;

+ 1 - 0
Projects/Src/IDE.InputQueryMemoForm.pas

@@ -77,6 +77,7 @@ end;
 procedure TInputQueryMemoForm.FormCreate(Sender: TObject);
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
   UpdateImages;
 end;
 

+ 4 - 0
Projects/Src/IDE.MainForm.dfm

@@ -14,6 +14,7 @@ object MainForm: TMainForm
   KeyPreview = True
   Menu = MainMenu1
   Position = poDefault
+  StyleElements = []
   OnAfterMonitorDpiChanged = FormAfterMonitorDpiChanged
   OnCloseQuery = FormCloseQuery
   OnKeyDown = FormKeyDown
@@ -47,6 +48,7 @@ object MainForm: TMainForm
       FullRepaint = False
       TabOrder = 1
       Visible = False
+      StyleName = 'Windows'
       OnMouseMove = SplitPanelMouseMove
     end
     object StatusPanel: TPanel
@@ -195,6 +197,7 @@ object MainForm: TMainForm
     Align = alTop
     BevelOuter = bvNone
     TabOrder = 0
+    StyleName = 'Windows'
     object ToolBar: TToolBar
       AlignWithMargins = True
       Left = 7
@@ -369,6 +372,7 @@ object MainForm: TMainForm
     BevelOuter = bvNone
     TabOrder = 1
     Visible = False
+    StyleName = 'Windows'
     object UpdatePanelClosePaintBox: TPaintBox
       AlignWithMargins = True
       Left = 330

+ 59 - 96
Projects/Src/IDE.MainForm.pas

@@ -680,7 +680,7 @@ var
 implementation
 
 uses
-  ActiveX, Clipbrd, ShellApi, ShlObj, IniFiles, Registry, Consts, Types, UITypes,
+  ActiveX, Clipbrd, ShellApi, ShlObj, IniFiles, Registry, Consts, Types, UITypes, Themes,
   Math, StrUtils, WideStrUtils, TypInfo,
   PathFunc, Shared.CommonFunc.Vcl, Shared.CommonFunc, Shared.FileClass, IDE.Messages, NewUxTheme.TmSchema, BrowseFunc,
   IDE.HtmlHelpFunc, TaskbarProgressFunc, IDE.ImagesModule,
@@ -783,6 +783,7 @@ begin
   Memo.SetAutoCompleteSeparators(InnoSetupStylerWordListSeparator, InnoSetupStylerWordListTypeSeparator);
   Memo.SetWordChars(Memo.GetDefaultWordChars+'#{}[]');
   Memo.Theme := FTheme;
+  Memo.StyleName := 'Windows';
   Memo.Visible := False;
   Result := Memo;
 end;
@@ -814,92 +815,6 @@ begin
   Result := Memo;
 end;
 
-function DarkStatusBarSubclassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM; uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall;
-const
-  { See TStatusBarStyleHook.Paint }
-  AlignStyles: array [TAlignment] of Integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
-  cGripSize = 17;
-begin
-  case uMsg of
-    WM_ERASEBKGND:
-      begin
-        const MainForm = TMainForm(dwRefData);
-        if MainForm.FTheme.Dark then begin
-          { See StatusBarStyleHook.WMEraseBkgnd }
-          Exit(1);
-        end;
-      end;
-    WM_PAINT, WM_PRINTCLIENT:
-      begin
-        const MainForm = TMainForm(dwRefData);
-        if MainForm.FTheme.Dark then begin
-          var PaintStruct: TPaintStruct;
-          const Canvas = TCanvas.Create;
-          try
-            if uMsg = WM_PAINT then
-              Canvas.Handle := BeginPaint(hWnd, PaintStruct)
-            else
-              Canvas.Handle := wParam;
-
-            const Control = MainForm.StatusBar;
-            Canvas.Font := Control.Font;
-            Canvas.Font.Color := MainForm.FTheme.Colors[tcFore];
-
-            { See TStatusBarStyleHook.Paint }
-
-            Canvas.Brush.Color := $171717; { Same as themed scrollbar drawn by Windows 11 }
-            Canvas.FillRect(Rect(0, 0, Control.Width, Control.Height));
-
-            const Count = Control.Panels.Count;
-            for var I := 0 to Count-1 do begin
-              var R := Default(TRect);
-              SendMessage(hWnd, SB_GETRECT, I, IntPtr(@R));
-              if IsRectEmpty(R) then
-                Continue;
-              var R1 := R;
-              if I = Count - 1 then
-                R1.Right := Control.ClientWidth + 10;
-              Canvas.FillRect(R1);
-              InflateRect(R, -1, -1);
-              var Flags := Control.DrawTextBiDiModeFlags(AlignStyles[Control.Panels[I].Alignment]);
-              Flags := Flags + DT_VCENTER;
-              var LText: String;
-              SetLength(LText, Word(SendMessage(hWnd, SB_GETTEXTLENGTH, I, 0)));
-              if Length(LText) > 0 then begin { Always False at the moment }
-                var Res := SendMessage(hWnd, SB_GETTEXT, I, IntPtr(@LText[1]));
-                if (Res and SBT_OWNERDRAW = 0) then
-                  DrawText(Canvas.Handle, LText, Length(LText), R, Flags)
-                else
-                  MainForm.StatusBarCanvasDrawPanel(Canvas, Control.Panels[I], R);
-              end else begin
-                if Control.Panels[I].Style <> psOwnerDraw then
-                  DrawText(Canvas.handle, Control.Panels[I].Text, Length(Control.Panels[I].Text), R, Flags)
-                else
-                  MainForm.StatusBarCanvasDrawPanel(Canvas, Control.Panels[I], R);
-              end;
-            end;
-
-            if not IsZoomed(MainForm.Handle) and (MainForm.FStatusBarThemeData <> 0) then begin
-              var R1 := Control.ClientRect;
-              R1.Left := R1.Right - MainForm.ToCurrentPPI(cGripSize);
-              R1.Top := R1.Bottom - MainForm.ToCurrentPPI(cGripSize);
-              DrawThemeBackground(MainForm.FStatusBarThemeData, Canvas.Handle, SP_GRIPPER, 0, R1, nil);
-            end;
-          finally
-            Canvas.Free;
-          end;
-          if uMsg = WM_PAINT then
-            EndPaint(hWnd, PaintStruct);
-          Exit(0);
-        end;
-      end;
-    WM_NCDESTROY:
-      RemoveWindowSubclass(hWnd, @DarkStatusBarSubclassProc, 0);
-  end;
-
-  Result := DefSubclassProc(hWnd, uMsg, wParam, lParam);
-end;
-
 constructor TMainForm.Create(AOwner: TComponent);
 
   procedure CheckUpdatePanelMessage(const Ini: TConfigIniFile; const ConfigIdent: String;
@@ -1155,8 +1070,6 @@ begin
 
   UpdateThemeData(True);
   
-  SetWindowSubclass(StatusBar.Handle, @DarkStatusBarSubclassProc, 0, DWORD_PTR(Self));
-
   FMenuBitmaps := TMenuBitmaps.Create;
   FMenuBitmapsSize.cx := 0;
   FMenuBitmapsSize.cy := 0;
@@ -1319,7 +1232,6 @@ begin
   UpdateMarginsAndSquigglyAndCaretWidths;
   UpdateOutputTabSetListsItemHeightAndDebugTimeWidth;
   UpdateStatusPanelHeight(StatusPanel.Height);
-  SetWindowSubclass(StatusBar.Handle, @DarkStatusBarSubclassProc, 0, DWORD_PTR(Self));
 end;
 
 procedure TMainForm.FormCloseQuery(Sender: TObject;
@@ -6556,19 +6468,45 @@ begin
 end;
 
 procedure TMainForm.UpdateTheme;
+
+  procedure SetListBoxWindowTheme(const ListBox: TListBox);
+  begin
+    ListBox.Font.Color := FTheme.Colors[tcFore];
+    ListBox.Color := FTheme.Colors[tcBack];
+    ListBox.Invalidate;
+    SetControlWindowTheme(ListBox, FTheme.Dark);
+  end;
+
 begin
   FTheme.Typ := FOptions.ThemeType;
 
   SetHelpFileDark(FTheme.Dark);
 
+  { For MainForm the active style only impacts message boxes and tooltips: FMemos, ToolbarPanel,
+    UpdatePanel, SplitPanel and the 4 ListBoxes all ignore it because their StyleName property is set
+    to 'Windows' always, either by the .dfm or by code. Additionally, for scrollbars and StatusBar,
+    MainForm's StyleElements is empty. Menus ignore it because shMenus is removed from
+    TStyleManager.SystemHooks at startup. }
+  if FTheme.Dark then
+    TStyleManager.TrySetStyle('Dark')
+  else
+    TStyleManager.TrySetStyle('Windows');
+  { For some reason only MainForm needs this: with StyleName set to an empty string, dialog boxes
+    it opens, such as MsgBox, look broken }
+  StyleName := TStyleManager.ActiveStyle.Name;
+
+  InitFormTheme(Self);
+
+  ToolbarPanel.Color := FTheme.Colors[tcToolBack];
+
   for var Memo in FMemos do begin
     Memo.UpdateThemeColorsAndStyleAttributes;
     SetControlWindowTheme(Memo, FTheme.Dark);
   end;
-
-  InitFormTheme(Self);
-  ToolbarPanel.Color := FTheme.Colors[tcToolBack];
-  BodyPanel.Color := FTheme.Colors[tcBack];
+  SetListBoxWindowTheme(CompilerOutputList);
+  SetListBoxWindowTheme(DebugOutputList);
+  SetListBoxWindowTheme(DebugCallStackList);
+  SetListBoxWindowTheme(FindResultsList);
 
   if FTheme.Dark then begin
     ThemedToolbarVirtualImageList.ImageCollection := ImagesModule.DarkToolBarImageCollection;
@@ -7278,6 +7216,13 @@ begin
           RGlyph.Left := RText.Right; { RGlyph is now a square }
           DrawThemeBackground(FToolbarThemeData, Canvas.Handle, TP_DROPDOWNBUTTONGLYPH, TS_NORMAL, RGlyph, nil);
         end;
+        var Color: TColor := FTheme.Colors[tcFore];
+        const LStyle = TStyleManager.ActiveStyle;
+        if LStyle <> nil then begin
+          const Details = LStyle.GetElementDetails(tsPane);
+          LStyle.GetElementColor(Details, ecTextColor, Color);
+        end;
+        Canvas.Font.Color := Color;
         var S := Format('Tabs closed: %d', [FHiddenFiles.Count]);
         Canvas.TextRect(RText, S, [tfCenter]);
       end;
@@ -7292,7 +7237,25 @@ begin
       if FCompiling and (FProgressMax > 0) then begin
         var R := Rect;
         InflateRect(R, -2, -2);
-        if FProgressThemeData = 0 then begin
+        var LStyle := StyleServices(Self);
+        if not LStyle.Enabled or LStyle.IsSystemStyle then
+          LStyle := nil;
+        if LStyle <> nil then begin
+          { See Vcl.ComCtrl's TProgressBarStyleHook.Paint, .PaintFrame, and .PaintBar }
+          var Details: TThemedElementDetails;
+          Details.Element := teProgress;
+          if LStyle.HasTransparentParts(Details) then
+            LStyle.DrawParentBackground(Handle, Canvas.Handle, Details, False, @R);
+          Details := LStyle.GetElementDetails(tpBar);
+          LStyle.DrawElement(Canvas.Handle, Details, R);
+          InflateRect(R, -1, -1);
+          const W = R.Width;
+          const Pos = Round(W * (FProgress / FProgressMax));
+          var FillR := R;
+          FillR.Right := FillR.Left + Pos;
+          Details := LStyle.GetElementDetails(tpChunk);
+          LStyle.DrawElement(Canvas.Handle, Details, FillR);
+        end else if FProgressThemeData = 0 then begin
           { Border }
           Canvas.Pen.Color := clBtnShadow;
           Canvas.Brush.Style := bsClear;
@@ -7488,7 +7451,7 @@ end;
 { Should be removed if the main menu ever gets removed }
 procedure TMainForm.UAHDrawMenuBottomLine;
 begin
-  if FTheme.Dark then begin
+  if not (csDestroying in ComponentState) and (FTheme <> nil) and FTheme.Dark then begin
     var ClientRect: TRect;
     Windows.GetClientRect(Handle, ClientRect);
 		MapWindowPoints(Handle, 0, ClientRect, 2);

+ 1 - 0
Projects/Src/IDE.MsgBoxDesignerForm.pas

@@ -117,6 +117,7 @@ uses
 procedure TMsgBoxDesignerForm.FormCreate(Sender: TObject);
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
 
   cb_Suppressible.Checked := True;
   MSGText.Lines[MSGText.CaretPos.Y] := '<Enter your text here...>';

+ 1 - 0
Projects/Src/IDE.OptionsForm.pas

@@ -82,6 +82,7 @@ uses
 procedure TOptionsForm.FormCreate(Sender: TObject);
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
 
   { Order must match CompFunc.TKeyMappingType }
   KeyMappingComboBox.Items.Add('Classic');

+ 1 - 0
Projects/Src/IDE.RegistryDesignerForm.pas

@@ -69,6 +69,7 @@ end;
 procedure TRegistryDesignerForm.FormCreate(Sender: TObject);
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
 
   FRegistryHelper := TWizardFormRegistryHelper.Create(Self, AppRegistryFileEdit,
     AppRegistryFileButton, AppRegistryUninsDeleteKeyCheck,

+ 1 - 0
Projects/Src/IDE.SignToolsForm.pas

@@ -80,6 +80,7 @@ procedure TSignToolsForm.FormCreate(Sender: TObject);
 begin
   FSignTools := TStringList.Create();
   InitFormFont(Self);
+  InitFormTheme(Self);
 end;
 
 { This and CreateParams make bsSizeable (which has an unwanted icon) look like bsDialog, see:

+ 1 - 0
Projects/Src/IDE.StartupForm.pas

@@ -99,6 +99,7 @@ begin
   FResult := srNone;
 
   InitFormFont(Self);
+  InitFormTheme(Self);
 
   DonateImage.Hint := MainForm.UpdatePanelDonateImage.Hint;
 

+ 1 - 0
Projects/Src/IDE.Wizard.WizardFileForm.pas

@@ -119,6 +119,7 @@ var
   I: Integer;
 begin
   InitFormFont(Self);
+  InitFormTheme(Self);
 
   MakeBold(SourceLabel);
   MakeBold(DestRootDirLabel);

+ 311 - 43
Projects/Src/IDE.Wizard.WizardForm.dfm

@@ -56,12 +56,8 @@ object WizardForm: TWizardForm
     Height = 314
     ActivePage = MainPage
     Anchors = [akLeft, akTop, akRight, akBottom]
-    Color = clBtnFace
-    ParentColor = False
     TabOrder = 3
     object WelcomePage: TNewNotebookPage
-      Color = clWindow
-      ParentColor = False
       DesignSize = (
         496
         314)
@@ -233,6 +229,166 @@ object WizardForm: TWizardForm
           7188BC220000000049454E44AE426082}
         Stretch = True
       end
+      object WelcomeImageDark: TImage
+        Left = 33
+        Top = 12
+        Width = 164
+        Height = 314
+        Anchors = [akLeft, akTop, akBottom]
+        Picture.Data = {
+          0954506E67496D61676589504E470D0A1A0A0000000D49484452000000A40000
+          013A080200000017CC6E91000000017352474200AECE1CE90000000467414D41
+          0000B18F0BFC6105000000097048597300000EC300000EC301C76FA864000000
+          1874455874536F667477617265005061696E742E4E455420352E312E381B69EA
+          A8000000B66558496649492A000800000005001A010500010000004A0000001B
+          010500010000005200000028010300010000000200000031010200100000005A
+          00000069870400010000006A0000000000000060000000010000006000000001
+          0000005061696E742E4E455420352E312E380003000090070004000000303233
+          3001A00300010000000100000005A00400010000009400000000000000020001
+          000200040000005239380002000700040000003031303000000000AB80211353
+          9E3828000011524944415478DAED9D0B701BE59DC0F7A1956C4B962C5996E457
+          1CC7719ED8319036A101CAA3B4CC9502074D0F98BE063AB407B992D03425254C
+          43798483030243E963FA005A62DA14EEDA4287B9D2E38692262910923889E3D8
+          4EFC922C5BB665C9926D3D76B7DFAE1C59B2654BB6A595E2FFFF379ECCB7D26A
+          B5DADFFEBFF77EA12FBEFE560A81018DB2E180B20181B20181B20181B20181B2
+          0181B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181
+          B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181B201
+          81B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181B2
+          0181B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181
+          B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181B201
+          81B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181B2
+          0181B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181
+          B20181B20181B20181B20181B20181B20181B20181B20181B20181B20181B201
+          81B2019143B24DEAF0E36B1D2191DE75B2D4135265FB74162139247BBDD1FFF8
+          45BD24B1ED58F9496F7EB64F67119243B2AFB57877AE7691C48E63B623C3DA6C
+          9FCE22248764DF5836FCEDDA4192D8D5643D34A4CBF6E92C427248F61D4B86EE
+          AC7693C4C3272D7F1B28CCF6E92C427248F6DDCB06BE54E921893DCD96BFF6A3
+          ECF49343B2EF5FEEFC97723F49FCD7E992B7FBF4D93E9D45480EC97E6855EFA7
+          ADA324F1DC99E23FF51665FB7416213924FBC93AFB25A67192F8719BE975BB31
+          DBA7B308C921D92F5EDCBD421F24899FB71B5FEB3165FB7416211991AD57F11B
+          4DFE43435A6F984DFD53AF7CA2A3AC8097121D45AF7416A7FE412317DE58EC3F
+          30A09BD3D7012423B23F6BF1EE58ED6AF6A8F79CB63AC6D5297EEAF5CBCE1AD4
+          22493476197E71CE9CE2A76AB481EFADEA5BA60B3DD95CF2BFFD58AD9B8D4C45
+          F66375F6D5FAD05080F9E129DB8994FA3EC5B7AF6857313449BDDEA3FF717B49
+          F253A7C42B8A7DDB57F517A8A866AFFAC1A6B22991EDDF707BB07AFDBC7F8528
+          4A771EC5870A3EFE435EFBA1B45F25E5C954995D9617DCDB603769044F907EA1
+          CDFCAE2B49CC15B0FC1F2FEF88A4FF682F7CBECD92EC1BC4AF550D6DAE18CE53
+          51EE00BDF568853D3E0B111976E4BAADBCB16CDE3F81C8A669E9E613C341DDE1
+          4675F7F14C5C2825C96005ADDE30BA7B8D53AF1679417CB9C3B4BFA728243233
+          ED6CD184F66DEC8AA4FFECC87FA6753649455CF83F96BB3E6D91DA69DE20BDFB
+          94EDB8A760CA3EBCB9CA7BCDBD14939E525C0C05B41FBEAEE9FC2843D74A1932
+          5B1BBFCEE2F9EE4A17C3D06141FC8B53F75C9B352CD209F75CA60DFC6C7D4F24
+          FD5767C19E96D2998E49F28C87D6386BB441725841109F6CB1BC33BDA8A6E991
+          6BB784CD4BD3F85B24DF871B353D4D99BB5C9926E34DAFAF560DDEB1C41D298C
+          8F0C699E3A637505B8E9BBD519469F6DE88DA4DF7315FCF05462D99B8A7D5B6B
+          FB8D1AA9342537506397F1E544F5F6228E2AA4430B3CF3E3B73C3FE51539BE7F
+          AFE93C92D12B9639322E9BA385ED2BFAAEB58D46363B7CAA874F95768F4DADA2
+          5F66F23D52D717491F1ACCDF75626A36CE50E24DE5C3772D1DCA3B3FADE19DDE
+          82A75BADD38B069D8A2AA24374E21C640E4C974DC9BE75871AD5F60B32BE95E8
+          5421BE9FAC77D41505229BA43EF5F419CB9441CCCF5ABD3B56B922E92343793B
+          9ACA63DF25D5B7FB6AFBAF2EF133CC84C313C39A1D4D654161AAE97C462866F9
+          859BA6E265D37C486427322431342EC7F7C799BE6E6947A11E345B5E704F9DA3
+          52EE33218C86A917DBCCF268C784969BCBDC5B6A8722E9A661CDB66315939FD5
+          8476AC70D69B82D157BA47D99D4D65CE692D78352D98553C9B0ED354BCECF28F
+          F6391A36C7FAD61DDAA7B69F54E0D2A511E5BA4BABB581A7EBED7AB9DB84924B
+          DCFFEED1FFB2A3242457D9BE5235F8B5A5C391B75ABCEA7B3FAE9493E23AC3E8
+          83ABFB49132E7A1C52FDDE7EBCFCAC5F33E5F82C255AB970BA4C53F1B2EBDFF8
+          B6BBE2D29E4BEF888BEF0FF66BBA8E2A73F5D282A27DE3579A4776ACEC8F16BA
+          A42EFDAE4BF75C6BC928CFFE7B8DEBD60A6FE4F5B33EEEEE8F9690C48DA5C377
+          560FE938317A84F13045AADFEF4D9BDA405362898AD730622AA7912253649366
+          F7E0D24FF5367C312EBE0FEE533B2E98F8567A20E4A6B2E17B6A06586632004F
+          7BB8479A4BBF5A35F4B9525FE4959E51D53D472AEEAA1EBCA97C24F6B3A4BD4E
+          32FF3F241EFD94F207528033B428FF2B55E8261334897B8AA545566A94A57AAA
+          53645372378BBB72BD7D6A7CFF4ED3754CC96B386F94964D42F0BEE5FD3794FB
+          625FECF2AB4836BD541B8E6C7A8234C9A5EB0D63B1F704E12D876E6FAB45A4E6
+          97534BEED5B46860793593D207A6CB968E4251527CAFBB75D2779094DFAFAA1D
+          A794BC8CF3230B439C1A46F8FECADE4D96F1397DEA407FDEE32DA501213551B3
+          417C0B858C9034C413CAA664DFEECA4FD82FB92DD6B714DFDDB91EDFD919CFD6
+          ABC2CF34D8A3A19C944E9FEAFE63E59E70BA9E1C108D2CAF639314F033C9A622
+          F15DBDA9B7FE96B8F83EF86B75EF6985AEE0BCC8DAE485CAFCE013750E6B3E9F
+          74CFBE3176E789D2AE514D0A474D1552905BB830376B70CF229B9A29BEFFF15B
+          4D4FEE8E976450761E231472BC4E25903F838AD7AA8442155FC849FFEAE4F472
+          5D20D2F1393BC341BA75443312667D616684FC855892F687198FFC8A4F7E657C
+          EED97B21C317A9845976985D363511DF97CBF13D91E548F1FDF75FAB9D391ADF
+          F3946DE2C235BA804176A9E7F842C96844A194D0CB46B934B6799311E2457207
+          7843C43DB91518F9269012DE90744378426CBB4F3314FFFC18478B366EB67224
+          A96C4AF63DB4E4938E8B6F8BF13D26C7772EF6A7CE53F68F1A3A571A522D7173
+          81168FEADEA35571BF9C122BD40B954DC9BE07965DE1ACFBD758DF727CB764FB
+          474F659EB25FBCB87385FE42927DC6A3BA2733B2A9487C576D7034FC5B5C7C1F
+          7E4D633F91EDDF1D0766E33392BA6C6A22BEAF74D6DD1C1FDFAFA89D6714BB08
+          49C970058DDC01DC8C15B41A5D30B6D37B2686024CBB4F7DBE82C68E8498B80A
+          9ABC99950ADA14E4F8DE686FF81215EBFB5063EEF4A766ADE965CB0B91A65745
+          41F2B2A06754F58034C6C5A570D4545978D32B21C4B78BC477FDCD1413E3FBC0
+          CBEABED60C5CC239931DD95A967F6A5DCF8AC2544BFD562FB7FD78B99F4FD7B4
+          F08576AACC7668A93FF53247C3E638DFB911DF5990CDD1C27757F65F63F5CFE9
+          53FFD7A77DAAC532CB94C59459687769F22F20E577CD55BD7537C6FA2E3CF032
+          97EDF8565EB6F8AD6503B7947B9898410EFB28AB614473DE64093A30CE0404BA
+          BC60B27F4D10C437EC869F9C3553591D0849F5CBE4F11247C317A3BEA9C0A8F6
+          D03E756F73A6AFEF2C282DFB7A9B676BAD4B1563BACDCB3DDC6CBBAFD6B5DE34
+          3934F2C160DEF36D253F58ED5CAE9F9C371816C4BDAD256F3B0D890E2C0F68CA
+          439C74CC10276910D0E91BE29C1352F9BDFC2AE74537C6FAD61D7889EB6F57F2
+          82C7A2A8EC0D26DF83ABFB0A62262FBC37A023FE4833E9C1D5CEAB2D9319FBBB
+          FDDAC79A6DA41547EE8C2BCDBE6836301AA61E6BB61E9EB60807516BCEF0E485
+          791C418EEF4D727C9FAF6D6435BE95935D9E1778B6C1116D6B9130FD93C3F0B3
+          B3C5916278AB34C83D3955E14D47E1DE56E9A11052C0DFBD6CF00B659E686640
+          5A62DB8E96D9C7959E9634BF83C8F17DB51CDF93BEB315DF0AC936AB437BEA7A
+          AB751379F25898FA49BBE9CFCEA2E84C84BB960EDC5EE589EEDFD869F845C7C4
+          B37D241FFEBC6DF89B3543F9E7B384733E6E6753E940706A632C73130EE72D9B
+          3A3F5EE258776B7C7CBFAAFC78A812B24961F9F845F64B4D1353893D41FA9933
+          9603837159F16D1543DFA8714737A73FA27D79F1C8B6152EC3F9F98A1F0D6ABE
+          7FB29C9FF67C490123983230957821B2A9487CD75EE35CFB85B8F87EFF579CEB
+          6C1AAF7352322E5B458B5B48165D36310FA9DBAFDA7DCAD6396D709AC4EEB695
+          83D1CD675B8ADF724E9D6B565510D8BDC659797ECAC39B0EDD0B6D96E9CF13E9
+          195ECF266F5925258DB2A9F3E325BDF5B7C4F8F66B0FBEAAE47849C6656FAE70
+          DF593DC8C9256ED3B0E63F4F5B9D891EFFB9AA6464D79AFEE8E6A3A72CFFEF4A
+          B060924D13FADEAABEC8F3062141FCE5B9E2FD3DD317E41049706B93F5992425
+          BDB229D9777FEDB57D6B6F88F5ADFBDBAFB881730B3F782A645636C97B1F5AD3
+          C7CA0FF6BDDBA77BA675C65E91F546FF13F5CEE8E603C76D1FBA132F7248AA6C
+          F7D7F65F6DF5912A1B2F888F9CB2BE3F38FDB610ADAA708AEDE99948F8F84FDA
+          91C6C73ED8AFCCFCB50CCA5E5938F6E8DA5EA346244DACDF74191BBB8CB3F47F
+          AD2A1C7FE1127B7473CB91F2D3237933ED4C7CDFBEC4FDE5256ED2247307A485
+          6D5B46A63EEFAFA18512D5820A6F656453B26FD31BBB14F8A24CC92ED1849E6B
+          E8B1E4092321FAC536F35F922D8051911F7CE993DDD1CDAFFFA3B2672CC9FA1C
+          D759BCF72C1F28E4C4FE71E6BEA315D31E0E5D68702B275B144DBFDDAEC01765
+          44B68EE577AF75341883C341FA9193D663DEE4ABCE1AB9F0FE4F75463737FFBD
+          CA9DC22AD4EBF4FE87D6F615A9C5A36EF5EE9365BEF89112131B5E48C9AD5036
+          2E2FE67101CB8E2CA073C6CBED396DEB4E16A01148CEFCD6E567233D6524DBFF
+          FCFBCBE2F37C694348D42B5E991FDCB9CAB9429F60011D032B55CB15B888F323
+          F66632BEF61D05BE31834B631D7617CC698DF83737B5471E031B0F53371CA889
+          3B4BF951AEC130CB27F26DE0C21B8CA3D357E232B2E1A4E398596491C89E1F8D
+          1BCE95C8035FAE71E6F6C3D5B16FB19458A60EF32235106683A98E7292329B57
+          A7B5B73CBD8096FDF3F59D9167443AFCAA6F7C183739303A5F8CF876F3EC580A
+          9390D4726D9C516E1ADC9C012D7BEFBA9E8BE4DE9213C39AAD310FE353723BCA
+          C24D8C6D930A8D87674624DFB398142DE91E044B3BA0653FBAD6B1D13C46255A
+          53259F16CCDCE44406E2DB2FD06EA9EE9DD0B758C40A85395C358B005AF6032B
+          9C9F299586B4DF71163C11BF349696114CAAA94F8505056A98670352DF7854B9
+          A8A625D3391ED31140CBDE52D37F738534A4FD3F3DBA17DAADB16FE918DE9868
+          DA2F09F1904805459AB4CA18C9B434EE92CBE5742CA0657FBD6AF0CBF2B22ABF
+          E930BCD419B750AD9EE50D399F2DCF15D0B23757B8BF59232D98F4D336D3FEF8
+          C5E58B583EF7CBE0B9025AF6F536CFF6950394F47F8498DFEE8B9B55B8C08ECF
+          DC04B4ECCB4CBEDD6B9DA4B2B5FB84ED60FC9442B32A9C7F21D4B9E60468D933
+          9386C1E91C04652720EDD3467304949D8099DA5D173AE0640BF90666CC33CB0E
+          8B35AC2980B2BDD77F477BF055D6E34CF82E478BA41EBEF84AEB08E064BB6F7B
+          9A0EF8F2CEBCAFEE3EC68CB82879DA064D892A5A9A01AE65844519D31120CA8E
+          A6D3325DF7020265030265030265030265030265030265030265030265030265
+          0302650302650302650302650302650302650302650302650302650302650302
+          6503026503026503026503026503026503026503026503026503026503026503
+          0265030265030265030265030265030265030265030265030265030265030265
+          0302650302650302650302650302650302650302650302650302650302650302
+          650302650302650302650302650302650302B46CC8A06C40A06C40A06C408090
+          8D2809CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA06
+          04CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA
+          0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604
+          CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA06
+          04CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA
+          0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604
+          CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA06
+          04CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA0604CA
+          0604CA0604CA0604CA0604CA0604CA0604CA0604CA06C43F0177A1F3EBFA099C
+          F20000000049454E44AE426082}
+        Stretch = True
+        Visible = False
+      end
       object WelcomeLabel1: TNewStaticText
         Left = 176
         Top = 16
@@ -1184,7 +1340,7 @@ object WizardForm: TWizardForm
         Height = 58
         Anchors = [akLeft, akTop, akRight]
         BevelOuter = bvNone
-        Color = clWindow
+        ParentColor = True
         TabOrder = 1
         DesignSize = (
           497
@@ -1197,43 +1353,157 @@ object WizardForm: TWizardForm
           Anchors = [akTop, akRight]
           Picture.Data = {
             0954506E67496D61676589504E470D0A1A0A0000000D49484452000000370000
-            003708030000009F052274000000017352474200AECE1CE90000000467414D41
-            0000B18F0BFC6105000001D7504C5445FFFFFFFAE7D6F1AE76F8DAC1EFA464F7
-            D3B4EEA05EFEFDFBF6CBA7EE9D58FEFCFAEFA364F4C39AED9952FEFBF9F2B684
-            F7D0AFE4F0F890C4E391C4E4A4CEE8FEFEFEFAE6D5EC9043F8DAC0F3BB8DED94
-            4CFDF3ECEFA160F1B0799CCAE62289C8228AC886BEE1F8D8BEEA8733F5C8A2F2
-            B47FEC9145FAE5D4EC9246EEA05FFEFBF8FAFCFCFDFDFDFCFCFC8FC3E3228AC9
-            86BFE1F5C79FEB852FF0AC72EB8F40F7D2B3EA8937EC944AFEFEFD82BBDF238A
-            C987BFE1EA842FEFA669EE9E5AEB8A38EA8630EB8B3BFBEADB8FC2E2FBFCFC81
-            BBDF88C0E1EB8732F9DCC32289C9F7D2B2F5C9A4F4C196F3B988F0A86BEB8B39
-            F2B480F3BD8FF5C59DF6CDABF8D6B9F9DEC8FDF7F180BADF89C0E2EB8D3BEA89
-            35ED9951EFA15F7FBADE8AC0E2FDF6F0FBEDE1FAE5D3F2B683EB8E3FFBE9DAFC
-            F1E8FEFAF78AC1E2FAE4D2EB8B3AF1AD757DB9DE8BC1E2FCF0E7EC9144EB8C3B
-            F9DDC6F8DBC2F1AD73F4C0947DB8DE8DC2E2FDF9F5EE9B56EC954BFBEADCF4BE
-            91EA85317CB8DEFEFDFCF0AA6FFDF4ECF2B37EFCF1E7FAE2CE8EC2E23493CDF1
-            AF78F3BB8CFDF8F4F9E0CAED974FFCEFE490C3E3238AC8F6D0AFF4C399EA8632
-            FBEDE0F9DFC9F6CAA6EB8D3EFCF0E5F7D1B1FCFDFE64ADD9D8EAF5F8FBFC90C3
-            E259A7D658A7D6976A4558000000097048597300000EC300000EC301C76FA864
-            0000023B4944415478DAED955F48145118C5BFB3195B52B622B377B6720343B6
-            C8AC5516F62522AD207A0BEAD5D7A82C7A11A4D422B08528A296A27A3302699F
-            9308AD087A8B5628F641D6226A4B19849642CBFE8CDF9D3F8BE9CCB8CE4B44FB
-            71B9C3CCE577CFB9E75EEE80FC15FE2A07FCF6C5ADC04F5FDC4ACC2E930B7E97
-            FD2ACC186FD5D36572C1AA699D1F6BF085FB1AE0732DA083F85B009A975E1898
-            208AE023D106E09B16B506A007DE7AAEAF01C85323C6280620B74DCAE9922A86
-            50D03C388A63FCC756BC48001F0AC9AF54E2D603CFBD38252458698CE51E9342
-            C21A0AE7D943EC91D73E54CF3673900A1EDA1309436FAD8AAA5F59CD81836861
-            A5D1F89346E6EA1FECA88751F7156170A4D6BD8F0E3A70ADB9E6864F7F1C94E8
-            C85E0C4F28AAF459432422CF760F38FB4CCA1847592F5ED808DC36BE35993EB9
-            5723E3DB6FB9ADEFE8CBA9FDAF62D96446AE4521231A8B2335966D493B739D2C
-            78279EC0D33D97CD48AC7D3038889D9923979CB82EC62EB6AEDEF2BA0DD9214E
-            C43E47727DB244F2EE7CD01EEFC19BCDE7E9DCF0BE3E0A75D4F5CA282DBD75A4
-            68B21D4666577A111739712F47D43F74B09B28057429AAC9756084DAED967BB7
-            900BF6A7641A57709A13D1AEE294DC838515CE2FE2ACBA864E4E7F92A768B27C
-            CE6F81A21B97684F4962924A7996C7A9C51927834BFA4CE3B84CD29CBE7CBD1B
-            C7F8A0F8D0BB099C15B47CBD036D033AF9E0369DB94E1EE5EAD3AF5EC567C567
-            C5E77FE4F3D0205FF1E6EF47D1EC67A99DBCE0E6939628B7FBBAFCFA57B83987
-            B69D473A0117C30000000049454E44AE426082}
+            00370806000000A8DBD246000000017352474200AECE1CE90000000467414D41
+            0000B18F0BFC6105000000097048597300000EC300000EC301C76FA864000000
+            1874455874536F667477617265005061696E742E4E455420352E312E381B69EA
+            A8000000B66558496649492A000800000005001A010500010000004A0000001B
+            010500010000005200000028010300010000000200000031010200100000005A
+            00000069870400010000006A0000000000000060000000010000006000000001
+            0000005061696E742E4E455420352E312E380003000090070004000000303233
+            3001A00300010000000100000005A00400010000009400000000000000020001
+            000200040000005239380002000700040000003031303000000000AB80211353
+            9E3828000007654944415478DAED99094C944714C7DF7C7BB00B0BCB7DA3EB81
+            8A58AC82E27D1595D6466C4B15AD68C0461BC4AB8A45AD152B5AEF8A89A66A6B
+            D17AB4464DEB5153E315B546D378342516D36A520E0FF00695E5F8A6FF597775
+            31C821A0EE8649DECE9BF9E69BF77EF3DECECC6619D97161AFDA8126B8970517
+            DFC59D560E0BECC4189BC9391F69989F450F4AE557CDD1307033FA7B53EA40BF
+            21503F05DC5B3609D7CA436DAA4BCB39E5DE2B7BD23F3FDA8F927A7B7D84C825
+            01AEA7359C5AC128D05565D28B8D32151497BF7E7002ECF4B476425542CAD37E
+            BB466B4F14124763C9D0001AD7CD7322D404C04558E0BC744AFA3EAE197535E8
+            C4ACAAF3C5EE6523FFEA58BD756EAEE472BA77EC07921FDD7F69704A44E720EC
+            4FE7C4CF6F3F7B8B527EB94A1B4735A7E810FDE7181607B80EBD32B249AD9468
+            5B7C73F275513B3062AB38B1337BA4DE990B95630D183316F3106A12B5098673
+            6B7337D05A579A97CDAF6F486E50C02AE182F42A3A9B120267A8331CDA076726
+            A07BEF89CB4526906E06DD72B818031F83D79C2CA0C4484FD2AA241F8CDF8129
+            73C94117FF67C7397CC195C085FFDD2D99550B3F56C0C6CCD2FC4B009C08C0A2
+            C6831325B9B727CD8BF617036240B90329948A087E6D7A89B16F510D86434124
+            A220B108446C37FA7248A18E721C30B5A42C3476A08B562D164685F10C3567E6
+            D059F48C535729E3F77C6E7E2E166CA65100AE6F9808B2EA1E64BC1F4823C3DD
+            45234522B644A40F9C980C5FB6E3711F78E98DBE78B4BF41FB3A9EF550B78DBA
+            E11CB32884291D4EA2CFDD02521D5C42B80FCB3C5720BA57E0718A31EF6FBABE
+            6152BD01AB3D0AC4EEB72BB18548430486ADC7E071F0EC2074105308641D641A
+            A4088EF502689666E852D2850EEA80BEF6103701080980C442BCADE75F2DE020
+            FFCE88A0F4A3B99479F686E85E06FCCF8C7997A8BE295A094E1CD0BECE4AD239
+            28C845A3206FEC809E90CE818E26562CF601C800EBD54755068941D781729953
+            897F2479B5082549EB4A4CE342CCD195146ECD48E1DEDC932954229A6D9F8DDC
+            95942E4C467A03906F3A5720E65C0A0BA9F54DD14A70850BC3C4CD23C0BCDA6E
+            56626937C7F30ECFC089A5FD03720772DB5C5BEBB749A939E7F44EDA1D4D6874
+            02DA1BAB82137302902F3892CB369F37A5280029B53E295A09EEE6A2B09DE832
+            5801B9D08BDD3F8DD6909CCB4BB53DC7EF75EC33311AED5F2D832C6979196969
+            29E290F8F2700E0150341703723676D1174AD1CA915B14F6C482E96C222EA1E5
+            4A9CB9A32980C7A17FC23391BB89463C1A7978E30E1791E2F4C8B47748B8ADA8
+            34A4F46A458E513349E5D77E0D5E4D7A5EE42CFD224501C8375F28149D8B21B3
+            4B0078A38EE760253827B5443EE6EF9C5E23E1D6A1A2FEAD9D282EDC438CEC8A
+            5DE5088689FB5509C419720BBE78C2A71D90B8F20ACE1F45265350C7BEC4B47A
+            622A2D83A84852BA61B5C663EC3CBCA3A809CE92A2698773D8D60B85A2FB2B3C
+            9C63CCCFAE538A569B7206DC54F68F6F898D451D049BA7D1E5082323E0682AF4
+            7E303A04FD8990582ECBE988F45CA741B348131E371C7D6922EA18A383EE64F6
+            BBCAA3A02A38A18B044A3B94435B2E14886C5D28E62FADC32EFA5C3837AD447B
+            C6B7A6763E1A710E9C109182B9A1A82FC2FE2ED4EFA1FD26EA2C4C924EE22710
+            F144A56FE866E7D85592A4F3FA911E6FFFCF2D557DE79E2D82CA0C482640CEE7
+            9A22B82E89B8F141DDE1D40AA2ADF106EA1BECAC909824403C30E907A80BC4F7
+            412149DFD1E38BB3A142E63918848958023E56C299A1EA90E813BAE8394E92C6
+            F938C674AAE9109FD233E0E9A5D3FA026A95A2484F76FB619988A62945AFAE1E
+            4BA580AC335C4B71719EDA9698C47025223FC83859E625B3F65FA5416D5C28AA
+            9D8BB8494C834DBDE6EDB42205C964BCB08BCAAF5DEC0F77D6CAC486E806A55E
+            D1868F10D1DD551DDCEA53F9A6EDCB1CA71AF5C7D94A527EC6987AC12901178F
+            BCC87C881F7509DB73E9C83F45B465B4810687E8E7C2D417B0A3D6276CE34ADF
+            F6B17251E1EE078797C9A5D98782F11B2650D365F451A7A819BD30DD716AA062
+            4963D8955E3872E266B2758CC194F0A515324DFF399FB20B8C8F0DE0BE392AC2
+            631254B1F379BA7EB20F3790C02C18CCE2C6E24463D6FE871577F3481316434A
+            EFE00CF44F7A5EE4EAAA5BD2B85E91ABAE885FE2137B7B8FC69B69D8E25BBB25
+            1F24C9C93D0FF6FD61FF1C86A4432F843E1C7AB265976C4838A852DEAAF88687
+            9B3BD097A6F4F779176A1AA9B411EE938FA870508BAD4C5FD7B9EA5A2C69D9F0
+            916312A9FDDBD0C850252DEFABC01D93FA491E2D36B97EBCD385498A5B585C45
+            75ABFE5A478EA91DC9907E8C7CA422C568CDD98A61018FC82B2C8A542DBA7F88
+            C73F3576D41A3572163807A57460F81B9E6B9322FD8A7D9CD5E210171B8BBEA6
+            55B789C8093F27F7F0A7C9DDFD9E18AF8D63360187224FE929E0FC6BFB6A8395
+            464F4BBB8E9C5DC351535ADA68E4EC1A8E9AD2D2462367D770D49496361A39BB
+            86A3A6B4B4D1C8D9351C35A5A58D46CEAEE1A8292D6D3472C2CFC820678A0CD4
+            3DFD47C6EC4155FFD03CD16B7A5E0BFD4C6E119DCEB9DFB86959DB771AB134CE
+            7F05B6549AE06CB5D835DCFF41CF90A123E252D40000000049454E44AE426082}
+          Stretch = True
+        end
+        object InnerImageDark: TImage
+          Left = 414
+          Top = 3
+          Width = 55
+          Height = 55
+          Anchors = [akTop, akRight]
+          Picture.Data = {
+            0954506E67496D61676589504E470D0A1A0A0000000D49484452000000370000
+            00370806000000A8DBD246000000017352474200AECE1CE90000000467414D41
+            0000B18F0BFC6105000000097048597300000EC300000EC301C76FA864000000
+            1874455874536F667477617265005061696E742E4E455420352E312E381B69EA
+            A8000000B66558496649492A000800000005001A010500010000004A0000001B
+            010500010000005200000028010300010000000200000031010200100000005A
+            00000069870400010000006A0000000000000060000000010000006000000001
+            0000005061696E742E4E455420352E312E380003000090070004000000303233
+            3001A00300010000000100000005A00400010000009400000000000000020001
+            000200040000005239380002000700040000003031303000000000AB80211353
+            9E3828000007714944415478DAED5909709345147EFBA7092D49539AA6698142
+            6329D2324C2B82CA288728481505E59016880E650667003944A08895E2002A2D
+            2ACE88E089CA218C1CA252611C7404471D0566B0220EA0E58A4DDA94A3E99134
+            F9D76FD3A4A6D813522499EEE465DFDBDD7FF77DFBBD7FF765C228840BFBBF1D
+            E80077A3C099EED0D1AB8F26F4678C2DE29C6719971751A553FEBF710406DCB3
+            C30D9433B2EB68A8CF00DCFD4109AE578CCA533B5D9CCE5DAEAD6F5F9ED19566
+            0E899D02E66602DC3DFEE0540A46095D941EDDEE90C96A77DD7CE004B01FE7A7
+            08350CE2CADBF737AD3B584A1CC62B63BAD3F441FA5950A701DC401FB8584D18
+            7D90D993EE346AC4ACCAA3D5B1B599A70635BD32E7FFAA6E375D29DC4072E5A5
+            1B062E0CECEC870B0B38F1A35B0FDB68E167667A7F722265A4463D8F619900D7
+            6FF0DA13A40A93688B2991E2B5AA4E8CD8EB9CD84FBB23466C5C193DDB88E79F
+            C43CC08256C6BCB8B8FF7216D81B9C678AB8B5E08980026C145C8F28251D5E98
+            0A67E87638F405167F0ACD9F1F3C5DE10132C8A829808B63E163EF370F5929FB
+            2E3D4528A5388CDF8E29CF55BA98A9E0D260BE2FE9C9950EB57E492BFC588335
+            1639CFFCC6ADF95349AEBADC7EE044993D444FCB32BA89016381723B6232070C
+            BEE67988B177518D82433D3CE125B181606C27DACED6CA3462DB99E89AAF6DB1
+            232597436C8C12E3196ACEBCD4F9744BEA83549292C1BDFD05F5000B4C016190
+            35D7B1765C02650DD00963A144EC15C0D80007E6C097ADE81E0A2F0D6833C15E
+            0FBB047D77FF62EB6C79E7B43ED5C5A54368D3F98034074E7FEA5B664BBE576C
+            D31A742F7414FF4A8108D166AF0271FAEDC8BE45842188616F63F07478B61F3A
+            10532A6403643EA402FE0E8673456B7F8FA1639735FDD0D617122D0042BA4326
+            400CFEF35BFA3E4496940C4ADB3597CC69E3A8ACD730D19C8FB9168341B2E64F
+            41885E090C387141C7478691A69382B4E10A32E004D4436E4FE8ECC18ACD2E84
+            DCE7BFFBA86A2163D154E89239FD6051919D7726BB4BA24A4805C45AA3244BB5
+            52EF2626D8EC733573E9BBE63271C40020078362CED5909CEB0DD106E04A57A6
+            89CCA3BB77B7A3FDC46727A2BFDF55E02A60FE0CB90829F7D6FE7A79B58B8E6C
+            FC33E6E2CFE59A69B0DF6F0C9C674E7CCC69E399ADD75011A2ABF18EE7388B8B
+            AE39441B802B5B95F6299A8C7E80B4746DF9A7C31F24E7F2EA3DE7A33EDF7D3E
+            3A03F65EDFA0FAB0DC39C7CF2389CCE908D1A4A1C27A19FBF01CAE09AA3B45DB
+            16A20D995B9556A770CF89888A4BB0BA10673A9802F074B43F75157365304C30
+            CEE3898B5C30C6A95A4CED86E190195DA852D296621D9DADEAF4261E9DD92473
+            BE39A19BD3C773CF3BC8B91720DEC136866803706A954471DE772E2A5C42D6A1
+            A4E1C96ACA1C102346DE8953E5008689FCAA061209B1C1173D16DF0EC974B939
+            5F7F22924A65ADE77D73B81973C89212AF62341C9E814996E119454BE07C217A
+            217D222B4F1A2C42F425742DF530D886106D36E48CC854BE9C91848345D5036B
+            FE88A6CEF0601268CD818EB39B8F467B36640297E515603A7713183A50A27D1C
+            6D7982758CD140577BFD6EF42A68149C27A591D885F409644B120731ADC457AE
+            535C13F9A6565DF44D828B8E9068CF8C644A890B17F7C041C114D61B83FA38D6
+            DF81FA31D8B7A12EC2242B48FC04229E5D6C577DF4C61F06E99253F109D51DFF
+            4D9646DFB9FF7888B04E9F2800920720E7B922442DABB38857DBDB0E4EA520DA
+            6C32D2B0DE910A894902480C261D8FDA2A63431592F41ED525CE46B7CCCF6210
+            2662D3F0F52AFAC7FC54A63EF8F15F3A758DACF80E63FAB77489C79FF8AA3E14
+            99D7A7863AE300C75C2A8D687E095F4B4BF21E2111A66D06972412E7797D4454
+            2087A4AE90E9B2CC6B967C69A6076ED5D28814ADC824E6C3C7A8B74FEA2AC465
+            3FCC60A75B348EE1F0795DAD9B8FDE5AACFBF3DB52AD60774773E0C05CC38CBA
+            059DD765DDD2DFD7092E0CE04CD8B68D55F851376DEB393A70B282364D35D2A8
+            D4A85C2CF502D651BDF86B577EA64A35A18BD2BD735262B93C20BAAAB742A284
+            7DE6C86FB69DD58958FA8E02547C618C75A592E563AE0D9CC84C363F61F4C486
+            D32DD382DD17E884D5E1E97B03F9E6E481314F435D863DD42F3EDA8DCA9CCA22
+            AC58141126670F8AA9AC8A0DAFA543A59164AE56AD85234F37C55C5B755F185F
+            1773CD15F14B7CD610C3543C99E7922979C19104A4588AF358BF1BD63F82212B
+            A097427F1CFA6CDF291948705025F3B287030F2E77643CCD1D1EF730D4BC1A37
+            1B38EF708212F7991576545BE76A6BF18565E099435AA44AEC4B59290A2A188A
+            1C13F79CB92AECC3DC63DDB478DB6DD85C4573BB7E5333C7C2D5D4F3AD22D2BB
+            6C8A472E7DE1EE63F99E8E59887EBB1C3E11EFDEB6F666AD5D99F381936457A1
+            AEF88775863FF6DB953557C4252E52AAA896763D2898137EC6FD5E4886E37BEB
+            176F8D6341010E458E17E02037BAB47B58863473210D8E3AC23248990B6970D4
+            119641CA5C4883A38EB00C52E6421A1C758465903217D2E0A8232C8394B99006
+            471D6119A4CC093FD5A527495D76AAFE5F188F034DFE4353A7B7D4DF1ADDAE4F
+            2648FB86656B9F69C7D23EFF150453E90017AC25A4C1FD0312C399A1223ED74E
+            0000000049454E44AE426082}
           Stretch = True
+          Visible = False
         end
         object PageNameLabel: TNewStaticText
           Left = 24
@@ -1260,8 +1530,6 @@ object WizardForm: TWizardForm
       end
     end
     object FinishedPage: TNewNotebookPage
-      Color = clWindow
-      ParentColor = False
       DesignSize = (
         496
         314)

+ 9 - 2
Projects/Src/IDE.Wizard.WizardForm.pas

@@ -140,6 +140,8 @@ type
     AppRegistryMinVerCheck: TCheckBox;
     AppRegistryMinVerEdit: TEdit;
     AppRegistryMinVerDocImage: TImage;
+    WelcomeImageDark: TImage;
+    InnerImageDark: TImage;
     procedure FormCreate(Sender: TObject);
     procedure FormShow(Sender: TObject);
     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
@@ -298,6 +300,9 @@ begin
   FLanguages.Insert(0, LanguagesDefaultIsl);
 
   InitFormFont(Self);
+  if not InitFormTheme(Self) then
+    OuterNotebook.Color := InitFormThemeGetBkColor(True);
+
   if Font.Name = 'Segoe UI' then begin
     { See Setup.WizardForm.pas }
     for I := 0 to OuterNotebook.PageCount-1 do
@@ -309,8 +314,6 @@ begin
   if FontExists('Verdana') then
     WelcomeLabel1.Font.Name := 'Verdana';
 
-  OuterNotebook.Color := clWindow;
-
   MakeBold(PageNameLabel);
   MakeBold(RequiredLabel1);
   MakeBold(AppNameLabel);
@@ -324,6 +327,10 @@ begin
   MakeBold(PrivilegesRequiredLabel);
   MakeBold(LanguagesLabel);
 
+  if InitFormThemeIsDark then begin
+    WelcomeImage.Picture := WelcomeImageDark.Picture;
+    InnerImage.Picture := InnerImageDark.Picture;
+  end;
   FinishedImage.Picture := WelcomeImage.Picture;
 
   RequiredLabel2.Left := RequiredLabel1.Left + RequiredLabel1.Width;

+ 7 - 2
Projects/Src/Shared.TaskDialogFunc.pas

@@ -2,7 +2,7 @@ unit Shared.TaskDialogFunc;
 
 {
   Inno Setup
-  Copyright (C) 1997-2020 Jordan Russell
+  Copyright (C) 1997-2025 Jordan Russell
   Portions by Martijn Laan
   For conditions of distribution and use, see LICENSE.TXT.
 
@@ -19,7 +19,7 @@ function TaskDialogMsgBox(const Icon, Instruction, Text, Caption: String; const
 implementation
 
 uses
-  Classes, StrUtils, Math, Forms, Dialogs, SysUtils,
+  Classes, StrUtils, Math, Forms, Dialogs, SysUtils, Themes,
   Commctrl, Shared.CommonFunc, {$IFDEF SETUPPROJ} Setup.InstFunc, {$ENDIF} PathFunc;
 
 var
@@ -81,9 +81,14 @@ begin
       TriggerMessageBoxCallbackFunc(TriggerMessageBoxCallbackFuncFlags, False);
       ActiveWindow := GetActiveWindow;
       WindowList := DisableTaskWindows(Config.hwndParent);
+      { Temporarily clear SystemHooks to stop it from breaking the title bar. Does not make it dark.
+        Also see BrowseFunc's NewGetOpenOrSaveFileName. }
+      const SaveHooks = TStyleManager.SystemHooks;
+      TStyleManager.SystemHooks := [];
       try
         Result := TaskDialogIndirectFunc(Config, @ModalResult, nil, pfVerificationFlagChecked) = S_OK;
       finally
+        TStyleManager.SystemHooks := SaveHooks;
         EnableTaskWindows(WindowList);
         SetActiveWindow(ActiveWindow);
         TriggerMessageBoxCallbackFunc(TriggerMessageBoxCallbackFuncFlags, True);

+ 1 - 1
whatsnew.htm

@@ -199,7 +199,7 @@ Source: "https://jrsoftware.org/download.php/iscrypt.dll?dontcount=1"; DestName:
     <ul>
       <li>The <i>Find in Files</i> result list will now update its line numbers when you add or delete lines.</li>
       <li>The <i>Highlight occurrences of current word</i> option (which is disabled by default) no longer highlights a section's directive names, parameter names, or Pascal keywords. The <i>Highlight occurrences of current selection</i> option (which is enabled by default) still does.</li>
-      <li>Added dark mode support to the status bar on all versions of Windows.</li>
+      <li>Improved dark mode support.</li>
     </ul>
   </li>
   <li><tt>[Files]</tt> section parameter <tt>Excludes</tt> can now be combined with the <tt>external</tt> flag.</li>