CnButtonEdit.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. {******************************************************************************}
  2. { CnPack For Delphi/C++Builder }
  3. { 中国人自己的开放源码第三方开发包 }
  4. { (C)Copyright 2001-2018 CnPack 开发组 }
  5. { ------------------------------------ }
  6. { }
  7. { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
  8. { 改和重新发布这一程序。 }
  9. { }
  10. { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
  11. { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
  12. { }
  13. { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
  14. { 还没有,可访问我们的网站: }
  15. { }
  16. { 网站地址:http://www.cnpack.org }
  17. { 电子邮件:master@cnpack.org }
  18. { }
  19. {******************************************************************************}
  20. unit CnButtonEdit;
  21. {* |<PRE>
  22. ================================================================================
  23. * 软件名称:界面控件包
  24. * 单元名称:CnButtonEdit 单元
  25. * 单元作者:dingbaosheng (yzdbs@msn.com)
  26. * 备 注:
  27. * 开发平台:PWinXP + Delphi 5.0
  28. * 兼容测试:PWin9X/2000/XP + Delphi 5/6/7
  29. * 本 地 化:该单元中的字符串均符合本地化处理方式
  30. * 单元标识:$Id$
  31. * 修改记录:2007.05.02 V1.0
  32. * LiuXiao 移植单元
  33. ================================================================================
  34. |</PRE>}
  35. interface
  36. {$I CnPack.inc}
  37. uses
  38. SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  39. Forms, Dialogs, StdCtrls, Buttons, Menus;
  40. type
  41. TButtonKind = (bkCustom, bkLookup, bkDropDown, bkAccept, bkReject,
  42. bkFolder, bkFind);
  43. TCnButtonEdit = class(TCustomMemo)
  44. private
  45. FButtonVisible: Boolean;
  46. FButtonFlat: Boolean;
  47. FButtonKind: TButtonKind;
  48. FOnButtonClick: TNotifyEvent;
  49. function GetButtonKind: TButtonKind;
  50. procedure SetButtonKind(const Value: TButtonKind);
  51. function GetButtonGlyph: TBitmap;
  52. procedure SetButtonGlyph(Value: TBitmap);
  53. procedure SetButtonVisible(const Value: Boolean);
  54. procedure SetButtonBounds;
  55. procedure SetButtonFlat(const Value: Boolean);
  56. function GetButtonHint: string;
  57. procedure SetButtonHint(const Value: string);
  58. protected
  59. FButton: TSpeedButton;
  60. procedure BtnClickHandler(Sender: TObject); virtual;
  61. procedure UpdateFormatRect;
  62. procedure WMSize(var Msg: TWMSize); message WM_SIZE;
  63. procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
  64. procedure CMEnabledChanged(var Msg: TWMNoParams); message CM_ENABLEDCHANGED;
  65. procedure CreateHandle; override;
  66. public
  67. constructor Create(AOwner: TComponent); override;
  68. destructor Destroy; override;
  69. published
  70. property ButtonVisible: Boolean read FButtonVisible write SetButtonVisible default True;
  71. property ButtonFlat: Boolean read FButtonFlat write SetButtonFlat;
  72. property ButtonHint: string read GetButtonHint write SetButtonHint;
  73. property ButtonKind: TButtonKind read GetButtonKind write SetButtonKind;
  74. property Align;
  75. property Alignment;
  76. property Anchors;
  77. property AutoSelect;
  78. property AutoSize;
  79. property BorderStyle;
  80. property CharCase;
  81. property Color;
  82. property Ctl3D;
  83. property Enabled;
  84. property Font;
  85. property HideSelection;
  86. property MaxLength;
  87. property ParentColor;
  88. property ParentCtl3D;
  89. property ParentFont;
  90. property ParentShowHint;
  91. property PasswordChar;
  92. property PopupMenu;
  93. property ReadOnly;
  94. property ShowHint;
  95. property TabOrder;
  96. property TabStop;
  97. property Text;
  98. property Visible;
  99. property OnChange;
  100. property OnClick;
  101. property OnEnter;
  102. property OnExit;
  103. property OnKeyDown;
  104. property OnKeyPress;
  105. property OnKeyUp;
  106. property OnMouseDown;
  107. property OnMouseMove;
  108. property OnMouseUp;
  109. property ButtonPic: TBitmap read GetButtonGlyph write SetButtonGlyph;
  110. property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
  111. end;
  112. implementation
  113. {$R CnButtonEdit.RES}
  114. const
  115. BtnEdtResNames: array[TButtonKind] of PChar = (nil,
  116. 'BTNEDT_LOOKUP',
  117. 'BTNEDT_DROPDOWN',
  118. 'BTNEDT_ACCEPT',
  119. 'BTNEDT_REJECT',
  120. 'BTNEDT_FOLDER',
  121. 'BTNEDT_FIND');
  122. var
  123. BtnEdtGlyphs: array[TButtonKind] of TBitmap;
  124. function GetBtnEdtGlyph(Kind: TButtonKind): TBitmap;
  125. begin
  126. if BtnEdtGlyphs[Kind] = nil then
  127. begin
  128. BtnEdtGlyphs[Kind] := TBitmap.Create;
  129. BtnEdtGlyphs[Kind].LoadFromResourceName(HInstance, BtnEdtResNames[Kind]);
  130. end;
  131. Result := BtnEdtGlyphs[Kind];
  132. end;
  133. function TCnButtonEdit.GetButtonGlyph: TBitmap;
  134. begin
  135. Result := FButton.Glyph;
  136. end;
  137. procedure TCnButtonEdit.SetButtonGlyph(Value: TBitmap);
  138. begin
  139. FButton.Glyph := Value;
  140. FButtonKind := bkCustom;
  141. end;
  142. function TCnButtonEdit.GetButtonKind: TButtonKind;
  143. begin
  144. Result := FButtonKind;
  145. end;
  146. procedure TCnButtonEdit.SetButtonKind(const Value: TButtonKind);
  147. begin
  148. if (Value <> FButtonKind) then
  149. begin
  150. FButtonKind := Value;
  151. if FButtonKind <> bkCustom then
  152. FButton.Glyph := GetBtnEdtGlyph(Value);
  153. end
  154. end;
  155. constructor TCnButtonEdit.Create(AOwner: TComponent);
  156. begin
  157. inherited Create(AOwner);
  158. Height := 21;
  159. Width := 121;
  160. WordWrap := False;
  161. WantReturns := False;
  162. FButtonVisible := True;
  163. FButton := TSpeedButton.Create(Self);
  164. with FButton do
  165. begin
  166. Parent := Self;
  167. FButtonKind := bkLookup; //设置为...图片
  168. Glyph := GetBtnEdtGlyph(FButtonKind);
  169. Align := alRight;
  170. Spacing := -1;
  171. ShowHint := True;
  172. Margin := -1;
  173. OnClick := BtnClickHandler;
  174. end;
  175. end;
  176. destructor TCnButtonEdit.Destroy;
  177. begin
  178. inherited;
  179. end;
  180. procedure TCnButtonEdit.CreateHandle;
  181. begin
  182. inherited CreateHandle;
  183. UpdateFormatRect;
  184. end;
  185. procedure TCnButtonEdit.UpdateFormatRect;
  186. var
  187. Rect: TRect;
  188. begin
  189. Rect := ClientRect;
  190. if FButtonVisible then
  191. Dec(Rect.Right, FButton.Height)
  192. else
  193. Inc(Rect.Right, FButton.Height);
  194. SendMessage(Handle, EM_SETRECTNP, 0, Longint(@Rect));
  195. end;
  196. procedure TCnButtonEdit.WMSize(var Msg: TWMSize);
  197. begin
  198. inherited;
  199. FButton.Width := FButton.Height;
  200. UpdateFormatRect;
  201. end;
  202. procedure TCnButtonEdit.WMSetCursor(var Msg: TWMSetCursor);
  203. var
  204. P: TPoint;
  205. PosWidth: Integer;
  206. begin
  207. GetCursorPos(P);
  208. P := ScreenToClient(P);
  209. PosWidth := ClientWidth;
  210. if FButtonVisible then
  211. PosWidth := PosWidth - FButton.Width;
  212. if (P.X >= PosWidth) then
  213. SetCursor(Screen.Cursors[crDefault])
  214. else
  215. inherited;
  216. end;
  217. procedure TCnButtonEdit.CMEnabledChanged(var Msg: TWMNoParams);
  218. begin
  219. inherited;
  220. FButton.Enabled := Enabled;
  221. end;
  222. procedure TCnButtonEdit.SetButtonBounds;
  223. begin
  224. if not FButtonVisible then
  225. FButton.Width := 0
  226. else
  227. FButton.Width := Height - 1;
  228. UpdateFormatRect;
  229. if not (csLoading in ComponentState) then
  230. begin
  231. SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN, 0);
  232. SendMessage(Handle, EM_SETMARGINS, EC_RIGHTMARGIN, MakeLong(0, 2));
  233. end;
  234. end;
  235. procedure TCnButtonEdit.SetButtonVisible(const Value: Boolean);
  236. begin
  237. if FButtonVisible <> Value then
  238. begin
  239. FButtonVisible := Value;
  240. FButton.Visible := Value;
  241. SetButtonBounds;
  242. Invalidate;
  243. end;
  244. end;
  245. procedure TCnButtonEdit.SetButtonFlat(const Value: Boolean);
  246. begin
  247. if FButtonFlat <> Value then
  248. begin
  249. FButtonFlat := Value;
  250. FButton.Flat := Value;
  251. Invalidate;
  252. end;
  253. end;
  254. function TCnButtonEdit.GetButtonHint: string;
  255. begin
  256. Result := FButton.Hint;
  257. end;
  258. procedure TCnButtonEdit.SetButtonHint(const Value: string);
  259. begin
  260. FButton.Hint := Value;
  261. end;
  262. procedure TCnButtonEdit.BtnClickHandler(Sender: TObject);
  263. begin
  264. if Assigned(FOnButtonClick) then
  265. FOnButtonClick(Self);
  266. end;
  267. procedure FreeBtnEdtGlyph;
  268. var
  269. Kind: TButtonKind;
  270. begin
  271. for Kind := Low(TButtonKind) to High(TButtonKind) do
  272. begin
  273. if BtnEdtGlyphs[Kind] <> nil then
  274. begin
  275. BtnEdtGlyphs[Kind].Free;
  276. BtnEdtGlyphs[Kind] := nil;
  277. end;
  278. end;
  279. end;
  280. initialization
  281. finalization
  282. FreeBtnEdtGlyph;
  283. end.