BitmapButton.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. unit BitmapButton;
  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. A TImage-like component for bitmaps and png files without the TPicture bloat and
  8. which is actually a button with a focus rectangle when focused - in
  9. other words: an accessible TImage
  10. Also supports other TGraphic types which can be assigned to a TBitmap
  11. Make sure to set the Caption property, even if it isn't visible
  12. Also see TBitmapImage which is the TGraphicControl version
  13. }
  14. interface
  15. uses
  16. Windows, Messages, ShellAPI, Controls, Graphics, Classes, Imaging.pngimage,
  17. BitmapImage;
  18. type
  19. TBitmapButton = class(TCustomControl)
  20. private
  21. FFocusBorderWidthHeight: Integer;
  22. FImpl: TBitmapImageImplementation;
  23. procedure SetBackColor(Value: TColor);
  24. procedure SetBitmap(Value: TBitmap);
  25. procedure SetCenter(Value: Boolean);
  26. procedure SetGraphic(Value: TGraphic);
  27. procedure SetPngImage(Value: TPngImage);
  28. procedure SetReplaceColor(Value: TColor);
  29. procedure SetReplaceWithColor(Value: TColor);
  30. procedure SetStretch(Value: Boolean);
  31. procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  32. procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  33. procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  34. protected
  35. procedure CreateParams(var Params: TCreateParams); override;
  36. function GetPalette: HPALETTE; override;
  37. procedure Paint; override;
  38. procedure SetAutoSize(Value: Boolean); override;
  39. public
  40. constructor Create(AOwner: TComponent); override;
  41. destructor Destroy; override;
  42. function InitializeFromIcon(const Instance: HINST; const Name: PChar; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  43. function InitializeFromStockIcon(const Siid: SHSTOCKICONID; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  44. property Bitmap: TBitmap read FImpl.Bitmap write SetBitmap;
  45. property Graphic: TGraphic write SetGraphic;
  46. published
  47. property Align;
  48. property Anchors;
  49. property AutoSize: Boolean read FImpl.AutoSize write SetAutoSize default False;
  50. property BackColor: TColor read FImpl.BackColor write SetBackColor default clNone;
  51. property Caption;
  52. property Center: Boolean read FImpl.Center write SetCenter default True;
  53. property Enabled;
  54. property ParentShowHint;
  55. property PngImage: TPngImage read FImpl.PngImage write SetPngImage;
  56. property PopupMenu;
  57. property ShowHint;
  58. property Stretch: Boolean read FImpl.Stretch write SetStretch default False;
  59. property ReplaceColor: TColor read FImpl.ReplaceColor write SetReplaceColor default clNone;
  60. property ReplaceWithColor: TColor read FImpl.ReplaceWithColor write SetReplaceWithColor default clNone;
  61. property TabOrder;
  62. property TabStop default True;
  63. property Visible;
  64. property OnClick;
  65. property OnDblClick;
  66. property OnPaint: TPaintEvent read FImpl.OnPaint write FImpl.OnPaint;
  67. end;
  68. procedure Register;
  69. implementation
  70. procedure Register;
  71. begin
  72. RegisterComponents('JR', [TBitmapButton]);
  73. end;
  74. constructor TBitmapButton.Create(AOwner: TComponent);
  75. begin
  76. inherited;
  77. ControlStyle := ControlStyle + [csParentBackground, csReplicatable] - [csClickEvents];
  78. { Using a fixed focus border width/height to avoid design problems between systems }
  79. FFocusBorderWidthHeight := 2;
  80. const DoubleFBWH = 2*FFocusBorderWidthHeight;
  81. FImpl.Init(Self, DoubleFBWH, DoubleFBWH);
  82. Center := True;
  83. TabStop := True;
  84. Width := 75+DoubleFBWH;
  85. Height := 25+DoubleFBWH;
  86. end;
  87. procedure TBitmapButton.CreateParams(var Params: TCreateParams);
  88. begin
  89. inherited;
  90. CreateSubClass(Params, 'BUTTON');
  91. Params.Style := Params.Style or BS_NOTIFY; { For BN_DBLCLK }
  92. end;
  93. destructor TBitmapButton.Destroy;
  94. begin
  95. FImpl.DeInit;
  96. inherited;
  97. end;
  98. function TBitmapButton.InitializeFromIcon(const Instance: HINST; const Name: PChar; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  99. begin
  100. Result := FImpl.InitializeFromIcon(HInstance, Name, BkColor, AscendingTrySizes);
  101. end;
  102. function TBitmapButton.InitializeFromStockIcon(const Siid: SHSTOCKICONID; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  103. begin
  104. Result := FImpl.InitializeFromStockIcon(siid, BkColor, AscendingTrySizes);
  105. end;
  106. procedure TBitmapButton.SetAutoSize(Value: Boolean);
  107. begin
  108. FImpl.SetAutoSize(Self, Value);
  109. end;
  110. procedure TBitmapButton.SetBackColor(Value: TColor);
  111. begin
  112. FImpl.SetBackColor(Self, Value);
  113. end;
  114. procedure TBitmapButton.SetBitmap(Value: TBitmap);
  115. begin
  116. FImpl.SetBitmap(Value);
  117. end;
  118. procedure TBitmapButton.SetCenter(Value: Boolean);
  119. begin
  120. FImpl.SetCenter(Self, Value);
  121. end;
  122. procedure TBitmapButton.SetGraphic(Value: TGraphic);
  123. begin
  124. FImpl.SetGraphic(Value);
  125. end;
  126. procedure TBitmapButton.SetPngImage(Value: TPngImage);
  127. begin
  128. FImpl.SetPngImage(Value);
  129. end;
  130. procedure TBitmapButton.SetReplaceColor(Value: TColor);
  131. begin
  132. FImpl.SetReplaceColor(Self, Value);
  133. end;
  134. procedure TBitmapButton.SetReplaceWithColor(Value: TColor);
  135. begin
  136. FImpl.SetReplaceWithColor(Self, Value);
  137. end;
  138. procedure TBitmapButton.SetStretch(Value: Boolean);
  139. begin
  140. FImpl.SetStretch(Self, Value);
  141. end;
  142. function TBitmapButton.GetPalette: HPALETTE;
  143. begin
  144. Result := FImpl.GetPalette;
  145. end;
  146. procedure TBitmapButton.Paint;
  147. begin
  148. Canvas.Font := Font;
  149. Canvas.Brush.Color := Color;
  150. var R := ClientRect;
  151. if Focused and (SendMessage(Handle, WM_QUERYUISTATE, 0, 0) and UISF_HIDEFOCUS = 0) then begin
  152. { See TBitBtn.DrawItem in Vcl.Buttons.pas }
  153. Canvas.Pen.Color := clWindowFrame;
  154. Canvas.Brush.Style := bsSolid;
  155. Canvas.Brush.Color := clBtnFace;
  156. { This might draw a focus border thinner or thicker than our FFocusBorderWidthHeight but that's okay }
  157. Canvas.DrawFocusRect(R);
  158. end;
  159. InflateRect(R, -FFocusBorderWidthHeight, -FFocusBorderWidthHeight);
  160. FImpl.Paint(Self, Canvas, R);
  161. end;
  162. procedure TBitmapButton.WMSetFocus(var Message: TWMSetFocus);
  163. begin
  164. inherited;
  165. Invalidate;
  166. end;
  167. procedure TBitmapButton.WMKillFocus(var Message: TWMKillFocus);
  168. begin
  169. inherited;
  170. Invalidate;
  171. end;
  172. procedure TBitmapButton.CNCommand(var Message: TWMCommand);
  173. begin
  174. if (Message.NotifyCode = BN_CLICKED) then
  175. Click
  176. else if (Message.NotifyCode = BN_DBLCLK) then
  177. DblClick;
  178. end;
  179. end.