CnButtons.pas 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197
  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 CnButtons;
  21. {* |<PRE>
  22. ================================================================================
  23. * 软件名称:界面控件包
  24. * 单元名称:界面控件包位图按钮实现单元
  25. * 单元作者:Bahamut
  26. * 备 注:
  27. * 开发平台:PWin98SE + Delphi 5.0
  28. * 兼容测试:PWin9X/2000/XP + Delphi 5/6
  29. * 本 地 化:该单元中的字符串均符合本地化处理方式
  30. * 单元标识:$Id$
  31. * 修改记录:2014.08.29
  32. * 增加WordWrap属性
  33. * 2013.07.24
  34. * 修正未处理Action的问题
  35. * 2013.07.03
  36. * 修补Glyph在某些BPL环境下宽高变为0从而出错的情况
  37. * 2009.06.29
  38. * 修补了当在设计期设置Caption为空时运行期会改为Name的BUG
  39. * 2007.12.18 V0.2
  40. * 加入 SpeedButton。
  41. * 2007.12.10 V0.1
  42. * 实现单元
  43. ================================================================================
  44. |</PRE>}
  45. interface
  46. {$I CnPack.inc}
  47. uses
  48. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Buttons,
  49. ImgList, ActnList, CnConsts;
  50. type
  51. TBtnColorStyle = (bcsCustom, bcsGold, bcsChrome, bcsBlue, bcsRed,
  52. bcsFlat1, bcsFlat2, bcsAqua);
  53. TModernBtnStyle = (bsNormal, bsThin, bsFlat, bsModern);
  54. {* 按钮绘制风格,正常、薄、平、渐变效果}
  55. TCnCustomButton = class(TCustomControl)
  56. private
  57. FAlignment: TAlignment;
  58. FShadowColor: TColor;
  59. FDownColor: TColor;
  60. FGlyph: TBitmap;
  61. FHotTrackColor: TColor;
  62. FKind: TBitBtnKind;
  63. FLayout: TButtonLayout;
  64. FLightColor: TColor;
  65. FModalResult: TModalResult;
  66. FNumGlyphs: Integer;
  67. FWordWrap: Boolean;
  68. FOnClick: TNotifyEvent;
  69. FOnMouseEnter: TNotifyEvent;
  70. FOnMouseLeave: TNotifyEvent;
  71. FBtnColorStyle: TBtnColorStyle;
  72. FModernBtnStyle: TModernBtnStyle;
  73. FDefault, FCancel: Boolean;
  74. FDown: Boolean;
  75. FCursorOnButton: Boolean;
  76. FDownBold: Boolean;
  77. FHotTrackBold: Boolean;
  78. FFlatBorder: Boolean;
  79. FSpacing: Integer;
  80. FMargin: Integer;
  81. FRoundCorner: Boolean;
  82. procedure SetCancel(const Value: Boolean);
  83. procedure SetDefault(const Value: Boolean);
  84. procedure SetFlatBorder(const Value: Boolean);
  85. procedure SetDownBold(const Value: Boolean);
  86. procedure SetDownColor(const Value: TColor);
  87. procedure SetHotTrackBold(const Value: Boolean);
  88. procedure SetHotTrackColor(const Value: TColor);
  89. procedure SetSpacing(const Value: Integer);
  90. procedure SetMargin(const Value: Integer);
  91. procedure SetRoundCorner(const Value: Boolean);
  92. procedure RenewBack;
  93. {* 刷新底部位图 *}
  94. procedure GlyphChanged(Sender: TObject);
  95. procedure SetWordWrap(const Value: Boolean);
  96. {* 2009-06-05 添加,处理FGlyph的OnChange事件,否则当直接调用Glyph的方法控件无法得到通知及时刷新 }
  97. protected
  98. procedure CreateParams(var Params: TCreateParams); override;
  99. procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
  100. procedure SetAlignment(const Value: TAlignment);
  101. procedure SetGlyph(const Value: TBitmap);
  102. procedure SetKind(const Value: TBitBtnKind);
  103. procedure SetLayout(const Value: TButtonLayout);
  104. procedure SetLightColor(const Value: TColor);
  105. procedure SetModalResult(const Value: TModalResult);
  106. procedure SetNumGlyphs(const Value: Integer);
  107. procedure SetModernBtnStyle(const Value: TModernBtnStyle);
  108. procedure SetShadowColor(const Value: TColor);
  109. procedure SetBtnColorStyle(const Value: TBtnColorStyle);
  110. procedure DoMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
  111. procedure DoMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
  112. procedure DoEnable(var Message: TMessage); message WM_ENABLE;
  113. procedure DoFocusChanged(var Msg: TMessage); message CM_FOCUSCHANGED;
  114. procedure DoKeyDown(var Msg: TMessage); message CN_KEYDOWN;
  115. procedure DoKeyUp(var Msg: TMessage); message CN_KEYUP;
  116. procedure DoDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
  117. procedure DoDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
  118. procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  119. procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  120. procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  121. procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  122. procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  123. procedure WMWindowPosChanged(var Message: TMessage); message WM_WINDOWPOSCHANGED;
  124. procedure Paint; override;
  125. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  126. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  127. property Glyph: TBitmap read FGlyph write SetGlyph;
  128. property Kind: TBitBtnKind read FKind write SetKind default bkCustom;
  129. property Layout: TButtonLayout read FLayout write SetLayout default blGlyphLeft;
  130. property NumGlyphs: Integer read FNumGlyphs write SetNumGlyphs default 0;
  131. public
  132. constructor Create(AOwner: TComponent); override;
  133. destructor Destroy; override;
  134. procedure Click; override;
  135. property Alignment: TAlignment read FAlignment write SetAlignment default taCenter;
  136. {* 文字和图片的左右对齐方式}
  137. property ShadowColor: TColor read FShadowColor write SetShadowColor default clGray;
  138. {* 阴影颜色,用于正常模式下的右下边缘绘制,以及 bsModern 时的渐变目标暗色}
  139. property Cancel: Boolean read FCancel write SetCancel default False;
  140. property BtnColorStyle: TBtnColorStyle read FBtnColorStyle write SetBtnColorStyle default bcsCustom;
  141. {* 用于设置一些预定义的效果}
  142. property DownColor: TColor read FDownColor write SetDownColor default clNone;
  143. {* 按下时的背景填充色}
  144. property Default: Boolean read FDefault write SetDefault default False;
  145. property DownBold: Boolean read FDownBold write SetDownBold;
  146. {* 按下时文字是否粗体显示}
  147. property FlatBorder: Boolean read FFlatBorder write SetFlatBorder;
  148. {* bsFlat 时是否绘制边框}
  149. property HotTrackBold: Boolean read FHotTrackBold write SetHotTrackBold;
  150. {* 鼠标移入时文字是否粗体显示}
  151. property HotTrackColor: TColor read FHotTrackColor write SetHotTrackColor default clNone;
  152. {* 鼠标移入时的颜色}
  153. property LightColor: TColor read FLightColor write SetLightColor default clWhite;
  154. {* 高亮颜色,用于正常模式下的左上边缘绘制,以及 bsModern 时的渐变目标高亮色}
  155. property Margin: Integer read FMargin write SetMargin default 4;
  156. {* 图片文字非居中时,距边缘的距离}
  157. property ModalResult: TModalResult read FModalResult write SetModalResult default mrNone;
  158. property RoundCorner: Boolean read FRoundCorner write SetRoundCorner default True;
  159. {* bsModern 风格时是否显示按钮圆角,默认显示}
  160. property ModernBtnStyle: TModernBtnStyle read FModernBtnStyle
  161. write SetModernBtnStyle default bsNormal;
  162. {* 按钮绘制风格}
  163. property Spacing: Integer read FSpacing write SetSpacing default 4;
  164. {* 图标和文字之间的距离,以象素为单位,默认为 4}
  165. property WordWrap: Boolean read FWordWrap write SetWordWrap default False;
  166. {* 文字是否自动换行}
  167. property OnClick: TNotifyEvent read FOnClick write FOnClick;
  168. property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  169. property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  170. end;
  171. TCnButton = class(TCnCustomButton)
  172. published
  173. property Action;
  174. property Align;
  175. property Alignment;
  176. property Anchors;
  177. property BiDiMode;
  178. property BtnColorStyle;
  179. property Cancel;
  180. property Caption;
  181. property Color;
  182. property Constraints;
  183. property Cursor;
  184. property DownColor;
  185. property Default;
  186. property DownBold;
  187. property DragCursor;
  188. property DragKind;
  189. property DragMode;
  190. property Enabled;
  191. property FlatBorder;
  192. property Font;
  193. property Hint;
  194. property HotTrackBold;
  195. property HotTrackColor;
  196. property LightColor;
  197. property Margin;
  198. property ModalResult;
  199. property ModernBtnStyle;
  200. property ParentColor;
  201. property ParentFont;
  202. property ParentShowHint;
  203. property PopupMenu;
  204. property RoundCorner;
  205. property ShadowColor;
  206. property ShowHint;
  207. property TabOrder;
  208. property TabStop;
  209. property Visible;
  210. property WordWrap;
  211. property Name;
  212. property OnClick;
  213. property OnDragDrop;
  214. property OnDragOver;
  215. property OnEndDrag;
  216. property OnEnter;
  217. property OnExit;
  218. property OnKeyDown;
  219. property OnKeyPress;
  220. property OnKeyUp;
  221. property OnMouseDown;
  222. property OnMouseEnter;
  223. property OnMouseLeave;
  224. property OnMouseMove;
  225. property OnMouseUp;
  226. property OnStartDrag;
  227. end;
  228. TCnBitBtn = class(TCnCustomButton)
  229. published
  230. property Action;
  231. property Align;
  232. property Alignment;
  233. property Anchors;
  234. property BiDiMode;
  235. property BtnColorStyle;
  236. property Cancel;
  237. property Caption;
  238. property Color;
  239. property Constraints;
  240. property Cursor;
  241. property Default;
  242. property DownColor;
  243. property DownBold;
  244. property DragCursor;
  245. property DragKind;
  246. property DragMode;
  247. property Enabled;
  248. property FlatBorder;
  249. property Font;
  250. property Glyph;
  251. property Hint;
  252. property HotTrackBold;
  253. property HotTrackColor;
  254. property Kind;
  255. property Layout;
  256. property LightColor;
  257. property Margin;
  258. property ModalResult;
  259. property ModernBtnStyle;
  260. property NumGlyphs;
  261. property ParentColor;
  262. property ParentFont;
  263. property ParentShowHint;
  264. property PopupMenu;
  265. property RoundCorner;
  266. property ShowHint;
  267. property ShadowColor;
  268. property Spacing;
  269. property TabOrder;
  270. property TabStop;
  271. property Visible;
  272. property WordWrap;
  273. property Name;
  274. property OnClick;
  275. property OnDragDrop;
  276. property OnDragOver;
  277. property OnEndDrag;
  278. property OnEnter;
  279. property OnExit;
  280. property OnKeyDown;
  281. property OnKeyPress;
  282. property OnKeyUp;
  283. property OnMouseDown;
  284. property OnMouseEnter;
  285. property OnMouseLeave;
  286. property OnMouseMove;
  287. property OnMouseUp;
  288. property OnStartDrag;
  289. end;
  290. TCnSpeedButton = class(TGraphicControl)
  291. private
  292. FGroupIndex: Integer;
  293. FGlyph: TBitmap;
  294. FNumGlyphs: Integer;
  295. FDown: Boolean;
  296. FDragging: Boolean;
  297. FAllowAllUp: Boolean;
  298. FLayout: TButtonLayout;
  299. FSpacing: Integer;
  300. FTransparent: Boolean;
  301. FMargin: Integer;
  302. FCursorOnButton: Boolean;
  303. FHotTrackBold: Boolean;
  304. FFlatBorder: Boolean;
  305. FDownBold: Boolean;
  306. FBtnColorStyle: TBtnColorStyle;
  307. FDownColor: TColor;
  308. FHotTrackColor: TColor;
  309. FShadowColor: TColor;
  310. FLightColor: TColor;
  311. FModernBtnStyle: TModernBtnStyle;
  312. FOnMouseLeave: TNotifyEvent;
  313. FOnMouseEnter: TNotifyEvent;
  314. FAlignment: TAlignment;
  315. FRoundCorner: Boolean;
  316. procedure UpdateExclusive;
  317. function GetGlyph: TBitmap;
  318. procedure SetGlyph(Value: TBitmap);
  319. function GetNumGlyphs: TNumGlyphs;
  320. procedure SetNumGlyphs(Value: TNumGlyphs);
  321. procedure SetDown(Value: Boolean);
  322. procedure SetAllowAllUp(Value: Boolean);
  323. procedure SetGroupIndex(Value: Integer);
  324. procedure SetLayout(Value: TButtonLayout);
  325. procedure SetSpacing(Value: Integer);
  326. procedure SetTransparent(Value: Boolean);
  327. procedure SetMargin(Value: Integer);
  328. procedure UpdateTracking;
  329. procedure WMLButtonDblClk(var Message: TWMLButtonDown); message WM_LBUTTONDBLCLK;
  330. procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  331. procedure CMButtonPressed(var Message: TMessage); message CM_BUTTONPRESSED;
  332. procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
  333. procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  334. procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  335. procedure CMSysColorChange(var Message: TMessage); message CM_SYSCOLORCHANGE;
  336. procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
  337. procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  338. procedure SetBtnColorStyle(const Value: TBtnColorStyle);
  339. procedure SetFlatBorder(const Value: Boolean);
  340. procedure SetLightColor(const Value: TColor);
  341. procedure SetModernBtnStyle(const Value: TModernBtnStyle);
  342. procedure SetShadowColor(const Value: TColor);
  343. procedure SetAlignment(const Value: TAlignment);
  344. procedure SetDownBold(const Value: Boolean);
  345. procedure SetDownColor(const Value: TColor);
  346. procedure SetHotTrackBold(const Value: Boolean);
  347. procedure SetHotTrackColor(const Value: TColor);
  348. procedure SetRoundCorner(const Value: Boolean);
  349. procedure GlyphChanged(Sender: TObject);
  350. {* 2009-06-05 添加,处理FGlyph的OnChange事件,否则当直接调用Glyph的方法控件无法得到通知及时刷新 }
  351. function GetFlat: Boolean;
  352. procedure SetFlat(const Value: Boolean);
  353. protected
  354. FState: TButtonState;
  355. procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
  356. function GetPalette: HPALETTE; override;
  357. procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  358. X, Y: Integer); override;
  359. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  360. procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  361. X, Y: Integer); override;
  362. procedure Paint; override;
  363. property CursorOnButton: Boolean read FCursorOnButton;
  364. public
  365. constructor Create(AOwner: TComponent); override;
  366. destructor Destroy; override;
  367. procedure Click; override;
  368. published
  369. property Action;
  370. property Align;
  371. property Alignment: TAlignment read FAlignment write SetAlignment default taCenter;
  372. {* 文字和图片的左右对齐方式}
  373. property AllowAllUp: Boolean read FAllowAllUp write SetAllowAllUp default False;
  374. property Anchors;
  375. property BiDiMode;
  376. property ShadowColor: TColor read FShadowColor write SetShadowColor default clGray;
  377. property BtnColorStyle: TBtnColorStyle read FBtnColorStyle write SetBtnColorStyle default bcsCustom;
  378. property Color;
  379. property DownColor: TColor read FDownColor write SetDownColor default clNone;
  380. property DownBold: Boolean read FDownBold write SetDownBold;
  381. property Flat: Boolean read GetFlat write SetFlat stored False;
  382. {* 兼容 SpeedButton 而提供的 Flat 属性,实质上是操作 FModernBtnStyle 为 bsFlat}
  383. property FlatBorder: Boolean read FFlatBorder write SetFlatBorder;
  384. property HotTrackBold: Boolean read FHotTrackBold write SetHotTrackBold;
  385. property HotTrackColor: TColor read FHotTrackColor write SetHotTrackColor default clNone;
  386. property LightColor: TColor read FLightColor write SetLightColor default clWhite;
  387. property ModernBtnStyle: TModernBtnStyle read FModernBtnStyle
  388. write SetModernBtnStyle default bsNormal;
  389. property Constraints;
  390. property GroupIndex: Integer read FGroupIndex write SetGroupIndex default 0;
  391. property Down: Boolean read FDown write SetDown default False;
  392. property Caption;
  393. property Enabled;
  394. property Font;
  395. property Glyph: TBitmap read GetGlyph write SetGlyph;
  396. property Layout: TButtonLayout read FLayout write SetLayout default blGlyphLeft;
  397. property Margin: Integer read FMargin write SetMargin;
  398. property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
  399. property ParentFont;
  400. property ParentShowHint;
  401. property ParentBiDiMode;
  402. property PopupMenu;
  403. property RoundCorner: Boolean read FRoundCorner write SetRoundCorner default True;
  404. {* Modern 风格时是否显示按钮圆角,默认显示}
  405. property ShowHint;
  406. property Spacing: Integer read FSpacing write SetSpacing default 4;
  407. property Transparent: Boolean read FTransparent write SetTransparent default False;
  408. {* 是否透明显示,此属性只在 bsFlat 时有效}
  409. property Visible;
  410. property OnClick;
  411. property OnDblClick;
  412. property OnMouseDown;
  413. property OnMouseMove;
  414. property OnMouseUp;
  415. property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  416. property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  417. end;
  418. implementation
  419. {$R CNBUTTONS.RES}
  420. var
  421. FImageList: TImageList = nil;
  422. {* 用来绘制灰度图像的 ImageList}
  423. procedure CopyImage(Glyph: TBitmap; ImageList: TCustomImageList; Index: Integer);
  424. begin
  425. if Glyph <> nil then
  426. with Glyph do
  427. begin
  428. Width := ImageList.Width;
  429. Height := ImageList.Height;
  430. Canvas.Brush.Color := clFuchsia;
  431. Canvas.FillRect(Rect(0, 0, Width, Height));
  432. ImageList.Draw(Canvas, 0, 0, Index);
  433. end;
  434. end;
  435. procedure GetPreDefinedColors(BtnColorStyle: TBtnColorStyle; var Color, LightColor,
  436. ShadowColor, DownColor, HotTrackColor: TColor; var ModernStyle: TModernBtnStyle;
  437. var FlatBorder: Boolean);
  438. begin
  439. case BtnColorStyle of
  440. bcsGold:
  441. begin
  442. Color := $0000C0C0;
  443. LightColor := clYellow;
  444. ShadowColor := clOlive;
  445. DownColor := clNone;
  446. HotTrackColor := $0000DFDF;
  447. ModernStyle := bsModern;
  448. FlatBorder := False;
  449. end;
  450. bcsChrome:
  451. begin
  452. Color := clSilver;
  453. LightColor := clWhite;
  454. ShadowColor := clGray;
  455. DownColor := clNone;
  456. HotTrackColor := clNone;
  457. ModernStyle := bsModern;
  458. FlatBorder := False;
  459. end;
  460. bcsBlue:
  461. begin
  462. Color := $00FF8000;
  463. LightColor := clAqua;
  464. ShadowColor := clBlue;
  465. DownColor := clNone;
  466. HotTrackColor := clNone;
  467. ModernStyle := bsModern;
  468. FlatBorder := False;
  469. end;
  470. bcsRed:
  471. begin
  472. Color := clRed;
  473. LightColor := $00C0C0FF;
  474. ShadowColor := $000000C0;
  475. DownColor := clNone;
  476. HotTrackColor := clNone;
  477. ModernStyle := bsModern;
  478. FlatBorder := False;
  479. end;
  480. bcsAqua:
  481. begin
  482. Color := $00ECCE94;
  483. LightColor := $00FCE6D4;
  484. ShadowColor := clBlack;
  485. DownColor := clNone;
  486. HotTrackColor := clNone;
  487. ModernStyle := bsModern;
  488. FlatBorder := False;
  489. end;
  490. bcsFlat1:
  491. begin
  492. Color := clBtnFace;
  493. LightColor := $00B59284;
  494. ShadowColor := $00B59284;
  495. DownColor := $00B59284;
  496. HotTrackColor := $00DED3D6;
  497. ModernStyle := bsFlat;
  498. FlatBorder := True;
  499. end;
  500. bcsFlat2:
  501. begin
  502. Color := clBtnFace;
  503. LightColor := clBlack;
  504. ShadowColor := clBlack;
  505. DownColor := $0024DABC;
  506. HotTrackColor := $008CF6E4;
  507. ModernStyle := bsFlat;
  508. FlatBorder := False;
  509. end;
  510. end;
  511. end;
  512. procedure PaintButton(Canvas: TCanvas; IsSpeedButton: Boolean;
  513. Width, Height, NumGlyphs, Spacing, Margin: Integer;
  514. Glyph: TBitmap; Down, DownBold, HotTrackBold, CursorOnButton, Transparent, Enabled,
  515. PopupArrow, Focused, Default, FlatBorder, RoundCorner: Boolean; ModernBtnStyle: TModernBtnStyle;
  516. Color, DownColor, HotTrackColor, LightColor, ShadowColor: TColor;
  517. Font: TFont; Layout: TButtonLayout; Caption: string; Alignment: TAlignment; Wrap: Boolean);
  518. const
  519. clDeepShadow = $00404040;
  520. DownStyles: array[Boolean] of Integer = (BDR_RAISEDINNER, BDR_SUNKENOUTER);
  521. FillStyles: array[Boolean] of Integer = (BF_MIDDLE, 0);
  522. WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK or DT_EDITCONTROL);
  523. var
  524. CaptionHeight, CaptionWidth, GlyphHeight, GlyphWidth: Integer;
  525. GlyphIndex: Integer;
  526. Offset: Integer;
  527. clBackColor: TColor;
  528. CapX, CapY, GlX, GlY: Integer;
  529. aRect, oRect, wRect: TRect;
  530. FArrowGlyph: TPicture;
  531. UseDisabledBitmap: Boolean;
  532. MonoBmp: TBitmap;
  533. OldBrushStyle: TBrushStyle;
  534. OldPenColor: TColor;
  535. DrawStyle: LongInt;
  536. procedure DrawColorFade(StartColor, StopColor: TColor; Left, Top, Right, Bottom: Integer);
  537. var
  538. Counter, Buffer, FillStep: Integer;
  539. bR1, bG1, bB1, bR2, bG2, bB2: byte;
  540. aColor1, aColor2: LongInt;
  541. dCurrentR, dCurrentG, dCurrentB, dRStep, dGStep, dBStep: double;
  542. aOldStyle: TPenStyle;
  543. Height, DrawBottom: Integer;
  544. begin
  545. Height := (Bottom - Top);
  546. aOldStyle := Canvas.Pen.Style;
  547. Canvas.Pen.Style := psClear;
  548. aColor1 := ColorToRGB(StartColor);
  549. bR1 := GetRValue(aColor1);
  550. bG1 := GetGValue(aColor1);
  551. bB1 := GetBValue(aColor1);
  552. aColor2 := ColorToRGB(StopColor);
  553. bR2 := GetRValue(aColor2);
  554. bG2 := GetGValue(aColor2);
  555. bB2 := GetBValue(aColor2);
  556. dCurrentR := bR1;
  557. dCurrentG := bG1;
  558. dCurrentB := bB1;
  559. dRStep := (bR2 - bR1) / 31;
  560. dGStep := (bG2 - bG1) / 31;
  561. dBStep := (bB2 - bB1) / 31;
  562. FillStep := (Height div 31) + 1;
  563. for Counter := 0 to 31 do
  564. begin
  565. Buffer := Counter * Height div 31;
  566. Canvas.Brush.Color := RGB(Trunc(dCurrentR), Trunc(dCurrentG), Trunc(dCurrentB));
  567. dCurrentR := dCurrentR + dRStep;
  568. dCurrentG := dCurrentG + dGStep;
  569. dCurrentB := dCurrentB + dBStep;
  570. DrawBottom := Top + Buffer + FillStep;
  571. if DrawBottom > Bottom then
  572. DrawBottom := Bottom;
  573. Canvas.FillRect(Rect(Left, Top + Buffer, Right, DrawBottom));
  574. end;
  575. Canvas.Pen.Style := aOldStyle;
  576. end;
  577. procedure DrawGlyph(AGlyph: TBitmap; DestLeft, DestTop, SrcLeft, SrcTop,
  578. Width, Height: Integer); // transparent draw
  579. var
  580. APicture: TPicture;
  581. begin
  582. if AGlyph = nil then
  583. Exit;
  584. APicture := TPicture.Create;
  585. try
  586. APicture.Bitmap.Assign(AGlyph);
  587. APicture.Bitmap.Width := Width;
  588. APicture.Bitmap.Height := Height;
  589. APicture.Bitmap.Canvas.Draw(-SrcLeft, -SrcTop, AGlyph);
  590. APicture.Graphic.Transparent := True;
  591. Canvas.Draw(DestLeft, DestTop, APicture.Graphic);
  592. finally
  593. FreeAndNil(APicture);
  594. end;
  595. end;
  596. begin
  597. if not Enabled then
  598. Down := False;
  599. Offset := 0;
  600. if Down {and (ModernBtnStyle in [bsNormal, bsThin, bsModern])} then
  601. Offset := 1;
  602. clBackColor := ColorToRGB(Color);
  603. if CursorOnButton and (HotTrackColor <> clNone) then
  604. clBackColor := HotTrackColor;
  605. if Down and (DownColor <> clNone) then
  606. clBackColor := DownColor;
  607. // 不透明时填充背景
  608. Canvas.Brush.Color := clBackColor;
  609. if not Transparent or (ModernBtnStyle <> bsFlat) then
  610. begin
  611. if (ModernBtnStyle = bsModern) and RoundCorner then
  612. begin
  613. // 圆角时填充区域小点儿,免得圆角外被画出
  614. Canvas.FillRect(Rect(2, 2, Width - 2, Height - 2));
  615. end
  616. else
  617. Canvas.FillRect(Rect(0, 0, Width, Height));
  618. end;
  619. if FlatBorder and (ModernBtnStyle = bsFlat) then
  620. begin
  621. // 画平的外缘,但不填充内部
  622. OldBrushStyle := Canvas.Brush.Style;
  623. Canvas.Brush.Style := bsClear;
  624. OldPenColor := Canvas.Pen.Color;
  625. Canvas.Pen.Color := ShadowColor;
  626. Canvas.Rectangle(0, 0, Width, Height);
  627. Canvas.Brush.Style := OldBrushStyle;
  628. Canvas.Pen.Color := OldPenColor;
  629. end;
  630. if ModernBtnStyle = bsModern then
  631. begin
  632. // bsModer 风格,直接画渐变
  633. DrawColorFade(LightColor, clBackColor, 2, 2, Width - 2, Height div 4);
  634. DrawColorFade(clBackColor, LightColor, 2, Height div 4, Width - 2, Height - 2);
  635. end;
  636. Canvas.Brush.Style := bsClear;
  637. if ModernBtnStyle <> bsModern then
  638. begin
  639. if (ModernBtnStyle = bsThin) or (ModernBtnStyle = bsFlat) and
  640. (CursorOnButton or Down) then // Thin。如果设计期也欲给平的画边缘,此处增加条件即可
  641. begin
  642. // 这一段画比较薄的凸起,先用浅色画左上,再用深色画右下,按下时相反
  643. if Down then
  644. Canvas.Pen.Color := ShadowColor
  645. else
  646. Canvas.Pen.Color := LightColor;
  647. Canvas.MoveTo(0, Height - 1);
  648. Canvas.LineTo(0, 0);
  649. Canvas.LineTo(Width, 0);
  650. if Down then
  651. Canvas.Pen.Color := LightColor
  652. else
  653. Canvas.Pen.Color := ShadowColor;
  654. Canvas.MoveTo(Width - 1, 1);
  655. Canvas.LineTo(Width - 1, Height - 1);
  656. Canvas.LineTo(0, Height - 1);
  657. end
  658. else if ModernBtnStyle = bsNormal then
  659. begin
  660. // 这一段画比较厚的(Normal)的凸起,先用浅色画左上,再用深色画右下,再黑色画外右下
  661. if Down then // 按下的比较简单
  662. begin
  663. if IsSpeedButton then // SpeedButton 的按下效果不一样
  664. begin
  665. Canvas.Pen.Color := clDeepShadow;
  666. Canvas.MoveTo(0, Height - 1);
  667. Canvas.LineTo(0, 0);
  668. Canvas.LineTo(Width - 1, 0);
  669. Canvas.Pen.Color := ShadowColor;
  670. Canvas.MoveTo(Width - 3, 1);
  671. Canvas.LineTo(1, 1);
  672. Canvas.LineTo(1, Height - 2);
  673. Canvas.Pen.Color := LightColor;
  674. Canvas.MoveTo(Width - 1, 0);
  675. Canvas.LineTo(Width - 1, Height - 1);
  676. Canvas.LineTo(-1, Height - 1);
  677. end
  678. else
  679. begin
  680. Canvas.Pen.Color := clDeepShadow;
  681. Canvas.Rectangle(0, 0, Width, Height);
  682. Canvas.Pen.Color := ShadowColor;
  683. Canvas.Rectangle(1, 1, Width - 1, Height - 1);
  684. end;
  685. end
  686. else
  687. begin
  688. if Focused or Default then // 多重框框
  689. begin
  690. Canvas.Pen.Color := clBlack;
  691. Canvas.Rectangle(0, 0, Width, Height);
  692. Canvas.Pen.Color := LightColor;
  693. Canvas.MoveTo(1, Height - 2);
  694. Canvas.LineTo(1, 1);
  695. Canvas.LineTo(Width - 2, 1);
  696. Canvas.Pen.Color := ShadowColor;
  697. Canvas.MoveTo(Width - 3, 2);
  698. Canvas.LineTo(Width - 3, Height - 3);
  699. Canvas.LineTo(1, Height - 3);
  700. // 取 ShadowColor 和 clBlack 的中间色
  701. Canvas.Pen.Color := ShadowColor div 2 + clDeepShadow div 2;
  702. Canvas.MoveTo(Width - 2, 1);
  703. Canvas.LineTo(Width - 2, Height - 2);
  704. Canvas.LineTo(0, Height - 2);
  705. end
  706. else // 正常未 Focused 的 Button,比 Thin 多层右下黑框
  707. begin
  708. Canvas.Pen.Color := LightColor;
  709. Canvas.MoveTo(0, Height - 1);
  710. Canvas.LineTo(0, 0);
  711. Canvas.LineTo(Width - 1, 0);
  712. Canvas.Pen.Color := ShadowColor;
  713. Canvas.MoveTo(Width - 2, 1);
  714. Canvas.LineTo(Width - 2, Height - 2);
  715. Canvas.LineTo(1, Height - 2);
  716. Canvas.Pen.Color := clDeepShadow;
  717. Canvas.MoveTo(Width - 1, 1);
  718. Canvas.LineTo(Width - 1, Height - 1);
  719. Canvas.LineTo(0, Height - 1);
  720. end;
  721. end;
  722. end;
  723. end
  724. else // ModernBtnStyle = bsModern
  725. begin
  726. Canvas.Pen.Color := clBackColor;
  727. if Down then
  728. Canvas.Pen.Color := ShadowColor;
  729. Canvas.Rectangle(1, 1, Width - 1, Height - 1);
  730. Canvas.Pen.Color := ShadowColor;
  731. if RoundCorner then
  732. Canvas.RoundRect(0, 0, Width, Height, 6, 6)
  733. else
  734. Canvas.RoundRect(0, 0, Width, Height, 0, 0);
  735. end;
  736. Canvas.Font := Font;
  737. if (Down and DownBold) or (CursorOnButton and HotTrackBold) then
  738. Canvas.Font.Style := Canvas.Font.Style + [fsBold];
  739. if Glyph.Empty then
  740. Spacing := 0;
  741. GlyphHeight := Glyph.Height;
  742. if NumGlyphs <> 0 then
  743. GlyphWidth := Glyph.Width div NumGlyphs
  744. else
  745. GlyphWidth := 0;
  746. if Wrap then
  747. begin
  748. // 根据图片与排版方式预先计算一个可绘制区域的大小,用 Wrap 方式进行排版
  749. wRect := Rect(0, 0, Width - Margin * 2, Height - Margin * 2);
  750. if Layout in [blGlyphLeft, blGlyphRight] then
  751. wRect.Right := wRect.Right - GlyphWidth - Spacing;
  752. if Layout in [blGlyphTop, blGlyphBottom] then
  753. wRect.Bottom := wRect.Bottom - GlyphHeight - Spacing;
  754. DrawStyle := DT_CENTER or DT_VCENTER or WordWraps[Wrap] or DT_CALCRECT;
  755. DrawText(Canvas.Handle, PChar(Caption), Length(Caption), wRect, DrawStyle);
  756. CaptionHeight := wRect.Bottom - wRect.Top;
  757. CaptionWidth := wRect.Right - wRect.Left;
  758. end
  759. else
  760. begin
  761. CaptionHeight := Canvas.TextHeight(Caption);
  762. CaptionWidth := Canvas.TextWidth(Caption);
  763. end;
  764. GlyphIndex := 0;
  765. MonoBmp := nil;
  766. UseDisabledBitmap := False;
  767. if not Enabled then
  768. begin
  769. if NumGlyphs >= 2 then
  770. GlyphIndex := GlyphWidth
  771. else
  772. UseDisabledBitmap := True;
  773. end
  774. else
  775. begin
  776. if CursorOnButton and (NumGlyphs > 3) then
  777. GlyphIndex := 3 * GlyphWidth;
  778. if Down and (NumGlyphs > 2) then
  779. GlyphIndex := 2 * GlyphWidth;
  780. end;
  781. CapX := 0;
  782. CapY := 0;
  783. GlX := 0;
  784. GlY := 0;
  785. case Layout of
  786. blGlyphLeft:
  787. begin
  788. CapY := (Height - CaptionHeight) div 2;
  789. GlY := (Height - GlyphHeight) div 2;
  790. case Alignment of
  791. taLeftJustify:
  792. begin
  793. CapX := Margin + GlyphWidth + Spacing;
  794. GlX := Margin;
  795. end;
  796. taRightJustify:
  797. begin
  798. CapX := Width - CaptionWidth - Margin;
  799. GlX := Width - CaptionWidth - Margin - GlyphWidth - Spacing;
  800. end;
  801. taCenter:
  802. begin
  803. CapX := (Width - CaptionWidth - GlyphWidth - Spacing) div 2 + GlyphWidth + Spacing;
  804. GlX := (Width - CaptionWidth - GlyphWidth - Spacing) div 2;
  805. end;
  806. end;
  807. end;
  808. blGlyphRight:
  809. begin
  810. CapY := (Height - CaptionHeight) div 2;
  811. GlY := (Height - GlyphHeight) div 2;
  812. case Alignment of
  813. taLeftJustify:
  814. begin
  815. CapX := Margin;
  816. GlX := Spacing + Margin + CaptionWidth;
  817. end;
  818. taRightJustify:
  819. begin
  820. CapX := Width - Spacing - CaptionWidth - GlyphWidth - Margin;
  821. GlX := Width - GlyphWidth - Margin;
  822. end;
  823. taCenter:
  824. begin
  825. CapX := (Width - CaptionWidth - GlyphWidth - Spacing) div 2;
  826. GlX := (Width - CaptionWidth - GlyphWidth - Spacing) div 2 + CaptionWidth + Spacing;
  827. end;
  828. end;
  829. end;
  830. blGlyphTop:
  831. begin
  832. CapY := (Height - CaptionHeight - GlyphHeight - Spacing) div 2 + GlyphHeight + Spacing;
  833. GlY := (Height - CaptionHeight - GlyphHeight - Spacing) div 2;
  834. case Alignment of
  835. taLeftJustify:
  836. begin
  837. CapX := Margin;
  838. GlX := Margin;
  839. end;
  840. taRightJustify:
  841. begin
  842. CapX := Width - CaptionWidth - Margin;
  843. GlX := Width - GlyphWidth - Margin;
  844. end;
  845. taCenter:
  846. begin
  847. CapX := (Width - CaptionWidth) div 2;
  848. GlX := (Width - GlyphWidth) div 2;
  849. end;
  850. end;
  851. end;
  852. blGlyphBottom:
  853. begin
  854. CapY := (Height - CaptionHeight - GlyphHeight - Spacing) div 2;
  855. GlY := (Height - CaptionHeight - GlyphHeight - Spacing) div 2 + CaptionHeight + Spacing;
  856. case Alignment of
  857. taLeftJustify:
  858. begin
  859. CapX := Margin;
  860. GlX := Margin;
  861. end;
  862. taRightJustify:
  863. begin
  864. CapX := Width - CaptionWidth - Margin;
  865. GlX := Width - GlyphWidth - Margin;
  866. end;
  867. taCenter:
  868. begin
  869. CapX := (Width - CaptionWidth) div 2;
  870. GlX := (Width - GlyphWidth) div 2;
  871. end;
  872. end;
  873. end;
  874. end;
  875. if Offset > 0 then
  876. begin
  877. Inc(CapX, Offset);
  878. Inc(CapY, Offset);
  879. Inc(GlX, Offset);
  880. Inc(GlY, Offset);
  881. end;
  882. aRect := Rect(CapX, CapY, CapX + CaptionWidth, CapY + CaptionHeight);
  883. DrawStyle := DT_CENTER or DT_VCENTER or WordWraps[Wrap];
  884. // calc rect, and if multi-line, re-adjust rect.
  885. oRect := aRect;
  886. DrawText(Canvas.Handle, PChar(Caption), Length(Caption), aRect, DrawStyle or DT_CALCRECT);
  887. OffsetRect(aRect, 0, (oRect.Bottom - aRect.Bottom) div 2);
  888. OffsetRect(aRect, (oRect.Right - aRect.Right) div 2, 0);
  889. if not Enabled then
  890. begin
  891. OffsetRect(aRect, 1, 1);
  892. Canvas.Font.Color := clWhite;
  893. DrawText(Canvas.Handle, PChar(Caption), Length(Caption), aRect, DrawStyle);
  894. Canvas.Font.Color := clGray;
  895. OffsetRect(aRect, -1, -1);
  896. end;
  897. DrawText(Canvas.Handle, PChar(Caption), Length(Caption), aRect, DrawStyle);
  898. if not UseDisabledBitmap then
  899. DrawGlyph(Glyph, GlX, GlY, GlyphIndex, 0, GlyphWidth, GlyphHeight)
  900. else if Glyph.Handle <> 0 then
  901. begin
  902. // DONE: 用 ImageList 来处理 GlyphIndex 0 来绘制生成的 Disable 图片
  903. if FImageList = nil then
  904. FImageList := TImageList.Create(nil)
  905. else
  906. FImageList.Clear;
  907. FImageList.Height := Glyph.Height;
  908. FImageList.Width := Glyph.Width;
  909. // In some BPL case, Height and Width will be 0 and cause error, so check here.
  910. if (FImageList.Height > 0) and (FImageList.Width > 0) then
  911. begin
  912. // TODO: 用临界区保证绘制不冲突
  913. FImageList.Add(Glyph, Glyph);
  914. FImageList.Draw(Canvas, GlX, GlY, 0, False);
  915. end;
  916. FImageList.Clear;
  917. end;
  918. if PopupArrow then
  919. begin
  920. FArrowGlyph := TPicture.Create;
  921. try
  922. FArrowGlyph.Bitmap.LoadFromResourceName(hInstance, 'CNBTNARROW');
  923. FArrowGlyph.Graphic.Transparent := True;
  924. Canvas.Draw(Width - 11, Height div 2 - 1, FArrowGlyph.Graphic);
  925. finally
  926. FreeAndNil(FArrowGlyph);
  927. end;
  928. end;
  929. MonoBmp.Free;
  930. end;
  931. { TCnCustomButton }
  932. procedure TCnCustomButton.Click;
  933. var
  934. Form: TCustomForm;
  935. begin
  936. if Visible and Enabled then
  937. begin
  938. if FModalResult <> mrNone then
  939. begin
  940. Form := GetParentForm(Self);
  941. if Form <> nil then
  942. Form.ModalResult := FModalResult;
  943. end;
  944. if Assigned(PopupMenu) then
  945. PopupMenu.PopUp(ClientToScreen(Point(0, Height)).X, ClientToScreen(Point(0, Height)).Y);
  946. if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
  947. FOnClick(Self)
  948. else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
  949. begin
  950. {$IFDEF COMPILER5}
  951. ActionLink.Execute;
  952. {$ELSE}
  953. ActionLink.Execute(Self);
  954. {$ENDIF}
  955. end
  956. else if Assigned(FOnClick) then
  957. FOnClick(Self);
  958. end;
  959. end;
  960. procedure TCnCustomButton.CMEnabledChanged(var Message: TMessage);
  961. begin
  962. inherited;
  963. Invalidate;
  964. end;
  965. procedure TCnCustomButton.CMTextChanged(var Message: TMessage);
  966. begin
  967. Invalidate;
  968. end;
  969. constructor TCnCustomButton.Create(AOwner: TComponent);
  970. begin
  971. inherited Create(AOwner);
  972. Height := 25;
  973. Width := 75;
  974. ControlStyle := [csSetCaption, csCaptureMouse];
  975. FGlyph := TBitmap.Create;
  976. FGlyph.OnChange := GlyphChanged;
  977. { 2009-06-05 添加,处理FGlyph的onchange事件,否则当直接调用Glyph的方法控件无法得到通知及时刷新 }
  978. FSpacing := 4;
  979. FMargin := 4;
  980. FLightColor := clWhite;
  981. FShadowColor := clGray;
  982. FDownColor := clNone;
  983. FModernBtnStyle := bsNormal;
  984. FKind := bkCustom;
  985. TabStop := True;
  986. FBtnColorStyle := bcsCustom;
  987. FHotTrackColor := clNone;
  988. FAlignment := taCenter;
  989. FNumGlyphs := 1;
  990. FDefault := False;
  991. FCancel := False;
  992. FRoundCorner := True;
  993. Color := clBtnFace;
  994. end;
  995. procedure TCnCustomButton.CreateParams(var Params: TCreateParams);
  996. begin
  997. inherited CreateParams(Params);
  998. //Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
  999. (* 2008-07-22 注释掉,原因是包含WS_EX_TRANSPARENT风格的窗口无法响应WM_WINDOWPOSCHANGED消息 *)
  1000. end;
  1001. destructor TCnCustomButton.Destroy;
  1002. begin
  1003. FreeAndNil(FGlyph);
  1004. inherited;
  1005. end;
  1006. procedure TCnCustomButton.DoDialogChar(var Message: TCMDialogChar);
  1007. begin
  1008. if IsAccel(Message.CharCode, Caption) and
  1009. (Parent <> nil) {and Parent.Showing} and CanFocus then
  1010. begin
  1011. FDown := False;
  1012. Invalidate;
  1013. Click;
  1014. Message.Result := 1;
  1015. end
  1016. else
  1017. inherited;
  1018. end;
  1019. procedure TCnCustomButton.DoDialogKey(var Message: TCMDialogKey);
  1020. begin
  1021. FDown := False;
  1022. Invalidate;
  1023. if ((Message.CharCode = VK_RETURN) and FDefault) or
  1024. ((Message.CharCode = VK_ESCAPE) and FCancel) and
  1025. (KeyDataToShiftState(Message.KeyData) = []) and CanFocus then
  1026. begin
  1027. FDown := False;
  1028. Invalidate;
  1029. Click;
  1030. Message.Result := 1;
  1031. end
  1032. else
  1033. inherited;
  1034. end;
  1035. procedure TCnCustomButton.DoEnable(var Message: TMessage);
  1036. begin
  1037. SetEnabled(Message.WParam <> 0);
  1038. end;
  1039. procedure TCnCustomButton.DoFocusChanged(var Msg: TMessage);
  1040. begin
  1041. if (GetFocus() <> Self.Handle) and FDown then
  1042. PostMessage(Handle, WM_KEYUP, VK_RETURN, 0)
  1043. else
  1044. Invalidate;
  1045. inherited;
  1046. end;
  1047. procedure TCnCustomButton.DoKeyDown(var Msg: TMessage);
  1048. begin
  1049. if not Enabled then
  1050. Exit;
  1051. if Msg.WParam in [VK_SPACE, VK_RETURN] then
  1052. begin
  1053. FDown := True;
  1054. Invalidate;
  1055. end
  1056. else // if Msg.WParam in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN] then
  1057. inherited; // 必须全部 inherited 免得拦截了其它 ShortCut,感谢 KADU
  1058. end;
  1059. procedure TCnCustomButton.DoKeyUp(var Msg: TMessage);
  1060. var
  1061. IsClick: Boolean;
  1062. begin
  1063. IsClick := FDown;
  1064. FDown := False;
  1065. Invalidate;
  1066. if Enabled then
  1067. if (Msg.WParam in [VK_SPACE, VK_RETURN]) and IsClick then
  1068. Click
  1069. else if Msg.WParam in [VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN] then
  1070. inherited;
  1071. end;
  1072. procedure TCnCustomButton.DoMouseEnter(var Msg: TMessage);
  1073. begin
  1074. if Assigned(FOnMouseEnter) then
  1075. FOnMouseEnter(Self);
  1076. FCursorOnButton := True;
  1077. Invalidate;
  1078. end;
  1079. procedure TCnCustomButton.DoMouseLeave(var Msg: TMessage);
  1080. begin
  1081. if Assigned(FOnMouseLeave) then
  1082. FOnMouseLeave(Self);
  1083. FCursorOnButton := False;
  1084. Invalidate;
  1085. end;
  1086. procedure TCnCustomButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1087. X, Y: Integer);
  1088. begin
  1089. inherited;
  1090. if Enabled then
  1091. begin
  1092. FDown := True;
  1093. SetFocus;
  1094. Invalidate;
  1095. end;
  1096. end;
  1097. procedure TCnCustomButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  1098. Y: Integer);
  1099. var
  1100. IsClick: Boolean;
  1101. begin
  1102. inherited;
  1103. IsClick := FDown;
  1104. FDown := False;
  1105. Invalidate;
  1106. if IsClick and FCursorOnButton then
  1107. Click;
  1108. end;
  1109. procedure TCnCustomButton.Paint;
  1110. var
  1111. Bmp: TBitmap;
  1112. begin
  1113. if (csLoading in ComponentState) or (Parent = nil) then
  1114. Exit;
  1115. // 2009-06-29添加判断判断是否在设计期,否则在Visible为False时在设计期无法刷新控件
  1116. if not Visible and not (csDesigning in ComponentState) then
  1117. Exit;
  1118. if FModernBtnStyle = bsModern then // 现代模式直接画,以避免圆角底色问题,但可能闪烁
  1119. begin
  1120. if FRoundCorner then // 圆角时处理透明问题
  1121. RenewBack;
  1122. PaintButton(Canvas, False, Width, Height, FNumGlyphs, FSpacing, FMargin, FGlyph, FDown, FDownBold,
  1123. FHotTrackBold, FCursorOnButton, False, Enabled,
  1124. Assigned(PopupMenu), Focused, FDefault, FFlatBorder, FRoundCorner, FModernBtnStyle, Color, FDownColor,
  1125. FHotTrackColor, FLightColor, FShadowColor, Font, FLayout,
  1126. Caption, FAlignment, FWordWrap);
  1127. end
  1128. else // 其他模式采用一次性绘制,避免闪烁
  1129. begin
  1130. Bmp := TBitmap.Create;
  1131. Bmp.Width := Width;
  1132. Bmp.Height := Height;
  1133. PaintButton(Bmp.Canvas, False, Width, Height, FNumGlyphs, FSpacing, FMargin, FGlyph, FDown, FDownBold,
  1134. FHotTrackBold, FCursorOnButton{ or Focused}, False, Enabled,
  1135. Assigned(PopupMenu), Focused, FDefault, FFlatBorder, FRoundCorner, FModernBtnStyle, Color, FDownColor,
  1136. FHotTrackColor, FLightColor, FShadowColor, Font, FLayout,
  1137. Caption, FAlignment, FWordWrap);
  1138. Canvas.Draw(0, 0, Bmp);
  1139. Bmp.Free;
  1140. end;
  1141. if Focused and Enabled then
  1142. begin
  1143. if FModernBtnStyle = bsNormal then
  1144. Canvas.DrawFocusRect(Rect(4, 4, Width - 4, Height - 4))
  1145. else
  1146. Canvas.DrawFocusRect(Rect(2, 2, Width - 2, Height - 2));
  1147. end;
  1148. end;
  1149. procedure TCnCustomButton.SetAlignment(const Value: TAlignment);
  1150. begin
  1151. FAlignment := Value;
  1152. Invalidate;
  1153. end;
  1154. procedure TCnCustomButton.SetBtnColorStyle(const Value: TBtnColorStyle);
  1155. var
  1156. AColor: TColor;
  1157. begin
  1158. FBtnColorStyle := Value;
  1159. if Value = bcsCustom then
  1160. Exit;
  1161. GetPreDefinedColors(Value, AColor, FLightColor, FShadowColor, FDownColor,
  1162. FHotTrackColor, FModernBtnStyle, FFlatBorder);
  1163. Color := AColor;
  1164. Invalidate;
  1165. end;
  1166. procedure TCnCustomButton.SetGlyph(const Value: TBitmap);
  1167. begin
  1168. if Value <> nil then
  1169. begin
  1170. FGlyph.Assign(Value);
  1171. if Value.Height <> 0 then
  1172. FNumGlyphs := Value.Width div Value.Height
  1173. else
  1174. FNumGlyphs := 0;
  1175. end
  1176. else
  1177. begin
  1178. FGlyph.Height := 0;
  1179. FNumGlyphs := 0;
  1180. end;
  1181. FKind := bkCustom;
  1182. Invalidate;
  1183. end;
  1184. procedure TCnCustomButton.SetKind(const Value: TBitBtnKind);
  1185. begin
  1186. if Value <> bkCustom then
  1187. FNumGlyphs := 2;
  1188. case Value of
  1189. bkOK:
  1190. begin
  1191. ModalResult := mrOK;
  1192. FGlyph.LoadFromResourceName(hInstance, 'CNBTNOK');
  1193. Caption := '&OK';
  1194. end;
  1195. bkCancel:
  1196. begin
  1197. ModalResult := mrCancel;
  1198. FGlyph.LoadFromResourceName(hInstance, 'CNBTNCANCEL');
  1199. Caption := '&Cancel';
  1200. end;
  1201. bkHelp:
  1202. begin
  1203. ModalResult := mrNone;
  1204. FGlyph.LoadFromResourceName(hInstance, 'CNBTNHELP');
  1205. Caption := '&Help';
  1206. end;
  1207. bkYes:
  1208. begin
  1209. ModalResult := mrYes;
  1210. FGlyph.LoadFromResourceName(hInstance, 'CNBTNYES');
  1211. Caption := '&Yes';
  1212. end;
  1213. bkNo:
  1214. begin
  1215. ModalResult := mrNo;
  1216. FGlyph.LoadFromResourceName(hInstance, 'CNBTNNO');
  1217. Caption := '&No';
  1218. end;
  1219. bkClose:
  1220. begin
  1221. ModalResult := mrNone;
  1222. FGlyph.LoadFromResourceName(hInstance, 'CNBTNCLOSE');
  1223. Caption := '&Close';
  1224. end;
  1225. bkAbort:
  1226. begin
  1227. ModalResult := mrAbort;
  1228. FGlyph.LoadFromResourceName(hInstance, 'CNBTNABORT');
  1229. Caption := '&Abort';
  1230. end;
  1231. bkRetry:
  1232. begin
  1233. ModalResult := mrRetry;
  1234. FGlyph.LoadFromResourceName(hInstance, 'CNBTNRETRY');
  1235. Caption := '&Retry';
  1236. end;
  1237. bkIgnore:
  1238. begin
  1239. ModalResult := mrIgnore;
  1240. FGlyph.LoadFromResourceName(hInstance, 'CNBTNIGNORE');
  1241. Caption := '&Ignore';
  1242. end;
  1243. bkAll:
  1244. begin
  1245. ModalResult := mrAll;
  1246. FGlyph.LoadFromResourceName(hInstance, 'CNBTNALL');
  1247. Caption := '&All';
  1248. end;
  1249. end;
  1250. FKind := Value;
  1251. Invalidate;
  1252. end;
  1253. procedure TCnCustomButton.SetLayout(const Value: TButtonLayout);
  1254. begin
  1255. FLayout := Value;
  1256. Invalidate;
  1257. end;
  1258. procedure TCnCustomButton.SetLightColor(const Value: TColor);
  1259. begin
  1260. if FLightColor <> Value then
  1261. begin
  1262. FLightColor := Value;
  1263. FBtnColorStyle := bcsCustom;
  1264. Invalidate;
  1265. end;
  1266. end;
  1267. procedure TCnCustomButton.SetModalResult(const Value: TModalResult);
  1268. begin
  1269. FModalResult := Value;
  1270. FKind := bkCustom;
  1271. end;
  1272. procedure TCnCustomButton.SetNumGlyphs(const Value: Integer);
  1273. begin
  1274. FNumGlyphs := Value;
  1275. Invalidate;
  1276. end;
  1277. procedure TCnCustomButton.SetShadowColor(const Value: TColor);
  1278. begin
  1279. if FShadowColor <> Value then
  1280. begin
  1281. FShadowColor := Value;
  1282. FBtnColorStyle := bcsCustom;
  1283. Invalidate;
  1284. end;
  1285. end;
  1286. procedure TCnCustomButton.SetModernBtnStyle(const Value: TModernBtnStyle);
  1287. begin
  1288. if FModernBtnStyle <> Value then
  1289. begin
  1290. FModernBtnStyle := Value;
  1291. FBtnColorStyle := bcsCustom;
  1292. Invalidate;
  1293. end;
  1294. end;
  1295. procedure TCnCustomButton.CMFontChanged(var Message: TMessage);
  1296. begin
  1297. Invalidate;
  1298. end;
  1299. procedure TCnCustomButton.CNCommand(var Message: TWMCommand);
  1300. begin
  1301. if Message.NotifyCode = BN_CLICKED then
  1302. Click;
  1303. end;
  1304. procedure TCnCustomButton.SetCancel(const Value: Boolean);
  1305. begin
  1306. FCancel := Value;
  1307. if FCancel then
  1308. Default := False;
  1309. end;
  1310. procedure TCnCustomButton.SetDefault(const Value: Boolean);
  1311. var
  1312. Form: TCustomForm;
  1313. begin
  1314. FDefault := Value;
  1315. if FDefault then
  1316. Cancel := False;
  1317. if HandleAllocated then
  1318. begin
  1319. Form := GetParentForm(Self);
  1320. if Form <> nil then
  1321. Form.Perform(CM_FOCUSCHANGED, 0, Longint(Form.ActiveControl));
  1322. end;
  1323. end;
  1324. procedure TCnCustomButton.SetFlatBorder(const Value: Boolean);
  1325. begin
  1326. if FFlatBorder <> Value then
  1327. begin
  1328. FFlatBorder := Value;
  1329. FBtnColorStyle := bcsCustom;
  1330. Invalidate;
  1331. end;
  1332. end;
  1333. procedure TCnCustomButton.ActionChange(Sender: TObject;
  1334. CheckDefaults: Boolean);
  1335. begin
  1336. inherited;
  1337. if Sender is TCustomAction then
  1338. with TCustomAction(Sender) do
  1339. begin
  1340. if (Glyph.Empty) and (ActionList <> nil) and (ActionList.Images <> nil) and
  1341. (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count) then
  1342. CopyImage(Glyph, ActionList.Images, ImageIndex);
  1343. end;
  1344. end;
  1345. procedure TCnCustomButton.SetDownBold(const Value: Boolean);
  1346. begin
  1347. if FDownBold <> Value then
  1348. begin
  1349. FDownBold := Value;
  1350. if FDown then
  1351. Invalidate;
  1352. end;
  1353. end;
  1354. procedure TCnCustomButton.SetDownColor(const Value: TColor);
  1355. begin
  1356. if FDownColor <> Value then
  1357. begin
  1358. FDownColor := Value;
  1359. if FDown then
  1360. Invalidate;
  1361. end;
  1362. end;
  1363. procedure TCnCustomButton.SetHotTrackBold(const Value: Boolean);
  1364. begin
  1365. if FHotTrackBold <> Value then
  1366. begin
  1367. FHotTrackBold := Value;
  1368. if FCursorOnButton then
  1369. Invalidate;
  1370. end;
  1371. end;
  1372. procedure TCnCustomButton.SetHotTrackColor(const Value: TColor);
  1373. begin
  1374. if FHotTrackColor <> Value then
  1375. begin
  1376. FHotTrackColor := Value;
  1377. if FCursorOnButton or Focused then
  1378. Invalidate;
  1379. end;
  1380. end;
  1381. procedure TCnCustomButton.SetSpacing(const Value: Integer);
  1382. begin
  1383. if FSpacing <> Value then
  1384. begin
  1385. FSpacing := Value;
  1386. Invalidate;
  1387. end;
  1388. end;
  1389. procedure TCnCustomButton.SetMargin(const Value: Integer);
  1390. begin
  1391. if FMargin <> Value then
  1392. begin
  1393. FMargin := Value;
  1394. Invalidate;
  1395. end;
  1396. end;
  1397. procedure TCnCustomButton.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  1398. begin
  1399. if (FModernBtnStyle = bsModern) and FRoundCorner then
  1400. Message.Result := 0;
  1401. end;
  1402. procedure TCnCustomButton.SetRoundCorner(const Value: Boolean);
  1403. begin
  1404. if FRoundCorner <> Value then
  1405. begin
  1406. FRoundCorner := Value;
  1407. Invalidate;
  1408. end;
  1409. end;
  1410. procedure TCnCustomButton.RenewBack;
  1411. var
  1412. ABitmap: TBitmap;
  1413. FBackBitmap: TBitmap;
  1414. begin
  1415. ABitmap := TBitmap.Create;
  1416. FBackBitmap := TBitmap.Create;
  1417. try
  1418. FBackBitmap.Width := Width;
  1419. FBackBitmap.Height := Height;
  1420. ABitmap.PixelFormat := pf24bit;
  1421. ABitmap.Width := -Parent.ClientOrigin.X + ClientOrigin.X + Width;
  1422. ABitmap.Height := -Parent.ClientOrigin.Y + ClientOrigin.Y + Height;
  1423. ABitmap.Canvas.Brush.Color := Parent.Brush.Color;
  1424. ABitmap.Canvas.FillRect(Rect(0, 0, ABitmap.Width, ABitmap.Height));
  1425. SendMessage(Parent.Handle, WM_PAINT, ABitmap.Canvas.Handle, 0);
  1426. if not (csDesigning in ComponentState) then // 2008年08月03日添加判断,否则在设计期会出现错误
  1427. Application.ProcessMessages;
  1428. FBackBitmap.Canvas.Draw(Parent.ClientOrigin.X - ClientOrigin.x,
  1429. Parent.ClientOrigin.Y - ClientOrigin.Y, ABitmap);
  1430. Canvas.Draw(0, 0, FBackBitmap);
  1431. finally
  1432. FreeAndNil(FBackBitmap);
  1433. FreeAndNil(ABitmap);
  1434. end;
  1435. end;
  1436. procedure TCnCustomButton.WMWindowPosChanged(var Message: TMessage);
  1437. begin
  1438. Invalidate;
  1439. inherited;
  1440. // 2008年08月03日添加,如果不继承原消息处理将会使控件无法改变大小- -
  1441. end;
  1442. procedure TCnCustomButton.GlyphChanged(Sender: TObject);
  1443. begin
  1444. Invalidate;
  1445. end;
  1446. procedure TCnCustomButton.SetWordWrap(const Value: Boolean);
  1447. begin
  1448. FWordWrap := Value;
  1449. end;
  1450. { TCnSpeedButton }
  1451. constructor TCnSpeedButton.Create(AOwner: TComponent);
  1452. begin
  1453. inherited Create(AOwner);
  1454. SetBounds(0, 0, 23, 22);
  1455. ControlStyle := [csCaptureMouse, csDoubleClicks];
  1456. ParentFont := True;
  1457. Color := clBtnFace;
  1458. FAlignment := taCenter;
  1459. FSpacing := 4;
  1460. FMargin := 4;
  1461. FLayout := blGlyphLeft;
  1462. FNumGlyphs := 1;
  1463. FLightColor := clWhite;
  1464. FShadowColor := clGray;
  1465. FDownColor := clNone;
  1466. FModernBtnStyle := bsNormal;
  1467. FRoundCorner := True;
  1468. FBtnColorStyle := bcsCustom;
  1469. FHotTrackColor := clNone;
  1470. FTransparent := False;
  1471. FGlyph := TBitmap.Create;
  1472. FGlyph.OnChange := GlyphChanged;
  1473. { 2009-06-05 添加,处理FGlyph的onchange事件,否则当直接调用Glyph的方法控件无法得到通知及时刷新 }
  1474. end;
  1475. destructor TCnSpeedButton.Destroy;
  1476. begin
  1477. FGlyph.Free;
  1478. inherited Destroy;
  1479. end;
  1480. procedure TCnSpeedButton.Click;
  1481. begin
  1482. inherited Click;
  1483. end;
  1484. procedure TCnSpeedButton.Paint;
  1485. var
  1486. Down: Boolean;
  1487. begin
  1488. if (csLoading in ComponentState) or (Parent = nil) then
  1489. Exit;
  1490. // 2009-06-29添加判断判断是否在设计期,否则在Visible为FALSE时在设计期无法刷新控件
  1491. if not Visible and not (csDesigning in ComponentState) then
  1492. Exit;
  1493. if not Enabled then
  1494. begin
  1495. FState := bsDisabled;
  1496. FDragging := False;
  1497. end
  1498. else if FState = bsDisabled then
  1499. if FDown and (GroupIndex <> 0) then
  1500. FState := bsExclusive
  1501. else
  1502. FState := bsUp;
  1503. Down := FDown;
  1504. case FState of
  1505. bsUp:
  1506. begin
  1507. if not Enabled then
  1508. Enabled := True;
  1509. if FDown then
  1510. begin
  1511. Down := False;
  1512. FDown := False;
  1513. end;
  1514. end;
  1515. bsDisabled:
  1516. begin
  1517. if Enabled then
  1518. Enabled := False;
  1519. if FDown then
  1520. begin
  1521. Down := False;
  1522. FDown := False;
  1523. end;
  1524. end;
  1525. bsDown:
  1526. begin
  1527. if not Enabled then
  1528. Enabled := True;
  1529. if not FDown then
  1530. begin
  1531. Down := True; // FDown 由其它消息处理
  1532. // FDown := True;
  1533. end;
  1534. end;
  1535. bsExclusive:
  1536. begin
  1537. if not Enabled then
  1538. Enabled := True;
  1539. if not FDown then
  1540. begin
  1541. Down := True;
  1542. FDown := True;
  1543. end;
  1544. end;
  1545. end;
  1546. PaintButton(Canvas, True, Width, Height, FNumGlyphs, FSpacing, FMargin, FGlyph, Down, FDownBold,
  1547. FHotTrackBold, CursorOnButton{ or Focused}, Transparent and (ModernBtnStyle <> bsModern), Enabled,
  1548. Assigned(PopupMenu), False, False, FFlatBorder, FRoundCorner, FModernBtnStyle, Color, FDownColor,
  1549. FHotTrackColor, FLightColor, FShadowColor, Font, FLayout,
  1550. Caption, FAlignment, False);
  1551. end;
  1552. procedure TCnSpeedButton.UpdateTracking;
  1553. var
  1554. P: TPoint;
  1555. begin
  1556. if Enabled then
  1557. begin
  1558. GetCursorPos(P);
  1559. FCursorOnButton := not (FindDragTarget(P, True) = Self);
  1560. if FCursorOnButton then
  1561. Perform(CM_MOUSELEAVE, 0, 0)
  1562. else
  1563. Perform(CM_MOUSEENTER, 0, 0);
  1564. end;
  1565. end;
  1566. procedure TCnSpeedButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1567. X, Y: Integer);
  1568. begin
  1569. inherited MouseDown(Button, Shift, X, Y);
  1570. if (Button = mbLeft) and Enabled then
  1571. begin
  1572. if not FDown then
  1573. begin
  1574. FState := bsDown;
  1575. Invalidate;
  1576. end;
  1577. FDragging := True;
  1578. end;
  1579. end;
  1580. procedure TCnSpeedButton.MouseMove(Shift: TShiftState; X, Y: Integer);
  1581. var
  1582. NewState: TButtonState;
  1583. begin
  1584. inherited MouseMove(Shift, X, Y);
  1585. if FDragging then
  1586. begin
  1587. if not FDown then NewState := bsUp
  1588. else NewState := bsExclusive;
  1589. if (X >= 0) and (X < ClientWidth) and (Y >= 0) and (Y <= ClientHeight) then
  1590. if FDown then NewState := bsExclusive else NewState := bsDown;
  1591. if NewState <> FState then
  1592. begin
  1593. FState := NewState;
  1594. Invalidate;
  1595. end;
  1596. end
  1597. else if not FCursorOnButton then
  1598. UpdateTracking;
  1599. end;
  1600. procedure TCnSpeedButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
  1601. X, Y: Integer);
  1602. var
  1603. DoClick: Boolean;
  1604. begin
  1605. inherited MouseUp(Button, Shift, X, Y);
  1606. if FDragging then
  1607. begin
  1608. FDragging := False;
  1609. DoClick := (X >= 0) and (X < ClientWidth) and (Y >= 0) and (Y <= ClientHeight);
  1610. if FGroupIndex = 0 then
  1611. begin
  1612. { Redraw face in-case mouse is captured }
  1613. FState := bsUp;
  1614. FCursorOnButton := False;
  1615. if DoClick and not (FState in [bsExclusive, bsDown]) then
  1616. Invalidate;
  1617. end
  1618. else
  1619. if DoClick then
  1620. begin
  1621. SetDown(not FDown);
  1622. if FDown then Repaint;
  1623. end
  1624. else
  1625. begin
  1626. if FDown then FState := bsExclusive;
  1627. Repaint;
  1628. end;
  1629. if DoClick then
  1630. Click;
  1631. UpdateTracking;
  1632. end;
  1633. end;
  1634. function TCnSpeedButton.GetPalette: HPALETTE;
  1635. begin
  1636. Result := Glyph.Palette;
  1637. end;
  1638. function TCnSpeedButton.GetGlyph: TBitmap;
  1639. begin
  1640. Result := FGlyph;
  1641. end;
  1642. procedure TCnSpeedButton.SetGlyph(Value: TBitmap);
  1643. begin
  1644. if Value <> nil then
  1645. begin
  1646. FGlyph.Assign(Value);
  1647. if Value.Height <> 0 then
  1648. FNumGlyphs := Value.Width div Value.Height
  1649. else
  1650. FNumGlyphs := 0;
  1651. end
  1652. else
  1653. begin
  1654. FGlyph.Height := 0;
  1655. FNumGlyphs := 0;
  1656. end;
  1657. Invalidate;
  1658. end;
  1659. function TCnSpeedButton.GetNumGlyphs: TNumGlyphs;
  1660. begin
  1661. Result := FNumGlyphs;
  1662. end;
  1663. procedure TCnSpeedButton.SetNumGlyphs(Value: TNumGlyphs);
  1664. begin
  1665. if Value < Low(TNumGlyphs) then
  1666. Value := Low(TNumGlyphs)
  1667. else if Value > High(TNumGlyphs) then
  1668. Value := High(TNumGlyphs);
  1669. if Value <> FNumGlyphs then
  1670. begin
  1671. FNumGlyphs := Value;
  1672. Invalidate;
  1673. end;
  1674. end;
  1675. procedure TCnSpeedButton.UpdateExclusive;
  1676. var
  1677. Msg: TMessage;
  1678. begin
  1679. if (FGroupIndex <> 0) and (Parent <> nil) then
  1680. begin
  1681. Msg.Msg := CM_BUTTONPRESSED;
  1682. Msg.WParam := FGroupIndex;
  1683. Msg.LParam := Longint(Self);
  1684. Msg.Result := 0;
  1685. Parent.Broadcast(Msg);
  1686. end;
  1687. end;
  1688. procedure TCnSpeedButton.SetDown(Value: Boolean);
  1689. begin
  1690. if FGroupIndex = 0 then Value := False;
  1691. if Value <> FDown then
  1692. begin
  1693. if FDown and (not FAllowAllUp) then Exit;
  1694. FDown := Value;
  1695. if Value then
  1696. begin
  1697. if FState = bsUp then Invalidate;
  1698. FState := bsExclusive
  1699. end
  1700. else
  1701. begin
  1702. FState := bsUp;
  1703. Repaint;
  1704. end;
  1705. if Value then
  1706. UpdateExclusive;
  1707. end;
  1708. end;
  1709. procedure TCnSpeedButton.SetGroupIndex(Value: Integer);
  1710. begin
  1711. if FGroupIndex <> Value then
  1712. begin
  1713. FGroupIndex := Value;
  1714. UpdateExclusive;
  1715. end;
  1716. end;
  1717. procedure TCnSpeedButton.SetLayout(Value: TButtonLayout);
  1718. begin
  1719. if FLayout <> Value then
  1720. begin
  1721. FLayout := Value;
  1722. Invalidate;
  1723. end;
  1724. end;
  1725. procedure TCnSpeedButton.SetMargin(Value: Integer);
  1726. begin
  1727. if (Value <> FMargin) and (Value >= 0) then
  1728. begin
  1729. FMargin := Value;
  1730. Invalidate;
  1731. end;
  1732. end;
  1733. procedure TCnSpeedButton.SetSpacing(Value: Integer);
  1734. begin
  1735. if Value <> FSpacing then
  1736. begin
  1737. FSpacing := Value;
  1738. Invalidate;
  1739. end;
  1740. end;
  1741. procedure TCnSpeedButton.SetTransparent(Value: Boolean);
  1742. begin
  1743. if not (csLoading in ComponentState) and (FModernBtnStyle <> bsFlat) then
  1744. Value := False;
  1745. if Value <> FTransparent then
  1746. begin
  1747. FTransparent := Value;
  1748. if Value then
  1749. ControlStyle := ControlStyle - [csOpaque] else
  1750. ControlStyle := ControlStyle + [csOpaque];
  1751. Invalidate;
  1752. end;
  1753. end;
  1754. procedure TCnSpeedButton.SetAllowAllUp(Value: Boolean);
  1755. begin
  1756. if FAllowAllUp <> Value then
  1757. begin
  1758. FAllowAllUp := Value;
  1759. UpdateExclusive;
  1760. end;
  1761. end;
  1762. procedure TCnSpeedButton.WMLButtonDblClk(var Message: TWMLButtonDown);
  1763. begin
  1764. inherited;
  1765. if FDown then DblClick;
  1766. end;
  1767. procedure TCnSpeedButton.CMEnabledChanged(var Message: TMessage);
  1768. begin
  1769. UpdateTracking;
  1770. Repaint;
  1771. end;
  1772. procedure TCnSpeedButton.CMButtonPressed(var Message: TMessage);
  1773. var
  1774. Sender: TCnSpeedButton;
  1775. begin
  1776. if Integer(Message.WParam) = FGroupIndex then
  1777. begin
  1778. Sender := TCnSpeedButton(Message.LParam);
  1779. if Sender <> Self then
  1780. begin
  1781. if Sender.Down and FDown then
  1782. begin
  1783. FDown := False;
  1784. FState := bsUp;
  1785. Invalidate;
  1786. end;
  1787. FAllowAllUp := Sender.AllowAllUp;
  1788. end;
  1789. end;
  1790. end;
  1791. procedure TCnSpeedButton.CMDialogChar(var Message: TCMDialogChar);
  1792. begin
  1793. with Message do
  1794. if IsAccel(CharCode, Caption) and Enabled and Visible and
  1795. (Parent <> nil) and Parent.Showing then
  1796. begin
  1797. Click;
  1798. Result := 1;
  1799. end
  1800. else
  1801. inherited;
  1802. end;
  1803. procedure TCnSpeedButton.CMFontChanged(var Message: TMessage);
  1804. begin
  1805. Repaint;
  1806. end;
  1807. procedure TCnSpeedButton.CMTextChanged(var Message: TMessage);
  1808. begin
  1809. Repaint;
  1810. end;
  1811. procedure TCnSpeedButton.CMSysColorChange(var Message: TMessage);
  1812. begin
  1813. Repaint;
  1814. end;
  1815. procedure TCnSpeedButton.CMMouseEnter(var Message: TMessage);
  1816. begin
  1817. inherited;
  1818. if not FCursorOnButton and Enabled and (DragMode <> dmAutomatic)
  1819. and (GetCapture = 0) then
  1820. begin
  1821. FCursorOnButton := True;
  1822. Invalidate;
  1823. end;
  1824. if Assigned(FOnMouseEnter) then
  1825. FOnMouseEnter(Self);
  1826. end;
  1827. procedure TCnSpeedButton.CMMouseLeave(var Message: TMessage);
  1828. begin
  1829. inherited;
  1830. if FCursorOnButton and Enabled and not FDragging then
  1831. begin
  1832. FCursorOnButton := False;
  1833. Invalidate;
  1834. end;
  1835. if Assigned(FOnMouseLeave) then
  1836. FOnMouseLeave(Self);
  1837. end;
  1838. procedure TCnSpeedButton.ActionChange(Sender: TObject; CheckDefaults: Boolean);
  1839. begin
  1840. inherited ActionChange(Sender, CheckDefaults);
  1841. if Sender is TCustomAction then
  1842. with TCustomAction(Sender) do
  1843. begin
  1844. if (Glyph.Empty) and (ActionList <> nil) and (ActionList.Images <> nil) and
  1845. (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count) then
  1846. CopyImage(Glyph, ActionList.Images, ImageIndex);
  1847. end;
  1848. end;
  1849. procedure TCnSpeedButton.SetBtnColorStyle(const Value: TBtnColorStyle);
  1850. var
  1851. AColor: TColor;
  1852. begin
  1853. FBtnColorStyle := Value;
  1854. if Value = bcsCustom then
  1855. Exit;
  1856. GetPreDefinedColors(Value, AColor, FLightColor, FShadowColor, FDownColor,
  1857. FHotTrackColor, FModernBtnStyle, FFlatBorder);
  1858. Color := AColor;
  1859. Invalidate;
  1860. end;
  1861. procedure TCnSpeedButton.SetFlatBorder(const Value: Boolean);
  1862. begin
  1863. if FFlatBorder <> Value then
  1864. begin
  1865. FFlatBorder := Value;
  1866. FBtnColorStyle := bcsCustom;
  1867. Invalidate;
  1868. end;
  1869. end;
  1870. procedure TCnSpeedButton.SetLightColor(const Value: TColor);
  1871. begin
  1872. if FLightColor <> Value then
  1873. begin
  1874. FLightColor := Value;
  1875. FBtnColorStyle := bcsCustom;
  1876. Invalidate;
  1877. end;
  1878. end;
  1879. procedure TCnSpeedButton.SetModernBtnStyle(const Value: TModernBtnStyle);
  1880. begin
  1881. if FModernBtnStyle <> Value then
  1882. begin
  1883. FModernBtnStyle := Value;
  1884. FBtnColorStyle := bcsCustom;
  1885. if Value <> bsFlat then
  1886. Transparent := False;
  1887. Invalidate;
  1888. end;
  1889. end;
  1890. procedure TCnSpeedButton.SetShadowColor(const Value: TColor);
  1891. begin
  1892. if FShadowColor <> Value then
  1893. begin
  1894. FShadowColor := Value;
  1895. FBtnColorStyle := bcsCustom;
  1896. Invalidate;
  1897. end;
  1898. end;
  1899. procedure TCnSpeedButton.SetAlignment(const Value: TAlignment);
  1900. begin
  1901. if FAlignment <> Value then
  1902. begin
  1903. FAlignment := Value;
  1904. Invalidate;
  1905. end;
  1906. end;
  1907. procedure TCnSpeedButton.SetDownBold(const Value: Boolean);
  1908. begin
  1909. if FDownBold <> Value then
  1910. begin
  1911. FDownBold := Value;
  1912. if FDown then
  1913. Invalidate;
  1914. end;
  1915. end;
  1916. procedure TCnSpeedButton.SetDownColor(const Value: TColor);
  1917. begin
  1918. if FDownColor <> Value then
  1919. begin
  1920. FDownColor := Value;
  1921. Transparent := False;
  1922. if FDown then
  1923. Invalidate;
  1924. end;
  1925. end;
  1926. procedure TCnSpeedButton.SetHotTrackBold(const Value: Boolean);
  1927. begin
  1928. if FHotTrackBold <> Value then
  1929. begin
  1930. FHotTrackBold := Value;
  1931. if FCursorOnButton then
  1932. Invalidate;
  1933. end;
  1934. end;
  1935. procedure TCnSpeedButton.SetHotTrackColor(const Value: TColor);
  1936. begin
  1937. if FHotTrackColor <> Value then
  1938. begin
  1939. FHotTrackColor := Value;
  1940. Transparent := False;
  1941. if FCursorOnButton then
  1942. Invalidate;
  1943. end;
  1944. end;
  1945. procedure TCnSpeedButton.SetRoundCorner(const Value: Boolean);
  1946. begin
  1947. if FRoundCorner <> Value then
  1948. begin
  1949. FRoundCorner := Value;
  1950. Invalidate;
  1951. end;
  1952. end;
  1953. procedure TCnSpeedButton.GlyphChanged(Sender: TObject);
  1954. begin
  1955. Invalidate;
  1956. end;
  1957. function TCnSpeedButton.GetFlat: Boolean;
  1958. begin
  1959. Result := FModernBtnStyle = bsFlat;
  1960. end;
  1961. procedure TCnSpeedButton.SetFlat(const Value: Boolean);
  1962. begin
  1963. if Flat <> Value then
  1964. begin
  1965. if Value then
  1966. ModernBtnStyle := bsFlat
  1967. else
  1968. ModernBtnStyle := bsNormal;
  1969. end;
  1970. end;
  1971. initialization
  1972. finalization
  1973. FreeAndNil(FImageList);
  1974. end.