BitmapButton.pas 5.5 KB

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