BitmapButton.pas 6.1 KB

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