PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Components/EhLib 4.2/Common/ToolCtrlsEh.pas

http://github.com/mitshel/tech-inv
Pascal | 1897 lines | 1560 code | 183 blank | 154 comment | 174 complexity | 10995667b0549dc887a299b27712be12 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. {*******************************************************}
  2. { }
  3. { EhLib v4.2 }
  4. { Tool controls }
  5. { (Build 4.2.05) }
  6. { }
  7. { Copyright (c) 2001-2006 by Dmitry V. Bolshakov }
  8. { }
  9. {*******************************************************}
  10. {$I EhLib.Inc}
  11. {$IFDEF EH_LIB_VCL}
  12. unit ToolCtrlsEh {$IFDEF CIL} platform {$ENDIF};
  13. {$ELSE}
  14. unit QToolCtrlsEh;
  15. {$ENDIF}
  16. interface
  17. {$IFDEF EH_LIB_VCL}
  18. uses
  19. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  20. {$IFDEF EH_LIB_5} Contnrs, ActnList, {$ENDIF}
  21. {$IFDEF EH_LIB_6} Variants, {$ENDIF}
  22. {$IFDEF CIL}
  23. EhLibVCLNET,
  24. {$ELSE}
  25. EhLibVCL,
  26. {$ENDIF}
  27. StdCtrls, Mask, Db, DBCtrls, Buttons, ExtCtrls, Menus, ComCtrls, CommCtrl,
  28. Imglist;
  29. {$ELSE}
  30. uses
  31. QGraphics, QControls, QForms, QDialogs, Variants, QStdCtrls, QMask,
  32. QDBCtrls, QButtons, QExtCtrls, QMenus, QComCtrls, QImglist,
  33. Db, SysUtils, Classes;
  34. {$ENDIF}
  35. const
  36. CM_IGNOREEDITDOWN = WM_USER + 102;
  37. type
  38. TLocateTextOptionEh = (ltoCaseInsensitiveEh, ltoAllFieldsEh, ltoMatchFormatEh, ltoIgnoteCurrentPosEh);
  39. TLocateTextOptionsEh = set of TLocateTextOptionEh;
  40. TLocateTextDirectionEh = (ltdUpEh, ltdDownEh, ltdAllEh);
  41. TLocateTextMatchingEh = (ltmAnyPartEh, ltmWholeEh, ltmFromBegingEh);
  42. TLocateTextTreeFindRangeEh = (lttInAllNodesEh, lttInExpandedNodesEh,
  43. lttInCurrentLevelEh, lttInCurrentNodeEh);
  44. IMemTableDataFieldValueListEh = interface
  45. ['{28F8194C-5FF3-42C4-87A6-8B3E06210FA6}']
  46. function GetValues: TStrings;
  47. end;
  48. IMemTableEh = interface
  49. ['{A8C3C87A-E556-4BDB-B8A7-5B33497D1624}']
  50. // property TreeViewMode: Boolean read GetTreeViewMode write SetTreeViewMode;
  51. function FetchRecords(Count: Integer): Integer;
  52. function GetInstantReadCurRowNum: Integer;
  53. function GetTreeNodeExpanded(RowNum: Integer): Boolean; overload;
  54. function GetTreeNodeExpanded: Boolean; overload;
  55. function GetTreeNodeHasChields: Boolean;
  56. function GetTreeNodeLevel: Integer;
  57. function GetPrevVisibleTreeNodeLevel: Integer;
  58. function GetNextVisibleTreeNodeLevel: Integer;
  59. function GetRecObject: TObject;
  60. function InstantReadIndexOfBookmark(Bookmark: TBookmarkStr): Integer;
  61. function InstantReadRowCount: Integer;
  62. function MemTableIsTreeList: Boolean;
  63. function ParentHasNextSibling(ParenLevel: Integer): Boolean;
  64. function SetToRec(Rec: TObject): Boolean;
  65. function SetTreeNodeExpanded(RowNum: Integer; Value: Boolean): Integer;
  66. function GetFieldValueList(FieldName: String): IMemTableDataFieldValueListEh;
  67. function MoveRecords(BookmarkList: TStrings; ToRecNo: Longint; TreeLevel: Integer; CheckOnly: Boolean): Boolean;
  68. procedure InstantReadEnter(RowNum: Integer);
  69. procedure InstantReadLeave;
  70. property InstantReadCurRowNum: Integer read GetInstantReadCurRowNum;
  71. // property TreeNodeCollapsed: Boolean read GetTreeNodeCollapsed write SetTreeNodeCollapsed;
  72. end;
  73. IComboEditEh = interface
  74. ['{B64255B5-386A-4524-8BC7-7F49DDB410F4}']
  75. procedure CloseUp(Accept: Boolean);
  76. end;
  77. TFieldsArrEh = array of TField;
  78. { Standard events }
  79. TButtonClickEventEh = procedure(Sender: TObject; var Handled: Boolean) of object;
  80. TButtonDownEventEh = procedure(Sender: TObject; TopButton: Boolean;
  81. var AutoRepeat: Boolean; var Handled: Boolean) of object;
  82. TCloseUpEventEh = procedure(Sender: TObject; Accept: Boolean) of object;
  83. TAcceptEventEh = procedure(Sender: TObject; var Accept: Boolean) of object;
  84. TNotInListEventEh = procedure(Sender: TObject; NewText: String;
  85. var RecheckInList: Boolean) of object;
  86. TUpdateDataEventEh = procedure(Sender: TObject; var Handled: Boolean) of object;
  87. { TBMListEh }
  88. TBMListEh = class
  89. private
  90. FCache: TBookmarkStr;
  91. FCacheFind: Boolean;
  92. FCacheIndex: Integer;
  93. FLinkActive:boolean;
  94. function GetCount: Integer;
  95. function GetCurrentRowSelected: Boolean;
  96. function GetItem(Index: Integer): TBookmarkStr;
  97. protected
  98. FList: TStringList;
  99. function Compare(const Item1, Item2: TBookmarkStr): Integer;
  100. function CurrentRow: TBookmarkStr;
  101. function GetDataSet:TDataSet; virtual; abstract;
  102. procedure Invalidate; virtual;
  103. procedure LinkActive(Value: Boolean);
  104. procedure RaiseBMListError(const S: string); virtual;
  105. procedure SetCurrentRowSelected(Value: Boolean); virtual;
  106. procedure StringsChanged(Sender: TObject); virtual;
  107. procedure UpdateState; virtual;
  108. public
  109. constructor Create;
  110. destructor Destroy; override;
  111. function Find(const Item: TBookmarkStr; var Index: Integer): Boolean;
  112. function IndexOf(const Item: TBookmarkStr): Integer;
  113. function Refresh: Boolean;
  114. procedure Clear; virtual;
  115. procedure Delete;
  116. procedure SelectAll;
  117. property Count: Integer read GetCount;
  118. property CurrentRowSelected: Boolean read GetCurrentRowSelected write SetCurrentRowSelected;
  119. property DataSet:TDataSet read GetDataSet;
  120. property Items[Index: Integer]: TBookmarkStr read GetItem; default;
  121. end;
  122. { TEditButtonControlEh }
  123. TEditButtonStyleEh = (ebsDropDownEh, ebsEllipsisEh, ebsGlyphEh, ebsUpDownEh,
  124. ebsPlusEh, ebsMinusEh);
  125. TEditButtonControlEh = class(TSpeedButton)
  126. private
  127. FActive: Boolean;
  128. FAlwaysDown: Boolean;
  129. FButtonNum: Integer;
  130. FNoDoClick: Boolean;
  131. FOnDown: TButtonDownEventEh;
  132. FStyle: TEditButtonStyleEh;
  133. FTimer: TTimer;
  134. function GetTimer: TTimer;
  135. procedure ResetTimer(Interval: Cardinal);
  136. procedure SetActive(const Value: Boolean);
  137. procedure SetAlwaysDown(const Value: Boolean);
  138. procedure SetStyle(const Value: TEditButtonStyleEh);
  139. procedure TimerEvent(Sender: TObject);
  140. procedure UpdateDownButtonNum(X, Y: Integer);
  141. protected
  142. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  143. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  144. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  145. procedure Paint; override;
  146. property Timer: TTimer read GetTimer;
  147. public
  148. procedure Click; override;
  149. procedure EditButtonDown(TopButton: Boolean; var AutoRepeat: Boolean);
  150. procedure SetState(NewState: TButtonState; IsActive: Boolean; ButtonNum: Integer);
  151. procedure SetWidthNoNotify(AWidth: Integer);
  152. property Active: Boolean read FActive write SetActive;
  153. property AlwaysDown: Boolean read FAlwaysDown write SetAlwaysDown;
  154. property Style: TEditButtonStyleEh read FStyle write SetStyle default ebsDropDownEh;
  155. property OnDown: TButtonDownEventEh read FOnDown write FOnDown;
  156. end;
  157. TSpeedButtonEh = class(TEditButtonControlEh)
  158. published
  159. property Active;
  160. property Style;
  161. end;
  162. TEditButtonControlLineRec = record
  163. ButtonLine: TShape;
  164. EditButtonControl: TEditButtonControlEh;
  165. end;
  166. TEditButtonControlList = array of TEditButtonControlLineRec;
  167. TEditButtonEh = class;
  168. TEditButtonActionLinkEh = class(TActionLink)
  169. protected
  170. FClient: TEditButtonEh;
  171. procedure AssignClient(AClient: TObject); override;
  172. function IsEnabledLinked: Boolean; override;
  173. function IsHintLinked: Boolean; override;
  174. function IsShortCutLinked: Boolean; override;
  175. function IsVisibleLinked: Boolean; override;
  176. procedure SetEnabled(Value: Boolean); override;
  177. procedure SetHint(const Value: string); override;
  178. procedure SetShortCut(Value: TShortCut); override;
  179. procedure SetVisible(Value: Boolean); override;
  180. end;
  181. TEditButtonActionLinkEhClass = class of TEditButtonActionLinkEh;
  182. { TEditButtonEh }
  183. TEditButtonEh = class(TCollectionItem)
  184. private
  185. FActionLink: TEditButtonActionLinkEh;
  186. FDropdownMenu: TPopupMenu;
  187. FEditControl: TWinControl;
  188. FEnabled: Boolean;
  189. FGlyph: TBitmap;
  190. FHint: String;
  191. FNumGlyphs: Integer;
  192. FOnButtonClick: TButtonClickEventEh;
  193. FOnButtonDown: TButtonDownEventEh;
  194. FOnChanged: TNotifyEvent;
  195. FShortCut: TShortCut;
  196. FStyle: TEditButtonStyleEh;
  197. FVisible: Boolean;
  198. FWidth: Integer;
  199. function GetAction: TBasicAction;
  200. function GetGlyph: TBitmap;
  201. function IsEnabledStored: Boolean;
  202. function IsHintStored: Boolean;
  203. function IsShortCutStored: Boolean;
  204. function IsVisibleStored: Boolean;
  205. procedure DoActionChange(Sender: TObject);
  206. procedure SetAction(const Value: TBasicAction);
  207. procedure SetEnabled(const Value: Boolean);
  208. procedure SetGlyph(const Value: TBitmap);
  209. procedure SetHint(const Value: String);
  210. procedure SetNumGlyphs(Value: Integer);
  211. procedure SetStyle(const Value: TEditButtonStyleEh);
  212. procedure SetVisible(const Value: Boolean);
  213. procedure SetWidth(const Value: Integer);
  214. protected
  215. function CreateEditButtonControl: TEditButtonControlEh; virtual;
  216. procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); dynamic;
  217. procedure Changed; overload;
  218. property ActionLink: TEditButtonActionLinkEh read FActionLink write FActionLink;
  219. public
  220. constructor Create(Collection: TCollection); overload; override;
  221. constructor Create(EditControl: TWinControl); reintroduce; overload;
  222. destructor Destroy; override;
  223. function GetActionLinkClass: TEditButtonActionLinkEhClass; dynamic;
  224. procedure Assign(Source: TPersistent); override;
  225. procedure Click(Sender: TObject; var Handled: Boolean); virtual;
  226. procedure InitiateAction; virtual;
  227. property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
  228. published
  229. property Action: TBasicAction read GetAction write SetAction;
  230. property DropdownMenu: TPopupMenu read FDropdownMenu write FDropdownMenu;
  231. property Enabled: Boolean read FEnabled write SetEnabled stored IsEnabledStored default True;
  232. property Glyph: TBitmap read GetGlyph write SetGlyph;
  233. property Hint: String read FHint write SetHint stored IsHintStored;
  234. property NumGlyphs: Integer read FNumGlyphs write SetNumGlyphs default 1;
  235. property ShortCut: TShortCut read FShortCut write FShortCut stored IsShortCutStored default scNone;
  236. //property ShortCut: TShortCut read FShortCut write FShortCut default 32808; //Menus.ShortCut(VK_DOWN, [ssAlt]);
  237. property Style: TEditButtonStyleEh read FStyle write SetStyle default ebsDropDownEh;
  238. property Visible: Boolean read FVisible write SetVisible stored IsVisibleStored default False;
  239. property Width: Integer read FWidth write SetWidth default 0;
  240. property OnClick: TButtonClickEventEh read FOnButtonClick write FOnButtonClick;
  241. property OnDown: TButtonDownEventEh read FOnButtonDown write FOnButtonDown;
  242. end;
  243. TEditButtonEhClass = class of TEditButtonEh;
  244. { TDropDownEditButtonEh }
  245. TDropDownEditButtonEh = class(TEditButtonEh)
  246. public
  247. constructor Create(Collection: TCollection); overload; override;
  248. constructor Create(EditControl: TWinControl); overload;
  249. published
  250. property ShortCut default 32808; //Menus.ShortCut(VK_DOWN, [ssAlt]);
  251. end;
  252. { TVisibleEditButtonEh }
  253. TVisibleEditButtonEh = class(TEditButtonEh)
  254. public
  255. constructor Create(Collection: TCollection); overload; override;
  256. constructor Create(EditControl: TWinControl); overload;
  257. published
  258. property ShortCut default 32808; //Menus.ShortCut(VK_DOWN, [ssAlt]);
  259. property Visible default True;
  260. end;
  261. { TEditButtonsEh }
  262. TEditButtonsEh = class(TCollection)
  263. private
  264. FOnChanged: TNotifyEvent;
  265. function GetEditButton(Index: Integer): TEditButtonEh;
  266. procedure SetEditButton(Index: Integer; Value: TEditButtonEh);
  267. protected
  268. FOwner: TPersistent;
  269. function GetOwner: TPersistent; override;
  270. procedure Update(Item: TCollectionItem); override;
  271. public
  272. constructor Create(Owner: TPersistent; EditButtonClass: TEditButtonEhClass);
  273. function Add: TEditButtonEh;
  274. property Items[Index: Integer]: TEditButtonEh read GetEditButton write SetEditButton; default;
  275. property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
  276. end;
  277. { TSpecRowEh }
  278. TSpecRowEh = class(TPersistent)
  279. private
  280. FCellsStrings: TStrings;
  281. FCellsText: String;
  282. FColor: TColor;
  283. FFont: TFont;
  284. FOnChanged: TNotifyEvent;
  285. FOwner: TPersistent;
  286. FSelected: Boolean;
  287. FShortCut: TShortCut;
  288. FShowIfNotInKeyList: Boolean;
  289. FUpdateCount: Integer;
  290. FValue: Variant;
  291. FVisible: Boolean;
  292. function GetCellText(Index: Integer): String;
  293. function GetColor: TColor;
  294. function GetFont: TFont;
  295. function IsColorStored: Boolean;
  296. function IsFontStored: Boolean;
  297. function IsValueStored: Boolean;
  298. procedure FontChanged(Sender: TObject);
  299. procedure SetCellsText(const Value: String);
  300. procedure SetColor(const Value: TColor);
  301. procedure SetFont(const Value: TFont);
  302. procedure SetShowIfNotInKeyList(const Value: Boolean);
  303. procedure SetValue(const Value: Variant);
  304. procedure SetVisible(const Value: Boolean);
  305. protected
  306. FColorAssigned: Boolean;
  307. FFontAssigned: Boolean;
  308. function GetOwner: TPersistent; override;
  309. procedure Changed;
  310. public
  311. constructor Create(Owner: TPersistent);
  312. destructor Destroy; override;
  313. function DefaultColor: TColor;
  314. function DefaultFont: TFont;
  315. function LocateKey(KeyValue: Variant): Boolean;
  316. procedure Assign(Source: TPersistent); override;
  317. procedure BeginUpdate;
  318. procedure EndUpdate;
  319. property CellText[Index: Integer]: String read GetCellText;
  320. property Selected: Boolean read FSelected write FSelected;
  321. property UpdateCount: Integer read FUpdateCount;
  322. property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
  323. published
  324. property CellsText: String read FCellsText write SetCellsText;
  325. property Color: TColor read GetColor write SetColor stored IsColorStored;
  326. property Font: TFont read GetFont write SetFont stored IsFontStored;
  327. property ShortCut: TShortCut read FShortCut write FShortCut default 32814; //Menus.ShortCut(VK_DOWN, [ssAlt]);
  328. property ShowIfNotInKeyList: Boolean read FShowIfNotInKeyList write SetShowIfNotInKeyList default True;
  329. property Value: Variant read FValue write SetValue stored IsValueStored;
  330. property Visible: Boolean read FVisible write SetVisible default False;
  331. end;
  332. { TSizeGripEh }
  333. TSizeGripPostion = (sgpTopLeft, sgpTopRight, sgpBottomRight, sgpBottomLeft);
  334. TSizeGripChangePosition = (sgcpToLeft, sgcpToRight, sgcpToTop, sgcpToBottom);
  335. TSizeGripEh = class(TCustomControl)
  336. private
  337. FInitScreenMousePos: TPoint;
  338. FInternalMove: Boolean;
  339. FOldMouseMovePos: TPoint;
  340. FParentRect: TRect;
  341. FParentResized: TNotifyEvent;
  342. FPosition: TSizeGripPostion;
  343. FTriangleWindow: Boolean;
  344. function GetVisible: Boolean;
  345. procedure SetPosition(const Value: TSizeGripPostion);
  346. procedure SetTriangleWindow(const Value: Boolean);
  347. procedure SetVisible(const Value: Boolean);
  348. procedure WMMove(var Message: TWMMove); message WM_MOVE;
  349. protected
  350. procedure CreateWnd; override;
  351. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  352. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  353. procedure Paint; override;
  354. procedure ParentResized; dynamic;
  355. public
  356. constructor Create(AOwner: TComponent); override;
  357. procedure ChangePosition(NewPosition: TSizeGripChangePosition);
  358. procedure UpdatePosition;
  359. procedure UpdateWindowRegion;
  360. property Position: TSizeGripPostion read FPosition write SetPosition default sgpBottomRight;
  361. property TriangleWindow: Boolean read FTriangleWindow write SetTriangleWindow default True;
  362. property Visible: Boolean read GetVisible write SetVisible;
  363. property OnParentResized: TNotifyEvent read FParentResized write FParentResized;
  364. end;
  365. const
  366. cm_SetSizeGripChangePosition = WM_USER + 100;
  367. { TPopupMonthCalendarEh }
  368. const
  369. CM_CLOSEUPEH = WM_USER + 101;
  370. type
  371. TPopupMonthCalendarEh = class(TMonthCalendar)
  372. private
  373. FBorderWidth: Integer;
  374. procedure CMCloseUpEh(var Message: TMessage); message CM_CLOSEUPEH;
  375. procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
  376. procedure CMWantSpecialKey(var Message: TCMWantSpecialKey); message CM_WANTSPECIALKEY;
  377. procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  378. procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  379. procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
  380. procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
  381. protected
  382. function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override;
  383. function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
  384. function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
  385. function MsgSetDateTime(Value: TSystemTime): Boolean; override;
  386. procedure CreateParams(var Params: TCreateParams); override;
  387. procedure CreateWnd; override;
  388. procedure DrawBorder; virtual;
  389. procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  390. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  391. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  392. procedure PostCloseUp(Accept: Boolean);
  393. procedure UpdateBorderWidth;
  394. public
  395. constructor Create(AOwner: TComponent); override;
  396. property Color;
  397. property Ctl3D;
  398. end;
  399. TListGetImageIndexEventEh = procedure(Sender: TObject; ItemIndex: Integer; var ImageIndex: Integer) of object;
  400. { TPopupListboxEh }
  401. TPopupListboxEh = class(TCustomListbox)
  402. private
  403. FBorderWidth: Integer;
  404. FImageList: TCustomImageList;
  405. FMousePos: TPoint;
  406. FRowCount: Integer;
  407. FSearchText: String;
  408. FSearchTickCount: Longint;
  409. FSizeGrip: TSizeGripEh;
  410. FSizeGripResized: Boolean;
  411. FOnGetImageIndex: TListGetImageIndexEventEh;
  412. FExtItems: TStrings;
  413. function CheckNewSize(var NewWidth, NewHeight: Integer): Boolean;
  414. function GetBorderSize: Integer;
  415. function GetExtItems: TStrings;
  416. procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
  417. procedure CMSetSizeGripChangePosition(var Message: TMessage); message cm_SetSizeGripChangePosition;
  418. procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
  419. procedure SetExtItems(Value: TStrings);
  420. procedure SetImageList(const Value: TCustomImageList);
  421. procedure SetRowCount(Value: Integer);
  422. procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
  423. procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
  424. procedure WMSize(var Message: TWMSize); message WM_SIZE;
  425. procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
  426. protected
  427. function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
  428. function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
  429. procedure CreateParams(var Params: TCreateParams); override;
  430. procedure CreateWnd; override;
  431. procedure DrawBorder; virtual;
  432. procedure DrawItem(Index: Integer; ARect: TRect; State: TOwnerDrawState); override;
  433. procedure KeyPress(var Key: Char); override;
  434. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  435. procedure UpdateBorderWidth;
  436. procedure SelfOnGetData(Control: TWinControl; Index: Integer; var Data: string); virtual;
  437. public
  438. constructor Create(Owner: TComponent); override;
  439. procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
  440. function CanFocus: Boolean; {$IFDEF EH_LIB_5} override; {$ENDIF}
  441. function GetTextHeight: Integer;
  442. property Color;
  443. property Ctl3D;
  444. property Font;
  445. property ImageList: TCustomImageList read FImageList write SetImageList;
  446. property IntegralHeight;
  447. property ItemHeight;
  448. property RowCount: Integer read FRowCount write SetRowCount;
  449. property ExtItems: TStrings read GetExtItems write SetExtItems;
  450. property SizeGrip: TSizeGripEh read FSizeGrip;
  451. property SizeGripResized: Boolean read FSizeGripResized write FSizeGripResized;
  452. property OnMouseUp;
  453. property OnGetImageIndex: TListGetImageIndexEventEh read FOnGetImageIndex write FOnGetImageIndex;
  454. end;
  455. { TMRUList }
  456. TFilterMRUItemEventEh = procedure (Sender: TObject; var Accept: Boolean) of object;
  457. TSetDropDownEventEh = procedure (Sender: TObject) of object;
  458. TSetCloseUpEventEh = procedure (Sender: TObject; Accept: Boolean) of object;
  459. TMRUListEh = class(TPersistent)
  460. private
  461. FActive: Boolean;
  462. FAutoAdd: Boolean;
  463. FCaseSensitive: Boolean;
  464. FItems: TStrings;
  465. FLimit: Integer;
  466. FOnActiveChanged: TNotifyEvent;
  467. FOnFilterItem: TFilterMRUItemEventEh;
  468. FOnSetCloseUpEvent: TSetCloseUpEventEh;
  469. FOnSetDropDown: TSetDropDownEventEh;
  470. FOwner: TPersistent;
  471. FRows: Integer;
  472. FWidth: Integer;
  473. FCancelIfKeyInQueue: Boolean;
  474. procedure SetActive(const Value: Boolean);
  475. procedure SetItems(const Value: TStrings);
  476. procedure SetLimit(const Value: Integer);
  477. procedure SetRows(const Value: Integer);
  478. protected
  479. FDroppedDown: Boolean;
  480. procedure UpdateLimit;
  481. public
  482. constructor Create(AOwner: TPersistent);
  483. destructor Destroy; override;
  484. procedure Add(s: String);
  485. procedure Assign(Source: TPersistent); override;
  486. procedure CloseUp(Accept: Boolean); virtual;
  487. procedure DropDown; virtual;
  488. function FilterItemsTo(FilteredItems: TStrings; MaskText: String): Boolean;
  489. property DroppedDown: Boolean read FDroppedDown write FDroppedDown;
  490. property Width: Integer read FWidth write FWidth;
  491. property OnActiveChanged: TNotifyEvent read FOnActiveChanged write FOnActiveChanged;
  492. property OnSetCloseUp: TSetCloseUpEventEh read FOnSetCloseUpEvent write FOnSetCloseUpEvent;
  493. property OnSetDropDown: TSetDropDownEventEh read FOnSetDropDown write FOnSetDropDown;
  494. property OnFilterItem: TFilterMRUItemEventEh read FOnFilterItem write FOnFilterItem;
  495. property CancelIfKeyInQueue: Boolean read FCancelIfKeyInQueue write FCancelIfKeyInQueue default True;
  496. published
  497. property AutoAdd: Boolean read FAutoAdd write FAutoAdd default True;
  498. property Active: Boolean read FActive write SetActive default False;
  499. property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive default False;
  500. property Items: TStrings read FItems write SetItems;
  501. property Limit: Integer read FLimit write SetLimit default 100;
  502. property Rows: Integer read FRows write SetRows default 7;
  503. end;
  504. { TMRUListboxEh }
  505. TMRUListboxEh = class(TPopupListboxEh)
  506. private
  507. FScrollBar: TScrollBar;
  508. FScrollBarLockMove: Boolean;
  509. procedure CMChanged(var Message: TCMChanged); message CM_CHANGED;
  510. procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL;
  511. procedure CMSetSizeGripChangePosition(var Message: TMessage); message cm_SetSizeGripChangePosition;
  512. procedure WMSize(var Message: TWMSize); message WM_SIZE;
  513. protected
  514. procedure CreateParams(var Params: TCreateParams); override;
  515. procedure ScrollBarScrolled(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer);
  516. procedure ScrollBarWindowProc(var Message: TMessage);
  517. public
  518. constructor Create(Owner: TComponent); override;
  519. procedure UpdateScrollBar;
  520. procedure UpdateScrollBarPos;
  521. property ParentCtl3D;
  522. property ScrollBar: TScrollBar read FScrollBar;
  523. property Sorted;
  524. property OnMouseUp;
  525. end;
  526. {$IFNDEF EH_LIB_5} // Delphi 4 doesn't have TObjectList but Delphi 8 required
  527. { TObjectList class }
  528. TObjectList = class(TList)
  529. private
  530. FOwnsObjects: Boolean;
  531. protected
  532. function GetItem(Index: Integer): TObject;
  533. procedure SetItem(Index: Integer; AObject: TObject);
  534. public
  535. constructor Create; overload;
  536. constructor Create(AOwnsObjects: Boolean); overload;
  537. function Add(AObject: TObject): Integer;
  538. function Remove(AObject: TObject): Integer;
  539. function IndexOf(AObject: TObject): Integer;
  540. function FindInstanceOf(AClass: TClass; AExact: Boolean = True; AStartAt: Integer = 0): Integer;
  541. procedure Insert(Index: Integer; AObject: TObject);
  542. property OwnsObjects: Boolean read FOwnsObjects write FOwnsObjects;
  543. property Items[Index: Integer]: TObject read GetItem write SetItem; default;
  544. end;
  545. {$ENDIF}
  546. {$IFNDEF EH_LIB_5}
  547. TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
  548. {$ENDIF}
  549. TStringListEh = class(TStringList)
  550. {$IFNDEF EH_LIB_6}
  551. private
  552. FCaseSensitive: Boolean;
  553. function CompareStrings(const S1, S2: string): Integer;
  554. procedure SetCaseSensitive(const Value: Boolean);
  555. public
  556. {$IFNDEF EH_LIB_5}
  557. procedure CustomSort(Compare: TStringListSortCompare);
  558. procedure QuickSort(L, R: Integer; SCompare: TStringListSortCompare);
  559. {$ENDIF}
  560. procedure Sort; override;
  561. property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive;
  562. {$ENDIF}
  563. end;
  564. { TDataLinkEh }
  565. {$IFDEF CIL}
  566. TDataEventEh = procedure (Event: TDataEvent; Info: TObject) of object;
  567. {$ELSE}
  568. TDataEventEh = procedure (Event: TDataEvent; Info: Longint) of object;
  569. {$ENDIF}
  570. TDataLinkEh = class(TDataLink)
  571. private
  572. FOnDataEvent: TDataEventEh;
  573. protected
  574. {$IFDEF CIL}
  575. procedure DataEvent(Event: TDataEvent; Info: TObject); virtual;
  576. {$ELSE}
  577. procedure DataEvent(Event: TDataEvent; Info: Integer); override;
  578. {$ENDIF}
  579. public
  580. property OnDataEvent: TDataEventEh read FOnDataEvent write FOnDataEvent;
  581. end;
  582. { TDatasetFieldValueListEh }
  583. TDatasetFieldValueListEh = class(TInterfacedObject, IMemTableDataFieldValueListEh)
  584. private
  585. FValues: TStringList;
  586. FDataObsoleted: Boolean;
  587. FFieldName: String;
  588. FDataLink: TDataLinkEh;
  589. FDataSource: TDataSource;
  590. function GetValues: TStrings;
  591. procedure SetFieldName(const Value: String);
  592. procedure SetDataSet(const Value: TDataSet);
  593. function GetDataSet: TDataSet;
  594. protected
  595. procedure RefreshValues;
  596. {$IFDEF CIL}
  597. procedure DataSetEvent(Event: TDataEvent; Info: TObject); virtual;
  598. {$ELSE}
  599. procedure DataSetEvent(Event: TDataEvent; Info: Integer); virtual;
  600. {$ENDIF}
  601. public
  602. constructor Create;
  603. destructor Destroy; override;
  604. property FieldName: String read FFieldName write SetFieldName;
  605. property DataSet: TDataSet read GetDataSet write SetDataSet;
  606. property Values: TStrings read GetValues;
  607. end;
  608. TLocateTextEventEh = function (Sender: TObject;
  609. const FieldName: string; const Text: String; Options: TLocateTextOptionsEh;
  610. Direction: TLocateTextDirectionEh; Matching: TLocateTextMatchingEh;
  611. TreeFindRange: TLocateTextTreeFindRangeEh): Boolean of object;
  612. TDrawButtonControlStyleEh = (bcsDropDownEh, bcsEllipsisEh, bcsUpDownEh,
  613. bcsCheckboxEh, bcsPlusEh, bcsMinusEh);
  614. TTreeElementEh = (tehMinusUpDown, tehMinusUp, tehMinusDown,
  615. tehPlusUpDown, tehPlusUp, tehPlusDown,
  616. tehCrossUpDown, tehCrossUp, tehCrossDown,
  617. tehVLine);
  618. procedure PaintButtonControlEh(DC: HDC; ARect: TRect; ParentColor: TColor;
  619. Style: TDrawButtonControlStyleEh; DownButton: Integer;
  620. Flat, Active, Enabled: Boolean; State: TCheckBoxState);
  621. function GetDefaultFlatButtonWidth: Integer;
  622. var
  623. FlatButtonWidth: Integer;
  624. type
  625. TFieldTypes = set of TFieldType;
  626. const
  627. ftNumberFieldTypes: TFieldTypes = [ftSmallint, ftInteger, ftWord, ftFloat, ftCurrency,
  628. ftBCD{$IFDEF EH_LIB_6}, ftFMTBcd{$ENDIF}];
  629. procedure GetFieldsProperty(List: TList; DataSet: TDataSet;
  630. Control: TComponent; const FieldNames: String); overload;
  631. function GetFieldsProperty(DataSet: TDataSet; Control: TComponent;
  632. const FieldNames: String): TFieldsArrEh; overload;
  633. procedure DataSetSetFieldValues(DataSet: TDataSet; Fields: String; Value: Variant);
  634. function VarEquals(const V1, V2: Variant): Boolean;
  635. {$IFNDEF EH_LIB_6}
  636. type
  637. TVariantRelationship = (vrEqual, vrLessThan, vrGreaterThan, vrNotEqual);
  638. {$ENDIF}
  639. function DBVarCompareValue(const A, B: Variant): TVariantRelationship;
  640. var UseButtonsBitmapCache: Boolean = True;
  641. procedure ClearButtonsBitmapCache;
  642. procedure DrawImage(DC: HDC; ARect: TRect; Images: TCustomImageList;
  643. ImageIndex: Integer; Selected: Boolean);
  644. procedure DrawTreeElement(Canvas: TCanvas; ARect: TRect;
  645. TreeElement: TTreeElementEh; BackDot: Boolean; ScaleX, ScaleY: Double;
  646. RightToLeft: Boolean);
  647. function AlignDropDownWindowRect(MasterAbsRect: TRect; DropDownWin: TWinControl; Align: TDropDownAlign): TPoint;
  648. function AlignDropDownWindow(MasterWin, DropDownWin: TWinControl; Align: TDropDownAlign): TPoint;
  649. {$IFNDEF EH_LIB_5}
  650. function Supports(const Instance: IUnknown; const IID: TGUID; out Intf): Boolean; overload;
  651. function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean; overload;
  652. {$ENDIF}
  653. var
  654. DefaultCheckBoxWidth, DefaultCheckBoxHeight: Integer;
  655. function AdjustCheckBoxRect(ClientRect: TRect; Alignment: TAlignment; Layout: TTextLayout): TRect;
  656. function IsDoubleClickMessage(OldPos, NewPos: TPoint; Interval: Longint): Boolean;
  657. function DefaultEditButtonHeight(EditButtonWidth: Integer; Flat: Boolean): Integer;
  658. function KillMouseUp(Control: TControl): Boolean; overload;
  659. function KillMouseUp(Control: TControl; Area: TRect): Boolean; overload;
  660. implementation
  661. uses DBConsts, Math,
  662. {$IFDEF EH_LIB_6} VDBConsts, Types, {$ENDIF}
  663. {$IFDEF EH_LIB_7} Themes, UxTheme, {$ENDIF}
  664. MultiMon;
  665. type
  666. TWinControlCracker = class(TWinControl) end;
  667. TControlCracker = class(TControl) end;
  668. {$IFNDEF EH_LIB_5}
  669. function Supports(const Instance: IUnknown; const IID: TGUID; out Intf): Boolean; overload;
  670. begin
  671. Result := (Instance <> nil) and (Instance.QueryInterface(IID, Intf) = 0);
  672. end;
  673. function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean; overload;
  674. var
  675. LUnknown: IUnknown;
  676. begin
  677. Result := (Instance <> nil) and
  678. ((Instance.GetInterface(IUnknown, LUnknown) and Supports(LUnknown, IID, Intf)) or
  679. Instance.GetInterface(IID, Intf));
  680. end;
  681. {$ENDIF}
  682. function IsDoubleClickMessage(OldPos, NewPos: TPoint; Interval: Longint): Boolean;
  683. begin
  684. Result := (Interval <= Longint(GetDoubleClickTime)) and
  685. (Abs(OldPos.X - NewPos.X) <= GetSystemMetrics(SM_CXDOUBLECLK)) and
  686. (Abs(OldPos.Y - NewPos.Y) <= GetSystemMetrics(SM_CYDOUBLECLK));
  687. end;
  688. procedure GetCheckSize;
  689. begin
  690. with TBitmap.Create do
  691. try
  692. Handle := LoadBitmapEh(0, OBM_CHECKBOXES);
  693. DefaultCheckBoxWidth := Width div 4;
  694. DefaultCheckBoxHeight := Height div 3;
  695. finally
  696. Free;
  697. end;
  698. end;
  699. function AdjustCheckBoxRect(ClientRect: TRect; Alignment: TAlignment; Layout: TTextLayout): TRect;
  700. var
  701. CheckWidth, CheckHeight: Integer;
  702. begin
  703. if (ClientRect.Right - ClientRect.Left) > DefaultCheckBoxWidth
  704. then CheckWidth := DefaultCheckBoxWidth
  705. else CheckWidth := ClientRect.Right - ClientRect.Left;
  706. if (ClientRect.Bottom - ClientRect.Top) > DefaultCheckBoxHeight
  707. then CheckHeight := DefaultCheckBoxHeight
  708. else CheckHeight := ClientRect.Bottom - ClientRect.Top;
  709. Result := ClientRect;
  710. if (ClientRect.Right - ClientRect.Left) > DefaultCheckBoxWidth then
  711. case Alignment of
  712. taRightJustify: Result.Left := Result.Right - CheckWidth;
  713. taCenter: Result.Left := Result.Left + (ClientRect.Right - ClientRect.Left) shr 1 - CheckWidth shr 1;
  714. end;
  715. Result.Right := Result.Left + CheckWidth;
  716. if (ClientRect.Bottom - ClientRect.Top) > DefaultCheckBoxHeight then
  717. case Layout of
  718. tlBottom: Result.Top := Result.Bottom - CheckWidth;
  719. tlCenter: Result.Top := Result.Top + (ClientRect.Bottom - ClientRect.Top) shr 1 - CheckHeight shr 1;
  720. end;
  721. Result.Bottom := Result.Top + CheckHeight;
  722. end;
  723. procedure DrawCheck(DC: HDC; R: TRect; AState: TCheckBoxState; AEnabled, AFlat, ADown, AActive: Boolean);
  724. var
  725. DrawState, oldRgn: Integer;
  726. DrawRect: TRect;
  727. // OldBrushColor: TColor;
  728. // OldBrushStyle: TBrushStyle;
  729. // OldPenColor: TColor;
  730. Rgn, SaveRgn: HRgn;
  731. {$IFDEF EH_LIB_7}
  732. ElementDetails: TThemedElementDetails;
  733. {$ENDIF}
  734. // Brush,SaveBrush: HBRUSH;
  735. begin
  736. SaveRgn := 0;
  737. oldRgn := 0;
  738. DrawRect := R;
  739. with DrawRect do
  740. if (Right - Left) > (Bottom - Top) then
  741. begin
  742. Left := Left + ((Right - Left) - (Bottom - Top)) div 2;
  743. Right := Left + (Bottom - Top);
  744. end else if (Right - Left) < (Bottom - Top) then
  745. begin
  746. Top := Top + ((Bottom - Top) - (Right - Left)) div 2;
  747. Bottom := Top + (Right - Left);
  748. end;
  749. case AState of
  750. cbChecked:
  751. DrawState := DFCS_BUTTONCHECK or DFCS_CHECKED;
  752. cbUnchecked:
  753. DrawState := DFCS_BUTTONCHECK;
  754. else // cbGrayed
  755. DrawState := DFCS_BUTTON3STATE or DFCS_CHECKED;
  756. end;
  757. if not AEnabled then
  758. DrawState := DrawState or DFCS_INACTIVE;
  759. if ADown then
  760. DrawState := DrawState or DFCS_PUSHED;
  761. // with Canvas do
  762. // begin
  763. if AFlat then
  764. begin
  765. { Remember current clipping region }
  766. SaveRgn := CreateRectRgn(0, 0, 0, 0);
  767. oldRgn := GetClipRgn(DC, SaveRgn);
  768. { Clip 3d-style checkbox to prevent flicker }
  769. with DrawRect do
  770. Rgn := CreateRectRgn(Left + 1, Top + 1, Right - 1, Bottom - 1);
  771. SelectClipRgn(DC, Rgn);
  772. DeleteObject(Rgn);
  773. end;
  774. if AFlat then InflateRect(DrawRect, 1, 1);
  775. {$IFDEF EH_LIB_7}
  776. if ThemeServices.ThemesEnabled then
  777. begin
  778. case AState of
  779. cbChecked:
  780. if AEnabled then
  781. ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal)
  782. else
  783. ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxCheckedDisabled);
  784. cbUnchecked:
  785. if AEnabled then
  786. ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxUncheckedNormal)
  787. else
  788. ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxUncheckedDisabled)
  789. else // cbGrayed
  790. if AEnabled then
  791. ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxMixedNormal)
  792. else
  793. ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxMixedDisabled);
  794. end;
  795. ThemeServices.DrawElement(DC, ElementDetails, R);
  796. end
  797. else
  798. {$ENDIF}
  799. DrawFrameControl(DC, DrawRect, DFC_BUTTON, DrawState);
  800. if AFlat then
  801. begin
  802. //SelectClipRgn(Handle, SaveRgn);
  803. if oldRgn = 0 then
  804. SelectClipRgn(DC, 0)
  805. else
  806. SelectClipRgn(DC, SaveRgn);
  807. DeleteObject(SaveRgn);
  808. { Draw flat rectangle in-place of clipped 3d checkbox above }
  809. InflateRect(DrawRect, -1, -1);
  810. if AActive
  811. then FrameRect(DC, DrawRect, GetSysColorBrush(COLOR_BTNFACE))
  812. else FrameRect(DC, DrawRect, GetSysColorBrush(COLOR_BTNSHADOW));
  813. { Caller drow in flat mode
  814. InflateRect(DrawRect, 1, 1);
  815. if AActive
  816. then DrawEdge(DC, DrawRect, BDR_SUNKENOUTER, BF_RECT)
  817. else FrameRect(DC, DrawRect, GetCurrentObject(DC, OBJ_BRUSH));}
  818. end;
  819. // end;
  820. end;
  821. const
  822. DownFlags: array[Boolean] of Integer = (0, DFCS_PUSHED {? or DFCS_FLAT});
  823. FlatFlags: array[Boolean] of Integer = (0, DFCS_FLAT);
  824. EnabledFlags: array[Boolean] of Integer = (DFCS_INACTIVE, 0);
  825. IsDownFlags: array[Boolean] of Integer = (DFCS_SCROLLUP, DFCS_SCROLLDOWN);
  826. PressedFlags: array[Boolean] of Integer = (EDGE_RAISED, EDGE_SUNKEN);
  827. procedure DrawEllipsisButton(DC: HDC; ARect: TRect; Enabled, Active, Flat, Pressed: Boolean);
  828. var
  829. InterP, PWid, W, H: Integer;
  830. ElRect: TRect;
  831. Brush, SaveBrush: HBRUSH;
  832. {$IFDEF EH_LIB_7}
  833. Button: TThemedButton;
  834. ToolButton: TThemedToolBar;
  835. Details: TThemedElementDetails;
  836. {$ENDIF}
  837. begin
  838. ElRect := ARect;
  839. {$IFDEF EH_LIB_7}
  840. if ThemeServices.ThemesEnabled then
  841. begin
  842. if not Enabled then
  843. Button := tbPushButtonDisabled
  844. else
  845. if Pressed then
  846. Button := tbPushButtonPressed
  847. else
  848. if Active
  849. then Button := tbPushButtonHot
  850. else Button := tbPushButtonNormal;
  851. ToolButton := ttbToolbarDontCare;
  852. if Flat then
  853. begin
  854. case Button of
  855. tbPushButtonDisabled:
  856. Toolbutton := ttbButtonDisabled;
  857. tbPushButtonPressed:
  858. Toolbutton := ttbButtonPressed;
  859. tbPushButtonHot:
  860. Toolbutton := ttbButtonHot;
  861. tbPushButtonNormal:
  862. Toolbutton := ttbButtonNormal;
  863. end;
  864. end;
  865. if ToolButton = ttbToolbarDontCare then
  866. begin
  867. Details := ThemeServices.GetElementDetails(Button);
  868. ThemeServices.DrawElement(DC, Details, ARect);
  869. // ARect := ThemeServices.ContentRect(DC, Details, ARect);
  870. InflateRect(ElRect, -2, -2);
  871. end else
  872. begin
  873. Details := ThemeServices.GetElementDetails(ToolButton);
  874. ThemeServices.DrawElement(DC, Details, ARect);
  875. InflateRect(ElRect, -1, -1)
  876. // ARect := ThemeServices.ContentRect(DC, Details, ARect);
  877. end;
  878. end else
  879. {$ENDIF}
  880. begin
  881. Brush := GetSysColorBrush(COLOR_BTNFACE);
  882. if Flat then
  883. begin
  884. Windows.FillRect(DC, ElRect, Brush);
  885. InflateRect(ElRect, -1, -1)
  886. end else
  887. begin
  888. DrawEdge(DC, ElRect, PressedFlags[Pressed], BF_RECT or BF_MIDDLE);
  889. InflateRect(ElRect, -2, -2);
  890. //Windows.FillRect(DC, ElRect, Brush);
  891. end;
  892. end;
  893. InterP := 2;
  894. PWid := 2;
  895. W := ElRect.Right - ElRect.Left; //+ Ord(not Active and Flat);
  896. if W < 12 then InterP := 1;
  897. if W < 8 then PWid := 1;
  898. W := ElRect.Left + W div 2 - PWid div 2 + Ord(Pressed); //- Ord(not Active and Flat);
  899. H := ElRect.Top + (ElRect.Bottom - ElRect.Top) div 2 - PWid div 2 + Ord(Pressed);
  900. if not Enabled then
  901. begin
  902. Inc(W); Inc(H);
  903. Brush := GetSysColorBrush(COLOR_BTNHILIGHT);
  904. SaveBrush := SelectObject(DC, Brush);
  905. PatBlt(DC, W, H, PWid, PWid, PATCOPY);
  906. PatBlt(DC, W - InterP - PWid, H, PWid, PWid, PATCOPY);
  907. PatBlt(DC, W + InterP + PWid, H, PWid, PWid, PATCOPY);
  908. Dec(W); Dec(H);
  909. SelectObject(DC, SaveBrush);
  910. Brush := GetSysColorBrush(COLOR_BTNSHADOW);
  911. end else
  912. Brush := GetSysColorBrush(COLOR_BTNTEXT);
  913. SaveBrush := SelectObject(DC, Brush);
  914. PatBlt(DC, W, H, PWid, PWid, PATCOPY);
  915. PatBlt(DC, W - InterP - PWid, H, PWid, PWid, PATCOPY);
  916. PatBlt(DC, W + InterP + PWid, H, PWid, PWid, PATCOPY);
  917. SelectObject(DC, SaveBrush);
  918. end;
  919. procedure DrawPlusMinusButton(DC: HDC; ARect: TRect; Enabled, Active, Flat, Pressed, Plus: Boolean);
  920. var PWid, PHet, W, H, PlusInd, MinWH: Integer;
  921. ElRect: TRect;
  922. Brush, SaveBrush: HBRUSH;
  923. {$IFDEF EH_LIB_7}
  924. Button: TThemedButton;
  925. ToolButton: TThemedToolBar;
  926. Details: TThemedElementDetails;
  927. {$ENDIF}
  928. begin
  929. ElRect := ARect;
  930. {$IFDEF EH_LIB_7}
  931. if ThemeServices.ThemesEnabled then
  932. begin
  933. if not Enabled then
  934. Button := tbPushButtonDisabled
  935. else
  936. if Pressed then
  937. Button := tbPushButtonPressed
  938. else
  939. if Active
  940. then Button := tbPushButtonHot
  941. else Button := tbPushButtonNormal;
  942. ToolButton := ttbToolbarDontCare;
  943. if Flat then
  944. begin
  945. case Button of
  946. tbPushButtonDisabled:
  947. Toolbutton := ttbButtonDisabled;
  948. tbPushButtonPressed:
  949. Toolbutton := ttbButtonPressed;
  950. tbPushButtonHot:
  951. Toolbutton := ttbButtonHot;
  952. tbPushButtonNormal:
  953. Toolbutton := ttbButtonNormal;
  954. end;
  955. end;
  956. if ToolButton = ttbToolbarDontCare then
  957. begin
  958. Details := ThemeServices.GetElementDetails(Button);
  959. ThemeServices.DrawElement(DC, Details, ARect);
  960. // ARect := ThemeServices.ContentRect(DC, Details, ARect);
  961. InflateRect(ElRect, -2, -2);
  962. end else
  963. begin
  964. Details := ThemeServices.GetElementDetails(ToolButton);
  965. ThemeServices.DrawElement(DC, Details, ARect);
  966. InflateRect(ElRect, -1, -1)
  967. // ARect := ThemeServices.ContentRect(DC, Details, ARect);
  968. end;
  969. end else
  970. {$ENDIF}
  971. begin
  972. Brush := GetSysColorBrush(COLOR_BTNFACE);
  973. if Flat then
  974. begin
  975. Windows.FillRect(DC, ElRect, Brush);
  976. InflateRect(ElRect, -1, -1)
  977. end else
  978. begin
  979. DrawEdge(DC, ElRect, PressedFlags[Pressed], BF_RECT or BF_MIDDLE);
  980. InflateRect(ElRect, -2, -2);
  981. Windows.FillRect(DC, ElRect, Brush);
  982. end;
  983. end;
  984. MinWH := ElRect.Right - ElRect.Left; //+ Ord(not Active and Flat);
  985. if ElRect.Bottom - ElRect.Top < MinWH then
  986. MinWH := ElRect.Bottom - ElRect.Top;
  987. PWid := MinWH * 4 div 7;
  988. if PWid = 0 then PWid := 1;
  989. PHet := PWid div 3;
  990. if PHet = 0 then PHet := 1;
  991. if Flat then Dec(PWid);
  992. if PWid mod 2 <> MinWH mod 2 then Inc(PWid);
  993. if Plus and (PWid mod 2 <> PHet mod 2) then
  994. if (MinWH < 12) then Inc(PWid) else Dec(PWid);
  995. PlusInd := PWid div 2 - PHet div 2;
  996. W := ElRect.Left + (ElRect.Right - ElRect.Left - PWid) div 2; //- Ord(not Active and Flat);
  997. //if W * 2 + PWid > (ElRect.Right - ElRect.Left) then Dec(W);
  998. Inc(W, Ord(Pressed));
  999. H := ElRect.Top + (ElRect.Bottom - ElRect.Top - PHet) div 2 + Ord(Pressed);
  1000. if not Enabled then
  1001. begin
  1002. Inc(W); Inc(H);
  1003. Brush := GetSysColorBrush(COLOR_BTNHILIGHT);
  1004. SaveBrush := SelectObject(DC, Brush);
  1005. PatBlt(DC, W, H, PWid, PHet, PATCOPY);
  1006. if Plus then PatBlt(DC, W + PlusInd, H - PlusInd, PHet, PWid, PATCOPY);
  1007. Dec(W); Dec(H);
  1008. SelectObject(DC, SaveBrush);
  1009. Brush := GetSysColorBrush(COLOR_BTNSHADOW);
  1010. end else
  1011. Brush := GetSysColorBrush(COLOR_BTNTEXT);
  1012. SaveBrush := SelectObject(DC, Brush);
  1013. PatBlt(DC, W, H, PWid, PHet, PATCOPY);
  1014. if Plus then PatBlt(DC, W + PlusInd, H - PlusInd, PHet, PWid, PATCOPY);
  1015. SelectObject(DC, SaveBrush);
  1016. end;
  1017. procedure DrawDropDownButton(DC: HDC; ARect: TRect; Enabled, Flat, Active, Down: Boolean);
  1018. var
  1019. Flags: Integer;
  1020. {$IFDEF EH_LIB_7}
  1021. Details: TThemedElementDetails;
  1022. {$ENDIF}
  1023. // Rgn, SaveRgn: HRGN;
  1024. // r: Integer;
  1025. // IsClip: Boolean;
  1026. begin
  1027. {$IFDEF EH_LIB_7}
  1028. if ThemeServices.ThemesEnabled then
  1029. begin
  1030. if not Enabled then
  1031. Details := ThemeServices.GetElementDetails(tcDropDownButtonDisabled)
  1032. else
  1033. if Down then
  1034. Details := ThemeServices.GetElementDetails(tcDropDownButtonPressed)
  1035. else
  1036. if Active
  1037. then Details := ThemeServices.GetElementDetails(tcDropDownButtonHot)
  1038. else Details := ThemeServices.GetElementDetails(tcDropDownButtonNormal);
  1039. { with Details do
  1040. GetThemeBackgroundRegion(ThemeServices.Theme[Element], DC, Part, State, ARect, Rgn);
  1041. IsClip := False;
  1042. SaveRgn := 0;
  1043. r := 0;
  1044. if Rgn <> 0 then
  1045. begin
  1046. IsClip := True;
  1047. SaveRgn := CreateRectRgn(0, 0, 0, 0);
  1048. r := GetClipRgn(DC, SaveRgn);
  1049. SelectClipRgn(DC, Rgn);
  1050. DeleteObject(Rgn);
  1051. end;}
  1052. ThemeServices.DrawElement(DC, Details, ARect);
  1053. { if IsClip = True then
  1054. begin
  1055. if r = 0
  1056. then SelectClipRgn(DC, 0)
  1057. else SelectClipRgn(DC, SaveRgn);
  1058. DeleteObject(SaveRgn);
  1059. end;}
  1060. end else
  1061. {$ENDIF}
  1062. begin
  1063. Flags := DownFlags[Down] or FlatFlags[Flat] or EnabledFlags[Enabled];
  1064. DrawFrameControl(DC, ARect, DFC_SCROLL, Flags or DFCS_SCROLLCOMBOBOX);
  1065. end;
  1066. end;
  1067. procedure DrawUpDownButton(DC: HDC; ARect: TRect; Enabled, Flat, Active, Down, DownDirection: Boolean);
  1068. var
  1069. Flags: Integer;
  1070. {$IFDEF EH_LIB_7}
  1071. Details: TThemedElementDetails;
  1072. {$ENDIF}
  1073. begin
  1074. {$IFDEF EH_LIB_7}
  1075. if ThemeServices.ThemesEnabled then
  1076. begin
  1077. if DownDirection then
  1078. if not Enabled then
  1079. Details := ThemeServices.GetElementDetails(tsDownDisabled)
  1080. else
  1081. if Down then
  1082. Details := ThemeServices.GetElementDetails(tsDownPressed)
  1083. else
  1084. if Active
  1085. then Details := ThemeServices.GetElementDetails(tsDownHot)
  1086. else Details := ThemeServices.GetElementDetails(tsDownNormal)
  1087. else
  1088. if not Enabled then
  1089. Details := ThemeServices.GetElementDetails(tsUpDisabled)
  1090. else
  1091. if Down then
  1092. Details := ThemeServices.GetElementDetails(tsUpPressed)
  1093. else
  1094. if Active
  1095. then Details := ThemeServices.GetElementDetails(tsUpHot)
  1096. else Details := ThemeServices.GetElementDetails(tsUpNormal);
  1097. ThemeServices.DrawElement(DC, Details, ARect);
  1098. end else
  1099. {$ENDIF}
  1100. begin
  1101. Flags := DownFlags[Down] or FlatFlags[Flat] or EnabledFlags[Enabled];
  1102. DrawFrameControl(DC, ARect, DFC_SCROLL, Flags or IsDownFlags[DownDirection]);
  1103. end;
  1104. end;
  1105. procedure DrawOneButton(DC: HDC; Style: TDrawButtonControlStyleEh;
  1106. ARect: TRect; Enabled, Flat, Active, Down, DownDirection: Boolean);
  1107. var
  1108. Rgn, SaveRgn: HRgn;
  1109. r: Integer;
  1110. IsClipRgn: Boolean;
  1111. DRect: TRect;
  1112. // Brush: HBRUSH;
  1113. begin
  1114. DRect := ARect;
  1115. // LPtoDP(DC, DRect, 2);
  1116. WindowsLPtoDP(DC, DRect);
  1117. {$IFDEF EH_LIB_7}
  1118. IsClipRgn := Flat and Active and not ThemeServices.ThemesEnabled;
  1119. {$ELSE}
  1120. IsClipRgn := Flat and Active;
  1121. {$ENDIF}
  1122. r := 0; SaveRgn := 0;
  1123. if IsClipRgn then
  1124. begin
  1125. SaveRgn := CreateRectRgn(0, 0, 0, 0);
  1126. r := GetClipRgn(DC, SaveRgn);
  1127. with DRect do
  1128. Rgn := CreateRectRgn(Left + 1, Top + 1, Right - 1, Bottom - 1);
  1129. SelectClipRgn(DC, Rgn);
  1130. DeleteObject(Rgn);
  1131. end;
  1132. if Flat {$IFDEF EH_LIB_7} and not ThemeServices.ThemesEnabled {$ENDIF} then
  1133. if not Active {and not (Style=bcsUpDownEh)}
  1134. then InflateRect(ARect, 2, 2)
  1135. else InflateRect(ARect, 1, 1);
  1136. case Style of
  1137. bcsDropDownEh: DrawDropDownButton(DC, ARect, Enabled, Flat, Active, Down);
  1138. bcsEllipsisEh: DrawEllipsisButton(DC, ARect, Enabled, Active, Flat, Down);
  1139. bcsUpDownEh: DrawUpDownButton(DC, ARect, Enabled, Flat, Active, Down, DownDirection);
  1140. bcsMinusEh, bcsPlusEh: DrawPlusMinusButton(DC, ARect, Enabled, Active, Flat, Down, bcsPlusEh = Style);
  1141. end;
  1142. if Flat then
  1143. if not Active {and not (Style=bcsUpDownEh)}
  1144. then InflateRect(ARect, -2, -2)
  1145. else InflateRect(ARect, -1, -1);
  1146. if IsClipRgn then
  1147. begin
  1148. if r = 0
  1149. then SelectClipRgn(DC, 0)
  1150. else SelectClipRgn(DC, SaveRgn);
  1151. DeleteObject(SaveRgn);
  1152. if Down
  1153. then DrawEdge(DC, ARect, BDR_SUNKENOUTER, BF_RECT)
  1154. else DrawEdge(DC, ARect, BDR_RAISEDINNER, BF_RECT)
  1155. end;
  1156. end;
  1157. type
  1158. PPoints = ^TPoints;
  1159. TPoints = array[0..0] of TPoint;
  1160. TButtonBitmapInfoEh = record
  1161. Size: TPoint;
  1162. BitmapType: TDrawButtonControlStyleEh;
  1163. Flat: Boolean;
  1164. Pressed: Boolean;
  1165. Active: Boolean;
  1166. Enabled: Boolean;
  1167. DownDirect: Boolean;
  1168. CheckState: TCheckBoxState;
  1169. end;
  1170. function CompareButtonBitmapInfo(Info1, Info2: TButtonBitmapInfoEh): Boolean;
  1171. begin
  1172. Result := (Info1.Size.X = Info2.Size.X) and (Info1.Size.Y = Info2.Size.Y)
  1173. and (Info1.BitmapType = Info2.BitmapType)
  1174. and (Info1.Flat = Info2.Flat)
  1175. and (Info1.Pressed = Info2.Pressed)
  1176. and (Info1.Active = Info2.Active)
  1177. and (Info1.Enabled = Info2.Enabled)
  1178. and (Info1.DownDirect = Info2.DownDirect)
  1179. and (Info1.CheckState = Info2.CheckState);
  1180. end;
  1181. type
  1182. { TButtonsBitmapCache }
  1183. TButtonBitmapInfoBitmapEh = class(TObject)
  1184. public
  1185. BitmapInfo: TButtonBitmapInfoEh;
  1186. Bitmap: TBitmap;
  1187. end;
  1188. // PButtonBitmapInfoBitmapEh = ^TButtonBitmapInfoBitmapEh;
  1189. TButtonsBitmapCache = class(TObjectList)
  1190. private
  1191. function Get(Index: Integer): TButtonBitmapInfoBitmapEh;
  1192. // procedure Put(Index: Integer; const Value: PButtonBitmapInfoBitmapEh);
  1193. public
  1194. constructor Create; overload;
  1195. procedure Clear; override;
  1196. function GetButtonBitmap(ButtonBitmapInfo: TButtonBitmapInfoEh): TBitmap;
  1197. property Items[Index: Integer]: TButtonBitmapInfoBitmapEh read Get {write Put}; default;
  1198. end;
  1199. var ButtonsBitmapCache: TButtonsBitmapCache;
  1200. procedure ClearButtonsBitmapCache;
  1201. begin
  1202. ButtonsBitmapCache.Clear;
  1203. end;
  1204. function RectSize(ARect: TRect): TSize;
  1205. begin
  1206. Result.cx := ARect.Right - ARect.Left;
  1207. Result.cy := ARect.Bottom - ARect.Top;
  1208. end;
  1209. procedure PaintButtonControlEh(DC: HDC; ARect: TRect; ParentColor: TColor;
  1210. Style: TDrawButtonControlStyleEh; DownButton: Integer;
  1211. Flat, Active, Enabled: Boolean; State: TCheckBoxState);
  1212. var
  1213. Rgn, SaveRgn: HRgn;
  1214. HalfRect, DRect: TRect;
  1215. ASize: TSize;
  1216. r: Integer;
  1217. Brush: HBRUSH;
  1218. IsClipRgn: Boolean;
  1219. BitmapInfo: TButtonBitmapInfoEh;
  1220. Bitmap: TBitmap;
  1221. begin
  1222. SaveRgn := 0; r := 0;
  1223. // FillChar(BitmapInfo, Sizeof(BitmapInfo), #0);
  1224. BitmapInfo.BitmapType := Style;
  1225. BitmapInfo.Flat := Flat;
  1226. if Style = bcsCheckboxEh then
  1227. begin
  1228. ASize := RectSize(ARect);
  1229. if ASize.cx < ASize.cy then
  1230. begin
  1231. ARect.Top := ARect.Top + (ASize.cy - ASize.cx) div 2;
  1232. ARect.Bottom := ARect.Bottom - (ASize.cy - ASize.cx) div 2 - (ASize.cy - ASize.cx) mod 2;
  1233. end else if ASize.cx > ASize.cy then
  1234. begin
  1235. ARect.Left := ARect.Left + (ASize.cx - ASize.cy) div 2;
  1236. ARect.Right := ARect.Right - (ASize.cx - ASize.cy) div 2 - (ASize.cx - ASize.cy) mod 2;
  1237. end;
  1238. if Flat then InflateRect(ARect, -1, -1);
  1239. if UseButtonsBitmapCache then
  1240. begin
  1241. BitmapInfo.Size := Point(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top);
  1242. BitmapInfo.CheckState := State;
  1243. BitmapInfo.Pressed := DownButton <> 0;
  1244. BitmapInfo.Active := Active;
  1245. BitmapInfo.Enabled := Enabled;
  1246. Bitmap := ButtonsBitmapCache.GetButtonBitmap(BitmapInfo);
  1247. StretchBlt(DC, ARect.Left, ARect.Top, ARect.Right - ARect.Left,
  1248. ARect.Bottom - ARect.Top, Bitmap.Canvas.Handle, 0, 0,
  1249. Bitmap.Width, Bitmap.Height, cmSrcCopy);
  1250. end else
  1251. DrawCheck(DC, ARect, State, Enabled, Flat, DownButton <> 0, Active);
  1252. if Flat then
  1253. begin
  1254. InflateRect(ARect, 1, 1);
  1255. if Active then
  1256. DrawEdge(DC, ARect, BDR_SUNKENOUTER, BF_RECT)
  1257. else
  1258. begin
  1259. // FrameRect(DC, ARect, GetCurrentObject(DC, OBJ_BRUSH));
  1260. Brush := CreateSolidBrush(ColorToRGB(ParentColor));
  1261. FrameRect(DC, ARect, Brush);
  1262. DeleteObject(Brush);
  1263. end;
  1264. end;
  1265. end else
  1266. begin
  1267. BitmapInfo.Active := Active;
  1268. BitmapInfo.Enabled := Enabled;
  1269. {$IFDEF EH_LIB_7}
  1270. IsClipRgn := Flat and not Active and not ThemeServices.ThemesEnabled;
  1271. {$ELSE}
  1272. IsClipRgn := Flat and not Active;
  1273. {$ENDIF}
  1274. if IsClipRgn then
  1275. begin
  1276. DRect := ARect;
  1277. WindowsLPtoDP(DC, DRect);
  1278. InflateRect(ARect, -1, -1);
  1279. if not UseButtons

Large files files are truncated, but you can click here to view the full file