Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
728b580
Add test style hook for custom backgrounds.
martijnlaan Oct 31, 2025
70a3520
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 4, 2025
5227c55
Make the hook use TBitmapImageImplementation so it can paint images a…
martijnlaan Nov 4, 2025
fff9135
Add missing ParentBackground properties.
martijnlaan Nov 4, 2025
58f0284
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 5, 2025
5eb30ab
Improve hook + make it support Setup.
martijnlaan Nov 5, 2025
fbe2cc6
Add WizardBackColor and WizardBackColorDynamicDark directives.
martijnlaan Nov 5, 2025
e15344e
Improve hook to not keep a reference but make a temporary copy instead.
martijnlaan Nov 5, 2025
cae60fc
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 5, 2025
13b1242
Add support for empty bitmaps.
martijnlaan Nov 5, 2025
46b819d
Add support for not having wizard images. Does not change layout.
martijnlaan Nov 5, 2025
4096d37
Cleanup.
martijnlaan Nov 5, 2025
569e84f
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 5, 2025
75bd74c
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 6, 2025
1b07cd5
Enable unstyled light buttons when auto-using the windows11 style. (T…
martijnlaan Nov 6, 2025
077d20e
Add WizardBackImage and WizardBackImageDynamicDark directives.
martijnlaan Nov 6, 2025
0f7e98c
Fix for 46b819d6.
martijnlaan Nov 6, 2025
31598ef
Adjust clWindow/clBtnFace also if only BackColor is used.
martijnlaan Nov 6, 2025
225cda7
Automatically stop using built-in wizard images if a back image is sp…
martijnlaan Nov 6, 2025
b355bfd
Bevel tweaks.
martijnlaan Nov 6, 2025
244dddc
Improve hook.
martijnlaan Nov 6, 2025
b46eee1
Add smart WizardBackColor(DynamicDark) defaults.
martijnlaan Nov 6, 2025
3720a28
Cleanup.
martijnlaan Nov 6, 2025
8b2ab69
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 10, 2025
9faad06
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 10, 2025
7b322f5
Add transparency support to TNewCheckListBox when it's styled and in …
martijnlaan Nov 10, 2025
bc962e6
Improve scroll handling.
martijnlaan Nov 10, 2025
409407d
Whitespace / semicolon cleanup.
martijnlaan Nov 10, 2025
baf1000
Improve scroll handling some more.
martijnlaan Nov 10, 2025
5b4443e
Fix warning.
martijnlaan Nov 10, 2025
9c167b6
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 12, 2025
297c0a4
Implement opacity handling for back image.
martijnlaan Nov 12, 2025
c36442e
Improve smart defaults from b46eee19.
martijnlaan Nov 12, 2025
10c97ff
Add separate WizardBackImageOpacity because sharing it with the regul…
martijnlaan Nov 12, 2025
d117466
Update more existing topics.
martijnlaan Nov 12, 2025
44bac2d
Add WizardBackImageFile sizes. Rest of topic todo later.
martijnlaan Nov 12, 2025
343772e
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 13, 2025
91f47f2
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 13, 2025
96c5907
Add documentation. Still have to double-check for typos and completen…
martijnlaan Nov 13, 2025
9e1e2ad
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 13, 2025
9611501
Add more documentation + make clWindow as background color work better.
martijnlaan Nov 13, 2025
1ecc166
Fix typo (there will probably be more).
martijnlaan Nov 13, 2025
96efa2c
Add extra info.
martijnlaan Nov 13, 2025
9efaf29
Mini cleanup.
martijnlaan Nov 14, 2025
b1951c8
Add comment.
martijnlaan Nov 14, 2025
049e68a
Add WizardBackColor support to Uninstall. This requires a bump of Uni…
martijnlaan Nov 14, 2025
d5baa96
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 14, 2025
8a3ccf9
Fix BeveledLabel custom back color.
martijnlaan Nov 14, 2025
5cdcf39
Clarify.
martijnlaan Nov 14, 2025
ee29143
Add extra info.
martijnlaan Nov 14, 2025
a674b48
Add example use cases.
martijnlaan Nov 14, 2025
d92ac33
Improve one of the examples.
martijnlaan Nov 14, 2025
711b420
Fix dynamic WizardBackColor support for Uninstall.
martijnlaan Nov 14, 2025
21a54e8
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 14, 2025
948850c
Update whatsnew + fix typo in help.
martijnlaan Nov 14, 2025
958198e
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 15, 2025
ea8b93c
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 15, 2025
32c93bb
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 15, 2025
1777ff5
Update for new directives.
martijnlaan Nov 15, 2025
afe15e0
Changing UninstallLogID will prevent Setup from appending to an exist…
martijnlaan Nov 15, 2025
1df6854
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 15, 2025
1637c90
Add workaround for clBack vs TUninstallLogHeader.
martijnlaan Nov 15, 2025
face993
Update for MainPanel's ParentBackground being dynamic now.
martijnlaan Nov 15, 2025
bb7effe
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 16, 2025
53230cd
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 17, 2025
d2debe3
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 18, 2025
c9e4e6e
Deal with clBack vs TUninstallLogHeader in the proper way.
martijnlaan Nov 18, 2025
da0b072
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 18, 2025
8c76bbb
Up to 1054 on branch. Can/should be reverted if there's no release be…
martijnlaan Nov 18, 2025
b0323e1
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 19, 2025
de1ee09
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 19, 2025
f9dc122
Update.
martijnlaan Nov 19, 2025
c53c066
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 19, 2025
a1121b0
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 22, 2025
a4dcbec
Allow [Code] to update or remove the wizard background image (but not…
martijnlaan Nov 22, 2025
5c6c462
ROPS update for previous.
martijnlaan Nov 22, 2025
3e59a9c
Add WizardSetBackImage documentation & examples + finishing touches.
martijnlaan Nov 22, 2025
8c10e4c
Am I crazy or is WizardImageStretch=no help wrong? Unrelated to branc…
martijnlaan Nov 22, 2025
487e955
Tweak.
martijnlaan Nov 22, 2025
58a4c14
Whitespace.
martijnlaan Nov 23, 2025
50fd30e
Clarify.
martijnlaan Nov 23, 2025
6e42428
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 24, 2025
eebe7ab
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 24, 2025
084b526
Fix 6.6.1 release date
martijnlaan Nov 24, 2025
df006f0
Merge branch 'main' into FormBackgroundStyleHook
martijnlaan Nov 24, 2025
9458262
VCL Styles has this 'CN_CTLCOLORMSGBOX..CN_CTLCOLORSTATIC' check ever…
martijnlaan Nov 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 41 additions & 29 deletions Components/BitmapImage.pas
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ TBitmapImageImplementation = record
procedure Init(const AControl: TControl; const AAutoSizeExtraWidth: Integer = 0;
const AAutoSizeExtraHeight: Integer = 0);
procedure DeInit;
class function AdjustColorForStyle(const Control: TControl; const Color: TColor): TColor; static;
function GetInitializeSize(const AscendingTrySizes: array of Integer): Integer;
function InitializeFromIcon(const Instance: HINST; const Name: PChar; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
function InitializeFromStockIcon(const Siid: SHSTOCKICONID; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
Expand Down Expand Up @@ -151,6 +152,23 @@ procedure TBitmapImageImplementation.DeInit;
FreeAndNil(Bitmap);
end;

class function TBitmapImageImplementation.AdjustColorForStyle(const Control: TControl;
const Color: TColor): TColor;
begin
Result := Color;
if (Result = clBtnFace) or (Result = clWindow) then begin
var LStyle := StyleServices(Control);
if not LStyle.Enabled or LStyle.IsSystemStyle then
LStyle := nil;
if LStyle <> nil then begin
if Result = clBtnFace then
Result := LStyle.GetStyleColor(scPanel)
else
Result := LStyle.GetStyleColor(scWindow);
end;
end;
end;

function TBitmapImageImplementation.GetInitializeSize(const AscendingTrySizes: array of Integer): Integer;
begin
{ Find the largest regular icon size smaller than the scaled image }
Expand Down Expand Up @@ -344,7 +362,7 @@ procedure TBitmapImageImplementation.Paint(const Sender: TObject; const Canvas:

var W, H: Integer;
var Bmp: TBitmap;
if Stretch then begin
if Stretch and not Bitmap.Empty then begin
W := R.Width;
H := R.Height;
Bmp := StretchedBitmap;
Expand Down Expand Up @@ -376,17 +394,8 @@ procedure TBitmapImageImplementation.Paint(const Sender: TObject; const Canvas:

if (BackColor <> clNone) and (Is32Bit or (Bmp.Width < FControl.Width) or (Bmp.Height < FControl.Height)) then begin
var BrushColor := BackColor;
if ((BrushColor = clBtnFace) or (BrushColor = clWindow)) and (Sender is TControl) then begin
var LStyle := StyleServices(TControl(Sender));
if not LStyle.Enabled or LStyle.IsSystemStyle then
LStyle := nil;
if LStyle <> nil then begin
if BrushColor = clBtnFace then
BrushColor := LStyle.GetStyleColor(scPanel)
else
BrushColor := LStyle.GetStyleColor(scWindow);
end;
end;
if Sender is TControl then
BrushColor := AdjustColorForStyle(TControl(Sender), BrushColor);
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := BrushColor;
Canvas.FillRect(R);
Expand All @@ -398,24 +407,27 @@ procedure TBitmapImageImplementation.Paint(const Sender: TObject; const Canvas:
Canvas.Rectangle(0, 0, FControl.Width, FControl.Height);
end;

var X := R.Left;
var Y := R.Top;
if Center then begin
Inc(X, (R.Width - W) div 2);
if X < 0 then
X := 0;
Inc(Y, (R.Height - H) div 2);
if Y < 0 then
Y := 0;
end;

if not Is32bit and (ReplaceColor <> clNone) and (ReplaceWithColor <> clNone) then begin
Canvas.Brush.Color := ReplaceWithColor;
Canvas.BrushCopy(Rect(X, Y, X + W, Y + H), Bmp, Rect(0, 0, Bmp.Width, Bmp.Height), ReplaceColor);
end else if Opacity <> 255 then
Canvas.Draw(X, Y, Bmp, Opacity)
else
Canvas.Draw(X, Y, Bmp);
if not Bmp.Empty then begin
var X := R.Left;
var Y := R.Top;
if Center then begin
Inc(X, (R.Width - W) div 2);
if X < 0 then
X := 0;
Inc(Y, (R.Height - H) div 2);
if Y < 0 then
Y := 0;
end;

if not Is32bit and (ReplaceColor <> clNone) and (ReplaceWithColor <> clNone) then begin
Canvas.Brush.Color := ReplaceWithColor;
Canvas.BrushCopy(Rect(X, Y, X + W, Y + H), Bmp, Rect(0, 0, Bmp.Width, Bmp.Height), ReplaceColor);
end else if Opacity <> 255 then
Canvas.Draw(X, Y, Bmp, Opacity)
else
Canvas.Draw(X, Y, Bmp);
end;

if Assigned(OnPaint) then
OnPaint(Sender, Canvas, R);
Expand Down
108 changes: 108 additions & 0 deletions Components/FormBackgroundStyleHook.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
unit FormBackgroundStyleHook;

{
Inno Setup
Copyright (C) 1997-2025 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.

Style hook for custom form backgrounds
}

interface

uses
Vcl.Forms, Vcl.Controls, Vcl.Graphics {$IFDEF VCLSTYLES}, BitmapImage {$ENDIF};

type
TFormBackgroundStyleHook = class(TFormStyleHook)
{$IFDEF VCLSTYLES}
private
class constructor Create;
class destructor Destroy;
class var FBitmapImageImpl: TBitmapImageImplementation;
class var FBitmapImageImplInitialized: Boolean;
class var FGraphic: TGraphic;
{$ENDIF}
class var FBackColor: TColor;
class var FCenter: Boolean;
class var FGraphicTarget: TControl;
class var FOpacity: Byte;
class var FStretch: Boolean;
class procedure SetGraphic(Value: TGraphic); static;
{$IFDEF VCLSTYLES}
protected
procedure PaintBackground(Canvas: TCanvas); override;
{$ENDIF}
public
class property BackColor: TColor write FBackColor;
class property Center: Boolean write FCenter;
class property Graphic: TGraphic write SetGraphic;
class property GraphicTarget: TControl write FGraphicTarget;
class property Opacity: Byte write FOpacity;
class property Stretch: Boolean write FStretch;
end;

implementation

{$IFDEF VCLSTYLES}

uses
System.Classes, System.SysUtils;

{ TFormBackgroundStyleHook }

class constructor TFormBackgroundStyleHook.Create;
begin
FBackColor := clNone;
end;

class destructor TFormBackgroundStyleHook.Destroy;
begin
if FBitmapImageImplInitialized then
FBitmapImageImpl.DeInit;
FGraphic.Free;
end;

procedure TFormBackgroundStyleHook.PaintBackground(Canvas: TCanvas);
begin
var R := Rect(0, 0, Control.ClientWidth, Control.ClientHeight);

if (FGraphicTarget = Control) and (FBitmapImageImplInitialized or (FGraphic <> nil)) then begin
if not FBitmapImageImplInitialized then begin
FBitmapImageImpl.Init(Control);
FBitmapImageImpl.SetGraphic(FGraphic);
FreeAndNil(FGraphic);
FBitmapImageImplInitialized := True;
end;
FBitmapImageImpl.BackColor := FBackColor;
FBitmapImageImpl.Center := FCenter;
FBitmapImageImpl.Opacity := FOpacity;
FBitmapImageImpl.Stretch := FStretch;
FBitmapImageImpl.Paint(Control, Canvas, R);
end else if (FBackColor <> clNone) and (FBackColor <> clWindow) then begin
Canvas.Brush.Color := TBitmapImageImplementation.AdjustColorForStyle(Control, FBackColor);
Canvas.FillRect(R);
end else
inherited;
end;

{$ENDIF}

class procedure TFormBackgroundStyleHook.SetGraphic(Value: TGraphic);
begin
{$IFDEF VCLSTYLES}
if FBitmapImageImplInitialized then begin
FBitmapImageImpl.DeInit;
FBitmapImageImplInitialized := False;
end;
if FGraphic <> nil then
FreeAndNil(FGraphic);
if Value <> nil then begin
FGraphic := TGraphicClass(Value.ClassType).Create;
FGraphic.Assign(Value);
end;
{$ENDIF}
end;

end.
Loading