BitmapButton.pas 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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 SetOpacity(Value: Byte);
  28. procedure SetPngImage(Value: TPngImage);
  29. procedure SetReplaceColor(Value: TColor);
  30. procedure SetReplaceWithColor(Value: TColor);
  31. procedure SetStretch(Value: Boolean);
  32. procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  33. procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  34. procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  35. protected
  36. procedure CreateParams(var Params: TCreateParams); override;
  37. function GetPalette: HPALETTE; override;
  38. procedure Paint; override;
  39. procedure SetAutoSize(Value: Boolean); override;
  40. public
  41. constructor Create(AOwner: TComponent); override;
  42. destructor Destroy; override;
  43. function InitializeFromIcon(const Instance: HINST; const Name: PChar; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  44. function InitializeFromStockIcon(const Siid: SHSTOCKICONID; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  45. property Bitmap: TBitmap read FImpl.Bitmap write SetBitmap;
  46. property Graphic: TGraphic write SetGraphic;
  47. published
  48. property Align;
  49. property Anchors;
  50. property AutoSize: Boolean read FImpl.AutoSize write SetAutoSize default False;
  51. property BackColor: TColor read FImpl.BackColor write SetBackColor default clNone;
  52. property Caption;
  53. property Center: Boolean read FImpl.Center write SetCenter default True;
  54. property Enabled;
  55. property Opacity: Byte read FImpl.Opacity write SetOpacity default 255;
  56. property ParentShowHint;
  57. property PngImage: TPngImage read FImpl.PngImage write SetPngImage;
  58. property PopupMenu;
  59. property ShowHint;
  60. property Stretch: Boolean read FImpl.Stretch write SetStretch default False;
  61. property ReplaceColor: TColor read FImpl.ReplaceColor write SetReplaceColor default clNone;
  62. property ReplaceWithColor: TColor read FImpl.ReplaceWithColor write SetReplaceWithColor default clNone;
  63. property TabOrder;
  64. property TabStop default True;
  65. property Visible;
  66. property OnClick;
  67. property OnDblClick;
  68. property OnPaint: TPaintEvent read FImpl.OnPaint write FImpl.OnPaint;
  69. end;
  70. procedure Register;
  71. implementation
  72. procedure Register;
  73. begin
  74. RegisterComponents('JR', [TBitmapButton]);
  75. end;
  76. constructor TBitmapButton.Create(AOwner: TComponent);
  77. begin
  78. inherited;
  79. ControlStyle := ControlStyle + [csParentBackground, csReplicatable] - [csClickEvents];
  80. { Using a fixed focus border width/height to avoid design problems between systems }
  81. FFocusBorderWidthHeight := 2;
  82. const DoubleFBWH = 2*FFocusBorderWidthHeight;
  83. FImpl.Init(Self, DoubleFBWH, DoubleFBWH);
  84. Center := True;
  85. TabStop := True;
  86. Width := 75+DoubleFBWH;
  87. Height := 25+DoubleFBWH;
  88. end;
  89. procedure TBitmapButton.CreateParams(var Params: TCreateParams);
  90. begin
  91. inherited;
  92. CreateSubClass(Params, 'BUTTON');
  93. Params.Style := Params.Style or BS_NOTIFY; { For BN_DBLCLK }
  94. end;
  95. destructor TBitmapButton.Destroy;
  96. begin
  97. FImpl.DeInit;
  98. inherited;
  99. end;
  100. function TBitmapButton.InitializeFromIcon(const Instance: HINST; const Name: PChar; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  101. begin
  102. Result := FImpl.InitializeFromIcon(HInstance, Name, BkColor, AscendingTrySizes);
  103. end;
  104. function TBitmapButton.InitializeFromStockIcon(const Siid: SHSTOCKICONID; const BkColor: TColor; const AscendingTrySizes: array of Integer): Boolean;
  105. begin
  106. Result := FImpl.InitializeFromStockIcon(siid, BkColor, AscendingTrySizes);
  107. end;
  108. procedure TBitmapButton.SetAutoSize(Value: Boolean);
  109. begin
  110. FImpl.SetAutoSize(Self, Value);
  111. end;
  112. procedure TBitmapButton.SetBackColor(Value: TColor);
  113. begin
  114. FImpl.SetBackColor(Self, Value);
  115. end;
  116. procedure TBitmapButton.SetBitmap(Value: TBitmap);
  117. begin
  118. FImpl.SetBitmap(Value);
  119. end;
  120. procedure TBitmapButton.SetCenter(Value: Boolean);
  121. begin
  122. FImpl.SetCenter(Self, Value);
  123. end;
  124. procedure TBitmapButton.SetGraphic(Value: TGraphic);
  125. begin
  126. FImpl.SetGraphic(Value);
  127. end;
  128. procedure TBitmapButton.SetOpacity(Value: Byte);
  129. begin
  130. FImpl.SetOpacity(Self, Value);
  131. end;
  132. procedure TBitmapButton.SetPngImage(Value: TPngImage);
  133. begin
  134. FImpl.SetPngImage(Value);
  135. end;
  136. procedure TBitmapButton.SetReplaceColor(Value: TColor);
  137. begin
  138. FImpl.SetReplaceColor(Self, Value);
  139. end;
  140. procedure TBitmapButton.SetReplaceWithColor(Value: TColor);
  141. begin
  142. FImpl.SetReplaceWithColor(Self, Value);
  143. end;
  144. procedure TBitmapButton.SetStretch(Value: Boolean);
  145. begin
  146. FImpl.SetStretch(Self, Value);
  147. end;
  148. function TBitmapButton.GetPalette: HPALETTE;
  149. begin
  150. Result := FImpl.GetPalette;
  151. end;
  152. procedure TBitmapButton.Paint;
  153. begin
  154. Canvas.Font := Font;
  155. Canvas.Brush.Color := Color;
  156. var R := ClientRect;
  157. if Focused and (SendMessage(Handle, WM_QUERYUISTATE, 0, 0) and UISF_HIDEFOCUS = 0) then begin
  158. { See TBitBtn.DrawItem in Vcl.Buttons.pas }
  159. Canvas.Pen.Color := clWindowFrame;
  160. Canvas.Brush.Style := bsSolid;
  161. Canvas.Brush.Color := clBtnFace;
  162. { This might draw a focus border thinner or thicker than our FFocusBorderWidthHeight but that's okay }
  163. Canvas.DrawFocusRect(R);
  164. end;
  165. InflateRect(R, -FFocusBorderWidthHeight, -FFocusBorderWidthHeight);
  166. FImpl.Paint(Self, Canvas, R);
  167. end;
  168. procedure TBitmapButton.WMSetFocus(var Message: TWMSetFocus);
  169. begin
  170. inherited;
  171. Invalidate;
  172. end;
  173. procedure TBitmapButton.WMKillFocus(var Message: TWMKillFocus);
  174. begin
  175. inherited;
  176. Invalidate;
  177. end;
  178. procedure TBitmapButton.CNCommand(var Message: TWMCommand);
  179. begin
  180. if (Message.NotifyCode = BN_CLICKED) then
  181. Click
  182. else if (Message.NotifyCode = BN_DBLCLK) then
  183. DblClick;
  184. end;
  185. end.