FormBackgroundStyleHook.pas 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. unit FormBackgroundStyleHook;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Style hook for custom form backgrounds
  8. }
  9. interface
  10. uses
  11. Vcl.Forms, Vcl.Controls, Vcl.Graphics {$IFDEF VCLSTYLES}, System.Classes, BitmapImage {$ENDIF};
  12. type
  13. {$IFDEF VCLSTYLES}
  14. TGraphicTargetNotifier = class(TComponent)
  15. protected
  16. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  17. end;
  18. {$ENDIF}
  19. TFormBackgroundStyleHook = class(TFormStyleHook)
  20. {$IFDEF VCLSTYLES}
  21. private
  22. class constructor Create;
  23. class destructor Destroy;
  24. class var FBitmapImageImpl: TBitmapImageImplementation;
  25. class var FBitmapImageImplInitialized: Boolean;
  26. class var FGraphic: TGraphic;
  27. {$ENDIF}
  28. class var FBackColor: TColor;
  29. class var FCenter: Boolean;
  30. class var FGraphicTarget: TControl;
  31. {$IFDEF VCLSTYLES}
  32. class var FGraphicTargetNotifier: TGraphicTargetNotifier;
  33. {$ENDIF}
  34. class var FOpacity: Byte;
  35. class var FStretch: Boolean;
  36. class procedure SetGraphic(Value: TGraphic); static;
  37. class procedure SetGraphicTarget(Value: TControl); static;
  38. {$IFDEF VCLSTYLES}
  39. protected
  40. procedure PaintBackground(Canvas: TCanvas); override;
  41. {$ENDIF}
  42. public
  43. class property BackColor: TColor write FBackColor;
  44. class property Center: Boolean write FCenter;
  45. class property Graphic: TGraphic write SetGraphic;
  46. class property GraphicTarget: TControl write SetGraphicTarget;
  47. class property Opacity: Byte write FOpacity;
  48. class property Stretch: Boolean write FStretch;
  49. end;
  50. implementation
  51. {$IFDEF VCLSTYLES}
  52. uses
  53. System.SysUtils;
  54. { TGraphicTargetNotifier }
  55. procedure TGraphicTargetNotifier.Notification(AComponent: TComponent; Operation: TOperation);
  56. begin
  57. inherited;
  58. if (Operation = opRemove) and (AComponent = TFormBackgroundStyleHook.FGraphicTarget) then
  59. TFormBackgroundStyleHook.FGraphicTarget := nil;
  60. end;
  61. { TFormBackgroundStyleHook }
  62. class constructor TFormBackgroundStyleHook.Create;
  63. begin
  64. FBackColor := clNone;
  65. FGraphicTargetNotifier := TGraphicTargetNotifier.Create(nil);
  66. end;
  67. class destructor TFormBackgroundStyleHook.Destroy;
  68. begin
  69. if FBitmapImageImplInitialized then
  70. FBitmapImageImpl.DeInit;
  71. FGraphic.Free;
  72. FGraphicTargetNotifier.Free;
  73. end;
  74. procedure TFormBackgroundStyleHook.PaintBackground(Canvas: TCanvas);
  75. begin
  76. var R := Rect(0, 0, Control.ClientWidth, Control.ClientHeight);
  77. if (FGraphicTarget = Control) and (FBitmapImageImplInitialized or (FGraphic <> nil)) then begin
  78. if not FBitmapImageImplInitialized then begin
  79. FBitmapImageImpl.Init(Control);
  80. FBitmapImageImpl.SetGraphic(FGraphic);
  81. FreeAndNil(FGraphic);
  82. FBitmapImageImplInitialized := True;
  83. end;
  84. FBitmapImageImpl.BackColor := FBackColor;
  85. FBitmapImageImpl.Center := FCenter;
  86. FBitmapImageImpl.Opacity := FOpacity;
  87. FBitmapImageImpl.Stretch := FStretch;
  88. FBitmapImageImpl.Paint(Control, Canvas, R);
  89. end else if (FBackColor <> clNone) and (FBackColor <> clWindow) then begin
  90. Canvas.Brush.Color := TBitmapImageImplementation.AdjustColorForStyle(Control, FBackColor);
  91. Canvas.FillRect(R);
  92. end else
  93. inherited;
  94. end;
  95. {$ENDIF}
  96. class procedure TFormBackgroundStyleHook.SetGraphic(Value: TGraphic);
  97. begin
  98. {$IFDEF VCLSTYLES}
  99. if FBitmapImageImplInitialized then begin
  100. FBitmapImageImpl.DeInit;
  101. FBitmapImageImplInitialized := False;
  102. end;
  103. if FGraphic <> nil then
  104. FreeAndNil(FGraphic);
  105. if Value <> nil then begin
  106. FGraphic := TGraphicClass(Value.ClassType).Create;
  107. FGraphic.Assign(Value);
  108. end;
  109. {$ENDIF}
  110. end;
  111. class procedure TFormBackgroundStyleHook.SetGraphicTarget(Value: TControl);
  112. begin
  113. {$IFDEF VCLSTYLES}
  114. if FGraphicTarget <> nil then
  115. FGraphicTarget.RemoveFreeNotification(FGraphicTargetNotifier);
  116. FGraphicTarget := Value;
  117. if FGraphicTarget <> nil then
  118. FGraphicTarget.FreeNotification(FGraphicTargetNotifier);
  119. {$ENDIF}
  120. end;
  121. end.