/KO208L.pas

http://github.com/rofl0r/KOL · Pascal · 29547 lines · 18264 code · 2650 blank · 8633 comment · 1055 complexity · a81b16c76440c8b48a9fd8dcd1486d3f MD5 · raw file

  1. //[START OF KOL.pas]
  2. {****************************************************************
  3. KKKKK KKKKK OOOOOOOOO LLLLL
  4. KKKKK KKKKK OOOOOOOOOOOOO LLLLL
  5. KKKKK KKKKK OOOOO OOOOO LLLLL
  6. KKKKK KKKKK OOOOO OOOOO LLLLL
  7. KKKKKKKKKK OOOOO OOOOO LLLLL
  8. KKKKK KKKKK OOOOO OOOOO LLLLL
  9. KKKKK KKKKK OOOOO OOOOO LLLLL
  10. KKKKK KKKKK OOOOOOOOOOOOO LLLLLLLLLLLLL
  11. KKKKK KKKKK OOOOOOOOO LLLLLLLLLLLLL
  12. Key Objects Library (C) 2000 by Kladov Vladimir.
  13. //[VERSION]
  14. ****************************************************************
  15. * VERSION 2.08
  16. ****************************************************************
  17. //[END OF VERSION]
  18. K.O.L. - is a set of objects to create small programs
  19. with the Delphi, but without the VCL. KOL allows to
  20. create executables of size about 10 times smaller then
  21. those created with the VCL. But this does not mean that
  22. KOL is less power then the VCL - perhaps just the opposite...
  23. KOL is provided free with the source code.
  24. Copyright (C) Vladimir Kladov, 2000-2003.
  25. For code provided by other developers (even if later
  26. changed by me) authors are noted in the source.
  27. mailto: bonanzas@online.sinor.ru
  28. Web-Page: http://bonanzas.rinet.ru
  29. See also Mirror Classes Kit (M.C.K.) which allows
  30. to create KOL programs visually.
  31. ****************************************************************}
  32. //[UNIT DEFINES]
  33. {$INCLUDE delphidef.inc}
  34. //[START OF UNIT]
  35. unit KOL;
  36. {-}
  37. {*
  38. Please note, that KOL does not use keyword 'class'. Instead,
  39. poor Pascal 'object' is the base of our objects. So, remember,
  40. how we worked earlier with such Object Pascal's objects:
  41. |<br>
  42. - to create objects dynamically, use P<objname> instead of
  43. T<objname> to allocate a pointer for dynamically created
  44. object instance;
  45. |<br>
  46. - remember, that constructors of objects can not be virtual.
  47. Override procedure Init instead in your own derived objects;
  48. |<br>
  49. - rather then call constructors of objects, call global procedures
  50. New<objname> (e.g. NewLabel). If not, first (for virtualally
  51. created objects) call New( ); then call constructor Create
  52. (which calls Init) - but this is possible only if the constructor
  53. is overriden by a new one.
  54. |<br>
  55. - the operator 'is' is not applicable to objects. And operator 'as'
  56. is not necessary (and is not applicable too), use typecast to desired
  57. object type, e.g.: "PSomeObjectType( C )" inplace of "C as TSomeClassType".
  58. |<br>
  59. |<hr>
  60. Also remember, that IF [ MyObj: PMyObj ] THEN
  61. NOT[ with MyObj do ] BUT[ with MyObj^ do ]
  62. Though it is possible to skip '^' symbol when accessing member
  63. fields, methods, properties, e.g. [ MyObj.Execute; ]
  64. |<hr>
  65. |&U=&nbsp;&nbsp;&nbsp;<a href="#%0">%0</a><br>
  66. |&B=<a href="%1.htm">%0</a><br>
  67. |&C=<a href="%1.htm">%0</a>
  68. | <table border=1 cellpadding=6 width=100%>
  69. | <colgroup valign=top span=2>
  70. | <tr>
  71. | <td> objects </td> <td> functions by category </td>
  72. | </tr>
  73. | <td>
  74. <C _TObj> <B TObj>
  75. <C TList> <C TListEx> <C TStrList> <B TStrListEx>
  76. <C TTree> <C TDirList> <C TIniFile> <C TCabFile>
  77. <B TStream>
  78. <B TControl>
  79. <C TGraphicTool> <C TCanvas> <C TImageList> <C TIcon> <C TBitmap>
  80. <C TGif> <C TGifDecoder> <B TJpeg>
  81. <C TTimer> <C TThread> <C TTrayIcon> <C TDirChange> <B TMediaPlayer>
  82. <C TMenu> <C TOpenSaveDialog> <C TOpenDirDialog> <B TColorDialog>
  83. <C TAction> <B TActionList>
  84. <B Exception>
  85. | </td>
  86. | <td>
  87. |<a href="kol_pas.htm#visual_objects_constructors">
  88. Visual objects constructing functions
  89. |</a><br><br>
  90. <U Working with null-terminated and ansi strings>
  91. <U Small bit arrays (max 32 bits in array)>
  92. <U Arithmetics, geometry and other utility functions>
  93. <U Data sorting (quicksort implementation)>
  94. <U String to number and number to string conversions>
  95. <U 64-bit integer numbers>
  96. <U Floating point numbers>
  97. <U Date and time handling>
  98. <U File and directory routines>
  99. <U System functions and working with windows>
  100. <U Text in clipboard operations>
  101. <U Wrappers to registry API functions>
  102. | </td>
  103. | </table>
  104. Several conditional symbols can be used in a project
  105. (Project | Options | Directories/Conditional Defines)
  106. to change code generated a bit. There are following:
  107. |<pre>
  108. PAS_VERSION - to use Pascal version of the code.
  109. PARANOIA - to force short versions of asm instructions (for D5
  110. and below, D6 and higher use those instructions always).
  111. USE_NAMES - to use property Name with any TObj. This makes also
  112. available global function FindObj( name ): PObj.
  113. (USE_CONSTRUCTORS - to use constructors like in VCL. Note: this option is
  114. not carefully tested!)
  115. USE_CUSTOMEXTENSIONS - to extend TControl with custom additions.
  116. UNICODE_CTRLS - to use Unicode versions of controls (WM_XXXXW messages,
  117. etc.)
  118. USE_MHTOOLTIP - to use MHTOOLTIP.
  119. NOT_USE_OnIdle - to stop using OnIdle event (to make code smaller
  120. if it is not used actually).
  121. USE_ASM_DODRAG - to use assembler version of code for DoDrag.
  122. ENUM_DYN_HANDLERS_AFTER_RUN - to allow all the events handling even when
  123. AppletTerminated become TRUE.
  124. ALL_BUTTONS_RESPOND_TO_ENTER - obvious (by default, buttons respond to key
  125. SPACE, since those are working this way in Windows).
  126. ESC_CLOSE_DIALOGS - to allow closing all dialogs with ESCAPE.
  127. KEY_PREVIEW - form also receive WM_KEYDOWN (OnKeyDown event fired)
  128. OpenSaveDialog_Extended - to allow using custom extensions for OpenSaveDialog.
  129. AUTO_CONTEXT_HELP - to use automatic respond to WM_CONTEXTMENU to call
  130. context help.
  131. NOT_FIX_CURINDEX - to use old version of TControl.SetItems, which could
  132. lead to loose CurIndex value (e.g. for Combobox)
  133. NOT_FIX_MODAL - not to fix modal (if fixed, click on any window
  134. activates the application. If not fixed, code is
  135. smaller very a little, but only click on modal form
  136. activates the application).
  137. NEW_MODAL - to use extended modalness.
  138. USE_SETMODALRESULT - to guarantee ModalResult property assigninig handling.
  139. USE_MENU_CURCTL - to use CurCtl property in popup menu to detect which
  140. control initiated a pop-up.
  141. NEW_MENU_ACCELL - to use another menu accelerators handling, without
  142. AcceleratorTable
  143. USE_DROPDOWNCOUNT - to force setting combobox dropdown count.
  144. NOT_UNLOAD_RICHEDITLIB - to stop unload Rich Edit library in finalization
  145. section (to economy several byte of code).
  146. DEBUG_GDIOBJECTS - to allow counting all the GDI objects used.
  147. CHK_BITBLT - to check BitBlt operations.
  148. DEBUG_ENDSESSION - to allow debugging WM_ENDSESSION handling.
  149. DEBUG_CREATEWINDOW - to debug CreateWindow.
  150. TEST_CLOSE - to debug Close.
  151. DEBUG_MENU - to debug menu.
  152. DEBUG_DBLBUFF - to debug DoubleBuffered.
  153. DEBUG - other debugging.
  154. PROVIDE_EXITCODE - PostQuitMessage( value ) assigns value to ExitCode
  155. INITIALFORMSIZE_FIXMENU - form size initially is really the same as defined at
  156. design time even for forms having main menu bar
  157. GRAPHCTL_XPSTYLES - to use XP themed Visual styles for drawing graphic
  158. controls. This does not affect windowed controls
  159. which visual style is controlled by the manifest.
  160. GRAPHCTL_HOTTRACK - to use hot-tracking also together with XP themed
  161. graphic controls (otherwise only static XP themed
  162. view is provided). Also, turn this option on if you
  163. want to handle OnMouseEnter and OnMouseLeabe events
  164. for graphic controls.
  165. |</pre>
  166. }
  167. {= K.O.L - êëþ÷åâàÿ áèáëèîòåêà îáúåêòîâ. (C) Êëàäîâ Âëàäèìèð, 2000-2003.
  168. }
  169. //[OPTIONS]
  170. {$A-} // align off, otherwise code is not good
  171. {+}
  172. {$Q-} // no overflow check: this option makes code wrong
  173. {$R-} // no range checking: this option makes code wrong
  174. {$T-} // not typed @-operator
  175. //{$D+}
  176. {$IFDEF INPACKAGE} // use this symbol in packages requiring kol.pas
  177. {$WARNINGS OFF}
  178. {$ENDIF}
  179. {$IFDEF _D7orHigher}
  180. {$WARN UNSAFE_TYPE OFF} // Too many such warnings in Delphi7
  181. {$WARN UNSAFE_CODE OFF}
  182. {$WARN UNSAFE_CAST OFF}
  183. {$ENDIF}
  184. //[START OF INTERFACE]
  185. interface
  186. //{$DEFINE DEBUG_GDIOBJECTS}
  187. //{$DEFINE CHK_GDI}
  188. //[USES]
  189. uses
  190. messages, windows, RichEdit {$IFDEF CHK_GDI}, ChkGdi {$ENDIF};
  191. //[END OF USES]
  192. {$IFDEF DEBUG_GDIOBJECTS}
  193. var
  194. BrushCount: Integer;
  195. FontCount: Integer;
  196. PenCount: Integer;
  197. {$ENDIF}
  198. //{_#IF [DELPHI]}
  199. {$INCLUDE delphicommctrl.inc}
  200. //{_#ENDIF}
  201. type
  202. //[_TObj DEFINITION]
  203. {-}
  204. _TObj = object
  205. {* auxiliary object type. See TObj. }
  206. protected
  207. procedure Init; virtual;
  208. {* Is called from a constructor to initialize created object instance
  209. filling its fields with 0. Can be overriden in descendant objects
  210. to add another initialization code there. (Main reason of intending
  211. is what constructors can not be virtual in poor objects). }
  212. {= Âûçûâàåòñÿ äëÿ èíèöèàëèçàöèè îáúåêòà. }
  213. public
  214. function VmtAddr: Pointer;
  215. {* Returns addres of virtual methods table of object. ? }
  216. {= âîçâðàùàåò àäðåñ òàáëèöû âèðòóàëüíûõ ìåòîäîâ (VMT). ? }
  217. end;
  218. {+}
  219. {++}(* TObj = class;*){--}
  220. PObj = {-}^{+}TObj;
  221. {* }
  222. {++}(* TList = class;*){--}
  223. PList = {-}^{+}TList;
  224. {* }
  225. //[TObjectMethod DECLARATION]
  226. TObjectMethod = procedure of object;
  227. {* }
  228. TOnEvent = procedure( Sender: PObj ) of object;
  229. {* This type of event is the most common - event handler when called can
  230. know only what object was a sender of this call. Replaces good known
  231. VCL TNotifyEvent event type. }
  232. //[TPointerList DECLARATION]
  233. PPointerList = ^TPointerList;
  234. TPointerList = array[0..MaxInt div 4 - 1] of Pointer;
  235. { ---------------------------------------------------------------------
  236. TObj - base object to derive all others
  237. ---------------------------------------------------------------------- }
  238. //[TObj DEFINITION]
  239. TObj = {-} object( _TObj ) {+}{++}(*class*){--}
  240. {* Prototype for all objects of KOL. All its methods are important to
  241. implement objects in a manner similar to Delphi TObject class. }
  242. {= Áàçîâûé êëàññ äëÿ âñåõ ïðî÷èõ îáúåêòîâ KOL. }
  243. protected
  244. fRefCount: Integer;
  245. fOnDestroy: TOnEvent;
  246. procedure DoDestroy;
  247. protected
  248. fAutoFree: PList;
  249. {* Is called from a constructor to initialize created object instance
  250. filling its fields with 0. Can be overriden in descendant objects
  251. to add another initialization code there. (Main reason of intending
  252. is what constructors can not be virtual in poor objects). }
  253. {= Âûçûâàåòñÿ äëÿ èíèöèàëèçàöèè îáúåêòà. }
  254. fTag: DWORD;
  255. {* Custom data. }
  256. {++}(*public*){--}
  257. destructor Destroy; {-} virtual; {+}{++}(* override; *){--}
  258. {* Disposes memory, allocated to an object. Does not release huge strings,
  259. dynamic arrays and so on. Such memory should be freeing in overriden
  260. destructor. }
  261. {= Îñâîáîæäàåò ïàìÿòü, âûäåëåííóþ äëÿ îáúåêòà. Íå îñâîáîæäàåò ïàìÿòü, âûäåëåííóþ
  262. äëÿ ñòðîê, äèíàìè÷èñêèõ ìàññèâîâ è ò.ï. Òàêàÿ ïàìÿòü äîëæíà áûòü îñâîáîæäåíà
  263. â ïåðåîïðåäåëåííîì äåñòðóêòîðå îáúåêòà. }
  264. {++}(*protected*){--}
  265. {++}(*
  266. procedure Init; virtual;
  267. {* Can be overriden in descendant objects
  268. to add initialization code there. (Main reason of intending
  269. is what constructors can not be virtual in poor objects). }
  270. *){--}
  271. procedure Final;
  272. {* It is called in destructor to perform OnDestroy event call and to
  273. released objects, added to fAutoFree list. }
  274. public
  275. procedure Free;
  276. {* Before calling destructor of object, checks if passed pointer is not
  277. nil - similar what is done in VCL for TObject. It is ALWAYS recommended
  278. to use Free instead of Destroy - see also comments to RefInc, RefDec. }
  279. {= Äî âûçîâà äåñòðóêòîðà, ïðîâåðÿåò, íå ïåðåäàí ëè nil â êà÷åñòâå ïàðàìåòðà.
  280. ÂÑÅÃÄÀ ðåêîìåíäóåòñÿ èñïîëüçîâàòü Free âìåñòî Destroy - ñì. òàê æå RefInc,
  281. RefDec. }
  282. {-}
  283. // By Vyacheslav Gavrik:
  284. function InstanceSize: Integer;
  285. {* Returns a size of object instance. }
  286. {+}
  287. constructor Create;
  288. {* Constructor. Do not call it. Instead, use New<objectname> function
  289. call for certain object, e.g., NewLabel( AParent, 'caption' ); }
  290. {= Êîíñòðóêòîð. Íå ñëåäóåò âûçûâàòü åãî. Äëÿ êîíñòðóèðîâàíèÿ îáúåêòîâ,
  291. âûçûâàéòå ñîîòâåòñòâóþùóþ ãëîáàëüíóþ ôóíêöèþ New<èìÿ-îáúåêòà>. Íàïðèìåð,
  292. NewLabel( MyForm, 'Ìåòêà¹1' ); }
  293. {-}
  294. class function AncestorOfObject( Obj: Pointer ): Boolean;
  295. {* Is intended to replace 'is' operator, which is not applicable to objects. }
  296. {= }
  297. function VmtAddr: Pointer;
  298. {* Returns addres of virtual methods table of object. }
  299. {= âîçâðàùàåò àëðåñ òàáëèöû âèðòóàëüíûõ ìåòîäîâ (VMT). }
  300. {+}
  301. procedure RefInc;
  302. {* See comments below. }
  303. {= Ñì. RefDec íèæå. }
  304. procedure RefDec;
  305. {* Decrements reference count. If it is becoming <0, and Free
  306. method was already called, object is (self-) destroyed. Otherwise,
  307. Free method does not destroy object, but only sets flag
  308. "Free was called".
  309. |<br>
  310. Use RefInc..RefDec to provide a block of code, where
  311. object can not be destroyed by call of Free method.
  312. This makes code more safe from intersecting flows of processing,
  313. where some code want to destroy object, but others suppose that it
  314. is yet existing.
  315. |<br>
  316. If You want to release object at the end of block RefInc..RefDec,
  317. do it immediately BEFORE call of last RefDec (to avoid situation,
  318. when object is released in result of RefDec, and attempt to
  319. destroy it follow leads to AV exception).
  320. }
  321. {= Óìåíüøàåò ñ÷åò÷èê èñïîëüçîâàíèÿ. Åñëè â ðåçóëüòàòå ñ÷åò÷èê ñòàíîâèòñÿ
  322. < 0, è ìåòîä Free óæå áûë âûçâàí, îáúåêò (ñàìî-) ðàçðóøàåòñÿ. Èíà÷å,
  323. ìåòîä Free íå ðàçðóøàåò îáúåêò, à òîëüêî óñòàíàâëèâàåò ôëàã "Free áûë
  324. âûçâàí".
  325. |<br>
  326. Èñïîëüçóéòå RefInc..RefDec äëÿ ïðåäîòâðàùåíèÿ ðàçðóøåíèÿ îáúåêòà íà
  327. íåêîòîðîì ó÷àñòêå êîäà (åñëè åñòü òàêàÿ íåîáõîäèìîñòü).
  328. |<br>
  329. Åñëè íóæíî óáèòü (âðåìåííûé) îáúåêò âìåñòå ñ ïîñëåäíèì RefDec, ñäåëàéòå
  330. âûçîâ Free íåìåäëåííî ÏÅÐÅÄ ïîñëåäíèì RefDec. }
  331. property RefCount: Integer read fRefCount;
  332. {* }
  333. property OnDestroy: TOnEvent read fOnDestroy write fOnDestroy;
  334. {* This event is provided for any KOL object, so You can provide your own
  335. OnDestroy event for it. }
  336. {= Äàííîå ñîáûòèå îáåñïå÷èâàåòñÿ äëÿ âñåõ îáúåêòîâ KOL. Ïîçâîëÿåò ñäåëàòü
  337. ÷òî-íèáóäü â ñâÿçè ñ ðàçðóøåíèåì îáúåêòà. }
  338. procedure Add2AutoFree( Obj: PObj );
  339. {* Adds an object to the list of objects, destroyed automatically
  340. when the object is destroyed. Do not add here child controls of
  341. the TControl (these are destroyed by another way). Only non-control
  342. objects, which are not destroyed automatically, should be added here. }
  343. procedure Add2AutoFreeEx( Proc: TObjectMethod );
  344. {* Adds an event handler to the list of events, called in destructor.
  345. This method is mainly for internal use, and allows to auto-destroy
  346. VCL components, located on KOL form at design time (in MCK project). }
  347. property Tag: DWORD read fTag write fTag;
  348. {* Custom data field. }
  349. protected
  350. {$IFDEF USE_NAMES}
  351. FName: String;
  352. procedure SetName( const NewName: String );
  353. {$ENDIF}
  354. public
  355. {$IFDEF USE_NAMES}
  356. property Name: String read FName write SetName;
  357. {$ENDIF}
  358. end;
  359. //[END OF TObj DEFINITION]
  360. { ---------------------------------------------------------------------
  361. TList - object to implement list of pointers (or dwords)
  362. ---------------------------------------------------------------------- }
  363. //[TList DEFINITION]
  364. TList = object( TObj )
  365. {* Simple list of pointers. It is used in KOL instead of standard VCL
  366. TList to store any kind data (or pointers to these ones). Can be created
  367. calling function NewList. }
  368. {= Ïðîñòîé ñïèñîê óêàçàòåëåé. }
  369. protected
  370. fItems: PPointerList;
  371. fCount: Integer;
  372. fCapacity: Integer;
  373. fAddBy: Integer;
  374. procedure SetCount(const Value: Integer);
  375. procedure SetAddBy(Value: Integer);
  376. {++}(*public*){--}
  377. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  378. {* Destroys list, freeing memory, allocated for pointers. Programmer
  379. is resposible for destroying of data, referenced by the pointers. }
  380. {= }
  381. {++}(*protected*){--}
  382. procedure SetCapacity( Value: Integer );
  383. function Get( Idx: Integer ): Pointer;
  384. procedure Put( Idx: Integer; Value: Pointer );
  385. {$IFDEF USE_CONSTRUCTORS}
  386. procedure Init; virtual;
  387. {$ENDIF USE_CONSTRUCTORS}
  388. public
  389. procedure Clear;
  390. {* Makes Count equal to 0. Not responsible for freeing (or destroying)
  391. data, referenced by released pointers. }
  392. procedure Add( Value: Pointer );
  393. {* Adds pointer to the end of list, increasing Count by one. }
  394. procedure Insert( Idx: Integer; Value: Pointer );
  395. {* Inserts pointer before given item. Returns Idx, i.e. index of
  396. inserted item in the list. Indeces of items, located after insertion
  397. point, are increasing. To add item to the end of list, pass Count
  398. as index parameter. To insert item before first item, pass 0 there. }
  399. function IndexOf( Value: Pointer ): Integer;
  400. {* Searches first (from start) item pointer with given value and returns
  401. its index (zero-based) if found. If not found, returns -1. }
  402. procedure Delete( Idx: Integer );
  403. {* Deletes given (by index) pointer item from the list, shifting all
  404. follow item indeces up by one. }
  405. procedure DeleteRange( Idx, Len: Integer );
  406. {* Deletes Len items starting from Idx. }
  407. procedure Remove( Value: Pointer );
  408. {* Removes first entry of a Value in the list. }
  409. property Count: Integer read fCount write SetCount;
  410. {* Returns count of items in the list. It is possible to delete a number
  411. of items at the end of the list, keeping only first Count items alive,
  412. assigning new value to Count property (less then Count it is). }
  413. property Capacity: Integer read fCapacity write SetCapacity;
  414. {* Returns number of pointers which could be stored in the list
  415. without reallocating of memory. It is possible change this value
  416. for optimize usage of the list (for minimize number of reallocating
  417. memory operations). }
  418. property Items[ Idx: Integer ]: Pointer read Get write Put; default;
  419. {* Provides access (read and write) to items of the list. Please note,
  420. that TList is not responsible for freeing memory, referenced by stored
  421. pointers. }
  422. function Last: Pointer;
  423. {* Returns the last item (or nil, if the list is empty). }
  424. procedure Swap( Idx1, Idx2: Integer );
  425. {* Swaps two items in list directly (fast, but without testing of
  426. index bounds). }
  427. procedure MoveItem( OldIdx, NewIdx: Integer );
  428. {* Moves item to new position. Pass NewIdx >= Count to move item
  429. after the last one. }
  430. procedure Release;
  431. {* Especially for lists of pointers to dynamically allocated memory.
  432. Releases all pointed memory blocks and destroys object itself. }
  433. procedure ReleaseObjects;
  434. {* Especially for a list of objects derived from TObj.
  435. Calls Free for every of the object in the list, and then calls
  436. Free for the object itself. }
  437. property AddBy: Integer read fAddBy write SetAddBy;
  438. {* Value to increment capacity when new items are added or inserted
  439. and capacity need to be increased. }
  440. property DataMemory: PPointerList read fItems;
  441. {* Raw data memory. Can be used for direct access to items of a list. }
  442. procedure Assign( SrcList: PList );
  443. {* Copies all source list items. }
  444. {$IFDEF _D4orHigher}
  445. procedure AddItems( const AItems: array of Pointer );
  446. {* Adds a list of items given by a dynamic array. }
  447. {$ENDIF}
  448. end;
  449. //[END OF TList DEFINITION]
  450. //[NewList DECLARATION]
  451. function NewList: PList;
  452. {* Returns pointer to newly created TList object. Use it instead usual
  453. TList.Create as it is done in VCL or XCL. }
  454. {$IFDEF _D4orHigher}
  455. function NewListInit( const AItems: array of Pointer ): PList;
  456. {* Creates a list filling it initially with certain Items. }
  457. {$ENDIF}
  458. procedure FastIncNum2Elements( List: TList; FromIdx, Count, Value: Integer );
  459. {* Very fast adds Value to List elements from List[FromIdx] to List[FromIdx+Count-1].
  460. Given elements must exist. Count must be > 0. }
  461. procedure Free_And_Nil( var Obj );
  462. {* Obj.Free and Obj := nil, where Obj *MUST* be TObj or its descendant
  463. (TControl, TMenu, etc.) This procedure is not compatible with VCL's
  464. FreeAndNil, which works with TObject, since this it has another name. }
  465. {$IFDEF USE_NAMES}
  466. var
  467. NamedObjectsList: PList;
  468. function FindObj( const Name: String ): PObj;
  469. {$ENDIF}
  470. { -- tree (non-visual) -- }
  471. type
  472. //[TTree DEFINITION]
  473. {++}(*TTree = class;*){--}
  474. PTree = {-}^{+}TTree;
  475. TTree = object( TObj )
  476. {* Object to store tree-like data in memory (non-visual). }
  477. protected
  478. fParent: PTree;
  479. fChildren: PList;
  480. fPrev: PTree;
  481. fNext: PTree;
  482. fNodeName: String;
  483. fData: Pointer;
  484. function GetCount: Integer;
  485. function GetItems(Idx: Integer): PTree;
  486. procedure Unlink;
  487. function GetRoot: PTree;
  488. function GetLevel: Integer;
  489. function GetTotal: Integer;
  490. function GetIndexAmongSiblings: Integer;
  491. protected
  492. {$IFDEF USE_CONSTRUCTORS}
  493. constructor CreateTree( AParent: PTree; const AName: String );
  494. {* }
  495. {$ENDIF}
  496. {++}(*public*){--}
  497. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  498. {* }
  499. {++}(*protected*){--}
  500. procedure Init; {-}virtual;{+}{++}(*override;*){--}
  501. public
  502. procedure Clear;
  503. {* Destoyes all child nodes. }
  504. property Name: String read fNodeName write fNodeName;
  505. {* Optional node name. }
  506. property Data: Pointer read fData write fData;
  507. {* Optional user-defined pointer. }
  508. property Count: Integer read GetCount;
  509. {* Number of child nodes of given node. }
  510. property Items[ Idx: Integer ]: PTree read GetItems;
  511. {* Child nodes list items. }
  512. procedure Add( Node: PTree );
  513. {* Adds another node as a child of given tree node. This operation
  514. as well as Insert can be used to move node together with its children
  515. to another location of the same tree or even from another tree.
  516. Anyway, added Node first correctly removed from old place (if it is
  517. defined for it). But for simplest task, such as filling of tree with
  518. nodes, code should looking as follows:
  519. ! Node := NewTree( nil, 'test of creating node without parent' );
  520. ! RootOfMyTree.Add( Node );
  521. Though, this code gives the same result as:
  522. ! Node := NewTree( RootOfMyTree, 'test of creatign node as a child' ); }
  523. procedure Insert( Before, Node: PTree );
  524. {* Inserts earlier created 'Node' just before given child node 'Before'
  525. as a child of given tree node. See also Add method. }
  526. property Parent: PTree read fParent;
  527. {* Returns parent node (or nil, if there is no parent). }
  528. property Index: Integer read GetIndexAmongSiblings;
  529. {* Returns an index of the node in a list of nodes of the same parent
  530. (or -1, if Parent is not defined). }
  531. property PrevSibling: PTree read fPrev;
  532. {* Returns previous node in a list of children of the Parent. Nil is
  533. returned, if given node is the first child of the Parent or has
  534. no Parent. }
  535. property NextSibling: PTree read fNext;
  536. {* Returns next node in a list of children of the Parent. Nil is returned,
  537. if given node is the last child of the Parent or has no Parent at all. }
  538. property Root: PTree read GetRoot;
  539. {* Returns root node (i.e. the last Parent, enumerating parents recursively). }
  540. property Level: Integer read GetLevel;
  541. {* Returns level of the node, i.e. integer value, equal to 0 for root
  542. of a tree, 1 for its children, etc. }
  543. property Total: Integer read GetTotal;
  544. {* Returns total number of children of the node and all its children
  545. counting its recursively (but node itself is not considered, i.e.
  546. Total for node without children is equal to 0). }
  547. procedure SortByName;
  548. {* Sorts children of the node in ascending order. Sorting is not
  549. recursive, i.e. only immediate children are sorted. }
  550. procedure SwapNodes( i1, i2: Integer );
  551. {* Swaps two child nodes. }
  552. function IsParentOfNode( Node: PTree ): Boolean;
  553. {* Returns true, if Node is the tree itself or is a parent of the given node
  554. on any level. }
  555. function IndexOf( Node: PTree ): Integer;
  556. {* Total index of the child node (on any level under this node). }
  557. end;
  558. //[END OF TTree DEFINITION]
  559. //[NewTree DECLARATION]
  560. function NewTree( AParent: PTree; const AName: String ): PTree;
  561. {* Constructs tree node, adding it to the end of children list of
  562. the AParent. If AParent is nil, new root tree node is created. }
  563. //[DummyObjProc, DummyObjProcParam DECLARATION]
  564. procedure DummyObjProc( Sender: PObj );
  565. procedure DummyObjProcParam( Sender: PObj; Param: Pointer );
  566. { --- threads --- }
  567. //[THREADS]
  568. const
  569. ABOVE_NORMAL_PRIORITY_CLASS = $8000; // only for Windows 2K
  570. BELOW_NORMAL_PRIORITY_CLASS = $4000; // and higher !
  571. type
  572. {++}(*TThread = class;*){--}
  573. PThread = {-}^{+}TThread;
  574. TThreadMethod = procedure of object;
  575. TThreadMethodEx = procedure( Sender: PThread; Param: Pointer ) of object;
  576. TOnThreadExecute = function(Sender:PThread): Integer of object;
  577. {* Event to be called when Execute method is called for TThread }
  578. { ---------------------------------------------------------------------
  579. TThread object
  580. ---------------------------------------------------------------------- }
  581. //[TThread DEFINITION]
  582. TThread = object(TObj)
  583. {* Thread object. It is possible not to derive Your own thread-based
  584. object, but instead create thread Suspended and assign event
  585. OnExecute. To create, use one of NewThread of NewThreadEx functions,
  586. or derive Your own descendant object and write creation function
  587. (or constructor) for it.
  588. |<br><br>
  589. Aknowledgements. Originally class ZThread was developed for XCL:
  590. |<br> * By: Tim Slusher : junior@nlcomm.com
  591. |<br> * Home: http://www.nlcomm.com/~junior
  592. }
  593. protected
  594. FSuspended,
  595. FTerminated: boolean;
  596. FHandle: THandle;
  597. FThreadId: DWORD;
  598. FOnSuspend: TObjectMethod;
  599. FOnResume: TOnEvent;
  600. FData : Pointer;
  601. FOnExecute : TOnThreadExecute;
  602. FMethod: TThreadMethod;
  603. FMethodEx: TThreadMethodEx;
  604. F_AutoFree: Boolean;
  605. function GetPriorityCls: Integer;
  606. function GetThrdPriority: Integer;
  607. procedure SetPriorityCls(Value: Integer);
  608. procedure SetThrdPriority(Value: Integer);
  609. {++}(*public*){--}
  610. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  611. {* }
  612. public
  613. function Execute: integer; virtual;
  614. {* Executes thread. Do not call this method from another thread! (Even do
  615. not call this method at all!) Instead, use Resume.
  616. |<br>
  617. Note also that in contrast to VCL, it is not necessary to create your
  618. own descendant object from TThread and override Execute method. In KOL,
  619. it is sufficient to create an instance of TThread object (see NewThread,
  620. NewThreadEx, NewThreadAutoFree functions) and assign OnExecute event
  621. handler for it. }
  622. procedure Resume;
  623. {* Continues executing. It is necessary to make call for every
  624. nested Suspend. }
  625. procedure Suspend;
  626. {* Suspends thread until it will be resumed. Can be called from another
  627. thread or from the thread itself. }
  628. procedure Terminate;
  629. {* Terminates thread. }
  630. function WaitFor: Integer;
  631. {* Waits (infinitively) until thead will be finished. }
  632. property Handle: THandle read FHandle;
  633. {* Thread handle. It is created immediately when object is created
  634. (using NewThread). }
  635. property Suspended: boolean read FSuspended;
  636. {* True, if suspended. }
  637. property Terminated: boolean read FTerminated;
  638. {* True, if terminated. }
  639. property ThreadId: DWORD read FThreadId;
  640. {* Thread id. }
  641. property PriorityClass: Integer read GetPriorityCls write SetPriorityCls;
  642. {* Thread priority class. One of following values: HIGH_PRIORITY_CLASS,
  643. IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS. }
  644. property ThreadPriority: Integer read GetThrdPriority write SetThrdPriority;
  645. {* Thread priority value. One of following values: THREAD_PRIORITY_ABOVE_NORMAL,
  646. THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_IDLE,
  647. THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_TIME_CRITICAL. }
  648. property Data : Pointer read FData write FData;
  649. {* Custom data pointer. Use it for Youe own purpose. }
  650. property OnExecute: TOnThreadExecute read FOnExecute write FOnExecute;
  651. {* Is called, when Execute is starting. }
  652. property OnSuspend: TObjectMethod read FOnSuspend write FOnSuspend;
  653. {* Is called, when Suspend is performed. }
  654. property OnResume: TOnEvent read FOnResume write FOnResume;
  655. {* Is called, when resumed. }
  656. procedure Synchronize( Method: TThreadMethod );
  657. {* Call it to execute given method in main thread context. Applet variable
  658. must exist for that time. }
  659. procedure SynchronizeEx( Method: TThreadMethodEx; Param: Pointer );
  660. {* Call it to execute given method in main thread context, with a given
  661. parameter. Applet variable must exist for that time. Param must not be nil. }
  662. {$IFDEF USE_CONSTRUCTORS}
  663. constructor ThreadCreate;
  664. constructor ThreadCreateEx( const Proc: TOnThreadExecute );
  665. {$ENDIF USE_CONSTRUCTORS}
  666. property AutoFree: Boolean read F_AutoFree write F_AutoFree;
  667. {* Set this property to true to provide automatic destroying of thread
  668. object when its executing is finished. }
  669. end;
  670. //[END OF TThread DEFINITION]
  671. //[NewThread, NewThreadEx, NewThreadAutoFree, Global_Synchronized DECLARATIONS]
  672. function NewThread: PThread;
  673. {* Creates thread object (always suspended). After creating, set event
  674. OnExecute and perform Resume operation. }
  675. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  676. {* Creates thread object, assigns Proc to its OnExecute event and runs
  677. it. }
  678. function NewThreadAutoFree( const Proc: TOnThreadExecute ): PThread;
  679. {* Creates thread object similar to NewThreadEx, but freeing automatically
  680. when executing of such thread finished. Be sure that a thread is resumed
  681. at least to provide its object keeper freeing. }
  682. var Global_Synchronized: procedure( Sender: PObj; Param: Pointer ) = DummyObjProcParam;
  683. // It is not necessary to declare it as threadvar.
  684. { -- streams -- }
  685. //[STREAMS]
  686. type
  687. TMoveMethod = ( spBegin, spCurrent, spEnd );
  688. {++}(*TStream = class;*){--}
  689. PStream = {-}^{+}TStream;
  690. PStreamMethods = ^TStreamMethods;
  691. TStreamMethods = Packed Record
  692. fSeek: function( Strm: PStream; MoveTo: Integer; MoveMethod: TMoveMethod ): DWORD;
  693. fGetSiz: function( Strm: PStream ): DWORD;
  694. fSetSiz: procedure( Strm: PStream; Value: DWORD );
  695. fRead: function( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  696. fWrite: function( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  697. fClose: procedure( Strm: PStream );
  698. fCustom: Pointer;
  699. fWait: procedure( Strm: PStream );
  700. end;
  701. TStreamData = Packed Record
  702. fHandle: THandle;
  703. fCapacity, fSize, fPosition: DWORD;
  704. fThread: PThread;
  705. end;
  706. { ---------------------------------------------------------------------
  707. TStream - streaming objects incapsulation
  708. ---------------------------------------------------------------------- }
  709. //[TStream DEFINITION]
  710. TStream = object(TObj)
  711. {* Simple stream object. Can be opened for file, or as memory stream (see
  712. NewReadFileStream, NewWriteFileStream, NewMemoryStream, etc.). And, another
  713. type of streaming object can be derived (without inheriting new object
  714. type, just by writing another New...Stream method, which calls
  715. _NewStream and pass methods record to it). }
  716. protected
  717. fPMethods: PStreamMethods;
  718. fMethods: TStreamMethods;
  719. fMemory: Pointer;
  720. fData: TStreamData;
  721. fParam1, fParam2: DWORD; // parameters to use in thread
  722. function GetCapacity: DWORD;
  723. procedure SetCapacity(const Value: DWORD);
  724. function DoAsyncRead( Sender: PThread ): Integer;
  725. function DoAsyncWrite( Sender: PThread ): Integer;
  726. function DoAsyncSeek( Sender: PThread ): Integer;
  727. protected
  728. function GetFileStreamHandle: THandle;
  729. procedure SetPosition(Value: DWord);
  730. function GetPosition: DWord;
  731. function GetSize: DWord;
  732. procedure SetSize(NewSize: DWord);
  733. {++}(*public*){--}
  734. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  735. public
  736. function Read(var Buffer; Count: DWord): DWord;
  737. {* Reads Count bytes from a stream. Returns number of bytes read. }
  738. function Seek(MoveTo: Integer; MoveMethod: TMoveMethod): DWord;
  739. {* Allows to change current position or to obtain it. Property
  740. Position uses this method both for get and set position. }
  741. function Write(var Buffer; Count: DWord): DWord;
  742. {* Writes Count bytes from Buffer, starting from current position
  743. in a stream. Returns how much bytes are written. }
  744. function WriteStr( S: String ): DWORD;
  745. {* Writes string to the stream, not including ending #0. Exactly
  746. Length( S ) characters are written. }
  747. function WriteStrZ( S: String ): DWORD;
  748. {* Writes string, adding #0. Number of bytes written is returned. }
  749. function ReadStrZ: String;
  750. {* Reads string, finished by #0. After reading, current position in
  751. the stream is set to the byte, follows #0. }
  752. function ReadStr: String;
  753. {* Reads string, finished by #13, #10 or #13#10 symbols. Terminating symbols
  754. #13 and/or #10 are not added to the end of returned string though
  755. stream positioned follow it. }
  756. function WriteStrEx(S: String): DWord;
  757. {* Writes string S to stream, also saving its size for future use by
  758. ReadStrEx* functions. Returns number of actually written characters. }
  759. function ReadStrExVar(var S: String): DWord;
  760. {* Reads string from stream and assigns it to S.
  761. Returns number of actually read characters.
  762. Note:
  763. String must be written by using WriteStrEx function.
  764. Return value is count of characters READ, not the length of string. }
  765. function ReadStrEx: String;
  766. {* Reads string from stream and returns it. }
  767. function WriteStrPas( S: String ): DWORD;
  768. {* Writes a string in Pascal short string format - 1 byte length, then string
  769. itself without trailing #0 char. S parameter length should not exceed 255
  770. chars, rest chars are truncated while writing. Total amount of bytes
  771. written is returned. }
  772. function ReadStrPas: String;
  773. {* Reads 1 byte from a stream, then treat it as a length of following string
  774. which is read and returned. A purpose of this function is reading strings
  775. written using WriteStrPas. }
  776. property Size: DWord read GetSize write SetSize;
  777. {* Returns stream size. For some custom streams, can be slow
  778. operation, or even always return undefined value (-1 recommended). }
  779. property Position: DWord read GetPosition write SetPosition;
  780. {* Current position. }
  781. property Memory: Pointer read fMemory;
  782. {* Only for memory stream. }
  783. property Handle: THandle read GetFileStreamHandle;
  784. {* Only for file stream. It is possible to check that Handle <>
  785. INVALID_HANDLE_VALUE to ensure that file stream is created OK. }
  786. //---------- for asynchronous operations (using thread - not tested):
  787. procedure SeekAsync(MoveTo: Integer; MoveMethod: TMoveMethod);
  788. {* Changes current position asynchronously. To wait for finishing the
  789. operation, use method Wait. }
  790. procedure ReadAsync(var Buffer; Count: DWord);
  791. {* Reads Count bytes from a stream asynchronously. To wait finishing the
  792. operation, use method Wait. }
  793. procedure WriteAsync(var Buffer; Count: DWord);
  794. {* Writes Count bytes from Buffer, starting from current position
  795. in a stream - asynchronously. To wait finishing the operation,
  796. use method Wait. }
  797. function Busy: Boolean;
  798. {* Returns TRUE until finishing the last asynchronous operation
  799. started by calling SeekAsync, ReadAsync, WriteAsync methods. }
  800. procedure Wait;
  801. {* Waits for finishing the last asynchronous operation. }
  802. property Methods: PStreamMethods read fPMethods;
  803. {* Pointer to TStreamMethods record. Useful to implement custom-defined
  804. streams, which can access its fCustom field, or even to change
  805. methods when necessary. }
  806. property Data: TStreamData read fData;
  807. {* Pointer to TStreamData record. Useful to implement custom-defined
  808. streams, which can access Data fields directly when implemented. }
  809. property Capacity: DWORD read GetCapacity write SetCapacity;
  810. {* Amound of memory allocated for data (MemoryStream). }
  811. end;
  812. //[END OF TStream DEFINITION]
  813. //[_NewStream DECLARATION]
  814. function _NewStream( const StreamMethods: TStreamMethods ): PStream;
  815. {* Use this method only to define your own stream type. See also declared
  816. below (in KOL.pas) methods used to implement standard KOL streams. You can use it in
  817. your code to create streams, which are partially based on standard
  818. methods. }
  819. // Methods below are declared here to simplify creating your
  820. // own streams with some methods standard and some non-standard
  821. // together:
  822. function SeekFileStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  823. function GetSizeFileStream( Strm: PStream ): DWORD;
  824. function ReadFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  825. function WriteFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  826. function WriteFileStreamEOF( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  827. procedure CloseFileStream( Strm: PStream );
  828. function SeekMemStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  829. function GetSizeMemStream( Strm: PStream ): DWORD;
  830. procedure SetSizeMemStream( Strm: PStream; NewSize: DWORD );
  831. function ReadMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  832. function WriteMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  833. procedure CloseMemStream( Strm: PStream );
  834. procedure SetSizeFileStream( Strm: PStream; NewSize: DWORD );
  835. function DummyReadWrite( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  836. procedure DummySetSize( Strm: PStream; Value: DWORD );
  837. procedure DummyStreamProc(Strm: PStream);
  838. //[NewFileStream DECLARATION]
  839. function NewFileStream( const FileName: String; Options: DWORD ): PStream;
  840. {* Creates file stream for read and write. Exact set of open attributes
  841. should be passed through Options parameter (see FileCreate where those
  842. flags are listed). }
  843. function NewReadFileStream( const FileName: String ): PStream;
  844. {* Creates file stream for read only. }
  845. function NewWriteFileStream( const FileName: String ): PStream;
  846. {* Creates file stream for write only. Truncating of file (if needed)
  847. is provided automatically. }
  848. function NewReadWriteFileStream( const FileName: String ): PStream;
  849. {* Creates stream for read and write file. To truncate file, if it is
  850. necessary, change Size property. }
  851. //[NewMemoryStream DECLARATION]
  852. function NewMemoryStream: PStream;
  853. {* Creates memory stream (read and write). }
  854. function NewExMemoryStream( ExistingMem: Pointer; Size: DWORD ): PStream;
  855. {* Creates memory stream on base of existing memory. It is not possible
  856. to write out of top bound given by Size (i.e. memory can not be resized,
  857. or reallocated. When stream object is destroyed this memory is not freed. }
  858. //[Stream2Stream DECLARATION]
  859. function Stream2Stream( Dst, Src: PStream; Count: DWORD ): DWORD;
  860. {* Copies Count (or less, if the rest of Src is not sufficiently long)
  861. bytes from Src to Dst, but with optimizing in cases, when Src or/and
  862. Dst are memory streams (intermediate buffer is not allocated). }
  863. function Stream2StreamEx( Dst, Src: PStream; Count: DWORD ): DWORD;
  864. {* Copies Count bytes from Src to Dst, but without any optimization.
  865. Unlike Stream2Stream function, it can be applied to very large streams.
  866. See also Stream2StreamExBufSz. }
  867. function Stream2StreamExBufSz( Dst, Src: PStream; Count, BufSz: DWORD ): DWORD;
  868. {* Copies Count bytes from Src to Dst using buffer of given size, but without
  869. other optimizations.
  870. Unlike Stream2Stream function, it can be applied to very large streams }
  871. //[Resource2Stream DECLARATION]
  872. function Resource2Stream( DestStrm : PStream; Inst : HInst;
  873. ResName : PChar; ResType : PChar ): Integer;
  874. {* Loads given resource to DestStrm. Useful for non-standard
  875. resources to load it into memory (use memory stream for such
  876. purpose). Use one of following resource types to pass as ResType:
  877. |<pre>
  878. RT_ACCELERATOR Accelerator table
  879. RT_ANICURSOR Animated cursor
  880. RT_ANIICON Animated icon
  881. RT_BITMAP Bitmap resource
  882. RT_CURSOR Hardware-dependent cursor resource
  883. RT_DIALOG Dialog box
  884. RT_FONT Font resource
  885. RT_FONTDIR Font directory resource
  886. RT_GROUP_CURSOR Hardware-independent cursor resource
  887. RT_GROUP_ICON Hardware-independent icon resource
  888. RT_ICON Hardware-dependent icon resource
  889. RT_MENU Menu resource
  890. RT_MESSAGETABLE Message-table entry
  891. RT_RCDATA Application-defined resource (raw data)
  892. RT_STRING String-table entry
  893. RT_VERSION Version resource
  894. |</pre>
  895. |<br>For example:
  896. !var MemStrm: PStream;
  897. ! JpgObj: PJpeg;
  898. !......
  899. ! MemStrm := NewMemoryStream;
  900. ! JpgObj := NewJpeg;
  901. !......
  902. ! Resource2Stream( MemStrm, hInstance, 'MYJPEG', RT_RCDATA );
  903. ! MemStrm.Position := 0;
  904. ! JpgObj.LoadFromStream( MemStrm );
  905. ! MemStrm.Free;
  906. !......
  907. }
  908. { -- string list objects -- }
  909. //[TStrList]
  910. type
  911. {++}(*TStrList = class;*){--}
  912. PStrList = {-}^{+}TStrList;
  913. { ---------------------------------------------------------------------
  914. TStrList - string list
  915. ---------------------------------------------------------------------- }
  916. //[TStrList DEFINITION]
  917. TStrList = object(TObj)
  918. {* Easy string list implementation (non-visual, just to store
  919. string data). It is well improved and has very high performance
  920. allowing to work fast with huge text files (more then megabyte
  921. of text data).
  922. |
  923. Please note that #0 charaster if stored in string lines, will cut it
  924. preventing reading the rest of a line. Be careful, if your data
  925. contain such characters. }
  926. protected
  927. procedure Init; virtual;
  928. protected
  929. fList: PList;
  930. fCount: Integer;
  931. fCaseSensitiveSort: Boolean;
  932. fTextBuf: PChar;
  933. fTextSiz: DWORD;
  934. function GetPChars(Idx: Integer): PChar;
  935. //procedure AddTextBuf( Src: PChar; Len: DWORD );
  936. protected
  937. function Get(Idx: integer): string;
  938. function GetTextStr: string;
  939. procedure Put(Idx: integer; const Value: string);
  940. procedure SetTextStr(const Value: string);
  941. {++}(*public*){--}
  942. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  943. protected
  944. // by Dod:
  945. procedure SetValue(const AName, Value: string);
  946. function GetValue(const AName: string): string;
  947. public
  948. // by Dod:
  949. function IndexOfName(AName: string): Integer;
  950. {* by Dod. Returns index of line starting like Name=... }
  951. property Values[const AName: string]: string read GetValue write SetValue;
  952. {* by Dod. Returns right side of a line starting like Name=... }
  953. public
  954. function Add(const S: string): integer;
  955. {* Adds a string to list. }
  956. procedure AddStrings(Strings: PStrList);
  957. {* Merges string list with given one. Very fast - more preferrable to
  958. use than any loop with calling Add method. }
  959. procedure Assign(Strings: PStrList);
  960. {* Fills string list with strings from other one. The same as AddStrings,
  961. but Clear is called first. }
  962. procedure Clear;
  963. {* Makes string list empty. }
  964. procedure Delete(Idx: integer);
  965. {* Deletes string with given index (it *must* exist). }
  966. function IndexOf(const S: string): integer;
  967. {* Returns index of first string, equal to given one. }
  968. function IndexOf_NoCase(const S: string): integer;
  969. {* Returns index of first string, equal to given one (while comparing it
  970. without case sensitivity). }
  971. function IndexOfStrL_NoCase( Str: PChar; L: Integer ): integer;
  972. {* Returns index of first string, equal to given one (while comparing it
  973. without case sensitivity). }
  974. function Find(const S: String; var Index: Integer): Boolean;
  975. {* Returns Index of the first string, equal or greater to given pattern, but
  976. works only for sorted TStrList object. Returns TRUE if exact string found,
  977. otherwise nearest (greater then a pattern) string index is returned,
  978. and the result is FALSE. }
  979. procedure Insert(Idx: integer; const S: string);
  980. {* Inserts string before one with given index. }
  981. function LoadFromFile(const FileName: string): Boolean;
  982. {* Loads string list from a file. (If file does not exist, nothing
  983. happens). Very fast even for huge text files. }
  984. procedure LoadFromStream(Stream: PStream; Append2List: boolean);
  985. {* Loads string list from a stream (from current position to the end of
  986. a stream). Very fast even for huge text. }
  987. procedure MergeFromFile(const FileName: string);
  988. {* Merges string list with strings in a file. Fast. }
  989. procedure Move(CurIndex, NewIndex: integer);
  990. {* Moves string to another location. }
  991. procedure SetText(const S: string; Append2List: boolean);
  992. {* Allows to set strings of string list from given string (in which
  993. strings are separated by $0D,$0A or $0D characters). Text must not
  994. contain #0 characters. Works very fast. This method is used in
  995. all others, working with text arrays (LoadFromFile, MergeFromFile,
  996. Assign, AddStrings). }
  997. procedure SetUnixText( const S: String; Append2List: Boolean );
  998. {* Allows to assign UNIX-style text (with #10 as string separator). }
  999. function SaveToFile(const FileName: string): Boolean;
  1000. {* Stores string list to a file. }
  1001. procedure SaveToStream(Stream: PStream);
  1002. {* Saves string list to a stream (from current position). }
  1003. function AppendToFile(const FileName: string): Boolean;
  1004. {* Appends strings of string list to the end of a file. }
  1005. property Count: integer read fCount;
  1006. {* Number of strings in a string list. }
  1007. property Items[Idx: integer]: string read Get write Put; default;
  1008. {* Strings array items. If item does not exist, empty string is returned.
  1009. But for assign to property, string with given index *must* exist. }
  1010. property ItemPtrs[ Idx: Integer ]: PChar read GetPChars;
  1011. {* Fast access to item strings as PChars. }
  1012. function Last: String;
  1013. {* Last item (or '', if string list is empty). }
  1014. property Text: string read GetTextStr write SetTextStr;
  1015. {* Content of string list as a single string (where strings are separated
  1016. by characters $0D,$0A). }
  1017. procedure Swap( Idx1, Idx2 : Integer );
  1018. {* Swaps to strings with given indeces. }
  1019. procedure Sort( CaseSensitive: Boolean );
  1020. {* Call it to sort string list. }
  1021. procedure AnsiSort( CaseSensitive: Boolean );
  1022. {* Call it to sort ANSI string list. }
  1023. // by Alexander Pravdin:
  1024. protected
  1025. fNameDelim: Char;
  1026. function GetLineName( Idx: Integer ): string;
  1027. procedure SetLineName( Idx: Integer; const NV: string );
  1028. function GetLineValue(Idx: Integer): string;
  1029. procedure SetLineValue(Idx: Integer; const Value: string);
  1030. public
  1031. property LineName[ Idx: Integer ]: string read GetLineName write SetLineName;
  1032. property LineValue[ Idx: Integer ]: string read GetLineValue write SetLineValue;
  1033. property NameDelimiter: Char read fNameDelim write fNameDelim;
  1034. function Join( const sep: String ): String;
  1035. {* by Sergey Shishmintzev. }
  1036. end;
  1037. //[END OF TStrList DEFINITION]
  1038. //[DefaultNameDelimiter]
  1039. var DefaultNameDelimiter: Char = '=';
  1040. ThsSeparator: Char = ',';
  1041. //[NewStrList DECLARATION]
  1042. function NewStrList: PStrList;
  1043. {* Creates string list object. }
  1044. function GetFileList(const dir: string): PStrList;
  1045. {* By Alexander Shakhaylo. Returns list of file names of the given directory. }
  1046. {$IFNDEF _FPC}
  1047. function WStrLen( W: PWideChar ): Integer;
  1048. {* Returns Length of null-terminated Unicode string. }
  1049. {$ENDIF _FPC}
  1050. //[TStrListEx]
  1051. type
  1052. {++}(*TStrListEx = class;*){--}
  1053. PStrListEx = {-}^{+}TStrListEx;
  1054. //[TStrListEx DEFINITION]
  1055. TStrListEx = object( TStrList )
  1056. {* Extended string list object. Has additional capability to associate
  1057. numbers or objects with string list items. }
  1058. protected
  1059. FObjects: PList;
  1060. function GetObjects(Idx: Integer): DWORD;
  1061. procedure SetObjects(Idx: Integer; const Value: DWORD);
  1062. procedure Init; {-}virtual;{+}{++}(*override;*){--}
  1063. procedure ProvideObjCapacity( NewCap: Integer );
  1064. public
  1065. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  1066. {* }
  1067. property Objects[ Idx: Integer ]: DWORD read GetObjects write SetObjects;
  1068. {* Objects are just 32-bit values. You can treat and use it as pointers to
  1069. any other data in the memory. But it is your task to free allocated
  1070. memory in such case therefore. }
  1071. procedure AddStrings(Strings: PStrListEx);
  1072. {* Merges string list with given one. Very fast - more preferrable to
  1073. use than any loop with calling Add method. }
  1074. procedure Assign(Strings: PStrListEx);
  1075. {* Fills string list with strings from other one. The same as AddStrings,
  1076. but Clear is called first. }
  1077. procedure Clear;
  1078. {* Makes string list empty. }
  1079. procedure Delete(Idx: integer);
  1080. {* Deletes string with given index (it *must* exist). }
  1081. procedure Move(CurIndex, NewIndex: integer);
  1082. {* Moves string to another location. }
  1083. procedure Swap( Idx1, Idx2 : Integer );
  1084. {* Swaps to strings with given indeces. }
  1085. procedure Sort( CaseSensitive: Boolean );
  1086. {* Call it to sort string list. }
  1087. procedure AnsiSort( CaseSensitive: Boolean );
  1088. {* Call it to sort ANSI string list. }
  1089. function LastObj: DWORD;
  1090. {* Object assotiated with the last string. }
  1091. function AddObject( const S: String; Obj: DWORD ): Integer;
  1092. {* Adds a string and associates given number with it. Index of the item added
  1093. is returned. }
  1094. procedure InsertObject( Before: Integer; const S: String; Obj: DWORD );
  1095. {* Inserts a string together with object associated. }
  1096. function IndexOfObj( Obj: Pointer ): Integer;
  1097. {* Returns an index of a string associated with the object passed as a
  1098. parameter. If there are no such strings, -1 is returned. }
  1099. end;
  1100. //[END OF TStrListEx DEFINITION]
  1101. //[NewStrListEx DECLARATION]
  1102. function NewStrListEx: PStrListEx;
  1103. {* Creates extended string list object. }
  1104. {+}
  1105. ////////////////////////////////////////////////////////////////////////////////
  1106. // GRAPHIC OBJECTS //
  1107. ////////////////////////////////////////////////////////////////////////////////
  1108. //[GRAPHIC OBJECTS]
  1109. {
  1110. It is very important, that the most of code, implementing graphic objets
  1111. from this section, is included into executable ONLY if really accessed in your
  1112. project directly (e.g., if Font or Brush properies of a control are accessed
  1113. or changed).
  1114. }
  1115. type
  1116. TColor = Integer;
  1117. const
  1118. //[COLOR CONSTANTS]
  1119. clScrollBar = TColor(COLOR_SCROLLBAR or $80000000);
  1120. clBackground = TColor(COLOR_BACKGROUND or $80000000);
  1121. clActiveCaption = TColor(COLOR_ACTIVECAPTION or $80000000);
  1122. clInactiveCaption = TColor(COLOR_INACTIVECAPTION or $80000000);
  1123. clMenu = TColor(COLOR_MENU or $80000000);
  1124. clWindow = TColor(COLOR_WINDOW or $80000000);
  1125. clWindowFrame = TColor(COLOR_WINDOWFRAME or $80000000);
  1126. clMenuText = TColor(COLOR_MENUTEXT or $80000000);
  1127. clWindowText = TColor(COLOR_WINDOWTEXT or $80000000);
  1128. clCaptionText = TColor(COLOR_CAPTIONTEXT or $80000000);
  1129. clActiveBorder = TColor(COLOR_ACTIVEBORDER or $80000000);
  1130. clInactiveBorder = TColor(COLOR_INACTIVEBORDER or $80000000);
  1131. clAppWorkSpace = TColor(COLOR_APPWORKSPACE or $80000000);
  1132. clHighlight = TColor(COLOR_HIGHLIGHT or $80000000);
  1133. clHighlightText = TColor(COLOR_HIGHLIGHTTEXT or $80000000);
  1134. clBtnFace = TColor(COLOR_BTNFACE or $80000000);
  1135. clBtnShadow = TColor(COLOR_BTNSHADOW or $80000000);
  1136. clGrayText = TColor(COLOR_GRAYTEXT or $80000000);
  1137. clBtnText = TColor(COLOR_BTNTEXT or $80000000);
  1138. clInactiveCaptionText = TColor(COLOR_INACTIVECAPTIONTEXT or $80000000);
  1139. clBtnHighlight = TColor(COLOR_BTNHIGHLIGHT or $80000000);
  1140. cl3DDkShadow = TColor(COLOR_3DDKSHADOW or $80000000);
  1141. cl3DLight = TColor(COLOR_3DLIGHT or $80000000);
  1142. clInfoText = TColor(COLOR_INFOTEXT or $80000000);
  1143. clInfoBk = TColor(COLOR_INFOBK or $80000000);
  1144. clBlack = TColor($000000);
  1145. clMaroon = TColor($000080);
  1146. clGreen = TColor($008000);
  1147. clOlive = TColor($008080);
  1148. clNavy = TColor($800000);
  1149. clPurple = TColor($800080);
  1150. clTeal = TColor($808000);
  1151. clGray = TColor($808080);
  1152. clSilver = TColor($C0C0C0);
  1153. clRed = TColor($0000FF);
  1154. clLime = TColor($00FF00);
  1155. clYellow = TColor($00FFFF);
  1156. clBlue = TColor($FF0000);
  1157. clFuchsia = TColor($FF00FF);
  1158. clAqua = TColor($FFFF00);
  1159. clLtGray = TColor($C0C0C0);
  1160. clDkGray = TColor($808080);
  1161. clWhite = TColor($FFFFFF);
  1162. clNone = TColor($1FFFFFFF);
  1163. clDefault = TColor($20000000);
  1164. clMoneyGreen = TColor($C0DCC0);
  1165. clSkyBlue = TColor($F0CAA6);
  1166. clCream = TColor($F0FBFF);
  1167. clMedGray = TColor($A4A0A0);
  1168. //[END OF COLOR CONSTANTS]
  1169. const
  1170. //[TGraphicTool FIELD OFFSET CONSTANTS]
  1171. go_Color = 0;
  1172. go_FontHeight = 4;
  1173. go_FontWidth = 8;
  1174. go_FontEscapement = 12;
  1175. go_FontOrientation = 16;
  1176. go_FontWeight = 20;
  1177. go_FontItalic = 24;
  1178. go_FontUnderline = 25;
  1179. go_FontStrikeOut = 26;
  1180. go_FontCharSet = 27;
  1181. go_FontOutPrecision = 28;
  1182. go_FontClipPrecision = 29;
  1183. go_FontQuality = 30;
  1184. go_FontPitch = 31;
  1185. go_FontName = 32;
  1186. go_BrushBitmap = 4;
  1187. go_BrushStyle = 8;
  1188. go_BrushLineColor = 9;
  1189. go_PenBrushBitmap = 4;
  1190. go_PenBrushStyle = 8;
  1191. go_PenStyle = 9;
  1192. go_PenWidth = 10;
  1193. go_PenMode = 14;
  1194. go_PenGeometric = 15;
  1195. go_PenEndCap = 16;
  1196. go_PenJoin = 17;
  1197. //[END OF TGraphicTool FIELD OFFSET CONSTANTS]
  1198. //[TGraphicTool]
  1199. type
  1200. TGraphicToolType = ( gttBrush, gttFont, gttPen );
  1201. {* Graphic object types, mainly for internal use. }
  1202. {++}(*TGraphicTool = class;*){--}
  1203. PGraphicTool = {-}^{+}TGraphicTool;
  1204. {* }
  1205. TOnGraphicChange = procedure ( Sender: PGraphicTool ) of object;
  1206. {* An event mainly for internal use. }
  1207. TBrushStyle = (bsSolid, bsClear, bsHorizontal, bsVertical,
  1208. bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross);
  1209. {* Available brush styles. }
  1210. TFontStyles = (fsBold, fsItalic, fsUnderline, fsStrikeOut);
  1211. {* Available font styles. }
  1212. TFontStyle = set of TFontStyles;
  1213. {* Font style is representing as a set of XFontStyles. }
  1214. TFontPitch = (fpDefault, fpFixed, fpVariable);
  1215. {* Availabe font pitch values. }
  1216. TFontName = type string;
  1217. {* Font name is represented as a string. }
  1218. TFontCharset = 0..255;
  1219. {* Font charset is represented by number from 0 to 255. }
  1220. TFontQuality = (fqDefault, fqDraft, fqProof, fqNonAntialiased, fqAntialiased);
  1221. {* Font quality. }
  1222. TPenStyle = (psSolid, psDash, psDot, psDashDot, psDashDotDot, psClear,
  1223. psInsideFrame);
  1224. {* Available pen styles. For more info see Delphi or Win32 help files. }
  1225. TPenMode = (pmBlack, pmNotMerge, pmMaskNotPen, pmNotCopy, pmMaskPenNot,
  1226. pmNot, pmXor, pmNotMask, pmMask, pmNotXor, pmNop, pmMergePenNot,
  1227. pmCopy, pmMergeNotPen, pmMerge, pmWhite);
  1228. {* Available pen modes. For more info see Delphi or Win32 help files. }
  1229. TPenEndCap = (pecRound, pecSquare, pecFlat);
  1230. {* Avalable (for geometric pen) end cap styles. }
  1231. TPenJoin = (pjRound, pjBevel, pjMiter);
  1232. {* Available (for geometric pen) join styles. }
  1233. //[TGdiFont]
  1234. TGDIFont = packed record
  1235. Height: Integer;
  1236. Width: Integer;
  1237. Escapement: Integer;
  1238. Orientation: Integer;
  1239. Weight: Integer;
  1240. Italic: Boolean;
  1241. Underline: Boolean;
  1242. StrikeOut: Boolean;
  1243. CharSet: TFontCharset;
  1244. OutPrecision: Byte;
  1245. ClipPrecision: Byte;
  1246. Quality: TFontQuality;
  1247. Pitch: TFontPitch;
  1248. Name: array[0..LF_FACESIZE - 1] of Char;
  1249. end;
  1250. //[TGDIBrush]
  1251. TGDIBrush = packed record
  1252. Bitmap: HBitmap;
  1253. Style: TBrushStyle;
  1254. LineColor: TColor;
  1255. end;
  1256. //[TGDIPen]
  1257. TGDIPen = packed record
  1258. BrushBitmap: HBitmap;
  1259. BrushStyle: TBrushStyle;
  1260. Style: TPenStyle;
  1261. Width: Integer;
  1262. Mode: TPenMode;
  1263. Geometric: Boolean;
  1264. EndCap: TPenEndCap;
  1265. Join: TPenJoin;
  1266. end;
  1267. //[TGDIToolData]
  1268. TGDIToolData = packed record
  1269. Color: TColor;
  1270. case Integer of
  1271. 1: (Font: TGDIFont);
  1272. 2: (Pen: TGDIPen);
  1273. 3: (Brush: TGDIBrush);
  1274. end;
  1275. //[TNewGraphicTool]
  1276. TNewGraphicTool = function: PGraphicTool;
  1277. { ---------------------------------------------------------------------
  1278. TGraphicTool - object to implement GDI-tools (brush, pen, font)
  1279. ---------------------------------------------------------------------- }
  1280. //[TGraphicTool DEFINITION]
  1281. TGraphicTool = object( TObj )
  1282. {* Incapsulates all GDI objects: Pen, Brush and Font. }
  1283. protected
  1284. fType: TGraphicToolType;
  1285. fHandle: THandle;
  1286. fParentGDITool: PGraphicTool;
  1287. fOnChange: TOnGraphicChange;
  1288. fColorRGB: TColor;
  1289. fData: TGDIToolData;
  1290. fNewProc: TNewGraphicTool;
  1291. fMakeHandleProc: function( Self_: PGraphicTool ): THandle;
  1292. procedure SetInt( const Index: Integer; Value: Integer );
  1293. {$IFDEF F_P}
  1294. function GetInt( const Index: Integer ): Integer;
  1295. {$ENDIF}
  1296. procedure SetColor( Value: TColor );
  1297. procedure SetBrushBitmap(const Value: HBitmap);
  1298. procedure SetBrushStyle(const Value: TBrushStyle);
  1299. procedure SetFontCharset(const Value: TFontCharset);
  1300. procedure SetFontQuality(const Value: TFontQuality);
  1301. function GetFontName: String;
  1302. procedure SetFontName(const Value: String);
  1303. procedure SetFontOrientation(Value: Integer);
  1304. procedure SetFontPitch(const Value: TFontPitch);
  1305. function GetFontStyle: TFontStyle;
  1306. procedure SetFontStyle(const Value: TFontStyle);
  1307. procedure SetPenMode(const Value: TPenMode);
  1308. procedure SetPenStyle(const Value: TPenStyle);
  1309. procedure SetGeometricPen(const Value: Boolean);
  1310. procedure SetPenEndCap(const Value: TPenEndCap);
  1311. procedure SetPenJoin(const Value: TPenJoin);
  1312. procedure SetFontWeight(const Value: Integer);
  1313. procedure SetLogFontStruct(const Value: TLogFont);
  1314. function GetLogFontStruct: TLogFont;
  1315. protected
  1316. procedure Changed;
  1317. {* }
  1318. function GetHandle: THandle;
  1319. {* }
  1320. public
  1321. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  1322. {* }
  1323. property Handle: THandle read GetHandle;
  1324. {* Every time, when accessed, real GDI object is created (if it is
  1325. not yet created). So, to prevent creating of the handle, use
  1326. HandleAllocated instead of comparing Handle with value 0. }
  1327. function HandleAllocated: Boolean;
  1328. {* Returns True, if handle is allocated (i.e., if real GDI
  1329. objet is created. }
  1330. property OnChange: TOnGraphicChange read fOnChange write fOnChange;
  1331. {* Called, when object is changed. }
  1332. function ReleaseHandle: Integer;
  1333. {* Returns Handle value (if allocated), releasing it from the
  1334. object (so, it is no more knows about this handle and its
  1335. HandleAllocated function returns False. }
  1336. property Color: TColor {index go_Color} read fData.Color write SetColor;
  1337. {* Color is the most common property for all Pen, Brush and
  1338. Font objects, so it is placed in its common for all of them. }
  1339. function Assign( Value: PGraphicTool ): PGraphicTool;
  1340. {* Assigns properties of the same (only) type graphic object,
  1341. excluding Handle. If assigning is really leading to change
  1342. object, procedure Changed is called. }
  1343. procedure AssignHandle( NewHandle: Integer );
  1344. {* Assigns value to Handle property. }
  1345. property BrushBitmap: HBitmap read fData.Brush.Bitmap write SetBrushBitmap;
  1346. {* Brush bitmap. For more info about using brush bitmap,
  1347. see Delphi or Win32 help files. }
  1348. property BrushStyle: TBrushStyle read fData.Brush.Style write SetBrushStyle;
  1349. {* Brush style. }
  1350. property BrushLineColor: TColor index go_BrushLineColor
  1351. {$IFDEF F_P}
  1352. read GetInt
  1353. {$ELSE DELPHI}
  1354. read fData.Brush.LineColor
  1355. {$ENDIF F_P/DELPHI}
  1356. write SetInt;
  1357. {* Brush line color, used to represent lines in hatched brush. Default value is clBlack. }
  1358. property FontHeight: Integer index go_FontHeight
  1359. {$IFDEF F_P}
  1360. read GetInt
  1361. {$ELSE DELPHI}
  1362. read fData.Font.Height
  1363. {$ENDIF F_P/DELPHI}
  1364. write SetInt;
  1365. {* Font height. Value 0 (default) seys to use system default value,
  1366. negative values are to represent font height in "points", positive
  1367. - in pixels. In XCL usually positive values (if not 0) are used to
  1368. make appearance independent from different local settings. }
  1369. property FontWidth: Integer index go_FontWidth
  1370. {$IFDEF F_P}
  1371. read GetInt
  1372. {$ELSE DELPHI}
  1373. read fData.Font.Width
  1374. {$ENDIF F_P/DELPHI}
  1375. write SetInt;
  1376. {* Font width in logical units. If FontWidth = 0, then as it is said
  1377. in Win32.hlp, "the aspect ratio of the device is matched against the
  1378. digitization aspect ratio of the available fonts to find the closest match,
  1379. determined by the absolute value of the difference." }
  1380. property FontPitch: TFontPitch read fData.Font.Pitch write SetFontPitch;
  1381. {* Font pitch. Change it very rare. }
  1382. property FontStyle: TFontStyle read GetFontStyle write SetFontStyle;
  1383. {* Very useful property to control text appearance. }
  1384. property FontCharset: TFontCharset read fData.Font.Charset write SetFontCharset;
  1385. {* Do not change it if You do not know what You do. }
  1386. property FontQuality: TFontQuality read fData.Font.Quality write SetFontQuality;
  1387. {* Font quality. }
  1388. property FontOrientation: Integer read fData.Font.Orientation write SetFontOrientation;
  1389. {* It is possible to rotate text in XCL just by changing this
  1390. property of a font (tenths of degree, i.e. value 900 represents
  1391. 90 degree - text written from bottom to top). }
  1392. property FontWeight: Integer read fData.Font.Weight write SetFontWeight;
  1393. {* Additional font weight for bold fonts (must be 0..1000). When set to
  1394. value <> 0, fsBold is added to FontStyle. And otherwise, when set to 0,
  1395. fsBold is removed from FontStyle. Value 700 corresponds to Bold,
  1396. 400 to Normal. }
  1397. property FontName: String read GetFontName write SetFontName;
  1398. {* Font face name. }
  1399. function IsFontTrueType: Boolean;
  1400. {* Returns True, if font is True Type. Requires of creating of a Handle,
  1401. if it is not yet created. }
  1402. property PenWidth: Integer index go_PenWidth
  1403. {$IFDEF F_P}
  1404. read GetInt
  1405. {$ELSE DELPHI}
  1406. read fData.Pen.Width
  1407. {$ENDIF F_P/DELPHI}
  1408. write SetInt;
  1409. {* Value 0 means default pen width. }
  1410. property PenStyle: TPenStyle read fData.Pen.Style write SetPenStyle;
  1411. {* Pen style. }
  1412. property PenMode: TPenMode read fData.Pen.Mode write SetPenMode;
  1413. {* Pen mode. }
  1414. property GeometricPen: Boolean read fData.Pen.Geometric write SetGeometricPen;
  1415. {* True if Pen is geometric. Note, that under Win95/98 only pen styles
  1416. psSolid, psNull, psInsideFrame are supported by OS. }
  1417. property PenBrushStyle: TBrushStyle read fData.Pen.BrushStyle write SetBrushStyle;
  1418. {* Brush style for hatched geometric pen. }
  1419. property PenBrushBitmap: HBitmap read fData.Pen.BrushBitmap write SetBrushBitmap;
  1420. {* Brush bitmap for geometric pen (if assigned Pen is functioning as
  1421. its style = BS_PATTERN, regadless of PenBrushStyle value). }
  1422. property PenEndCap: TPenEndCap read fData.Pen.EndCap write SetPenEndCap;
  1423. {* Pen end cap mode - for GeometricPen only. }
  1424. property PenJoin: TPenJoin read fData.Pen.Join write SetPenJoin;
  1425. {* Pen join mode - for GeometricPen only. }
  1426. property LogFontStruct: TLogFont read GetLogFontStruct write SetLogFontStruct;
  1427. {* by Alex Pravdin: a property to change all font structure items at once. }
  1428. end;
  1429. //[END OF TGraphicTool DEFINITION]
  1430. //[Color2XXX FUNCTIONS]
  1431. function Color2RGB( Color: TColor ): TColor;
  1432. {* Function to get RGB color from system color. Parameter can be also RGB
  1433. color, in that case result is just equal to a parameter. }
  1434. function ColorsMix( Color1, Color2: TColor ): TColor;
  1435. {* Returns color, which RGB components are build as an (approximate)
  1436. arithmetic mean of correspondent RGB components of both source
  1437. colors (these both are first converted from system to RGB, and
  1438. result is always RGB color). Please note: this function is fast,
  1439. but can be not too exact. }
  1440. function Color2RGBQuad( Color: TColor ): TRGBQuad;
  1441. {* Converts color to RGB, used to represent RGB values in palette entries
  1442. (actually swaps R and B bytes). }
  1443. function Color2Color16( Color: TColor ): WORD;
  1444. {* Converts Color to RGB, packed to word (as it is used in format pf16bit). }
  1445. //[DefFont VARIABLE]
  1446. var // New TFont instances are intialized with the values in this structure:
  1447. DefFont: TGDIFont = (
  1448. Height: 0;
  1449. Width: 0;
  1450. Escapement: 0;
  1451. Orientation: 0;
  1452. Weight: 0;
  1453. Italic: FALSE;
  1454. Underline: FALSE;
  1455. StrikeOut: FALSE;
  1456. CharSet: 1;
  1457. OutPrecision: 0;
  1458. ClipPrecision: 0;
  1459. Quality: fqDefault;
  1460. Pitch: fpDefault;
  1461. Name: 'MS Sans Serif';
  1462. );
  1463. DefFontColor: TColor = clWindowText;
  1464. {* Default font color. }
  1465. //[GlobalGraphics_UseFontOrient]
  1466. GlobalGraphics_UseFontOrient: Boolean;
  1467. {* Global flag. If stays False (default), Orientation property of Font
  1468. objects is ignored. This flag is set to True automatically in
  1469. RotateFonts add-on. }
  1470. { -- Constructors for different GDI tools -- }
  1471. //[New FUNCTIONS FOR TGraphicTool]
  1472. function NewFont: PGraphicTool;
  1473. {* Creates and returns font graphic tool object. }
  1474. function NewBrush: PGraphicTool;
  1475. {* Creates and returns new brush object. }
  1476. function NewPen: PGraphicTool;
  1477. {* Creates and returns new pen object. }
  1478. { -- TCanvas object -- }
  1479. //[TCanvas]
  1480. const
  1481. HandleValid = 1;
  1482. PenValid = 2;
  1483. BrushValid = 4;
  1484. FontValid = 8;
  1485. ChangingCanvas = 16;
  1486. type
  1487. TFillStyle = (fsSurface, fsBorder);
  1488. {* Available filling styles. For more info see Win32 or Delphi help files. }
  1489. TFillMode = (fmAlternate, fmWinding);
  1490. {* Available filling modes. For more info see Win32 or Delphi help files. }
  1491. TCopyMode = Integer;
  1492. {* Available copying modes are following:
  1493. | cmBlackness<br>
  1494. | cmDstInvert<br>
  1495. | cmMergeCopy<br>
  1496. | cmMergePaint<br>
  1497. | cmNotSrcCopy<br>
  1498. | cmNotSrcErase<br>
  1499. | cmPatCopy<br>
  1500. | cmPatInvert<br>
  1501. | cmPatPaint<br>
  1502. | cmSrcAnd<br>
  1503. | cmSrcCopy<br>
  1504. | cmSrcErase<br>
  1505. | cmSrcInvert<br>
  1506. | cmSrcPaint<br>
  1507. | cmWhiteness<br>&nbsp;&nbsp;&nbsp;
  1508. Also it is possible to use any other available ROP2 modes. For more info,
  1509. see Win32 help files. }
  1510. const
  1511. cmBlackness = BLACKNESS;
  1512. cmDstInvert = DSTINVERT;
  1513. cmMergeCopy = MERGECOPY;
  1514. cmMergePaint = MERGEPAINT;
  1515. cmNotSrcCopy = NOTSRCCOPY;
  1516. cmNotSrcErase = NOTSRCERASE;
  1517. cmPatCopy = PATCOPY;
  1518. cmPatInvert = PATINVERT;
  1519. cmPatPaint = PATPAINT;
  1520. cmSrcAnd = SRCAND;
  1521. cmSrcCopy = SRCCOPY;
  1522. cmSrcErase = SRCERASE;
  1523. cmSrcInvert = SRCINVERT;
  1524. cmSrcPaint = SRCPAINT;
  1525. cmWhiteness = WHITENESS;
  1526. type
  1527. {++}(*TCanvas = class;*){--}
  1528. PCanvas = {-}^{+}TCanvas;
  1529. {* }
  1530. TOnGetHandle = function( Canvas: PCanvas ): HDC of object;
  1531. {* For internal use mainly. }
  1532. TOnTextArea = procedure( Sender: PCanvas; var Size : TSize; var P0 : TPoint );
  1533. {* Event to calculate actual area, occupying by a text. It is used
  1534. to optionally extend calculating of TextArea taking into considaration
  1535. font Orientation property. }
  1536. { ---------------------------------------------------------------------
  1537. TCanvas - high-level drawing helper object
  1538. ----------------------------------------------------------------------- }
  1539. //[TCanvas DEFINITION]
  1540. TCanvas = object( TObj )
  1541. {* Very similar to VCL's TCanvas object. But with some changes, specific
  1542. for KOL: there is no necessary to use canvases in all applications.
  1543. And graphic tools objects are not created with canvas, but only
  1544. if really accessed in program. (Actually, even if paint box used,
  1545. only programmer decides, if to implement painting using Canvas or
  1546. to call low level API drawing functions working directly with DC).
  1547. Therefore TCanvas has some powerful extensions: rotated text support,
  1548. geometric pen support - just by changing correspondent properties
  1549. of certain graphic tool objects (Font.FontOrientation, Pen.GeometricPen).
  1550. See also additional Font properties (Font.FontWeight, Font.FontQuality,
  1551. etc. }
  1552. protected
  1553. fOwnerControl: Pointer; //PControl;
  1554. fHandle : HDC;
  1555. fPenPos : TPoint;
  1556. fBrush, fFont, fPen : PGraphicTool; // order is important for ASM version
  1557. fState : Byte;
  1558. fCopyMode : TCopyMode;
  1559. fOnChange: TOnEvent;
  1560. fOnGetHandle: TOnGetHandle;
  1561. procedure SetHandle( Value : HDC );
  1562. procedure SetPenPos( const Value : TPoint );
  1563. procedure CreatePen;
  1564. procedure CreateBrush;
  1565. procedure CreateFont;
  1566. procedure ObjectChanged( Sender : PGraphicTool );
  1567. procedure Changing;
  1568. function GetBrush: PGraphicTool;
  1569. function GetFont: PGraphicTool;
  1570. function GetPen: PGraphicTool;
  1571. function GetHandle: HDC;
  1572. procedure AssignChangeEvents;
  1573. function GetPixels(X, Y: Integer): TColor;
  1574. procedure SetPixels(X, Y: Integer; const Value: TColor);
  1575. protected
  1576. fIsPaintDC : Boolean;
  1577. {* TRUE, if DC obtained during current WM_PAINT (or WM_ERASEBKGND?)
  1578. processing for a control. This affects a way how Handle is released. }
  1579. {++}(*public*){--}
  1580. destructor Destroy;{-}virtual;{+}{++}(*override;*){--}
  1581. {* }
  1582. {++}(*protected*){--}
  1583. property OnGetHandle: TOnGetHandle read fOnGetHandle write fOnGetHandle;
  1584. {* For internal use only. }
  1585. public
  1586. property Handle : HDC read GetHandle write SetHandle;
  1587. {* GDI device context object handle. Never created by
  1588. Canvas itself (to use Canvas with memory bitmaps,
  1589. always create DC by yourself and assign it to the
  1590. Handle property of Canvas object, or use property
  1591. Canvas of a bitmap). }
  1592. property PenPos : TPoint read FPenPos write SetPenPos;
  1593. {* Position of a pen. }
  1594. property Pen : PGraphicTool read GetPen;
  1595. {* Pen of Canvas object. Do not change its Pen.OnChange event value. }
  1596. property Brush : PGraphicTool read GetBrush;
  1597. {* Brush of Canvas object. Do not change its Brush.OnChange event value. }
  1598. property Font : PGraphicTool read GetFont;
  1599. {* Font of Canvas object. Do not change its Font.OnChange event value. }
  1600. procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  1601. {* Draws arc. For more info, see Delphi TCanvas help. }
  1602. procedure Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  1603. {* Draws chord. For more info, see Delphi TCanvas help. }
  1604. procedure DrawFocusRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  1605. {* Draws rectangle to represent focused visual object.
  1606. For more info, see Delphi TCanvas help. }
  1607. procedure Ellipse(X1, Y1, X2, Y2: Integer);
  1608. {* Draws an ellipse. For more info, see Delphi TCanvas help. }
  1609. procedure FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  1610. {* Fills rectangle. For more info, see Delphi TCanvas help. }
  1611. procedure FillRgn( const Rgn : HRgn );
  1612. {* Fills region. For more info, see Delphi TCanvas help. }
  1613. procedure FloodFill(X, Y: Integer; Color: TColor; FillStyle: TFillStyle);
  1614. {* Fills a figure with givien color, floodfilling its surface.
  1615. For more info, see Delphi TCanvas help. }
  1616. procedure FrameRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  1617. {* Draws a rectangle using Brush settings (color, etc.).
  1618. For more info, see Delphi TCanvas help. }
  1619. procedure MoveTo( X, Y : Integer );
  1620. {* Moves current PenPos to a new position.
  1621. For more info, see Delphi TCanvas help. }
  1622. procedure LineTo( X, Y : Integer );
  1623. {* Draws a line from current PenPos up to new position.
  1624. For more info, see Delphi TCanvas help. }
  1625. procedure Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  1626. {* Draws a pie. For more info, see Delphi TCanvas help. }
  1627. procedure Polygon(const Points: array of TPoint);
  1628. {* Draws a polygon. For more info, see Delphi TCanvas help. }
  1629. procedure Polyline(const Points: array of TPoint);
  1630. {* Draws a bound for polygon. For more info, see Delphi TCanvas help. }
  1631. procedure Rectangle(X1, Y1, X2, Y2: Integer);
  1632. {* Draws a rectangle using current Pen and/or Brush.
  1633. For more info, see Delphi TCanvas help. }
  1634. procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
  1635. {* Draws a rounded rectangle. For more info, see Delphi TCanvas help. }
  1636. procedure TextOut(X, Y: Integer; const Text: String); stdcall;
  1637. {* Draws a text. For more info, see Delphi TCanvas help. }
  1638. procedure ExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect; const Text: String;
  1639. const Spacing: array of Integer );
  1640. {* }
  1641. procedure DrawText(Text:String; var Rect:TRect; Flags:DWord);
  1642. {* }
  1643. procedure TextRect(const Rect: TRect; X, Y: Integer; const Text: string);
  1644. {* Draws a text, clipping output into given rectangle.
  1645. For more info, see Delphi TCanvas help. }
  1646. function TextExtent(const Text: string): TSize;
  1647. {* Calculates size of a Text, using current Font settings.
  1648. Does not need in Handle for Canvas object (if it is not
  1649. yet allocated, temporary device context is created and used. }
  1650. procedure TextArea( const Text : String; var Sz : TSize; var P0 : TPoint );
  1651. {* Calculates size and starting point to output Text,
  1652. taking into considaration all Font attributes, including
  1653. Orientation (only if GlobalGraphics_UseFontOrient flag
  1654. is set to True, i.e. if rotated fonts are used).
  1655. Like for TextExtent, does not need in Handle (and if this
  1656. last is not yet allocated/assigned, temporary device context
  1657. is created and used). }
  1658. function TextWidth(const Text: string): Integer;
  1659. {* Calculates text width (using TextArea). }
  1660. function TextHeight(const Text: string): Integer;
  1661. {* Calculates text height (using TextArea). }
  1662. function ClipRect: TRect;
  1663. {* returns ClipBox. by Dmitry Zharov. }
  1664. {$IFNDEF _FPC}
  1665. {$IFNDEF _D2} //------- WideString not supported in D2
  1666. procedure WTextOut(X, Y: Integer; const WText: WideString); stdcall;
  1667. {* Draws a Unicode text. }
  1668. procedure WExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect;
  1669. const WText: WideString; const Spacing: array of Integer );
  1670. {* }
  1671. procedure WDrawText(WText: WideString; var Rect:TRect; Flags:DWord);
  1672. {* }
  1673. procedure WTextRect(const Rect: TRect; X, Y: Integer;
  1674. const WText: WideString);
  1675. {* Draws a Unicode text, clipping output into given rectangle. }
  1676. function WTextExtent( const WText: WideString ): TSize;
  1677. {* Calculates Unicode text width and height. }
  1678. function WTextWidth( const WText: WideString ): Integer;
  1679. {* Calculates Unicode text width. }
  1680. function WTextHeight( const WText: WideString ): Integer;
  1681. {* Calculates Unicode text height. }
  1682. {$ENDIF _D2}
  1683. {$ENDIF _FPC}
  1684. property ModeCopy : TCopyMode read fCopyMode write fCopyMode;
  1685. {* Current copy mode. Is used in CopyRect method. }
  1686. procedure CopyRect( const DstRect : TRect; SrcCanvas : PCanvas; const SrcRect : TRect );
  1687. {* Copyes a rectangle from source to destination, using StretchBlt. }
  1688. property OnChange: TOnEvent read fOnChange write fOnChange;
  1689. {* }
  1690. function Assign( SrcCanvas : PCanvas ) : Boolean;
  1691. {* }
  1692. function RequiredState( ReqState : DWORD ): Integer; stdcall;// public now
  1693. {* It is possible to call this method before using Handle property
  1694. to pass it into API calls - to provide valid combinations of
  1695. pen, brush and font, selected into device context. This method
  1696. can not provide valid Handle - You always must create it by
  1697. yourself and assign to TCanvas.Handle property manually.
  1698. To optimize assembler version, returns Handle value. }
  1699. procedure DeselectHandles;
  1700. {* Call this method to deselect all graphic tool objects from the canvas. }
  1701. property Pixels[ X, Y: Integer ]: TColor read GetPixels write SetPixels;
  1702. {* Obvious. }
  1703. end;
  1704. //[END OF TCanvas DEFINITION]
  1705. //[GlobalCanvas_OnTextArea]
  1706. var
  1707. GlobalCanvas_OnTextArea : TOnTextArea;
  1708. {* Global event to extend Canvas with possible add-ons, applied
  1709. when rotated fonts are used only (to take into consideration
  1710. Font.Orientation property in TextArea method). }
  1711. //[NewCanvas DECLARATION]
  1712. function NewCanvas( DC: HDC ): PCanvas;
  1713. {* Use to construct Canvas on base of memory DC. }
  1714. //[Extended FUNCTIONS TO WORK WITH CANVAS]
  1715. {++}(*
  1716. {$IFDEF F_P}
  1717. function Windows_Polygon(DC: HDC; var Points; Count: Integer): BOOL; stdcall;
  1718. function Windows_Polyline(DC: HDC; var Points; Count: Integer): BOOL; stdcall;
  1719. function FillRect(hDC: HDC; const lprc: TRect; hbr: HBRUSH): Integer; stdcall;
  1720. function OffsetRect(var lprc: TRect; dx, dy: Integer): BOOL; stdcall;
  1721. function CreateAcceleratorTable(var Accel; Count: Integer): HACCEL; stdcall;
  1722. function TrackPopupMenu(hMenu: HMENU; uFlags: UINT; x, y, nReserved: Integer;
  1723. hWnd: HWND; prcRect: PRect): BOOL; stdcall;
  1724. function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL;
  1725. const NewState: TTokenPrivileges; BufferLength: DWORD;
  1726. var PreviousState: TTokenPrivileges; var ReturnLength: DWORD): BOOL; stdcall;
  1727. function InflateRect(var lprc: TRect; dx, dy: Integer): BOOL; stdcall;
  1728. {$IFDEF F_P105ORBELOW}
  1729. function InvalidateRect(hWnd: HWND; lpRect: PRect; bErase: BOOL): BOOL; stdcall;
  1730. function ValidateRect(hWnd: HWND; lpRect: PRect): BOOL; stdcall;
  1731. {$ENDIF F_P105ORBELOW}
  1732. {$ENDIF}
  1733. *){--}
  1734. { -- Image list object -- }
  1735. //[IMAGE LIST]
  1736. type
  1737. TImageListColors = (ilcColor,ilcColor4,ilcColor8,ilcColor16,
  1738. ilcColor24,ilcColor32,ilcColorDDB,ilcDefault);
  1739. {* ImageList color schemes available. }
  1740. TDrawingStyles = ( dsBlend25, dsBlend50, dsMask, dsTransparent );
  1741. {* ImageList drawing styles available. }
  1742. TDrawingStyle = Set of TDrawingStyles;
  1743. {* Style of drawing is a combination of all available drawing styles. }
  1744. TImageType = (itBitmap,itIcon,itCursor);
  1745. {* ImageList types available. }
  1746. {++}(*TImageList = class;*){--}
  1747. PImageList = {-}^{+}TImageList;
  1748. {* }
  1749. TImgLOVrlayIdx = 1..15;
  1750. { ---------------------------------------------------------------------
  1751. TImageList - images container
  1752. ----------------------------------------------------------------------- }
  1753. //[TImageList DEFINITION]
  1754. TImageList = object( TObj )
  1755. {* ImageList incapsulation. }
  1756. protected
  1757. FHandle: THandle;
  1758. FControl: Pointer; // PControl;
  1759. fPrev, fNext: PImageList;
  1760. FColors: TImageListColors;
  1761. FMasked: Boolean;
  1762. FImgWidth: Integer;
  1763. FImgHeight: Integer;
  1764. FDrawingStyle: TDrawingStyle;
  1765. FBlendColor: TColor;
  1766. fBkColor: TColor;
  1767. FAllocBy: Integer;
  1768. FShareImages: Boolean;
  1769. FOverlay: array[ TImgLOVrlayIdx ] of Integer;
  1770. function HandleNeeded : Boolean;
  1771. procedure SetColors(const Value: TImageListColors);
  1772. procedure SetMasked(const Value: Boolean);
  1773. procedure SetImgWidth(const Value: Integer);
  1774. procedure SetImgHeight(const Value: Integer);
  1775. function GetCount: Integer;
  1776. function GetBkColor: TColor;
  1777. procedure SetBkColor(const Value: TColor);
  1778. function GetBitmap: HBitmap;
  1779. function GetMask: HBitmap;
  1780. function GetDrawStyle : DWord;
  1781. procedure SetAllocBy(const Value: Integer);
  1782. function GetHandle: THandle;
  1783. function GetOverlay(Idx: TImgLOVrlayIdx): Integer;
  1784. procedure SetOverlay(Idx: TImgLOVrlayIdx; const Value: Integer);
  1785. protected
  1786. procedure SetHandle(const Value: THandle);
  1787. {*}
  1788. public
  1789. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  1790. {*}
  1791. property Handle : THandle read GetHandle write SetHandle;
  1792. {* Handle of ImageList object. }
  1793. property ShareImages : Boolean read FShareImages write FShareImages;
  1794. {* True if images are shared between processes (it is set to True,
  1795. if its Handle is assigned to given value, which is a handle of
  1796. already existing ImageList object). }
  1797. property Colors : TImageListColors read FColors write SetColors;
  1798. {* Colors used to represent images. }
  1799. property Masked : Boolean read FMasked write SetMasked;
  1800. {* True, if mask is used. It is set to True, if first added image
  1801. is icon, e.g. }
  1802. property ImgWidth : Integer read FImgWidth write SetImgWidth;
  1803. {* Width of every image in list. If change, ImageList is cleared. }
  1804. property ImgHeight : Integer read FImgHeight write SetImgHeight;
  1805. {* Height of every image in list. If change, ImageList is cleared. }
  1806. property Count : Integer read GetCount;
  1807. {* Number of images in list. }
  1808. property AllocBy : Integer read FAllocBy write SetAllocBy;
  1809. {* Allocation factor. Default is 1. Set it to size of ImageList if this
  1810. value is known - to optimize speed of allocation. }
  1811. property BkColor : TColor read GetBkColor write SetBkColor;
  1812. {* Background color. }
  1813. property BlendColor : TColor read FBlendColor write FBlendColor;
  1814. {* Blend color. }
  1815. property Bitmap : HBitmap read GetBitmap;
  1816. {* Bitmap, containing all ImageList images (tiled horizontally). }
  1817. property Mask : HBitmap read GetMask;
  1818. {* Monochrome bitmap, containing masks for all images in list (if not
  1819. Masked, always returns nil). }
  1820. function ImgRect( Idx : Integer ) : TRect;
  1821. {* Rectangle occupied of given image in ImageList. }
  1822. function Add( Bmp, Msk : HBitmap ) : Integer;
  1823. {* Adds bitmap and given mask to ImageList. }
  1824. function AddMasked( Bmp : HBitmap; Color : TColor ) : Integer;
  1825. {* Adds bitmap to ImageList, using given color to create mask. }
  1826. function AddIcon( Ico : HIcon ) : Integer;
  1827. {* Adds icon to ImageList (always masked). }
  1828. procedure Delete( Idx : Integer );
  1829. {* Deletes given image from ImageList. }
  1830. procedure Clear;
  1831. {* Makes ImageList empty. }
  1832. function Replace( Idx : Integer; Bmp, Msk : HBitmap ) : Boolean;
  1833. {* Replaces given (by index) image with bitmap and its mask with mask bitmap. }
  1834. function ReplaceIcon( Idx : Integer; Ico : HIcon ) : Boolean;
  1835. {* Replaces given (by index) image with an icon. }
  1836. function Merge( Idx : Integer; ImgList2 : PImageList; Idx2 : Integer; X, Y : Integer )
  1837. : PImageList;
  1838. {* Merges two ImageList objects, returns resulting ImageList. }
  1839. function ExtractIcon( Idx : Integer ) : HIcon;
  1840. {* Extracts icon by index. }
  1841. function ExtractIconEx( Idx : Integer ) : HIcon;
  1842. {* Extracts icon (is created using current drawing style). }
  1843. property DrawingStyle : TDrawingStyle read FDrawingStyle write FDrawingStyle;
  1844. {* Drawing style. }
  1845. procedure Draw( Idx : Integer; DC : HDC; X, Y : Integer );
  1846. {* Draws given (by index) image from ImageList onto passed Device Context. }
  1847. procedure StretchDraw( Idx : Integer; DC : HDC; const Rect : TRect );
  1848. {* Draws given image with stratching. }
  1849. function LoadBitmap( ResourceName : PChar; TranspColor : TColor ) : Boolean;
  1850. {* Loads ImageList from resource. }
  1851. //function LoadIcon( ResourceName : PChar ) : Boolean;
  1852. //function LoadCursor( ResourceName : PChar ) : Boolean;
  1853. function LoadFromFile( FileName : PChar; TranspColor : TColor; ImgType : TImageType ) : Boolean;
  1854. {* Loads ImageList from file. }
  1855. function LoadSystemIcons( SmallIcons : Boolean ) : Boolean;
  1856. {* Assigns ImageList to system icons list (big or small). }
  1857. property Overlay[ Idx: TImgLOVrlayIdx ]: Integer read GetOverlay write SetOverlay;
  1858. {* Overlay images for image list (images, used as overlay images to draw over
  1859. other images from the image list). These overalay images can be used in
  1860. listview and treeview as overlaying images (up to four masks at the same
  1861. time). }
  1862. {$IFDEF USE_CONSTRUCTORS}
  1863. constructor CreateImageList( POwner: Pointer );
  1864. {$ENDIF USE_CONSTRUCTORS}
  1865. end;
  1866. //[END OF TImageList DEFINITION]
  1867. //[IMAGE LIST API]
  1868. const
  1869. CLR_NONE = $FFFFFFFF;
  1870. CLR_DEFAULT = $FF000000;
  1871. type
  1872. HImageList = THandle;
  1873. const
  1874. ILC_MASK = $0001;
  1875. ILC_COLOR = $00FE;
  1876. ILC_COLORDDB = $00FE;
  1877. ILC_COLOR4 = $0004;
  1878. ILC_COLOR8 = $0008;
  1879. ILC_COLOR16 = $0010;
  1880. ILC_COLOR24 = $0018;
  1881. ILC_COLOR32 = $0020;
  1882. ILC_PALETTE = $0800;
  1883. const
  1884. ILD_NORMAL = $0000;
  1885. ILD_TRANSPARENT = $0001;
  1886. ILD_MASK = $0010;
  1887. ILD_IMAGE = $0020;
  1888. ILD_BLEND25 = $0002;
  1889. ILD_BLEND50 = $0004;
  1890. ILD_OVERLAYMASK = $0F00;
  1891. const
  1892. ILD_SELECTED = ILD_BLEND50;
  1893. ILD_FOCUS = ILD_BLEND25;
  1894. ILD_BLEND = ILD_BLEND50;
  1895. CLR_HILIGHT = CLR_DEFAULT;
  1896. function ImageList_Create(CX, CY: Integer; Flags: UINT;
  1897. Initial, Grow: Integer): HImageList; stdcall;
  1898. function ImageList_Destroy(ImageList: HImageList): Bool; stdcall;
  1899. function ImageList_GetImageCount(ImageList: HImageList): Integer; stdcall;
  1900. function ImageList_SetImageCount(ImageList: HImageList; Count: Integer): Integer; stdcall;
  1901. function ImageList_Add(ImageList: HImageList; Image, Mask: HBitmap): Integer; stdcall;
  1902. function ImageList_ReplaceIcon(ImageList: HImageList; Index: Integer;
  1903. Icon: HIcon): Integer; stdcall;
  1904. function ImageList_SetBkColor(ImageList: HImageList; ClrBk: TColorRef): TColorRef; stdcall;
  1905. function ImageList_GetBkColor(ImageList: HImageList): TColorRef; stdcall;
  1906. function ImageList_SetOverlayImage(ImageList: HImageList; Image: Integer;
  1907. Overlay: Integer): Bool; stdcall;
  1908. function ImageList_AddIcon(ImageList: HImageList; Icon: HIcon): Integer;
  1909. function Index2OverlayMask(Index: Integer): Integer;
  1910. function ImageList_Draw(ImageList: HImageList; Index: Integer;
  1911. Dest: HDC; X, Y: Integer; Style: UINT): Bool; stdcall;
  1912. function ImageList_Replace(ImageList: HImageList; Index: Integer;
  1913. Image, Mask: HBitmap): Bool; stdcall;
  1914. function ImageList_AddMasked(ImageList: HImageList; Image: HBitmap;
  1915. Mask: TColorRef): Integer; stdcall;
  1916. function ImageList_DrawEx(ImageList: HImageList; Index: Integer;
  1917. Dest: HDC; X, Y, DX, DY: Integer; Bk, Fg: TColorRef; Style: Cardinal): Bool; stdcall;
  1918. function ImageList_Remove(ImageList: HImageList; Index: Integer): Bool; stdcall;
  1919. function ImageList_GetIcon(ImageList: HImageList; Index: Integer;
  1920. Flags: Cardinal): HIcon; stdcall;
  1921. function ImageList_LoadImageA(Instance: THandle; Bmp: PAnsiChar; CX, Grow: Integer;
  1922. Mask: TColorRef; pType, Flags: Cardinal): HImageList; stdcall;
  1923. function ImageList_LoadImageW(Instance: THandle; Bmp: PWideChar; CX, Grow: Integer;
  1924. Mask: TColorRef; pType, Flags: Cardinal): HImageList; stdcall;
  1925. function ImageList_LoadImage(Instance: THandle; Bmp: PChar; CX, Grow: Integer;
  1926. Mask: TColorRef; pType, Flags: Cardinal): HImageList; stdcall;
  1927. function ImageList_BeginDrag(ImageList: HImageList; Track: Integer;
  1928. XHotSpot, YHotSpot: Integer): Bool; stdcall;
  1929. function ImageList_EndDrag: Bool; stdcall;
  1930. function ImageList_DragEnter(LockWnd: HWnd; X, Y: Integer): Bool; stdcall;
  1931. function ImageList_DragLeave(LockWnd: HWnd): Bool; stdcall;
  1932. function ImageList_DragMove(X, Y: Integer): Bool; stdcall;
  1933. function ImageList_SetDragCursorImage(ImageList: HImageList; Drag: Integer;
  1934. XHotSpot, YHotSpot: Integer): Bool; stdcall;
  1935. function ImageList_DragShowNolock(Show: Bool): Bool; stdcall;
  1936. function ImageList_GetDragImage(Point, HotSpot: PPoint): HImageList; stdcall;
  1937. { macros }
  1938. procedure ImageList_RemoveAll(ImageList: HImageList); stdcall;
  1939. function ImageList_ExtractIcon(Instance: THandle; ImageList: HImageList;
  1940. Image: Integer): HIcon; stdcall;
  1941. function ImageList_LoadBitmap(Instance: THandle; Bmp: PChar;
  1942. CX, Grow: Integer; MasK: TColorRef): HImageList; stdcall;
  1943. //function ImageList_Read(Stream: IStream): HImageList; stdcall;
  1944. //function ImageList_Write(ImageList: HImageList; Stream: IStream): BOOL; stdcall;
  1945. //[TImageInfo]
  1946. type
  1947. PImageInfo = ^TImageInfo;
  1948. TImageInfo = packed record
  1949. hbmImage: HBitmap;
  1950. hbmMask: HBitmap;
  1951. Unused1: Integer;
  1952. Unused2: Integer;
  1953. rcImage: TRect;
  1954. end;
  1955. function ImageList_GetIconSize(ImageList: HImageList; var CX, CY: Integer): Bool; stdcall;
  1956. function ImageList_SetIconSize(ImageList: HImageList; CX, CY: Integer): Bool; stdcall;
  1957. function ImageList_GetImageInfo(ImageList: HImageList; Index: Integer;
  1958. var ImageInfo: TImageInfo): Bool; stdcall;
  1959. function ImageList_Merge(ImageList1: HImageList; Index1: Integer;
  1960. ImageList2: HImageList; Index2: Integer; DX, DY: Integer)://Bool - ERROR IN VCL
  1961. HImageList; stdcall;
  1962. //[LoadBmp]
  1963. function LoadBmp( Instance: Integer; Rsrc: PChar; MasterObj: PObj ): HBitmap;
  1964. //[BITMAPS]
  1965. type
  1966. tagBitmap = Windows.TBitmap;
  1967. TPixelFormat = ( pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit,
  1968. pf32bit, pfCustom );
  1969. {* Available pixel formats. }
  1970. TBitmapHandleType = ( bmDIB, bmDDB );
  1971. {* Available bitmap handle types. }
  1972. {++}(*TBitmap = class;*){--}
  1973. PBitmap = {-}^{+}TBitmap;
  1974. { ----------------------------------------------------------------------
  1975. TBitmap - bitmap image
  1976. ----------------------------------------------------------------------- }
  1977. //[TBitmap DEFINITION]
  1978. TBitmap = object( TObj )
  1979. {* Bitmap incapsulation object. }
  1980. protected
  1981. fHeight: Integer;
  1982. fWidth: Integer;
  1983. fHandle: HBitmap;
  1984. fCanvas: PCanvas;
  1985. fScanLineSize: Integer;
  1986. fBkColor: TColor;
  1987. fApplyBkColor2Canvas: procedure( Sender: PBitmap );
  1988. fDetachCanvas: procedure( Sender: PBitmap );
  1989. fCanvasAttached : Integer;
  1990. fHandleType: TBitmapHandleType;
  1991. fDIBHeader: PBitmapInfo;
  1992. fDIBBits: Pointer;
  1993. fDIBSize: Integer;
  1994. fNewPixelFormat: TPixelFormat;
  1995. fFillWithBkColor: procedure( BmpObj: PBitmap; DC: HDC; oldW, oldH: Integer );
  1996. //stdcall;
  1997. fTransMaskBmp: PBitmap;
  1998. fTransColor: TColor;
  1999. fGetDIBPixels: function( Bmp: PBitmap; X, Y: Integer ): TColor;
  2000. fSetDIBPixels: procedure( Bmp: PBitmap; X, Y: Integer; Value: TColor );
  2001. fScanLine0: PByte;
  2002. fScanLineDelta: Integer;
  2003. fPixelMask: DWORD;
  2004. fPixelsPerByteMask: Integer;
  2005. fBytesPerPixel: Integer;
  2006. fDIBAutoFree: Boolean;
  2007. procedure SetHeight(const Value: Integer);
  2008. procedure SetWidth(const Value: Integer);
  2009. function GetEmpty: Boolean;
  2010. function GetHandle: HBitmap;
  2011. function GetHandleAllocated: Boolean;
  2012. procedure SetHandle(const Value: HBitmap);
  2013. procedure SetPixelFormat(Value: TPixelFormat);
  2014. procedure FormatChanged;
  2015. function GetCanvas: PCanvas;
  2016. procedure CanvasChanged( Sender: PObj );
  2017. function GetScanLine(Y: Integer): Pointer;
  2018. function GetScanLineSize: Integer;
  2019. procedure ClearData;
  2020. procedure ClearTransImage;
  2021. procedure SetBkColor(const Value: TColor);
  2022. function GetDIBPalEntries(Idx: Integer): TColor;
  2023. function GetDIBPalEntryCount: Integer;
  2024. procedure SetDIBPalEntries(Idx: Integer; const Value: TColor);
  2025. procedure SetHandleType(const Value: TBitmapHandleType);
  2026. function GetPixelFormat: TPixelFormat;
  2027. function GetPixels(X, Y: Integer): TColor;
  2028. procedure SetPixels(X, Y: Integer; const Value: TColor);
  2029. function GetDIBPixels(X, Y: Integer): TColor;
  2030. procedure SetDIBPixels(X, Y: Integer; const Value: TColor);
  2031. function GetBoundsRect: TRect;
  2032. protected
  2033. {++}(*public*){--}
  2034. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  2035. public
  2036. property Width: Integer read fWidth write SetWidth;
  2037. {* Width of bitmap. To make code smaller, avoid changing Width or Height
  2038. after bitmap is created (using NewBitmap) or after it is loaded from
  2039. file, stream of resource. }
  2040. property Height: Integer read fHeight write SetHeight;
  2041. {* Height of bitmap. To make code smaller, avoid changing Width or Height
  2042. after bitmap is created (using NewBitmap) or after it is loaded from
  2043. file, stream of resource. }
  2044. property BoundsRect: TRect read GetBoundsRect;
  2045. {* Returns rectangle (0,0,Width,Height). }
  2046. property Empty: Boolean read GetEmpty;
  2047. {* Returns True if Width or Height is 0. }
  2048. procedure Clear;
  2049. {* Makes bitmap empty, setting its Width and Height to 0. }
  2050. procedure LoadFromFile( const Filename: String );
  2051. {* Loads bitmap from file (LoadFromStream used). }
  2052. function LoadFromFileEx( const Filename: String ): Boolean;
  2053. {* Loads bitmap from a file. If necessary, bitmap is RLE-decoded. Code given
  2054. by Vyacheslav A. Gavrik. }
  2055. procedure SaveToFile( const Filename: String );
  2056. {* Stores bitmap to file (SaveToStream used). }
  2057. procedure LoadFromStream( Strm: PStream );
  2058. {* Loads bitmap from stream. Follow loading, bitmap has DIB format (without
  2059. handle allocated). It is possible to draw DIB bitmap without creating
  2060. handle for it, which can economy GDI resources. }
  2061. function LoadFromStreamEx( Strm: PStream ): Boolean;
  2062. {* Loads bitmap from a stream. Difference is that RLE decoding supported.
  2063. Code given by Vyacheslav A. Gavrik. }
  2064. procedure SaveToStream( Strm: PStream );
  2065. {* Saves bitmap to stream. If bitmap is not DIB, it is converted to DIB
  2066. before saving. }
  2067. procedure LoadFromResourceID( Inst: DWORD; ResID: Integer );
  2068. {* Loads bitmap from resource using integer ID of resource. To load by name,
  2069. use LoadFromResurceName. To load resource of application itself, pass
  2070. hInstance as first parameter. This method also can be used to load system
  2071. predefined bitmaps, if 0 is passed as Inst parameter:
  2072. |<pre>
  2073. OBM_BTNCORNERS OBM_REDUCE
  2074. OBM_BTSIZE OBM_REDUCED
  2075. OBM_CHECK OBM_RESTORE
  2076. OBM_CHECKBOXES OBM_RESTORED
  2077. OBM_CLOSE OBM_RGARROW
  2078. OBM_COMBO OBM_RGARROWD
  2079. OBM_DNARROW OBM_RGARROWI
  2080. OBM_DNARROWD OBM_SIZE
  2081. OBM_DNARROWI OBM_UPARROW
  2082. OBM_LFARROW OBM_UPARROWD
  2083. OBM_LFARROWD OBM_UPARROWI
  2084. OBM_LFARROWI OBM_ZOOM
  2085. OBM_MNARROW OBM_ZOOMD
  2086. |</pre> }
  2087. procedure LoadFromResourceName( Inst: DWORD; ResName: PChar );
  2088. {* Loads bitmap from resurce (using passed name of bitmap resource. }
  2089. function Assign( SrcBmp: PBitmap ): Boolean;
  2090. {* Assigns bitmap from another. Returns False if not success.
  2091. Note: remember, that Canvas is not assigned - only bitmap image
  2092. is copied. And for DIB, handle is not allocating due this process. }
  2093. property Handle: HBitmap read GetHandle write SetHandle;
  2094. {* Handle of bitmap. Created whenever property accessed. To check if handle
  2095. is allocated (without allocating it), use HandleAllocated property. }
  2096. property HandleAllocated: Boolean read GetHandleAllocated;
  2097. {* Returns True, if Handle already allocated. }
  2098. function ReleaseHandle: HBitmap;
  2099. {* Returns Handle and releases it, so bitmap no more know about handle.
  2100. This method does not destroy bitmap image, but converts it into DIB.
  2101. Returned Handle actually is a handle of copy of original bitmap. If
  2102. You need not in keping it up, use Dormant method instead. }
  2103. procedure Dormant;
  2104. {* Releases handle from bitmap and destroys it. But image is not destroyed
  2105. and its data are preserved in DIB format. Please note, that in KOL, DIB
  2106. bitmaps can be drawn onto given device context without allocating of
  2107. handle. So, it is very useful to call Dormant preparing it using
  2108. Canvas drawing operations - to economy GDI resources. }
  2109. property HandleType: TBitmapHandleType read fHandleType write SetHandleType;
  2110. {* bmDIB, if DIB part of image data is filled and stored internally in
  2111. TBitmap object. DIB image therefore can have Handle allocated, which
  2112. require resources. Use HandleAllocated funtion to determine if handle
  2113. is allocated and Dormant method to remove it, if You want to economy
  2114. GDI resources. (Actually Handle needed for DIB bitmap only in case
  2115. when Canvas is used to draw on bitmap surface). Please note also, that
  2116. before saving bitmap to file or stream, it is converted to DIB. }
  2117. property PixelFormat: TPixelFormat read GetPixelFormat write SetPixelFormat;
  2118. {* Current pixel format. If format of bitmap is unknown, or bitmap is DDB,
  2119. value is pfDevice. Setting PixelFormat to any other format converts
  2120. bitmap to DIB, back to pfDevice converts bitmap to DDB again. Avoid
  2121. such conversations for large bitmaps or for numerous bitmaps in your
  2122. application to keep good performance. }
  2123. function BitsPerPixel: Integer;
  2124. {* Returns bits per pixel if possible. }
  2125. procedure Draw( DC: HDC; X, Y: Integer );
  2126. {* Draws bitmap to given device context. If bitmap is DIB, it is always
  2127. drawing using SetDIBitsToDevice API call, which does not require bitmap
  2128. handle (so, it is very sensible to call Dormant method to free correspondent
  2129. GDI resources). }
  2130. procedure StretchDraw( DC: HDC; const Rect: TRect );
  2131. {* Draws bitmap onto DC, stretching it to fit given rectangle Rect. }
  2132. procedure DrawTransparent( DC: HDC; X, Y: Integer; TranspColor: TColor );
  2133. {* Draws bitmap onto DC transparently, using TranspColor as transparent. }
  2134. procedure StretchDrawTransparent( DC: HDC; const Rect: TRect; TranspColor: TColor );
  2135. {* Draws bitmap onto given rectangle of destination DC (with stretching it
  2136. to fit Rect) - transparently, using TranspColor as transparent. }
  2137. procedure DrawMasked( DC: HDC; X, Y: Integer; Mask: HBitmap );
  2138. {* Draws bitmap to destination DC transparently by mask. It is possible
  2139. to pass as a mask handle of another TBitmap, previously converted to
  2140. monochrome mask using Convert2Mask method. }
  2141. procedure StretchDrawMasked( DC: HDC; const Rect: TRect; Mask: HBitmap );
  2142. {* Like DrawMasked, but with stretching image onto given rectangle. }
  2143. procedure Convert2Mask( TranspColor: TColor );
  2144. {* Converts bitmap to monochrome (mask) bitmap with TranspColor replaced
  2145. to clBlack and all other ones to clWhite. Such mask bitmap can be used
  2146. to draw original bitmap transparently, with given TranspColor as
  2147. transparent. (To preserve original bitmap, create new instance of
  2148. TBitmap and assign original bitmap to it). See also DrawTransparent and
  2149. StretchDrawTransparent methods. }
  2150. procedure Invert;
  2151. {* Obvious. }
  2152. property Canvas: PCanvas read GetCanvas;
  2153. {* Canvas can be used to draw onto bitmap. Whenever it is accessed, handle
  2154. is allocated for bitmap, if it is not yet (to make it possible
  2155. to select bitmap to display compatible device context). }
  2156. procedure RemoveCanvas;
  2157. {* Call this method to destroy Canvas and free GDI resources. }
  2158. property BkColor: TColor read fBkColor write SetBkColor;
  2159. {* Used to fill background for Bitmap, when its width or height is increased.
  2160. Although this value always synchronized with Canvas.Brush.Color, use it
  2161. instead if You do not use Canvas for drawing on bitmap surface. }
  2162. property Pixels[ X, Y: Integer ]: TColor read GetPixels write SetPixels;
  2163. {* Allows to obtain or change certain pixels of a bitmap. This method is
  2164. both for DIB and DDB bitmaps, and leads to allocate handle anyway. For
  2165. DIB bitmaps, it is possible to use property DIBPixels[ ] instead,
  2166. which is much faster and does not require in Handle. }
  2167. property ScanLineSize: Integer read GetScanLineSize;
  2168. {* Returns size of scan line in bytes. Use it to measure size of a single
  2169. ScanLine. To calculate increment value from first byte of ScanLine to
  2170. first byte of next ScanLine, use difference
  2171. ! Integer(ScanLine[1]-ScanLine[0])
  2172. (this is because bitmap can be oriented from bottom to top, so
  2173. step can be negative). }
  2174. property ScanLine[ Y: Integer ]: Pointer read GetScanLine;
  2175. {* Use ScanLine to access DIB bitmap pixels in memory to direct access it
  2176. fast. Take in attention, that for different pixel formats, different
  2177. bit counts are used to represent bitmap pixels. Also do not forget, that
  2178. for formats pf4bit and pf8bit, pixels actually are indices to palette
  2179. entries, and for formats pf16bit, pf24bit and pf32bit are actually
  2180. RGB values (for pf16bit B:5-G:6-R:5, for pf15bit B:5-G:5-R:5 (high order
  2181. bit not used), for pf24bit B:8-G:8-R:8, and for pf32bit high order byte
  2182. of TRGBQuad structure is not used). }
  2183. property DIBPixels[ X, Y: Integer ]: TColor read GetDIBPixels write SetDIBPixels;
  2184. {* Allows direct access to pixels of DIB bitmap, faster then Pixels[ ]
  2185. property. Access to read is slower for pf15bit, pf16bit formats (because
  2186. some conversation needed to translate packed RGB color to TColor). And
  2187. for write, operation performed most slower for pf4bit, pf8bit (searching
  2188. nearest color required) and fastest for pf24bit, pf32bit and pf1bit. }
  2189. property DIBPalEntryCount: Integer read GetDIBPalEntryCount;
  2190. {* Returns palette entries count for DIB image. Always returns 2 for pf1bit,
  2191. 16 for pf4bit, 256 for pf8bit and 0 for other pixel formats. }
  2192. property DIBPalEntries[ Idx: Integer ]: TColor read GetDIBPalEntries write
  2193. SetDIBPalEntries;
  2194. {* Provides direct access to DIB palette. }
  2195. function DIBPalNearestEntry( Color: TColor ): Integer;
  2196. {* Returns index of entry in DIB palette with color nearest (or matching)
  2197. to given one. }
  2198. property DIBBits: Pointer read fDIBBits;
  2199. {* This property is mainly for internal use. }
  2200. property DIBSize: Integer read fDIBSize;
  2201. {* Size of DIBBits array. }
  2202. property DIBHeader: PBitmapInfo read fDIBHeader;
  2203. {* This property is mainly for internal use. }
  2204. procedure DIBDrawRect( DC: HDC; X, Y: Integer; const R: TRect );
  2205. {* This procedure copies given rectangle to the target device context,
  2206. but only for DIB bitmap (using SetDIBBitsToDevice API call). }
  2207. procedure RotateRight;
  2208. {* Rotates bitmap right (90 degree). Bitmap must be DIB. If You definitevely
  2209. know format of a bitmap, use instead one of methods RotateRightMono,
  2210. RotateRight4bit, RotateRight8bit, RotateRight16bit or RotateRightTrueColor
  2211. - this will economy code. But if for most of formats such methods are
  2212. called, this can be more economy just to call always universal method
  2213. RotateRight. }
  2214. procedure RotateLeft;
  2215. {* Rotates bitmap left (90 degree). Bitmap must be DIB. If You definitevely
  2216. know format of a bitmap, use instead one of methods RotateLeftMono,
  2217. RotateLeft4bit, RotateLeft8bit, RotateLeft16bit or RotateLeftTrueColor
  2218. - this will economy code. But if for most of formats such methods are
  2219. called, this can be more economy just to call always universal method
  2220. RotateLeft. }
  2221. procedure RotateRightMono;
  2222. {* Rotates bitmat right, but only if bitmap is monochrome (pf1bit). }
  2223. procedure RotateLeftMono;
  2224. {* Rotates bitmap left, but only if bitmap is monochrome (pf1bit). }
  2225. procedure RotateRight4bit;
  2226. {* Rotates bitmap right, but only if PixelFormat is pf4bit. }
  2227. procedure RotateLeft4bit;
  2228. {* Rotates bitmap left, but only if PixelFormat is pf4bit. }
  2229. procedure RotateRight8bit;
  2230. {* Rotates bitmap right, but only if PixelFormat is pf8bit. }
  2231. procedure RotateLeft8bit;
  2232. {* Rotates bitmap left, but only if PixelFormat is pf8bit. }
  2233. procedure RotateRight16bit;
  2234. {* Rotates bitmap right, but only if PixelFormat is pf16bit. }
  2235. procedure RotateLeft16bit;
  2236. {* Rotates bitmap left, but only if PixelFormat is pf16bit. }
  2237. procedure RotateRightTrueColor;
  2238. {* Rotates bitmap right, but only if PixelFormat is pf24bit or pf32bit. }
  2239. procedure RotateLeftTrueColor;
  2240. {* Rotates bitmap left, but only if PixelFormat is pf24bit or pf32bit. }
  2241. procedure FlipVertical;
  2242. {* Flips bitmap vertically }
  2243. procedure FlipHorizontal;
  2244. {* Flips bitmap horizontally }
  2245. procedure CopyRect( const DstRect : TRect; SrcBmp : PBitmap; const SrcRect : TRect );
  2246. {* It is possible to use Canvas.CopyRect for such purpose, but if You
  2247. do not want use TCanvas, it is possible to copy rectangle from one
  2248. bitmap to another using this function. }
  2249. function CopyToClipboard: Boolean;
  2250. {* Copies bitmap to clipboard. }
  2251. function PasteFromClipboard: Boolean;
  2252. {* Takes CF_DIB format bitmap from clipboard and assigns it to the
  2253. TBitmap object. }
  2254. end;
  2255. //[END OF TBitmap DEFINITION]
  2256. //[NewBitmap DECLARATION]
  2257. function NewBitmap( W, H: Integer ): PBitmap;
  2258. {* Creates bitmap object of given size. If it is possible, do not change its
  2259. size (Width and Heigth) later - this can economy code a bit. See TBitmap. }
  2260. function NewDIBBitmap( W, H: Integer; PixelFormat: TPixelFormat ): PBitmap;
  2261. {* Creates DIB bitmap object of given size and pixel format. If it is possible,
  2262. do not change its size (Width and Heigth) later - this can economy code a bit.
  2263. See TBitmap. }
  2264. //[CalcScanLineSize DECLARATION]
  2265. function CalcScanLineSize( Header: PBitmapInfoHeader ): Integer;
  2266. {* May be will be useful. }
  2267. //[DefaultPixelFormat VARIABLE]
  2268. var
  2269. //DefaultBitsPerPixel: Integer = 16;
  2270. DefaultPixelFormat: TPixelFormat = pf16bit;
  2271. //[Mapped bitmaps]
  2272. { -- Function to load bitmap mapping some its colors. -- }
  2273. function LoadMappedBitmap( hInst: THandle; BmpResID: Integer; const Map: array of TColor )
  2274. : HBitmap;
  2275. {* This function can be used to load bitmap and replace some it colors to
  2276. desired ones. This function especially useful when loaded by the such way
  2277. bitmap is used as toolbar bitmap - to replace some original colors to
  2278. system default colors. To use this function properly, the bitmap shoud
  2279. be prepared as 16-color bitmap, which uses only system colors. To do so,
  2280. create a new 16-color bitmap with needed dimensions in Borland Image Editor
  2281. and paste a bitmap image, copyed in another graphic tool, and then save it.
  2282. If this is not done, bitmap will not be loaded correctly! }
  2283. function LoadMappedBitmapEx( MasterObj: PObj; hInst: THandle; BmpResName: PChar; const Map: array of TColor )
  2284. : HBitmap;
  2285. {* Like LoadMappedBitmap, but much powerful. It uses CreateMappedBitmapEx
  2286. by Alex Pravdin, so it understands any bitmap color format, including
  2287. pf24bit. Also, LoadMappedBitmapEx provides auto-destroying loaded resource
  2288. when MasterObj is destroyed. }
  2289. function CreateMappedBitmap(Instance: THandle; Bitmap: Integer;
  2290. Flags: UINT; ColorMap: PColorMap; NumMaps: Integer): HBitmap; stdcall;
  2291. {* Creates mapped bitmap replacing colors correspondently to the
  2292. ColorMap (each pare of colors defines color replaced and a color
  2293. used for replace it in the bitmap). See also CreateMappedBitmapEx. }
  2294. function CreateMappedBitmapEx(Instance: THandle; BmpRsrcName: PChar; Flags:
  2295. Cardinal; ColorMap: PColorMap; NumMaps: Integer): HBitmap;
  2296. {* By Alex Pravdin.
  2297. Creates mapped bitmap independently from bitmap color format (works
  2298. correctly with bitmaps having format deeper than 8bit per pixel). }
  2299. //[ICONS]
  2300. type
  2301. {++}(*TIcon = class;*){--}
  2302. PIcon = {-}^{+}TIcon;
  2303. { ----------------------------------------------------------------------
  2304. TIcon - icon image
  2305. ----------------------------------------------------------------------- }
  2306. //[TIcon DEFINITION]
  2307. TIcon = object( TObj )
  2308. {* Object type to incapsulate icon or cursor image. }
  2309. protected
  2310. FSize : Integer;
  2311. FHandle: HIcon;
  2312. FShareIcon: Boolean;
  2313. procedure SetSize(const Value: Integer);
  2314. procedure SetHandle(const Value: HIcon);
  2315. function GetHotSpot: TPoint;
  2316. function GetEmpty: Boolean;
  2317. protected
  2318. {++}(*public*){--}
  2319. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  2320. public
  2321. property Size : Integer read FSize write SetSize;
  2322. {* Icon dimension (width and/or height, which are equal to each other always). }
  2323. property Handle : HIcon read FHandle write SetHandle;
  2324. {* Windows icon object handle. }
  2325. procedure Clear;
  2326. {* Clears icon, freeing image and allocated GDI resource (Handle). }
  2327. property Empty: Boolean read GetEmpty;
  2328. {* Returns True if icon is Empty. }
  2329. property ShareIcon : Boolean read FShareIcon write FShareIcon;
  2330. {* True, if icon object is shared and can not be deleted when TIcon object
  2331. is destroyed (set this flag is to True, if an icon is obtained from another
  2332. TIcon object, for example). }
  2333. property HotSpot : TPoint read GetHotSpot;
  2334. {* Hot spot point - for cursors. }
  2335. procedure Draw( DC : HDC; X, Y : Integer );
  2336. {* Draws icon onto given device context. Icon always is drawn transparently
  2337. using its transparency mask (stored internally in icon object). }
  2338. procedure StretchDraw( DC : HDC; Dest : TRect );
  2339. {* Draws icon onto given device context with stretching it to fit destination
  2340. rectangle. See also Draw. }
  2341. procedure LoadFromStream( Strm : PStream );
  2342. {* Loads icon from stream. If stream contains several icons (of
  2343. different dimentions), icon with the most appropriate size is loading. }
  2344. procedure LoadFromFile( const FileName : String );
  2345. {* Load icon from file. If file contains several icons (of
  2346. different dimensions), icon with the most appropriate size is loading. }
  2347. procedure LoadFromResourceID( Inst: Integer; ResID: Integer; DesiredSize: Integer );
  2348. {* Loads icon from resource. To load system default icon, pass 0 as Inst and
  2349. one of followin values as ResID:
  2350. |<pre>
  2351. IDI_APPLICATION Default application icon.
  2352. IDI_ASTERISK Asterisk (used in informative messages).
  2353. IDI_EXCLAMATION Exclamation point (used in warning messages).
  2354. IDI_HAND Hand-shaped icon (used in serious warning messages).
  2355. IDI_QUESTION Question mark (used in prompting messages).
  2356. IDI_WINLOGO Windows logo.
  2357. |</pre> It is also possible to load icon from resources of another module,
  2358. if pass instance handle of loaded module as Inst parameter. }
  2359. procedure LoadFromResourceName( Inst: Integer; ResName: PChar; DesiredSize: Integer );
  2360. {* Loads icon from resource. To load own application resource, pass
  2361. hInstance as Inst parameter. It is possible to load resource from
  2362. another module, if pass its instance handle as Inst. }
  2363. procedure LoadFromExecutable( const FileName: String; IconIdx: Integer );
  2364. {* Loads icon from executable (exe or dll file). Always default sized icon
  2365. is loaded. It is possible also to get know how much icons are contained
  2366. in executable using gloabl function GetFileIconCount. To obtain icon of
  2367. another size, try to load given executable and use LoadFromResourceID
  2368. method. }
  2369. procedure SaveToStream( Strm : PStream );
  2370. {* Saves single icon to stream. To save icons with several different
  2371. dimensions, use global procedure SaveIcons2Stream. }
  2372. procedure SaveToFile( const FileName : String );
  2373. {* Saves single icon to file. To save icons with several different
  2374. dimensions, use global procedure SaveIcons2File. }
  2375. function Convert2Bitmap( TranColor: TColor ): HBitmap;
  2376. {* Converts icon to bitmap, returning Windows GDI bitmap resource as
  2377. a result. It is possible later to assign returned bitmap handle to
  2378. Handle property of TBitmap object to use features of TBitmap.
  2379. Pass TranColor to replace transparent area of icon with given color. }
  2380. end;
  2381. //[END OF TIcon DEFINITION]
  2382. //[Icon save functions]
  2383. procedure SaveIcons2Stream( const Icons : array of PIcon; Strm : PStream );
  2384. {* Saves several icons (of different dimentions) to stream. }
  2385. function SaveIcons2StreamEx( const BmpHandles: array of HBitmap; Strm: PStream ): Boolean;
  2386. {* Saves icons creating it from pairs of bitmaps and their masks.
  2387. BmpHandles array must contain pairs of bitmap handles, each pair
  2388. of color bitmap and mask bitmap of the same size. }
  2389. procedure SaveIcons2File( const Icons : array of PIcon; const FileName : String );
  2390. {* Saves several icons (of different dimentions) to file. (Single file
  2391. with extension .ico can contain several different sized icon images
  2392. to use later one with the most appropriate size). }
  2393. //[NewIcon DECLARATION]
  2394. function NewIcon: PIcon;
  2395. {* Creates new icon object, setting its Size to 32 by default. Created icon
  2396. is Empty. }
  2397. //[GetFileIconCount DECLARATION]
  2398. function GetFileIconCount( const FileName: String ): Integer;
  2399. {* Returns number of icon resources stored in given (executable) file. }
  2400. //[ICON STRUCTURES]
  2401. type
  2402. TIconHeader = packed record
  2403. idReserved: Word; (* Always set to 0 *)
  2404. idType: Word; (* Always set to 1 *)
  2405. idCount: Word; (* Number of icon images *)
  2406. (* immediately followed by idCount TIconDirEntries *)
  2407. end;
  2408. TIconDirEntry = packed record
  2409. bWidth: Byte; (* Width *)
  2410. bHeight: Byte; (* Height *)
  2411. bColorCount: Byte; (* Nr. of colors used, see below *)
  2412. bReserved: Byte; (* not used, 0 *)
  2413. wPlanes: Word; (* not used, 0 *)
  2414. wBitCount: Word; (* not used, 0 *)
  2415. dwBytesInRes: Longint; (* total number of bytes in images *)
  2416. dwImageOffset: Longint;(* location of image from the beginning of file *)
  2417. end;
  2418. //[LoadImgIcon DECLARATION]
  2419. function LoadImgIcon( RsrcName: PChar; Size: Integer ): HIcon;
  2420. {* Loads icon of specified size from the resource. }
  2421. ////////////////////////////////////////////////////////////////////////////////
  2422. // UNIVERSAL CONTROL OBJECT //
  2423. ////////////////////////////////////////////////////////////////////////////////
  2424. //[CM_XXX CONSTANTS]
  2425. const
  2426. CM_EXECPROC = $8FFF;
  2427. CM_BASE = $B000;
  2428. CM_ACTIVATE = CM_BASE + 0;
  2429. CM_DEACTIVATE = CM_BASE + 1;
  2430. CM_ENTER = CM_BASE + 2;
  2431. CM_RELEASE = CM_BASE + 3;
  2432. CM_QUIT = CM_BASE + 4;
  2433. CM_COMMAND = CM_BASE + 5;
  2434. CM_MEASUREITEM = CM_BASE + 6;
  2435. CM_DRAWITEM = CM_BASE + 7;
  2436. CM_TRAYICON = CM_BASE + 8;
  2437. CM_INVALIDATE = CM_BASE + 9;
  2438. CM_UPDATE = CM_BASE + 10;
  2439. CM_NCUPDATE = CM_BASE + 11;
  2440. CM_SIZEPOS = CM_BASE + 12;
  2441. CM_SIZE = CM_BASE + 13;
  2442. CM_SETFOCUS = CM_BASE + 14;
  2443. CM_CBN_SELCHANGE = 15;
  2444. CM_UIACTIVATE = CM_BASE + 16;
  2445. CM_UIDEACTIVATE = CM_BASE + 17;
  2446. CM_PROCESS = CM_BASE + 18;
  2447. CM_SHOW = CM_BASE + 19;
  2448. //CM_CLOSE = CM_BASE + 20;
  2449. CM_MDIClientShowEdge = CM_BASE + 21;
  2450. CM_INVALIDATECHILD = CM_BASE + 22;
  2451. CM_FOCUSGRAPHCTL = CM_BASE + 23;
  2452. //[CN_XXX CONSTANTS]
  2453. CN_BASE = $BC00;
  2454. CN_CHARTOITEM = CN_BASE + WM_CHARTOITEM;
  2455. CN_COMMAND = CN_BASE + WM_COMMAND;
  2456. CN_COMPAREITEM = CN_BASE + WM_COMPAREITEM;
  2457. CN_CTLCOLORMSGBOX = CN_BASE + WM_CTLCOLORMSGBOX;
  2458. CN_CTLCOLOREDIT = CN_BASE + WM_CTLCOLOREDIT;
  2459. CN_CTLCOLORLISTBOX = CN_BASE + WM_CTLCOLORLISTBOX;
  2460. CN_CTLCOLORBTN = CN_BASE + WM_CTLCOLORBTN;
  2461. CN_CTLCOLORDLG = CN_BASE + WM_CTLCOLORDLG;
  2462. CN_CTLCOLORSCROLLBAR = CN_BASE + WM_CTLCOLORSCROLLBAR;
  2463. CN_CTLCOLORSTATIC = CN_BASE + WM_CTLCOLORSTATIC;
  2464. CN_DELETEITEM = CN_BASE + WM_DELETEITEM;
  2465. CN_DRAWITEM = CN_BASE + WM_DRAWITEM;
  2466. CN_HSCROLL = CN_BASE + WM_HSCROLL;
  2467. CN_MEASUREITEM = CN_BASE + WM_MEASUREITEM;
  2468. CN_PARENTNOTIFY = CN_BASE + WM_PARENTNOTIFY;
  2469. CN_VKEYTOITEM = CN_BASE + WM_VKEYTOITEM;
  2470. CN_VSCROLL = CN_BASE + WM_VSCROLL;
  2471. CN_KEYDOWN = CN_BASE + WM_KEYDOWN;
  2472. CN_KEYUP = CN_BASE + WM_KEYUP;
  2473. CN_CHAR = CN_BASE + WM_CHAR;
  2474. CN_SYSKEYDOWN = CN_BASE + WM_SYSKEYDOWN;
  2475. CN_SYSCHAR = CN_BASE + WM_SYSCHAR;
  2476. CN_NOTIFY = CN_BASE + WM_NOTIFY;
  2477. //[ID_SELF DEFINED]
  2478. ID_SELF: array[ 0..5 ] of Char = ( 'S','E','L','F','_',#0 );
  2479. {* Identifier for window property "Self", stored directly in window, when
  2480. it is created. This property is used to [fast] find TControl object,
  2481. correspondent to given window handle (using API call GetProp). }
  2482. //[ID_PREVPROC DEFINED]
  2483. ID_PREVPROC: array[ 0..9 ] of Char = ( 'P','R','E','V','_','P','R','O','C',#0 );
  2484. {* }
  2485. //[MK_ALT DEFINED]
  2486. MK_ALT = $20;
  2487. //[RICHEDIT STRUCTURES]
  2488. type
  2489. TCharFormat2A = packed record
  2490. cbSize: UINT;
  2491. dwMask: DWORD;
  2492. dwEffects: DWORD;
  2493. yHeight: Longint;
  2494. yOffset: Longint;
  2495. crTextColor: TColorRef;
  2496. bCharSet: Byte;
  2497. bPitchAndFamily: Byte;
  2498. szFaceName: array[0..LF_FACESIZE - 1] of AnsiChar;
  2499. R2Bytes: Word;
  2500. wWeight: Word; { Font weight (LOGFONT value) }
  2501. sSpacing: Smallint; { Amount to space between letters }
  2502. crBackColor: TColorRef; { Background color }
  2503. lid: LCID; { Locale ID }
  2504. dwReserved: DWORD; { Reserved. Must be 0 }
  2505. sStyle: Smallint; { Style handle }
  2506. wKerning: Word; { Twip size above which to kern char pair }
  2507. bUnderlineType: Byte; { Underline type }
  2508. bAnimation: Byte; { Animated text like marching ants }
  2509. bRevAuthor: Byte; { Revision author index }
  2510. bReserved1: Byte;
  2511. end;
  2512. TCharFormat2 = TCharFormat2A;
  2513. TParaFormat2 = packed record
  2514. cbSize: UINT;
  2515. dwMask: DWORD;
  2516. wNumbering: Word;
  2517. wReserved: Word;
  2518. dxStartIndent: Longint;
  2519. dxRightIndent: Longint;
  2520. dxOffset: Longint;
  2521. wAlignment: Word;
  2522. cTabCount: Smallint;
  2523. rgxTabs: array [0..MAX_TAB_STOPS - 1] of Longint;
  2524. dySpaceBefore: Longint; { Vertical spacing before para }
  2525. dySpaceAfter: Longint; { Vertical spacing after para }
  2526. dyLineSpacing: Longint; { Line spacing depending on Rule }
  2527. sStyle: Smallint; { Style handle }
  2528. bLineSpacingRule: Byte; { Rule for line spacing (see tom.doc) }
  2529. bCRC: Byte; { Reserved for CRC for rapid searching }
  2530. wShadingWeight: Word; { Shading in hundredths of a per cent }
  2531. wShadingStyle: Word; { Nibble 0: style, 1: cfpat, 2: cbpat }
  2532. wNumberingStart: Word; { Starting value for numbering }
  2533. wNumberingStyle: Word; { Alignment, roman/arabic, (), ), ., etc. }
  2534. wNumberingTab: Word; { Space bet 1st indent and 1st-line text }
  2535. wBorderSpace: Word; { Space between border and text (twips) }
  2536. wBorderWidth: Word; { Border pen width (twips) }
  2537. wBorders: Word; { Byte 0: bits specify which borders }
  2538. { Nibble 2: border style, 3: color index }
  2539. end;
  2540. TGetTextLengthEx = packed record
  2541. flags: DWORD; { flags (see GTL_XXX defines) }
  2542. codepage: UINT; { code page for translation (CP_ACP for default,
  2543. 1200 for Unicode }
  2544. end;
  2545. const
  2546. PFM_SPACEBEFORE = $00000040;
  2547. PFM_SPACEAFTER = $00000080;
  2548. PFM_LINESPACING = $00000100;
  2549. PFM_STYLE = $00000400;
  2550. PFM_BORDER = $00000800; { (*) }
  2551. PFM_SHADING = $00001000; { (*) }
  2552. PFM_NUMBERINGSTYLE = $00002000; { (*) }
  2553. PFM_NUMBERINGTAB = $00004000; { (*) }
  2554. PFM_NUMBERINGSTART = $00008000; { (*) }
  2555. PFM_RTLPARA = $00010000;
  2556. PFM_KEEP = $00020000; { (*) }
  2557. PFM_KEEPNEXT = $00040000; { (*) }
  2558. PFM_PAGEBREAKBEFORE = $00080000; { (*) }
  2559. PFM_NOLINENUMBER = $00100000; { (*) }
  2560. PFM_NOWIDOWCONTROL = $00200000; { (*) }
  2561. PFM_DONOTHYPHEN = $00400000; { (*) }
  2562. PFM_SIDEBYSIDE = $00800000; { (*) }
  2563. PFM_TABLE = $c0000000; { (*) }
  2564. EM_REDO = WM_USER + 84;
  2565. EM_AUTOURLDETECT = WM_USER + 91;
  2566. EM_GETAUTOURLDETECT = WM_USER + 92;
  2567. CFM_UNDERLINETYPE = $00800000; { (*) }
  2568. CFM_HIDDEN = $0100; { (*) }
  2569. CFM_BACKCOLOR = $04000000;
  2570. CFE_AUTOBACKCOLOR = CFM_BACKCOLOR;
  2571. GTL_USECRLF = 1; { compute answer using CRLFs for paragraphs }
  2572. GTL_PRECISE = 2; { compute a precise answer }
  2573. GTL_CLOSE = 4; { fast computation of a "close" answer }
  2574. GTL_NUMCHARS = 8; { return the number of characters }
  2575. GTL_NUMBYTES = 16; { return the number of _bytes_ }
  2576. EM_GETTEXTLENGTHEX = WM_USER + 95;
  2577. EM_SETLANGOPTIONS = WM_USER + 120;
  2578. EM_GETLANGOPTIONS = WM_USER + 121;
  2579. EM_SETEDITSTYLE = $400 + 204;
  2580. EM_GETEDITSTYLE = $400 + 205;
  2581. SES_EMULATESYSEDIT = 1;
  2582. SES_BEEPONMAXTEXT = 2;
  2583. SES_EXTENDBACKCOLOR = 4;
  2584. SES_MAPCPS = 8;
  2585. SES_EMULATE10 = 16;
  2586. SES_USECRLF = 32;
  2587. SES_USEAIMM = 64;
  2588. SES_NOIME = 128;
  2589. SES_ALLOWBEEPS = 256;
  2590. SES_UPPERCASE = 512;
  2591. SES_LOWERCASE = 1024;
  2592. SES_NOINPUTSEQUENCECHK = 2048;
  2593. SES_BIDI = 4096;
  2594. SES_SCROLLONKILLFOCUS = 8192;
  2595. SES_XLTCRCRLFTOCR = 16384;
  2596. //[CONTROLS]
  2597. type
  2598. {++}(*TControl = class;*){--}
  2599. PControl = {-}^{+}TControl;
  2600. {* Type of pointer to TControl visual object. All
  2601. |<a href="kol_pas.htm#visual_objects_constructors">
  2602. constructing functions
  2603. |</a>
  2604. New[ControlName] are returning
  2605. pointer of this type. Do not forget about some difference
  2606. of using objects from using classes. Identifier Self for
  2607. methods of object is not of pointer type, and to pass
  2608. pointer to Self, it is necessary to pass @Self instead.
  2609. At the same time, to use pointer to object in 'WITH' operator,
  2610. it is necessary to apply suffix '^' to pointer to get know
  2611. to compiler, what do You want. }
  2612. //[TWindowFunc TYPE]
  2613. TWindowFunc = function( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  2614. : Boolean;
  2615. {* Event type to define custom extended message handlers (as pointers to
  2616. procedure entry points). Such handlers are usually defined like add-ons,
  2617. extending behaviour of certain controls and attached using AttachProc
  2618. method of TControl. If the handler detects, that it is necessary to stop
  2619. further message processing, it should return True. }
  2620. //[Mouse TYPES]
  2621. TMouseButton = ( mbNone, mbLeft, mbRight, mbMiddle );
  2622. {* Available mouse buttons. mbNone is useful to get know, that
  2623. there were no mouse buttons pressed. }
  2624. TMouseEventData = packed Record
  2625. {* Record to pass it to mouse handling routines, assigned to OnMouseXXXX
  2626. events. }
  2627. Button: TMouseButton;
  2628. StopHandling: Boolean; // Set it to True in OnMouseXXXX event handler to
  2629. // stop further processing
  2630. R1, R2: Byte; // Not used
  2631. Shift : DWORD; // HiWord( Shift ) = zDelta in WM_MOUSEWHEEL
  2632. X, Y : SmallInt;
  2633. end;
  2634. TOnMouse = procedure( Sender: PControl; var Mouse: TMouseEventData ) of object;
  2635. {* Common mouse handling event type. }
  2636. //[Key TYPES]
  2637. TOnKey = procedure( Sender: PControl; var Key: Longint; Shift: DWORD ) of object;
  2638. {* Key events. Shift is a combination of flags MK_SHIFT, MK_CONTROL, MK_ALT.
  2639. (See GetShiftState funtion). }
  2640. TOnChar = procedure( Sender: PControl; var Key: Char; Shift: DWORD ) of object;
  2641. {* Char event. Shift is a combination of flags MK_SHIFT, MK_CONTROL, MK_ALT. }
  2642. TTabKey = ( tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn );
  2643. {* Available tabulating key groups. }
  2644. TTabKeys = Set of TTabKey;
  2645. {* Set of tabulating key groups, allowed to be used in with a control
  2646. (are installed by TControl.LookTabKey property). }
  2647. //[Event TYPES]
  2648. TOnMessage = function( var Msg: TMsg; var Rslt: Integer ): Boolean of object;
  2649. {* Event type for events, which allows to extend behaviour of windowed controls
  2650. descendants using add-ons. }
  2651. TOnEventAccept = procedure( Sender: PObj; var Accept: Boolean ) of object;
  2652. {* Event type for OnClose event. }
  2653. TCloseQueryReason = ( qClose, qShutdown, qLogoff );
  2654. {* Request reason type to call OnClose and OnQueryEndSession. }
  2655. TWindowState = ( wsNormal, wsMinimized, wsMaximized );
  2656. {* Avalable states of TControl's window object. }
  2657. TOnSplit = function( Sender: PControl; NewSize1, NewSize2: Integer ): Boolean of object;
  2658. {* Event type for OnSplit event handler, designed specially for splitter
  2659. control. Event handler must return True to accept new size of previous
  2660. (to splitter) control and new size of the rest of client area of parent. }
  2661. TOnTVBeginDrag = procedure( Sender: PControl; Item: THandle ) of object;
  2662. {* Event type for OnTVBeginDrag event (defined for tree view control). }
  2663. TOnTVBeginEdit = function( Sender: PControl; Item: THandle ): Boolean of object;
  2664. {* Event type for OnTVBeginEdit event (for tree view control). }
  2665. TOnTVEndEdit = function( Sender: PControl; Item: THandle; const NewTxt: String )
  2666. : Boolean of object;
  2667. {* Event type for TOnTVEndEdit event. }
  2668. TOnTVExpanding = function( Sender: PControl; Item: THandle; Expand: Boolean )
  2669. : Boolean of object;
  2670. {* Event type for TOnTVExpanding event. }
  2671. TOnTVExpanded = procedure( Sender: PControl; Item: THandle; Expand: Boolean )
  2672. of object;
  2673. {* Event type for OnTVExpanded event. }
  2674. TOnTVDelete = procedure( Sender: PControl; Item: THandle ) of object;
  2675. {* Event type for OnTVDelete event. }
  2676. //--------- by Sergey Shisminzev:
  2677. TOnTVSelChanging = function(Sender: PControl; oldItem, newItem: THandle): Boolean //~ss
  2678. of object;
  2679. {* When the handler returns False, selection is not changed. }
  2680. //-------------------------------
  2681. TOnDrag = function( Sender: PControl; ScrX, ScrY: Integer; var CursorShape: Integer;
  2682. var Stop: Boolean ): Boolean of object;
  2683. {* Event, called during dragging operation (it is initiated
  2684. with method Drag, where callback function of type TOnDrag is
  2685. passed as a parameter). Callback function receives Stop parameter True,
  2686. when operation is finishing. Otherwise, it can set it to True to force
  2687. finishing the operation (in such case, returning False means cancelling
  2688. drag operation, True - successful drag and in this last case callback is
  2689. no more called). During the operation, when input Stop value is False,
  2690. callback function can control Cursor shape, and return True, if the operation
  2691. can be finished successfully at the given ScrX, ScrY position.
  2692. ScrX, ScrY are screen coordinates of the mouse cursor. }
  2693. //[Create Window STRUCTURES]
  2694. TCreateParams = packed record
  2695. {* Record to pass it through CreateSubClass method. }
  2696. Caption: PChar;
  2697. Style: cardinal;
  2698. ExStyle: cardinal;
  2699. X, Y: Integer;
  2700. Width, Height: Integer;
  2701. WndParent: HWnd;
  2702. Param: Pointer;
  2703. WindowClass: TWndClass;
  2704. WinClassName: array[0..63] of Char;
  2705. end;
  2706. TCreateWndParams = packed Record
  2707. ExStyle: DWORD;
  2708. WinClassName: PChar;
  2709. Caption: PChar;
  2710. Style: DWORD;
  2711. X, Y, Width, Height: Integer;
  2712. WndParent: HWnd;
  2713. Menu: HMenu;
  2714. Inst: THandle;
  2715. Param: Pointer;
  2716. WinClsNamBuf: array[ 0..63 ] of Char;
  2717. WindowClass: TWndClass;
  2718. end;
  2719. //[COMMAND ACTIONS TYPE FOR DIFFERENT CONTROLS]
  2720. PCommandActions = ^TCommandActions;
  2721. TCommandActions = packed Record
  2722. aClear: procedure( Sender: PControl );
  2723. aAddText: procedure( Sender: PControl; const S: String );
  2724. aClick, aEnter, aLeave: WORD; aChange: SmallInt; aSelChange: SmallInt;
  2725. aGetCount, aSetCount, aGetItemLength, aGetItemText, aSetItemText,
  2726. aGetItemData, aSetItemData: WORD;
  2727. aAddItem, aDeleteItem, aInsertItem: WORD;
  2728. aFindItem, aFindPartial: WORD;
  2729. aItem2Pos, aPos2Item: BYTE;
  2730. aGetSelCount, aGetSelected, aGetSelRange, aExGetSelRange, aGetCurrent,
  2731. aSetSelected, aSetCurrent, aSetSelRange, aExSetSelRange,
  2732. aGetSelection, aReplaceSel: WORD;
  2733. aTextAlignLeft, aTextAlignRight, aTextAlignCenter: WORD;
  2734. aTextAlignMask: Byte;
  2735. aVertAlignCenter, aVertAlignTop, aVertAlignBottom: Byte;
  2736. aDir, aSetLimit: Word; aSetImgList: Word;
  2737. aAutoSzX, aAutoSzY: Word;
  2738. aSetBkColor: Word;
  2739. aItem2XY: Word;
  2740. end;
  2741. //[Align TYPES]
  2742. TTextAlign = ( taLeft, taRight, taCenter );
  2743. {* Text alignments available. }
  2744. TRichTextAlign = ( raLeft, raRight, raCenter,
  2745. // all other are only set but can not be displayed:
  2746. raJustify, // displayed like raLeft (though stored normally)
  2747. raInterLetter, raScaled, raGlyphs, raSnapGrid );
  2748. {* Text alignment styles, available for RichEdit control. }
  2749. TVerticalAlign = ( vaCenter, vaTop, vaBottom );
  2750. {* Vertical alignments available. }
  2751. TControlAlign = ( caNone, caLeft, caTop, caRight, caBottom, caClient );
  2752. {* Control alignments available. }
  2753. //[BitBtn TYPES]
  2754. TBitBtnOption = ( bboImageList,
  2755. bboNoBorder,
  2756. bboNoCaption,
  2757. bboFixed );
  2758. {* Options available for NewBitBtn. }
  2759. TBitBtnOptions = set of TBitBtnOption;
  2760. {* Set of options, available for NewBitBtn. }
  2761. TGlyphLayout = ( glyphLeft, glyphTop, glyphRight, glyphBottom, glyphOver );
  2762. {* Layout of glyph (for NewBitBtn). Layout glyphOver means that text is
  2763. drawn over glyph. }
  2764. TOnBitBtnDraw = function( Sender: PControl; BtnState: Integer ): Boolean of object;
  2765. {* Event type for TControl.OnBitBtnDraw event (which is called just before
  2766. drawing the BitBtn). If handler returns True, there are no drawing occure.
  2767. BtnState, passed to a handler, determines current button state and can
  2768. be following: 0 - not pressed, 1 - pressed, 2 - disabled, 3 - focused.
  2769. Value 4 is reserved for highlight state (then mouse is over it), but
  2770. highlighting is provided only if property Flat is set to True (or one
  2771. of events OnMouseEnter / OnMouseLeave is assigned to something). }
  2772. //[ListView TYPES]
  2773. TListViewStyle = ( lvsIcon, lvsSmallIcon, lvsList, lvsDetail, lvsDetailNoHeader );
  2774. {* Styles of view for ListView control (see NewListVew). }
  2775. TListViewItemStates = ( lvisFocus, lvisSelect, lvisBlend, lvisHighlight );
  2776. TListViewItemState = Set of TListViewItemStates;
  2777. TListViewOption = (
  2778. lvoIconLeft, // in lvsIcon, lvsSmallIcon plce icon left from text (rather then top)
  2779. lvoAutoArrange, // keep icons auto arranged in lvsIcon and lvsSmallIcon view
  2780. lvoButton, // icons look like buttons in lvsIcon view
  2781. lvoEditLabel, // allows edit labels inplace (first column #0 text)
  2782. lvoNoLabelWrap, // item text on a single line in lvsIcon view (by default, item text may wrap in lvsIcon view).
  2783. lvoNoScroll, // obvious
  2784. lvoNoSortHeader, // click on header button does not lead to sort items
  2785. lvoHideSel, // hide selection when not in focus
  2786. lvoMultiselect, // allow to select multiple items
  2787. lvoSortAscending,
  2788. lvoSortDescending,
  2789. // extended styles (not documented in my Win32.hlp :( , got from VCL source:
  2790. lvoGridLines,
  2791. lvoSubItemImages,
  2792. lvoCheckBoxes,
  2793. lvoTrackSelect,
  2794. lvoHeaderDragDrop,
  2795. lvoRowSelect,
  2796. lvoOneClickActivate,
  2797. lvoTwoClickActivate,
  2798. lvoFlatsb,
  2799. lvoRegional,
  2800. lvoInfoTip,
  2801. lvoUnderlineHot,
  2802. lvoMultiWorkares,
  2803. // virtual list view style:
  2804. lvoOwnerData,
  2805. // custom draw style:
  2806. lvoOwnerDrawFixed
  2807. );
  2808. TListViewOptions = Set of TListViewOption;
  2809. TOnEditLVItem = function( Sender: PControl; Idx, Col: Integer; NewText: PChar ): Boolean
  2810. of object;
  2811. {* Event type for OnEndEditLVItem. Return True in handler to accept new text value. }
  2812. TOnDeleteLVItem = procedure( Sender: PControl; Idx: Integer ) of object;
  2813. {* Event type for OnDeleteLVItem event. }
  2814. TOnLVData = procedure( Sender: PControl; Idx, SubItem: Integer;
  2815. var Txt: String; var ImgIdx: Integer; var State: DWORD;
  2816. var Store: Boolean ) of object;
  2817. {* Event type for OnLVData event. Used to provide virtual list view control
  2818. (i.e. having lvoOwnerData style) with actual data on request. Use parameter
  2819. Store as a flag if control should store obtained data by itself or not. }
  2820. {$IFNDEF _D2}
  2821. {$IFNDEF _FPC}
  2822. TOnLVDataW = procedure( Sender: PControl; Idx, SubItem: Integer;
  2823. var Txt: WideString; var ImgIdx: Integer; var State: DWORD;
  2824. var Store: Boolean ) of object;
  2825. {* Event type for OnLVDataW event (the same as OnLVData, but for unicode verion
  2826. of the control OnLVDataW allows to return WideString text in the event
  2827. handler). Used to provide virtual list view control
  2828. (i.e. having lvoOwnerData style) with actual data on request. Use parameter
  2829. Store as a flag if control should store obtained data by itself or not. }
  2830. {$ENDIF _FPC}
  2831. {$ENDIF _D2}
  2832. TOnCompareLVItems = function( Sender: PControl; Idx1, Idx2: Integer ): Integer
  2833. of object;
  2834. {* Event type to compare two items of the list view (while sorting it). }
  2835. TOnLVColumnClick = procedure( Sender: PControl; Idx: Integer ) of object;
  2836. {* Event type for OnColumnClick event. }
  2837. TOnLVStateChange = procedure( Sender: PControl; IdxFrom, IdxTo: Integer; OldState, NewState: DWORD )
  2838. of object;
  2839. {* Event type for OnLVStateChange event, called in responce to select/unselect
  2840. a single item or items range in list view control). }
  2841. TOnLVDelete = procedure( Sender: PControl; Idx: Integer ) of object;
  2842. {* Event type for OnLVDelete event, called when an item is been deleting. }
  2843. TDrawActions = ( odaEntire, odaFocus, odaSelect );
  2844. TDrawAction = Set of TDrawActions;
  2845. TDrawStates = ( odsSelected, odsGrayed, odsDisabled, odsChecked, odsFocused,
  2846. odsDefault, odsHotlist, odsInactive,
  2847. odsNoAccel, odsNoFocusRect,
  2848. ods400reserved, ods800reserved,
  2849. odsComboboxEdit,
  2850. // specific for common controls:
  2851. odsMarked, odsIndeterminate );
  2852. {* Possible draw states.
  2853. |<br>odsSelected - The menu item's status is selected.
  2854. |<br>odsGrayed - The item is to be grayed. This bit is used only in a menu.
  2855. |<br>odsDisabled - The item is to be drawn as disabled.
  2856. |<br>odsChecked - The menu item is to be checked. This bit is used only in
  2857. a menu.
  2858. |<br>odsFocused - The item has the keyboard focus.
  2859. |<br>odsDefault - The item is the default item.
  2860. |<br>odsHotList - <b>Windows 98, Windows 2000:</b> The item is being
  2861. hot-tracked, that is, the item will be highlighted when
  2862. the mouse is on the item.
  2863. |<br>odsInactive - <b>Windows 98, Windows 2000:</b> The item is inactive
  2864. and the window associated with the menu is inactive.
  2865. |<br>odsNoAccel - <b>Windows 2000:</b> The control is drawn without the
  2866. keyboard accelerator cues.
  2867. |<br>odsNoFocusRect - <b>Windows 2000:</b> The control is drawn without
  2868. focus indicator cues.
  2869. |<br>odsComboboxEdit - The drawing takes place in the selection field
  2870. (edit control) of an owner-drawn combo box.
  2871. |<br>odsMarked - for Common controls only. The item is marked. The meaning
  2872. of this is up to the implementation.
  2873. |<br>odsIndeterminate - for Common Controls only. The item is in an
  2874. indeterminate state. }
  2875. TDrawState = Set of TDrawStates;
  2876. {* Set of possible draw states. }
  2877. TOnDrawItem = function( Sender: PObj; DC: HDC; const Rect: TRect; ItemIdx: Integer;
  2878. DrawAction: TDrawAction; ItemState: TDrawState ): Boolean of object;
  2879. {* Event type for OnDrawItem event (applied to list box, combo box, list view). }
  2880. TOnMeasureItem = function( Sender: PObj; Idx: Integer ): Integer of object;
  2881. {* Event type for OnMeasureItem event. The event handler must return height of list box
  2882. item as a result. }
  2883. TGetLVItemPart = ( lvipBounds, lvipIcon, lvipLabel, lvupIconAndLabel );
  2884. {* }
  2885. TWherePosLVItem = ( lvwpOnIcon, lvwpOnLabel, lvwpOnStateIcon, lvwpOnColumn,
  2886. lvwpOnItem );
  2887. {* }
  2888. TOnLVCustomDraw = function( Sender: PControl; DC: HDC; Stage: DWORD;
  2889. ItemIdx, SubItemIdx: Integer; const Rect: TRect;
  2890. ItemState: TDrawState; var TextColor, BackColor: TColor )
  2891. : DWORD of object;
  2892. {* Event type for OnLVCustomDraw event. }
  2893. //[Paint TYPES]
  2894. TOnPaint = procedure( Sender: PControl; DC: HDC ) of object;
  2895. TPaintProc = procedure( DC: HDC ) of object;
  2896. TGradientStyle = ( gsVertical, gsHorizontal, gsRectangle, gsElliptic, gsRombic );
  2897. {* Gradient fill styles. See also TGradientLayout. }
  2898. TGradientLayout = ( glTopLeft, glTop, glTopRight,
  2899. glLeft, glCenter, glRight,
  2900. glBottomLeft, glBottom, glBottomRight );
  2901. {* Position of starting line / point for gradient filling. Depending on
  2902. TGradientStyle, means either position of first line of first rectangle
  2903. (ellipse) to be expanded in a loop to fit entire gradient panel area. }
  2904. //[Edit TYPES]
  2905. TEditOption = ( eoNoHScroll, eoNoVScroll, eoLowercase, eoMultiline,
  2906. eoNoHideSel, eoOemConvert, eoPassword, eoReadonly,
  2907. eoUpperCase, eoWantReturn, eoWantTab, eoNumber );
  2908. {* Available edit options.
  2909. |<br> Please note, that eoWantTab option just removes TAB key from a list
  2910. of keys available to tabulate from the edit control. To provide insertion
  2911. of tabulating key, do so in TControl.OnChar event handler. Sorry for
  2912. inconvenience, but this is because such behaviour is not must in all cases.
  2913. See also TControl.EditTabChar property. }
  2914. TEditOptions = Set of TEditOption;
  2915. {* Set of available edit options. }
  2916. TRichFmtArea = ( raSelection, raWord, raAll );
  2917. {* Characters formatting area for RichEdit. }
  2918. TRETextFormat = ( reRTF, reText, rePlainRTF, reRTFNoObjs, rePlainRTFNoObjs,
  2919. reTextized );
  2920. {* Available formats for transfer RichEdit text using property
  2921. TControl.RE_Text.
  2922. |<pre>
  2923. reRTF - normal rich text (no transformations)
  2924. reText - plain text only (without OLE objects)
  2925. reTextized - plain text with text representation of OLE objects
  2926. rePlainRTF - reRTF without language-specific keywords
  2927. reRTFNoObjs - reRTF without OLE objects
  2928. rePlainRTFNoObjs - rePlainRTF without OLE objects
  2929. |</pre> }
  2930. TRichUnderline = ( ruSingle, ruWord, ruDouble, ruDotted,
  2931. //all other - only for RichEditv3.0:
  2932. ruDash, ruDashDot, ruDashDotDot, ruWave, ruThick, ruHairLine );
  2933. {* Rich text exteded underline styles (available only for RichEdit v2.0,
  2934. and even for RichEdit v2.0 additional styles can not displayed - but
  2935. ruDotted under Windows2000 is working). }
  2936. TRichTextSizes = ( rtsNoUseCRLF, rtsNoPrecise, rtsClose, rtsBytes );
  2937. {* Options to calculate size of rich text. Available only for RichEdit2.0
  2938. or higher. }
  2939. TRichTextSize = set of TRichTextSizes;
  2940. {* Set of all available optioins to calculate rich text size using
  2941. property TControl.RE_TextSize[ options ]. }
  2942. TRichNumbering = ( rnNone, rnBullets, rnArabic, rnLLetter, rnULetter,
  2943. rnLRoman, rnURoman );
  2944. {* Advanced numbering styles for paragraph (RichEdit).
  2945. |<pre>
  2946. rnNone - no numbering
  2947. rnBullets - bullets only
  2948. rnArabic - 1, 2, 3, 4, ...
  2949. rnLLetter - a, b, c, d, ...
  2950. rnULetter - A, B, C, D, ...
  2951. rnLRoman - i, ii, iii, iv, ...
  2952. rnURoman - I, II, III, IV, ...
  2953. rnNoNumber - do not show any numbers (but numbering is taking place).
  2954. |</pre> }
  2955. TRichNumBrackets = ( rnbRight, rnbBoth, rnbPeriod, rnbPlain, rnbNoNumber );
  2956. {* Brackets around number:
  2957. |<pre>
  2958. rnbRight - 1) 2) 3) - this is default !
  2959. rnbBoth - (1) (2) (3)
  2960. rnbPeriod - 1. 2. 3.
  2961. rnbPlain - 1 2 3
  2962. |</pre> }
  2963. TBorderEdge = (beLeft, beTop, beRight, beBottom);
  2964. {* Borders of rectangle. }
  2965. TCharFormat = TCharFormat2;
  2966. TParaFormat = TParaFormat2;
  2967. TOnTestMouseOver = function( Sender: PControl ): Boolean of object;
  2968. {* Event type for TControl.OnTestMouseOver event. The handler should
  2969. return True, if it dectects, that mouse is over control. }
  2970. TEdgeStyle = ( esRaised, esLowered, esNone );
  2971. {* Edge styles (for panel - see NewPanel). }
  2972. //[List TYPES]
  2973. TListOption = ( loNoHideScroll, loNoExtendSel, loMultiColumn, loMultiSelect,
  2974. loNoIntegralHeight, loNoSel, loSort, loTabstops,
  2975. loNoStrings, loNoData, loOwnerDrawFixed, loOwnerDrawVariable );
  2976. {* Options for ListBox (see NewListbox). }
  2977. TListOptions = Set of TListOption;
  2978. {* Set of available options for Listbox. }
  2979. TComboOption = ( coReadOnly, coNoHScroll, coAlwaysVScroll, coLowerCase,
  2980. coNoIntegralHeight, coOemConvert, coSort, coUpperCase,
  2981. coOwnerDrawFixed, coOwnerDrawVariable, coSimple );
  2982. {* Options for combobox. }
  2983. TComboOptions = Set of TComboOption;
  2984. {* Set of options available for combobox. }
  2985. //[Progress TYPES]
  2986. TProgressbarOption = ( pboVertical, pboSmooth );
  2987. {* Options for progress bar. }
  2988. TProgressbarOptions = set of TProgressbarOption;
  2989. {* Set of options available for progress bar. }
  2990. //[TreeView TYPES]
  2991. TTreeViewOption = ( tvoNoLines, tvoLinesRoot, tvoNoButtons, tvoEditLabels, tvoHideSel,
  2992. tvoDragDrop, tvoNoTooltips, tvoCheckBoxes, tvoTrackSelect,
  2993. tvoSingleExpand, tvoInfoTip, tvoFullRowSelect, tvoNoScroll,
  2994. tvoNonEvenHeight );
  2995. {* Tree view options. }
  2996. TTreeViewOptions = set of TTreeViewOption;
  2997. {* Set of tree view options. }
  2998. //[TabControl TYPES]
  2999. TTabControlOption = ( tcoButtons, tcoFixedWidth, tcoFocusTabs,
  3000. tcoIconLeft, tcoLabelLeft,
  3001. tcoMultiline, tcoMultiselect, tcoFitRows, tcoScrollOpposite,
  3002. tcoBottom, tcoVertical, tcoFlat, tcoHotTrack, tcoBorder,
  3003. tcoOwnerDrawFixed );
  3004. {* Options, available for TabControl. }
  3005. TTabControlOptions = set of TTabControlOption;
  3006. {* Set of options, available for TAbControl during its creation (by
  3007. NewTabControl function). }
  3008. //[Toolbar TYPES]
  3009. TToolbarOption = ( tboTextRight, tboTextBottom, tboFlat, tboTransparent,
  3010. tboWrapable, tboNoDivider, tbo3DBorder );
  3011. {* Toolbar options. When tboFlat is set and toolbar is placed onto panel,
  3012. set its property Transparent to TRUE to provide its correct view. }
  3013. TToolbarOptions = Set of TToolbarOption;
  3014. {* Set of toolbar options. }
  3015. TOnToolbarButtonClick = procedure( Sender: PControl; BtnID: Integer ) of object;
  3016. {* Special event type to handle separate toolbar buttons click events. }
  3017. TDateTimePickerOption = ( dtpoTime, dtpoDateLong, dtpoUpDown, dtpoRightAlign,
  3018. dtpoShowNone, dtpoParseInput );
  3019. {* }
  3020. TDateTimePickerOptions = set of TDateTimePickerOption;
  3021. {* }
  3022. TDTParseInputEvent = procedure(Sender: PControl; const UserString: string;
  3023. var DateAndTime: TDateTime; var AllowChange: Boolean) of object;
  3024. {* }
  3025. TDateTimeRange = array[ 0..1 ] of TDateTime;
  3026. {* }
  3027. TDateTimePickerColor = ( dtpcBackground, dtpcMonthBk, dtpcText, dtpcTitleBk,
  3028. dtpcTitleText, dtpcTrailingText );
  3029. //[TOnDropFiles TYPE]
  3030. TOnDropFiles = procedure( Sender: PControl; const FileList: String; const Pt: TPoint ) of object;
  3031. {* An event type for OnDropFiles event. When the event is occur, FileList
  3032. parameter contains a list of files dropped. File names in a list are
  3033. separated with #13 character. This allows You to assign it to TStrList
  3034. object using its property Text (for example):
  3035. ! procedure TSomeObject.DropFiles( Sender: PControl; const FileList: String;
  3036. ! const Pt: TPoint ); )
  3037. ! var FList: PStrList;
  3038. ! I: Integer;
  3039. ! begin
  3040. ! FList := NewStrList;
  3041. ! FList.Text := FileList;
  3042. ! for I := 0 to FList.Count-1 do
  3043. ! begin
  3044. ! // do something with FList.Items[ I ]
  3045. ! end;
  3046. ! FList.Free;
  3047. ! end; }
  3048. //[Scroll TYPES]
  3049. TScrollerBar = ( sbHorizontal, sbVertical );
  3050. TScrollerBars = set of TScrollerBar;
  3051. TOnScroll = procedure( Sender: PControl; Bar: TScrollerBar; ScrollCmd: DWORD;
  3052. ThumbPos: DWORD ) of object;
  3053. //[TOnHelp EVENT TYPE]
  3054. TOnHelp = procedure( var Sender: PControl; var Context: Integer; var Popup: Boolean )
  3055. of object;
  3056. //[ScrollBar TYPES]
  3057. TOnSBBeforeScroll =
  3058. procedure(
  3059. Sender: PControl; OldPos, NewPos: Integer; Cmd: Word;
  3060. var AllowChange: Boolean) of object;
  3061. TOnSBScroll = procedure(Sender: PControl; Cmd: Word) of object;
  3062. TOnGraphCtlMouse = procedure( var Msg: TMsg ) of object;
  3063. TTriStateCheck = (tsUnchecked{=0}, tsChecked{=1}, tsIndeterminate{=2});
  3064. {$IFDEF USE_MHTOOLTIP}
  3065. {$DEFINE pre_interface}
  3066. {$I KOLMHToolTip}
  3067. {$UNDEF pre_interface}
  3068. {$ENDIF}
  3069. { ----------------------------------------------------------------------
  3070. TControl - object to implement any visual control
  3071. ----------------------------------------------------------------------- }
  3072. //[TControl DEFINITION]
  3073. TControl = object( TObj )
  3074. protected
  3075. fSBMinMax: TPoint;
  3076. fSBPageSize: Integer;
  3077. fSBPosition: Integer;
  3078. procedure SetSBMax(Value: Longint);
  3079. procedure SetSBMin(Value: Longint);
  3080. procedure SetSBPageSize(Value: Integer);
  3081. procedure SetSBPosition(Value: Integer);
  3082. procedure SetSBMinMax(const Value: TPoint);
  3083. function GetDate: TDateTime;
  3084. function GetTime: TDateTime;
  3085. procedure SetDate(const Value: TDateTime);
  3086. procedure SetTime(const Value: TDateTime);
  3087. {*! TControl is the basic visual object of KOL. And now, all visual
  3088. objects have the same type PControl, differing only in "constructor",
  3089. which during creating of object adjusts it so it can play role of
  3090. desired control. Idea of incapsulating of all visual objects having
  3091. the most common set of properties, is belonging to Vladimir Kladov,
  3092. (C) 2000.
  3093. |<br>&nbsp;&nbsp;&nbsp;<b> Since all visual objects are represented
  3094. in KOL by this single object type, not all methods, properties and
  3095. events defined in TControl, are applicable to different visual objects.
  3096. See also notes about certain control kinds, located together with its
  3097. |<a href="kol_pas.htm#visual_objects_constructors">
  3098. |constructing functions definitions</a></b>. }
  3099. protected
  3100. function GetHelpPath: String;
  3101. procedure SetHelpPath(const Value: String);
  3102. procedure SetOnQueryEndSession(const Value: TOnEventAccept);
  3103. procedure SetOnMinMaxRestore(const Index: Integer; const Value: TOnEvent);
  3104. procedure SetConstraint(const Index, Value: Integer);
  3105. {$IFDEF F_P}
  3106. function GetOnMinMaxRestore(const Index: Integer): TOnEvent;
  3107. function GetConstraint(const Index: Integer): Integer;
  3108. {$ENDIF F_P}
  3109. procedure SetOnScroll(const Value: TOnScroll);
  3110. function GetLVColalign(Idx: Integer): TTextAlign;
  3111. procedure SetLVColalign(Idx: Integer; const Value: TTextAlign);
  3112. procedure SetParent( Value: PControl );
  3113. function GetLeft: Integer;
  3114. procedure SetLeft( Value: Integer );
  3115. function GetTop: Integer;
  3116. procedure SetTop( Value: Integer );
  3117. function GetWidth: Integer;
  3118. procedure SetWidth( Value: Integer );
  3119. function GetHeight: Integer;
  3120. procedure SetHeight( Value: Integer );
  3121. function GetPosition: TPoint;
  3122. procedure Set_Position( Value: TPoint );
  3123. function GetMembers(Idx: Integer): PControl;
  3124. function GetFont: PGraphicTool;
  3125. procedure FontChanged( Sender: PGraphicTool );
  3126. function GetBrush: PGraphicTool;
  3127. procedure BrushChanged( Sender: PGraphicTool );
  3128. function GetClientHeight: Integer;
  3129. function GetClientWidth: Integer;
  3130. procedure SetClientHeight(const Value: Integer);
  3131. procedure SetClientWidth(const Value: Integer);
  3132. function GetHasBorder: Boolean;
  3133. procedure SetHasBorder(const Value: Boolean);
  3134. function GetHasCaption: Boolean;
  3135. procedure SetHasCaption(const Value: Boolean);
  3136. function GetCanResize: Boolean;
  3137. procedure SetCanResize( const Value: Boolean );
  3138. function GetStayOnTop: Boolean;
  3139. procedure SetStayOnTop(const Value: Boolean);
  3140. function GetChecked: Boolean;
  3141. procedure Set_Checked(const Value: Boolean);
  3142. function GetCheck3: TTriStateCheck;
  3143. procedure SetCheck3(value: TTriStateCheck);
  3144. function GetSelStart: Integer;
  3145. procedure SetSelStart(const Value: Integer);
  3146. function GetSelLength: Integer;
  3147. procedure SetSelLength(const Value: Integer);
  3148. function GetItems(Idx: Integer): String;
  3149. procedure SetItems(Idx: Integer; const Value: String);
  3150. function GetItemsCount: Integer;
  3151. function GetItemSelected(ItemIdx: Integer): Boolean;
  3152. procedure SetItemSelected(ItemIdx: Integer; const Value: Boolean);
  3153. procedure SetCtl3D(const Value: Boolean);
  3154. function GetCurIndex: Integer;
  3155. procedure SetCurIndex(const Value: Integer);
  3156. function GetTextAlign: TTextAlign;
  3157. function GetVerticalAlign: TVerticalAlign;
  3158. procedure SetTextAlign(const Value: TTextAlign);
  3159. procedure SetVerticalAlign(const Value: TVerticalAlign);
  3160. function GetCanvas: PCanvas;
  3161. function Dc2Canvas( Sender: PCanvas ): HDC;
  3162. procedure SetShadowDeep(const Value: Integer);
  3163. procedure SetDoubleBuffered(const Value: Boolean);
  3164. procedure SetStatusText(Index: Integer; Value: PChar);
  3165. function GetStatusText( Index: Integer ): PChar;
  3166. function GetStatusPanelX(Idx: Integer): Integer;
  3167. procedure SetStatusPanelX(Idx: Integer; const Value: Integer);
  3168. procedure SetTransparent(const Value: Boolean);
  3169. function GetImgListIdx(const Index: Integer): PImageList;
  3170. procedure SetImgListIdx(const Index: Integer; const Value: PImageList);
  3171. function GetLVColText(Idx: Integer): String;
  3172. procedure SetLVColText(Idx: Integer; const Value: String);
  3173. {$IFNDEF _FPC}
  3174. {$IFNDEF _D2}
  3175. function GetLVColTextW(Idx: Integer): WideString;
  3176. procedure SetLVColTextW(Idx: Integer; const Value: WideString);
  3177. {$ENDIF _D2}
  3178. {$ENDIF _FPC}
  3179. function LVGetItemText(Idx, Col: Integer): String;
  3180. procedure LVSetItemText(Idx, Col: Integer; const Value: String);
  3181. {$IFNDEF _FPC}
  3182. {$IFNDEF _D2}
  3183. function LVGetItemTextW(Idx, Col: Integer): WideString;
  3184. procedure LVSetItemTextW(Idx, Col: Integer; const Value: WideString);
  3185. {$ENDIF _D2}
  3186. {$ENDIF _FPC}
  3187. procedure SetLVOptions(const Value: TListViewOptions);
  3188. procedure SetLVStyle(const Value: TListViewStyle);
  3189. function GetLVColEx(Idx: Integer; const Index: Integer): Integer;
  3190. procedure SetLVColEx(Idx: Integer; const Index: Integer;
  3191. const Value: Integer);
  3192. function GetChildCount: Integer;
  3193. function LVGetItemPos(Idx: Integer): TPoint;
  3194. procedure LVSetItemPos(Idx: Integer; const Value: TPoint);
  3195. procedure LVSetColorByIdx(const Index: Integer; const Value: TColor);
  3196. {$IFDEF F_P}
  3197. function LVGetColorByIdx(const Index: Integer): TColor;
  3198. {$ENDIF F_P}
  3199. function GetIntVal(const Index: Integer): Integer;
  3200. procedure SetIntVal(const Index, Value: Integer);
  3201. function GetItemVal(Item: Integer; const Index: Integer): Integer;
  3202. procedure SetItemVal(Item: Integer; const Index, Value: Integer);
  3203. function TBGetButtonVisible(BtnID: Integer): Boolean;
  3204. procedure TBSetButtonVisible(BtnID: Integer; const Value: Boolean);
  3205. function TBGetBtnStt(BtnID: Integer; const Index: Integer): Boolean;
  3206. procedure TBSetBtnStt(BtnID: Integer; const Index: Integer; const Value: Boolean);
  3207. function TBGetButtonText(BtnID: Integer): String;
  3208. function TBGetButtonRect(BtnID: Integer): TRect;
  3209. function TBGetRows: Integer;
  3210. procedure TBSetRows(const Value: Integer);
  3211. procedure SetProgressColor(const Value: TColor);
  3212. function TBGetBtnImgIdx(BtnID: Integer): Integer;
  3213. procedure TBSetBtnImgIdx(BtnID: Integer; const Value: Integer);
  3214. procedure TBSetButtonText(BtnID: Integer; const Value: String);
  3215. function TBGetBtnWidth(BtnID: Integer): Integer;
  3216. procedure TBSetBtnWidth(BtnID: Integer; const Value: Integer);
  3217. procedure TBSetBtMinMaxWidth(const Idx: Integer; const Value: Integer);
  3218. {$IFDEF F_P}
  3219. function TBGetBtMinMaxWidth(const Idx: Integer): Integer;
  3220. {$ENDIF F_P}
  3221. procedure TBFreeTBevents;
  3222. procedure Set_Align(const Value: TControlAlign);
  3223. function GetSelection: String;
  3224. procedure SetSelection(const Value: String);
  3225. procedure SetTabOrder(const Value: Integer);
  3226. function GetFocused: Boolean;
  3227. procedure SetFocused(const Value: Boolean);
  3228. function REGetFont: PGraphicTool;
  3229. procedure RESetFont(Value: PGraphicTool);
  3230. procedure RESetFontEx(const Index: Integer);
  3231. function REGetFontEffects(const Index: Integer): Boolean;
  3232. function REGetFontMask(const Index: Integer): Boolean;
  3233. procedure RESetFontEffect(const Index: Integer; const Value: Boolean);
  3234. function REGetFontAttr(const Index: Integer): Integer;
  3235. procedure RESetFontAttr(const Index, Value: Integer);
  3236. procedure RESetFontAttr1(const Index, Value: Integer);
  3237. function REGetFontSizeValid: Boolean;
  3238. function REGetCharformat: TCharFormat;
  3239. procedure RESetCharFormat(const Value: TCharFormat);
  3240. function REReadText(Format: TRETextFormat;
  3241. SelectionOnly: Boolean): String;
  3242. procedure REWriteText(Format: TRETextFormat; SelectionOnly: Boolean;
  3243. const Value: String);
  3244. function REGetFontName: String;
  3245. procedure RESetFontName(const Value: String);
  3246. function REGetParaFmt: TParaFormat;
  3247. procedure RESetParaFmt(const Value: TParaFormat);
  3248. function REGetNumbering: Boolean;
  3249. function REGetParaAttr( const Index: Integer ): Integer;
  3250. function REGetParaAttrValid( const Index: Integer ): Boolean;
  3251. function REGetTabCount: Integer;
  3252. function REGetTabs(Idx: Integer): Integer;
  3253. function REGetTextAlign: TRichTextAlign;
  3254. procedure RESetNumbering(const Value: Boolean);
  3255. procedure RESetParaAttr(const Index, Value: Integer);
  3256. procedure RESetTabCount(const Value: Integer);
  3257. procedure RESetTabs(Idx: Integer; const Value: Integer);
  3258. procedure RESetTextAlign(const Value: TRichTextAlign);
  3259. function REGetStartIndentValid: Boolean;
  3260. function REGetAutoURLDetect: Boolean;
  3261. procedure RESetAutoURLDetect(const Value: Boolean);
  3262. function GetMaxTextSize: DWORD;
  3263. procedure SetMaxTextSize(const Value: DWORD);
  3264. procedure SetOnResize(const Value: TOnEvent);
  3265. procedure DoSelChange;
  3266. function REGetUnderlineEx: TRichUnderline;
  3267. procedure RESetUnderlineEx(const Value: TRichUnderline);
  3268. function GetTextSize: Integer;
  3269. function REGetTextSize(Units: TRichTextSize): Integer;
  3270. function REGetNumStyle: TRichNumbering;
  3271. procedure RESetNumStyle(const Value: TRichNumbering);
  3272. function REGetNumBrackets: TRichNumBrackets;
  3273. procedure RESetNumBrackets(const Value: TRichNumBrackets);
  3274. function REGetNumTab: Integer;
  3275. procedure RESetNumTab(const Value: Integer);
  3276. function REGetNumStart: Integer;
  3277. procedure RESetNumStart(const Value: Integer);
  3278. function REGetSpacing(const Index: Integer): Integer;
  3279. procedure RESetSpacing(const Index, Value: Integer);
  3280. function REGetSpacingRule: Integer;
  3281. procedure RESetSpacingRule(const Value: Integer);
  3282. function REGetLevel: Integer;
  3283. function REGetBorder(Side: TBorderEdge; const Index: Integer): Integer;
  3284. procedure RESetBorder(Side: TBorderEdge; const Index: Integer;
  3285. const Value: Integer);
  3286. function REGetParaEffect(const Index: Integer): Boolean;
  3287. procedure RESetParaEffect(const Index: Integer; const Value: Boolean);
  3288. function REGetOverwite: Boolean;
  3289. procedure RESetOverwrite(const Value: Boolean);
  3290. procedure RESetOvrDisable(const Value: Boolean);
  3291. function REGetTransparent: Boolean;
  3292. procedure RESetTransparent(const Value: Boolean);
  3293. procedure RESetOnURL(const Index: Integer; const Value: TOnEvent);
  3294. {$IFDEF F_P}
  3295. function REGetOnURL(const Index: Integer): TOnEvent;
  3296. {$ENDIF F_P}
  3297. function REGetLangOptions(const Index: Integer): Boolean;
  3298. procedure RESetLangOptions(const Index: Integer; const Value: Boolean);
  3299. function LVGetItemImgIdx(Idx: Integer): Integer;
  3300. procedure LVSetItemImgIdx(Idx: Integer; const Value: Integer);
  3301. procedure SetFlat(const Value: Boolean);
  3302. procedure SetOnMouseEnter(const Value: TOnEvent);
  3303. procedure SetOnMouseLeave(const Value: TOnEvent);
  3304. procedure EdSetTransparent(const Value: Boolean);
  3305. procedure SetOnTestMouseOver(const Value: TOnTestMouseOver);
  3306. function GetPages(Idx: Integer): PControl;
  3307. function TCGetItemText(Idx: Integer): String;
  3308. procedure TCSetItemText(Idx: Integer; const Value: String);
  3309. function TCGetItemImgIDx(Idx: Integer): Integer;
  3310. procedure TCSetItemImgIdx(Idx: Integer; const Value: Integer);
  3311. function TCGetItemRect(Idx: Integer): TRect;
  3312. function TVGetItemIdx(const Index: Integer): THandle;
  3313. procedure TVSetItemIdx(const Index: Integer; const Value: THandle);
  3314. function TVGetItemNext(Item: THandle; const Index: Integer): THandle;
  3315. function TVGetItemRect(Item: THandle; TextOnly: Boolean): TRect;
  3316. function TVGetItemVisible(Item: THandle): Boolean;
  3317. procedure TVSetITemVisible(Item: THandle; const Value: Boolean);
  3318. function TVGetItemStateFlg(Item: THandle; const Index: Integer): Boolean;
  3319. procedure TVSetItemStateFlg(Item: THandle; const Index: Integer;
  3320. const Value: Boolean);
  3321. function TVGetItemImage(Item: THandle; const Index: Integer): Integer;
  3322. procedure TVSetItemImage(Item: THandle; const Index: Integer;
  3323. const Value: Integer);
  3324. function TVGetItemText(Item: THandle): String;
  3325. procedure TVSetItemText(Item: THandle; const Value: String);
  3326. {$IFNDEF _FPC}
  3327. {$IFNDEF _D2}
  3328. function TVGetItemTextW(Item: THandle): WideString;
  3329. procedure TVSetItemTextW(Item: THandle; const Value: WideString);
  3330. {$ENDIF _D2}
  3331. {$ENDIF _FPC}
  3332. function TV_GetItemHasChildren(Item: THandle): Boolean;
  3333. procedure TV_SetItemHasChildren(Item: THandle; const Value: Boolean);
  3334. function TV_GetItemChildCount(Item: THandle): Integer;
  3335. function TVGetItemData(Item: THandle): Pointer;
  3336. procedure TVSetItemData(Item: THandle; const Value: Pointer);
  3337. function GetToBeVisible: Boolean;
  3338. procedure SetAlphaBlend(const Value: Integer);
  3339. procedure SetMaxProgress(const Index, Value: Integer);
  3340. procedure SetDroppedWidth(const Value: Integer);
  3341. function LVGetItemState(Idx: Integer): TListViewItemState;
  3342. procedure LVSetItemState(Idx: Integer; const Value: TListViewItemState);
  3343. function LVGetSttImgIdx(Idx: Integer): Integer;
  3344. procedure LVSetSttImgIdx(Idx: Integer; const Value: Integer);
  3345. function LVGetOvlImgIdx(Idx: Integer): Integer;
  3346. procedure LVSetOvlImgIdx(Idx: Integer; const Value: Integer);
  3347. function LVGetItemData(Idx: Integer): DWORD;
  3348. procedure LVSetItemData(Idx: Integer; const Value: DWORD);
  3349. function LVGetItemIndent(Idx: Integer): Integer;
  3350. procedure LVSetItemIndent(Idx: Integer; const Value: Integer);
  3351. procedure SetOnDeleteAllLVItems(const Value: TOnEvent);
  3352. procedure SetOnDeleteLVItem(const Value: TOnDeleteLVItem);
  3353. procedure SetOnEditLVItem(const Value: TOnEditLVItem);
  3354. procedure SetOnLVData(const Value: TOnLVData);
  3355. {$IFNDEF _FPC}
  3356. {$IFNDEF _D2}
  3357. procedure SetOnLVDataW(const Value: TOnLVDataW);
  3358. {$ENDIF _D2}
  3359. {$ENDIF _FPC}
  3360. procedure SetOnColumnClick(const Value: TOnLVColumnClick);
  3361. procedure SetOnDrawItem(const Value: TOnDrawItem);
  3362. procedure SetOnMeasureItem(const Value: TOnMeasureItem);
  3363. procedure SetItemsCount(const Value: Integer);
  3364. function GetItemData(Idx: Integer): DWORD;
  3365. procedure SetItemData(Idx: Integer; const Value: DWORD);
  3366. function GetLVCurItem: Integer;
  3367. procedure SetLVCurItem(const Value: Integer);
  3368. function GetLVFocusItem: Integer;
  3369. procedure SetOnDropFiles(const Value: TOnDropFiles);
  3370. procedure SetOnHide(const Value: TOnEvent);
  3371. procedure SetOnShow(const Value: TOnEvent);
  3372. procedure SetClientMargin(const Index, Value: Integer);
  3373. {$IFDEF F_P}
  3374. function GetClientMargin(const Index: Integer): Integer;
  3375. {$ENDIF F_P}
  3376. procedure SetOnPaint(const Value: TOnPaint);
  3377. procedure SetOnEraseBkgnd(const Value: TOnPaint);
  3378. procedure SetTVRightClickSelect(const Value: Boolean);
  3379. procedure SetOnLVStateChange(const Value: TOnLVStateChange);
  3380. procedure SetOnLVDelete(const Value: TOnLVDelete);
  3381. procedure SetOnMove(const Value: TOnEvent);
  3382. procedure SetColor1(const Value: TColor);
  3383. procedure SetColor2(const Value: TColor);
  3384. procedure SetGradientLayout(const Value: TGradientLayout);
  3385. procedure SetGradientStyle(const Value: TGradientStyle);
  3386. procedure SetDroppedDown(const Value: Boolean);
  3387. function get_ClassName: String;
  3388. procedure set_ClassName(const Value: String);
  3389. procedure SetClsStyle( Value: DWord );
  3390. procedure SetStyle( Value: DWord );
  3391. procedure SetExStyle( Value: DWord );
  3392. procedure SetCursor( Value: HCursor );
  3393. procedure SetIcon( Value: HIcon );
  3394. procedure SetMenu( Value: HMenu );
  3395. function GetCaption: String;
  3396. procedure SetCaption( const Value: String );
  3397. procedure SetWindowState( Value: TWindowState );
  3398. function GetWindowState: TWindowState;
  3399. procedure ApplyFont2Wnd;
  3400. procedure DoClick;
  3401. function TBAddInsButtons( Idx: Integer; const Buttons: array of PChar; const BtnImgIdxArray: array
  3402. of Integer ): Integer; stdcall;
  3403. procedure SetBitBtnDrawMnemonic(const Value: Boolean);
  3404. function GetBitBtnImgIdx: Integer;
  3405. procedure SetBitBtnImgIdx(const Value: Integer);
  3406. function GetBitBtnImageList: THandle;
  3407. procedure SetBitBtnImageList(const Value: THandle);
  3408. function GetModal: Boolean;
  3409. {$IFDEF USE_SETMODALRESULT}
  3410. procedure SetModalResult( const Value: Integer );
  3411. {$ENDIF}
  3412. protected
  3413. fHandle: HWnd;
  3414. fFocusHandle: HWnd;
  3415. fClsStyle: DWord;
  3416. fStyle: DWord;
  3417. fExStyle: DWord;
  3418. fCursor: HCursor;
  3419. fCursorShared: Boolean;
  3420. fIcon: HIcon;
  3421. fIconShared: Boolean;
  3422. fCaption: PChar; // it is now preferred to store Caption as PChar (null-
  3423. // terminated string), dynamically allocated in memory.
  3424. fIgnoreWndCaption: Boolean;
  3425. fWindowState: TWindowState;
  3426. fShowAction: Integer;
  3427. fCanvas: PCanvas;
  3428. fDefWndProc: Pointer;
  3429. fNCDestroyed: Boolean;
  3430. FParent: PControl;
  3431. //FTag: Integer;
  3432. fEnabled: Boolean; // Caution!!! fVisible must follow fEnabled! ___
  3433. fVisible: Boolean; //____________________________________________//
  3434. fTabstop: Boolean;
  3435. fTabOrder: Integer;
  3436. fTextAlign: TTextAlign;
  3437. fVerticalAlign: TVerticalAlign;
  3438. fWordWrap: Boolean;
  3439. fPreventResize: Boolean;
  3440. fAlphaBlend: Integer;
  3441. FDroppedWidth: Integer;
  3442. fChildren: PList;
  3443. {* List of children. }
  3444. fMDIClient: PControl;
  3445. {* MDI client window control }
  3446. fPass2DefProc: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  3447. {* MDI children list }
  3448. fMDIChildren: PList;
  3449. {* List of MDI children. It is filled for MDI client window. }
  3450. fWndFunc: Pointer;
  3451. {* Initially pointer to WndFunc. For MDI child window, points to DefMDIChildProc. }
  3452. fExMsgProc: function( Applet: PControl; var Msg: TMsg ): Boolean;
  3453. {* Additional message handler called directly from Applet.ProcessMessage.
  3454. Used to call TranslateMDISysAccel API function for MDI application. }
  3455. fMDIDestroying: Boolean;
  3456. {* }
  3457. fTmpBrush: HBrush;
  3458. {* Brush handle to return in response to some color set messages.
  3459. Intended for internal use instead of Brush.Color if possible
  3460. to avoid using it. }
  3461. fTmpBrushColorRGB: TColor;
  3462. { }
  3463. fMembersCount: Integer;
  3464. {* Memebers count is first used in XCustomControl to separate
  3465. some internal child controls from common XControl.Children
  3466. and make it invisible among Children[]. }
  3467. fDrawCtrl1st: PControl;
  3468. {* Child control to draw it first, i.e. foreground of others. }
  3469. FCreating: Boolean;
  3470. {* True, when creating of object is in progress. }
  3471. fDestroying: Boolean;
  3472. {* True, when destroying of the window is started. Made protected to
  3473. be accessible in descending classes. }
  3474. fMenu: HMenu;
  3475. {* Usually used to store handle of attached main menu, but sometimes
  3476. is used to store control ID (for standard GUI controls only). }
  3477. fMenuObj: PObj;
  3478. {* PMenu pointer to TMenu object. Freed automatically with entire
  3479. chain of menu objects attached to a control (or form). }
  3480. {$IFNDEF NEW_MENU_ACCELL}
  3481. fAccelTable: HAccel;
  3482. {$ENDIF}
  3483. {* Handle of accelerator table created by menu(s). }
  3484. fImageList: PImageList;
  3485. {* Pointer to first private image list. Control can own several image,
  3486. lists, linked to a chain of image list objects. All these image lists
  3487. are released automatically, when control is destroyed. }
  3488. fCtlImageListSml: PImageList;
  3489. {* ImageList object (with small icons 16x16) to use with a control (e.g.,
  3490. with ListView control).
  3491. If not set, but control has a list of image list objects, last added
  3492. image list with small icons is used automatically. }
  3493. fCtlImageListNormal: PImageList;
  3494. {* ImageList object (with big icons 32x32) to use with a control.
  3495. If not set, last added image list with big icons is used. }
  3496. fCtlImgListState: PImageList;
  3497. {* ImageList object to use as a state image list (for ListView control). }
  3498. fIsApplet: Boolean;
  3499. {* True, if the object represent application taskbar button. }
  3500. fIsForm: Boolean;
  3501. {* True, if the object is form. }
  3502. fIsMDIChild: Boolean;
  3503. {* TRUE, if the object is MDI child form. }
  3504. fIsControl: Boolean;
  3505. {* True, if it is a control on form. }
  3506. fIsStaticControl: Byte;
  3507. {* True, if it is static control with a caption. (To prevent flickering
  3508. it in DoubleBuffered mode. }
  3509. fIsCommonControl: Boolean;
  3510. {* True, if it is common control. }
  3511. fChangedPosSz: Byte;
  3512. {* Flags of changing left (1), top (2), width (4) or height (8) }
  3513. fCannotDoubleBuf: Boolean;
  3514. {* True, if cannot set DoubleBuffered to True (RichEdit). }
  3515. fUpdRgn: HRgn;
  3516. fCollectUpdRgn: HRGN;
  3517. fEraseUpdRgn: Boolean;
  3518. fPaintDC: HDC;
  3519. fDblBufBmp: HBitmap;
  3520. {* Memory bitmap, used for DoubleBuffered painting. }
  3521. fDblBufW, fDblBufH: Integer;
  3522. {* Dimensions of fDblBufBmp. }
  3523. fDblBufPainting: Boolean;
  3524. fLookTabKeys: TTabKeys;
  3525. fNotUpdate: Boolean;
  3526. fDynHandlers: PList;
  3527. fColumn: Integer;
  3528. FSupressTab: Boolean;
  3529. fUpdateCount: Integer;
  3530. fPaintLater: Boolean;
  3531. fOnLeave: TOnEvent;
  3532. fEditing: Boolean;
  3533. fAutoPopupMenu: PObj;
  3534. fHelpContext: Integer;
  3535. // Order of following fields is important:
  3536. //_______________________________________________________________________________________________
  3537. fOnDynHandlers: TWindowFunc; //
  3538. fWndProcKeybd: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; //
  3539. fControlClick: procedure( Sender : PObj ); //
  3540. fControlClassName: PChar; //
  3541. fWindowed: Boolean; //
  3542. {* True, if control is windowed (or is a form). Now always True, //
  3543. because KOL does not yet contain Graphic controls. } //
  3544. // //
  3545. fCtlClsNameChg: Boolean; //
  3546. {* True, if control class name changed and memory is allocated to store it. } //
  3547. fWndProcResizeFlicks: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; //
  3548. fGotoControl: function( Self_: PControl; Key: DWORD; CheckOnly: Boolean ): Boolean; //
  3549. fCtl3Dchild: Boolean; //
  3550. fCtl3D: Boolean; //
  3551. fTextColor: TColor; //
  3552. {* Color of text. Used instead of fFont.Color internally to //
  3553. avoid usage of Font object if user is not accessing and changing it. } //
  3554. fFont: PGraphicTool; //
  3555. fColor: TColor; //
  3556. {* Color of control background. } //
  3557. fBrush: PGraphicTool; //
  3558. fMargin: Integer; //
  3559. fBoundsRect: TRect; //
  3560. fClientTop, fClientBottom, fClientLeft, fClientRight: Integer; //
  3561. {* Store adjustment factor of ClientRect for some 'idiosincrasies' windows, //
  3562. such as Groupbox or Tabcontrol. } //
  3563. //_____________________________________________________________________________________________//
  3564. // this is the end of fiels set, which order is important
  3565. fDoubleBuffered: Boolean; //
  3566. fTransparent: Boolean; //
  3567. fOnMessage: TOnMessage;
  3568. fOldOnMessage: TOnMessage;
  3569. fOnClick: TOnEvent;
  3570. fRightClick: Boolean;
  3571. fCurrentControl: PControl;
  3572. fCreateVisible, fCreateHidden: Boolean;
  3573. fRadio1st, fRadioLast : THandle;
  3574. fDropDownProc: procedure( Sender : PObj );
  3575. fDropped: Boolean;
  3576. fCurIdxAtDrop: Integer;
  3577. fPrevWndProc: Pointer;
  3578. fClickDisabled: Byte;
  3579. fCurItem, fCurIndex: Integer;
  3580. FOnScroll: TOnScroll;
  3581. FScrollLineDist: array[ 0..1 ] of Integer;
  3582. fDefaultBtn: Boolean;
  3583. fCancelBtn: Boolean;
  3584. fDefaultBtnCtl: PControl;
  3585. fCancelBtnCtl: PControl;
  3586. fAllBtnReturnClick: Boolean;
  3587. fIgnoreDefault: Boolean;
  3588. fOnMouseDown: TOnMouse; // CAUTION!!! Order of mouse event handlers is important. ____
  3589. fOnMouseUp: TOnMouse; //
  3590. fOnMouseMove: TOnMouse; //
  3591. fOnMouseDblClk: TOnMouse; //
  3592. fOnMouseWheel: TOnMouse; //_____________________________________________________//
  3593. fOldDefWndProc: Pointer;
  3594. fOnChange: TOnEvent;
  3595. fOnEnter: TOnEvent;
  3596. FOnLVCustomDraw: TOnLVCustomDraw;
  3597. FOnSBBeforeScroll: TOnSBBeforeScroll;
  3598. FOnSBScroll: TOnSBScroll;
  3599. protected
  3600. procedure SetOnLVCustomDraw(const Value: TOnLVCustomDraw);
  3601. public
  3602. fCommandActions: TCommandActions;
  3603. protected
  3604. fOnChar: TOnChar;
  3605. fOnKeyUp: TOnKey;
  3606. fOnKeyDown: TOnKey;
  3607. fOnPaint: TOnPaint;
  3608. fOnPaint2: TOnPaint;
  3609. fPaintMsg: TMsg;
  3610. fOnPrepaint: TOnPaint;
  3611. fOnPostPaint: TOnPaint;
  3612. fPaintProc: TPaintProc;
  3613. FMaxWidth: Integer;
  3614. FMinWidth: Integer;
  3615. FMaxHeight: Integer;
  3616. FMinHeight: Integer;
  3617. fShadowDeep: Integer;
  3618. fStatusCtl: PControl;
  3619. fStatusWnd: HWnd;
  3620. fStatusTxt: PChar;
  3621. fColor1: TColor;
  3622. fColor2: TColor;
  3623. fLVColCount: Integer;
  3624. fLVOptions: TListViewOptions;
  3625. fLVStyle: TListViewStyle;
  3626. fOnEditLVITem: TOnEditLVItem;
  3627. fLVTextBkColor: TColor;
  3628. fLVItemHeight: Integer;
  3629. fOnDropDown: TOnEvent;
  3630. fOnCloseUp: TOnEvent;
  3631. fModalResult: Integer;
  3632. fModal: Integer;
  3633. fModalForm: PControl;
  3634. FAlign: TControlAlign;
  3635. fNotUseAlign: Boolean;
  3636. fDragCallback: TOnDrag;
  3637. fDragging: Boolean;
  3638. fDragStartPos: TPoint;
  3639. fMouseStartPos: TPoint;
  3640. fSplitStartPos: TPoint;
  3641. fSplitStartPos2: TPoint;
  3642. fSplitStartSize: Integer;
  3643. fSplitMinSize1, fSplitMinSize2: Integer;
  3644. fOnSplit: TOnSplit;
  3645. fSecondControl: PControl;
  3646. fOnSelChange: TOnEvent;
  3647. fTmpFont: PGraphicTool;
  3648. fRECharFormatRec: TCharFormat2;
  3649. fREError: Integer;
  3650. fREStream: PStream;
  3651. fREStrLoadLen: DWORD;
  3652. fREParaFmtRec: TParaFormat2;
  3653. FOnResize: TOnEvent;
  3654. fOnProgress: TOnEvent;
  3655. fCharFmtDeltaSz: Integer;
  3656. fParaFmtDeltaSz: Integer;
  3657. fREOvr: Boolean;
  3658. fReOvrDisable: Boolean;
  3659. fOnREInsModeChg: TOnEvent;
  3660. fREScrolling: Boolean;
  3661. fUpdCount: Integer;
  3662. fOnREOverURL: TOnEvent;
  3663. fOnREURLClick: TOnEvent;
  3664. fRECharArea: TRichFmtArea;
  3665. fBitBtnOptions : TBitBtnOptions;
  3666. fGlyphLayout : TGlyphLayout;
  3667. fGlyphBitmap : HBitmap;
  3668. fGlyphCount : Integer;
  3669. fGlyphWidth, fGlyphHeight: Integer;
  3670. fOnBitBtnDraw: TOnBitBtnDraw;
  3671. fFlat: Boolean;
  3672. fSizeRedraw: Boolean; {YS}
  3673. fOnMouseLeave: TOnEvent;
  3674. fOnMouseEnter: TOnEvent;
  3675. fOnTestMouseOver: TOnTestMouseOver;
  3676. fMouseInControl: Boolean;
  3677. fRepeatInterval: Integer;
  3678. fChecked: Boolean;
  3679. fPushed: Boolean;
  3680. fPrevFocusWnd: HWnd;
  3681. fOnTVBeginDrag: TOnTVBeginDrag;
  3682. fOnTVBeginEdit: TOnTVBeginEdit;
  3683. fOnTVEndEdit: TOnTVEndEdit;
  3684. fOnTVExpanded: TOnTVExpanded;
  3685. fOnTVExpanding: TOnTVExpanding;
  3686. fOnTVDelete: TOnTVDelete;
  3687. fOnDeleteLVItem: TOnDeleteLVItem;
  3688. fOnDeleteAllLVItems: TOnEvent;
  3689. fOnLVData: TOnLVData;
  3690. {$IFNDEF _FPC}
  3691. {$IFNDEF _D2}
  3692. fOnLVDataW: TOnLVDataW;
  3693. {$ENDIF _D2}
  3694. {$ENDIF _FPC}
  3695. fOnCompareLVItems: TOnCompareLVItems;
  3696. fOnColumnClick: TOnLVColumnClick;
  3697. fOnDrawItem: TOnDrawItem;
  3698. fOnMeasureItem: TOnMeasureItem;
  3699. fREUrl: String;
  3700. FMinimizeWnd: PControl;
  3701. FFixWidth: Integer;
  3702. FFixHeight: Integer;
  3703. FOnDropFiles: TOnDropFiles;
  3704. FOnHide: TOnEvent;
  3705. FOnShow: TOnEvent;
  3706. fOnEraseBkgnd: TOnPaint;
  3707. fCustomData: Pointer;
  3708. fCustomObj: PObj;
  3709. fOnTVSelChanging: TOnTVSelChanging;
  3710. fOnClose: TOnEventAccept;
  3711. fOnQueryEndSession: TOnEventAccept;
  3712. fCloseQueryReason: TCloseQueryReason;
  3713. //----- order of following 3 events important: //
  3714. fOnMinimize: TOnEvent; //
  3715. fOnMaximize: TOnEvent; //
  3716. fOnRestore: TOnEvent; //
  3717. //---------------------------------------------//
  3718. //fCreateParamsExt: procedure( Self_: PControl; var Params: TCreateParams );
  3719. fCreateWndExt: procedure( Sender: PControl );
  3720. fTBttCmd: PList;
  3721. fTBttTxt: PStrList;
  3722. fTBevents: PList; // events for TBAssignEvents
  3723. fTBBtnImgWidth: Integer; // custom toolbar bitmap width
  3724. FTBBtMinWidth: Integer;
  3725. FTBBtMaxWidth: Integer;
  3726. fGradientStyle: TGradientStyle;
  3727. fGradientLayout: TGradientLayout;
  3728. fVisibleWoParent: Boolean;
  3729. fTVRightClickSelect: Boolean;
  3730. FOnMove: TOnEvent;
  3731. FOnLVStateChange: TOnLVStateChange;
  3732. FOnLVDelete: TOnLVDelete;
  3733. fAutoSize: procedure( Self_: PControl );
  3734. fIsButton: Boolean;
  3735. fSizeGrip: Boolean;
  3736. fNotAvailable: Boolean;
  3737. FPressedMnemonic: DWORD;
  3738. FBitBtnDrawMnemonic: Boolean;
  3739. FBitBtnGetCaption: function( Self_: PControl; const S: String ): String;
  3740. FBitBtnExtDraw: procedure( Self_: PControl; DC: HDC; X, Y: Integer; const R: TRect;
  3741. const CapText, CapTxtOrig: String; Color: TColor );
  3742. FTextShiftX, FTextShiftY: Integer;
  3743. fNotifyChild: procedure( Self_, Child: PControl );
  3744. fScrollChildren: procedure( Self_: PControl );
  3745. fOnHelp: TOnHelp;
  3746. FOnDTPUserString: TDTParseInputEvent;
  3747. {$IFDEF USE_MHTOOLTIP}
  3748. {$DEFINE var}
  3749. {$I KOLMHToolTip}
  3750. {$UNDEF var}
  3751. {$DEFINE function}
  3752. {$I KOLMHToolTip}
  3753. {$UNDEF function}
  3754. {$ENDIF}
  3755. procedure Init; {-}virtual;{+}{++}(*override;*){--}
  3756. {* }
  3757. procedure InitParented( AParent: PControl ); virtual;
  3758. {* Initialization of visual object. }
  3759. procedure DestroyChildren;
  3760. {* Destroys children. Is called in destructor, and can be
  3761. called in descending classes as earlier as needed to
  3762. prevent problems of too late destroying of visuals. }
  3763. function GetParentWnd( NeedHandle: Boolean ): HWnd;
  3764. {* Returns handle of parent window. }
  3765. function GetParentWindow: HWnd;
  3766. {* }
  3767. procedure SetEnabled( Value: Boolean );
  3768. {* Changes Enabled property value. Overriden here to change enabling
  3769. status of a window. }
  3770. function GetEnabled: Boolean;
  3771. {* Returns True, if Enabled. Overriden here to obtain real window
  3772. state. }
  3773. procedure SetVisible( Value: Boolean );
  3774. {* Sets Visible property value. Overriden here to change visibility
  3775. of correspondent window. }
  3776. procedure Set_Visible( Value: Boolean );
  3777. {* }
  3778. function GetVisible: Boolean;
  3779. {* Returns True, if correspondent window is Visible. Overriden
  3780. to get visibility of real window, not just value stored in object. }
  3781. function Get_Visible: Boolean;
  3782. {* Returns True, if correspondent window is Visible, for forms and applet,
  3783. or if fVisible flag is set, for controls. }
  3784. procedure SetCtlColor( Value: TColor );
  3785. {* Sets TControl's Color property value. }
  3786. procedure SetBoundsRect( const Value: TRect );
  3787. {* Sets BoudsRect property value. }
  3788. function GetBoundsRect: TRect;
  3789. {* Returns bounding rectangle. }
  3790. function GetIcon: HIcon;
  3791. {* Returns Icon property. By default, if it is not set,
  3792. returns Icon property of an Applet. }
  3793. procedure CreateSubclass( var Params: TCreateParams; ControlClassName: PChar );
  3794. {* Can be used in descending classes to subclass window with given
  3795. standard Windows ControlClassName - must be called after
  3796. creating Params but before CreateWindow. Usually it is called
  3797. in overriden method CreateParams after calling of the inherited one. }
  3798. function UpdateWndStyles: PControl;
  3799. {* Updates fStyle, fExStyle, fClsStyle from window handle }
  3800. procedure SetOnChar(const Value: TOnChar);
  3801. {* }
  3802. procedure SetOnKeyDown(const Value: TOnKey);
  3803. {* }
  3804. procedure SetOnKeyUp(const Value: TOnKey);
  3805. {* }
  3806. procedure SetMouseDown(const Value: TOnMouse);
  3807. {* }
  3808. procedure SetMouseMove(const Value: TOnMouse);
  3809. {* }
  3810. procedure SetMouseUp(const Value: TOnMouse);
  3811. {* }
  3812. procedure SetMouseWheel(const Value: TOnMouse);
  3813. {* }
  3814. procedure SetMouseDblClk(const Value: TOnMouse);
  3815. {* }
  3816. procedure SetHelpContext( Value: Integer );
  3817. {* }
  3818. procedure SetOnTVDelete( const Value: TOnTVDelete );
  3819. {* }
  3820. procedure SetDefaultBtn(const Index: Integer; const Value: Boolean);
  3821. {$IFDEF F_P}
  3822. function GetDefaultBtn(const Index: Integer): Boolean;
  3823. {$ENDIF F_P}
  3824. function DefaultBtnProc( var Msg: TMsg; var Rslt: Integer ): Boolean;
  3825. {* }
  3826. procedure SetDateTime( Value: TDateTime );
  3827. function GetDateTime: TDateTime;
  3828. procedure SetDateTimeRange( Value: TDateTimeRange );
  3829. function GetDateTimeRange: TDateTimeRange;
  3830. procedure SetDateTimePickerColor( Index: TDateTimePickerColor; Value: TColor );
  3831. function GetDateTimePickerColor( Index: TDateTimePickerColor ): TColor;
  3832. procedure SetDateTimeFormat( const Value: String );
  3833. public
  3834. constructor CreateParented( AParent: PControl );
  3835. {* Creates new instance of TControl object, calling InitParented }
  3836. //FormPointer_DoNotUseItPlease_ItIsUsedByMCK: Pointer;
  3837. { ^ no more needed }
  3838. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  3839. {* Destroyes object. First of all, destructors for all children
  3840. are called. }
  3841. function GetWindowHandle: HWnd;
  3842. {* Returns window handle. If window is not yet created,
  3843. method CreateWindow is called. }
  3844. procedure CreateChildWindows;
  3845. {* Enumerates all children recursively and calls CreateWindow for all
  3846. of these. }
  3847. property Parent: PControl read fParent write SetParent;
  3848. {* Parent of TParent object. Also must be of TParent type or derived from TParent. }
  3849. //property Tag: Integer read FTag write FTag; //--------- moved to TObj --------
  3850. {* User-defined pointer, which can contain any data or reference to
  3851. anywhere in memory (when used as a pointer).
  3852. }
  3853. function ChildIndex( Child: PControl ): Integer;
  3854. {* Returns index of given child. }
  3855. procedure MoveChild( Child: PControl; NewIdx: Integer );
  3856. {* Moves given Child into new position. }
  3857. property Enabled: Boolean read GetEnabled write SetEnabled;
  3858. {* Enabled usually used to decide if control can get keyboard focus
  3859. or been clicked by mouse. }
  3860. procedure EnableChildren( Enable, Recursive: Boolean );
  3861. {* Enables (Enable = TRUE) or disables (Enable = FALSE) all the children
  3862. of the control. If Recursive = TRUE then all the children of all the
  3863. children are enabled or disabled recursively. }
  3864. property Visible: Boolean read Get_Visible write SetVisible;
  3865. {* Obvious. }
  3866. property ToBeVisible: Boolean read GetToBeVisible;
  3867. {* Returns True, if a control is supposed to be visible when its
  3868. form is showing. Thus is, True is returned if either control
  3869. is Visible or hidden, but marked with flag fCreateHidden. }
  3870. property CreateVisible: Boolean read fCreateVisible write fCreateVisible;
  3871. {* False by default. If You want your form to be created visible and
  3872. flick due creation, set it to True. This does not affect size of
  3873. executable anyway. }
  3874. property Align: TControlAlign read FAlign write Set_Align;
  3875. {* Align style of a control. If this property is not used in your
  3876. application, there are no additional code added. Aligning of
  3877. controls is made in KOL like in VCL. To align controls when
  3878. initially create ones, use "transparent" function SetAlign
  3879. ("transparent" means that it returns @Self as a result).
  3880. |<br>
  3881. Note, that it is better not to align combobox caClient, caLeft or
  3882. caRight (better way is to place a panel with Border = 0 and
  3883. EdgeStyle = esNone, align it as desired and to place a combobox on it
  3884. aligning caTop or caBottom). Otherwise, big problems could be under
  3885. Win9x/Me, and some delay could occur under any other systems.
  3886. |<br> Do not attempt to align some kinds of controls (like combobox or
  3887. toolbar) caLeft or caRight, this can cause infinite recursion in the
  3888. application. }
  3889. property BoundsRect: TRect read GetBoundsRect write SetBoundsRect;
  3890. {* Bounding rectangle of the visual. Coordinates are relative
  3891. to top left corner of parent's ClientRect, or to top left corner
  3892. of screen (for TForm). }
  3893. property Left: Integer read GetLeft write SetLeft;
  3894. {* Left horizontal position. }
  3895. property Top: Integer read GetTop write SetTop;
  3896. {* Top vertical position. }
  3897. property Width: Integer read GetWidth write SetWidth;
  3898. {* Width of TVisual object. }
  3899. property Height: Integer read GetHeight write SetHeight;
  3900. {* Height of TVisual object. }
  3901. property Position: TPoint read GetPosition write Set_Position;
  3902. {* Represents top left position of the object. See also BoundsRect. }
  3903. property MinWidth: Integer index 0
  3904. {$IFDEF F_P} read GetConstraint
  3905. {$ELSE DELPHI} read FMinWidth
  3906. {$ENDIF F_P/DELPHI} write SetConstraint;
  3907. {* Minimal width constraint. }
  3908. property MinHeight: Integer index 1
  3909. {$IFDEF F_P} read GetConstraint
  3910. {$ELSE DELPHI} read FMinHeight
  3911. {$ENDIF F_P/DELPHI} write SetConstraint;
  3912. {* Minimal height constraint. }
  3913. property MaxWidth: Integer index 2
  3914. {$IFDEF F_P} read GetConstraint
  3915. {$ELSE DELPHI} read FMaxWidth
  3916. {$ENDIF F_P/DELPHI} write SetConstraint;
  3917. {* Maximal width constraint. }
  3918. property MaxHeight: Integer index 3
  3919. {$IFDEF F_P} read GetConstraint
  3920. {$ELSE DELPHI} read FMaxHeight
  3921. {$ENDIF F_P/DELPHI} write SetConstraint;
  3922. {* Maximal height constraint. }
  3923. function ClientRect: TRect;
  3924. {* Client rectangle of TControl. Contrary to VCL, for some
  3925. classes (e.g. for graphic controls) can be relative
  3926. not to itself, but to top left corner of the parent's ClientRect
  3927. rectangle. }
  3928. property ClientWidth: Integer read GetClientWidth write SetClientWidth;
  3929. {* Obvious. Accessing this property, program forces window latent creation. }
  3930. property ClientHeight: Integer read GetClientHeight write SetClientHeight;
  3931. {* Obvious. Accessing this property, program forces window latent creation. }
  3932. function ControlRect: TRect;
  3933. {* Absolute bounding rectangle relatively to nearest
  3934. Windowed parent client rectangle (at least to a form, but usually to
  3935. a Parent).
  3936. Useful while drawing on device context, provided by such
  3937. Windowed parent. For form itself is the same as BoundsRect. }
  3938. function ControlAtPos( X, Y: Integer; IgnoreDisabled: Boolean ): PControl;
  3939. {* Searches TVisual at the given position (relatively to top left
  3940. corner of the ClientRect). }
  3941. procedure Invalidate;
  3942. {* Invalidates rectangle, occupied by the visual (but only if Showing =
  3943. True). }
  3944. procedure InvalidateEx;
  3945. {* Invalidates the window and all its children. }
  3946. procedure InvalidateNC( Recursive: Boolean );
  3947. {* Invalidates the window and all its children including non-client area. }
  3948. procedure Update;
  3949. {* Updates control's window and calls Update for all child controls. }
  3950. procedure BeginUpdate;
  3951. {* |<#treeview>
  3952. |<#listview>
  3953. |<#richedit>
  3954. |<#memo>
  3955. |<#listbox>
  3956. Call this method to stop visual updates of the control until correspondent
  3957. EndUpdate called (pairs BeginUpdate - EndUpdate can be nested). }
  3958. procedure EndUpdate;
  3959. {* See BeginUpdate. }
  3960. property Windowed: Boolean read fWindowed;
  3961. {* Constantly returns True, if object is windowed (i.e. owns
  3962. correspondent window handle). Otherwise, returns False.
  3963. |<br>
  3964. By now, all the controls are windowed (there are no controls in KOL, which are
  3965. emulating window, acually belonging to Parent - like TGraphicControl
  3966. in VCL). }
  3967. function HandleAllocated: Boolean;
  3968. {* Returns True, if window handle is allocated. Has no sense for
  3969. non-Windowed objects (but now, the KOL has no non-Windowed controls). }
  3970. property MDIClient: PControl read fMDIClient;
  3971. {* For MDI forms only: returns MDI client window control, containng all MDI
  3972. children. Use this window to send specific messages to rule MDI children. }
  3973. property ChildCount: Integer read GetChildCount;//GetChildCountWOMembers;
  3974. {* Returns number of commonly accessed child objects (without
  3975. MembersCount). }
  3976. property Children[ Idx: Integer ]: PControl read GetMembers;
  3977. {* Child items of TVisual object. Property is reintroduced here
  3978. to separate access to always visible Children[] from restricted
  3979. a bit Members[]. }
  3980. property MembersCount: Integer read FMembersCount;
  3981. {* Returns number of "internal" child objects, which are
  3982. not accessible through common Children[] property. }
  3983. property Members[ Idx: Integer ]: PControl read GetMembers;
  3984. {* Members and children array of the object (first from 0 to
  3985. MembersCount-1 are Members[], and Children[] are followed by
  3986. them. Usually You do not need to use this list. Use instead
  3987. Children[0..ChildCount] property, Members[] is intended for
  3988. internal needs of XCL (and in KOL by now Members and Children
  3989. actually are the same properties). }
  3990. procedure PaintBackground( DC: HDC; Rect: PRect );
  3991. {* Is called to paint background in given rectangle. This
  3992. method is filling clipped area of the Rect rectangle with
  3993. Color, but only if global event Global_OnPaintBkgnd is
  3994. not assigned. If assigned, this one is called instead here.
  3995. |<br>&nbsp;&nbsp;&nbsp;
  3996. This method made public, so it can be called directly to
  3997. fill some device context's rectangle. But remember, that
  3998. independantly of Rect, top left corner of background piece
  3999. will be located so, if drawing is occure into ControlRect
  4000. rectangle. }
  4001. property WindowedParent: PControl read fParent;
  4002. {* Returns nearest windowed parent, the same as Parent. }
  4003. function ParentForm: PControl;
  4004. {* |<#form>
  4005. Returns parent form for a control (of @Self for form itself. }
  4006. property ActiveControl: PControl read fCurrentControl write fCurrentControl;
  4007. {* }
  4008. function Client2Screen( const P: TPoint ): TPoint;
  4009. {* Converts the client coordinates of a specified point to screen coordinates. }
  4010. function Screen2Client( const P: TPoint ): TPoint;
  4011. {* Converts screen coordinates of a specified point to client coordinates. }
  4012. function CreateWindow: Boolean; virtual;
  4013. {* |<#form>
  4014. Creates correspondent window object. Returns True if success (if
  4015. window is already created, False is returned). If applied to a form,
  4016. all child controls also allocates handles that time.
  4017. |<br>&nbsp;&nbsp;&nbsp;
  4018. Call this method to ensure, that a hanle is allocated for a form,
  4019. an application button or a control. (It is not necessary to do so in
  4020. the most cases, even if You plan to work with control's handle directly.
  4021. But immediately after creating the object, if You want to pass its
  4022. handle to API function, this can be helpful). }
  4023. procedure Close;
  4024. {* |<#appbutton>
  4025. |<#form>
  4026. Closes window. If a window is the main form, this closes application,
  4027. terminating it. Also it is possible to call Close method for Applet
  4028. window to stop application. }
  4029. {$IFDEF USE_MHTOOLTIP}
  4030. {$DEFINE public}
  4031. {$I KOLMHToolTip}
  4032. {$UNDEF public}
  4033. {$ENDIF}
  4034. property Handle: HWnd read fHandle; //GetHandle;
  4035. {* Returns descriptor of system window object. If window is not yet
  4036. created, 0 is returned. To allocate handle, call CreateWindow method. }
  4037. property ParentWindow: HWnd read GetParentWindow;
  4038. {* Returns handle of parent window (not TControl object, but system
  4039. window object handle). }
  4040. property ClsStyle: DWord read fClsStyle write SetClsStyle;
  4041. {* Window class style. Available styles are:
  4042. |<table border=0>
  4043. |&L=<tr><td valign=top><font face=Fixedsys>%1</font></td><td>
  4044. |&E=</td></tr>
  4045. |&N=<br>&nbsp;&nbsp;&nbsp;
  4046. <L CS_BYTEALIGNCLIENT> - Aligns the window's client area on the byte boundary
  4047. (in the x direction) to enhance performance during
  4048. drawing operations. <E>
  4049. <L CS_BYTEALIGNWINDOW> - Aligns a window on a byte boundary (in the x
  4050. direction). <E>
  4051. <L CS_CLASSDC> - Allocates one device context to be shared by all
  4052. windows in the class. <E>
  4053. <L CS_DBLCLKS> - Sends double-click messages to the window
  4054. procedure when the user double-clicks the mouse while the
  4055. cursor is within a window belonging to the class. <E>
  4056. <L CS_GLOBALCLASS> - Allows an application to create a window of
  4057. the class regardless of the value of the hInstance parameter.
  4058. <N> You can create a global class by creating
  4059. the window class in a dynamic-link library (DLL) and listing the
  4060. name of the DLL in the registry under specific keys. <E>
  4061. <L CS_HREDRAW> - Redraws the entire window if a movement or
  4062. size adjustment changes the width of the client area. <E>
  4063. <L CS_NOCLOSE> - Disables the Close command on the System menu. <E>
  4064. <L CS_OWNDC> - Allocates a unique device context for each window
  4065. in the class. <E>
  4066. <L CS_PARENTDC> - Sets the clipping region of the child window to
  4067. that of the parent window so that the child can draw on the parent. <E>
  4068. <L CS_SAVEBITS> - Saves, as a bitmap, the portion of the screen
  4069. image obscured by a window. Windows uses the saved bitmap to re-create
  4070. the screen image when the window is removed. <E>
  4071. <L CS_VREDRAW> - Redraws the entire window if a movement or size
  4072. adjustment changes the height of the client area. <E>
  4073. |</table> For more info, see Win32.hlp (keyword 'WndClass');
  4074. }
  4075. property Style: DWord read fStyle write SetStyle;
  4076. {* Window styles. Available styles are:
  4077. |<table border=0>
  4078. <L WS_BORDER> Creates a window that has a thin-line border. <E>
  4079. <L WS_CAPTION> Creates a window that has a title bar (includes the
  4080. WS_BORDER style). <E>
  4081. <L WS_CHILD> Creates a child window. This style cannot be used with
  4082. the WS_POPUP style. <E>
  4083. <L WS_CHILDWINDOW> Same as the WS_CHILD style. <E>
  4084. <L WS_CLIPCHILDREN> Excludes the area occupied by child windows
  4085. when drawing occurs within the parent window. This style is used
  4086. when creating the parent window. <E>
  4087. <L WS_CLIPSIBLINGS> Clips child windows relative to each other;
  4088. that is, when a particular child window receives a WM_PAINT message,
  4089. the WS_CLIPSIBLINGS style clips all other overlapping child windows
  4090. out of the region of the child window to be updated. If
  4091. WS_CLIPSIBLINGS is not specified and child windows overlap, it is
  4092. possible, when drawing within the client area of a child window,
  4093. to draw within the client area of a neighboring child window. <E>
  4094. <L WS_DISABLED> Creates a window that is initially disabled. A
  4095. disabled window cannot receive input from the user. <E>
  4096. <L WS_DLGFRAME> Creates a window that has a border of a style
  4097. typically used with dialog boxes. A window with this style cannot
  4098. have a title bar. <E>
  4099. <L WS_GROUP> Specifies the first control of a group of controls.
  4100. The group consists of this first control and all controls defined
  4101. after it, up to the next control with the WS_GROUP style.
  4102. The first control in each group usually has the WS_TABSTOP
  4103. style so that the user can move from group to group. The user
  4104. can subsequently change the keyboard focus from one control in
  4105. the group to the next control in the group by using the direction
  4106. keys. <E>
  4107. <L WS_HSCROLL> Creates a window that has a horizontal scroll bar. <E>
  4108. <L WS_ICONIC> Creates a window that is initially minimized. Same as
  4109. the WS_MINIMIZE style. <E>
  4110. <L WS_MAXIMIZE> Creates a window that is initially maximized. <E>
  4111. <L WS_MAXIMIZEBOX> Creates a window that has a Maximize button.
  4112. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU
  4113. style must also be specified. <E>
  4114. <L WS_MINIMIZE> Creates a window that is initially minimized.
  4115. Same as the WS_ICONIC style. <E>
  4116. <L WS_MINIMIZEBOX> Creates a window that has a Minimize button.
  4117. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU
  4118. style must also be specified. <E>
  4119. <L WS_OVERLAPPED> Creates an overlapped window. An overlapped
  4120. window has a title bar and a border. Same as the WS_TILED style. <E>
  4121. <L WS_OVERLAPPEDWINDOW> Creates an overlapped window with the
  4122. WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX,
  4123. and WS_MAXIMIZEBOX styles. Same as the WS_TILEDWINDOW style. <E>
  4124. <L WS_POPUP> Creates a pop-up window. This style cannot be used with
  4125. the WS_CHILD style. <E>
  4126. <L WS_POPUPWINDOW> Creates a pop-up window with WS_BORDER,
  4127. WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION and WS_POPUPWINDOW
  4128. styles must be combined to make the window menu visible. <E>
  4129. <L WS_SIZEBOX> Creates a window that has a sizing border. Same as the
  4130. WS_THICKFRAME style. <E>
  4131. <L WS_SYSMENU> Creates a window that has a window-menu on its title
  4132. bar. The WS_CAPTION style must also be specified. <E>
  4133. <L WS_TABSTOP> Specifies a control that can receive the keyboard focus
  4134. when the user presses the TAB key. Pressing the TAB key changes
  4135. the keyboard focus to the next control with the WS_TABSTOP style. <E>
  4136. <L WS_THICKFRAME> Creates a window that has a sizing border.
  4137. Same as the WS_SIZEBOX style. <E>
  4138. <L WS_TILED> Creates an overlapped window. An overlapped window has
  4139. a title bar and a border. Same as the WS_OVERLAPPED style. <E>
  4140. <L WS_TILEDWINDOW> Creates an overlapped window with the
  4141. WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME,
  4142. WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles. Same as the
  4143. WS_OVERLAPPEDWINDOW style. <E>
  4144. <L WS_VISIBLE> Creates a window that is initially visible. <E>
  4145. <L WS_VSCROLL> Creates a window that has a vertical scroll bar. <E>
  4146. |</table>
  4147. See also Win32.hlp (topic CreateWindow).
  4148. }
  4149. property ExStyle: DWord read fExStyle write SetExStyle;
  4150. {* Extra window styles. Available flags are following:
  4151. |<table border=0>
  4152. <L WS_EX_ACCEPTFILES> Specifies that a window created with this style
  4153. accepts drag-drop files. <E>
  4154. <L WS_EX_APPWINDOW> Forces a top-level window onto the taskbar
  4155. when the window is minimized. <E>
  4156. <L WS_EX_CLIENTEDGE> Specifies that a window has a border with a
  4157. sunken edge. <E>
  4158. <L WS_EX_CONTEXTHELP> Includes a question mark in the title bar of
  4159. the window. When the user clicks the question mark, the cursor
  4160. changes to a question mark with a pointer. If the user then clicks
  4161. a child window, the child receives a WM_HELP message. The child
  4162. window should pass the message to the parent window procedure,
  4163. which should call the WinHelp function using the HELP_WM_HELP
  4164. command. The Help application displays a pop-up window that
  4165. typically contains help for the child window.WS_EX_CONTEXTHELP
  4166. cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles. <E>
  4167. <L WS_EX_CONTROLPARENT> Allows the user to navigate among the child
  4168. windows of the window by using the TAB key. <E>
  4169. <L WS_EX_DLGMODALFRAME> Creates a window that has a double border;
  4170. the window can, optionally, be created with a title bar by
  4171. specifying the WS_CAPTION style in the dwStyle parameter. <E>
  4172. <L WS_EX_LEFT> Window has generic "left-aligned" properties. This
  4173. is the default. <E>
  4174. <L WS_EX_LEFTSCROLLBAR> If the shell language is Hebrew, Arabic, or
  4175. another language that supports reading order alignment, the
  4176. vertical scroll bar (if present) is to the left of the client
  4177. area. For other languages, the style is ignored and not treated
  4178. as an error. <E>
  4179. <L WS_EX_LTRREADING> The window text is displayed using Left to
  4180. Right reading-order properties. This is the default. <E>
  4181. <L WS_EX_MDICHILD> Creates an MDI child window. <E>
  4182. <L WS_EX_NOPARENTNOTIFY> Specifies that a child window created
  4183. with this style does not send the WM_PARENTNOTIFY message to its
  4184. parent window when it is created or destroyed. <E>
  4185. <L WS_EX_OVERLAPPEDWINDOW> Combines the WS_EX_CLIENTEDGE and
  4186. WS_EX_WINDOWEDGE styles. <E>
  4187. <L WS_EX_PALETTEWINDOW> Combines the WS_EX_WINDOWEDGE,
  4188. WS_EX_TOOLWINDOW, and WS_EX_TOPMOST styles. <E>
  4189. <L WS_EX_RIGHT> Window has generic "right-aligned" properties.
  4190. This depends on the window class. This style has an effect only
  4191. if the shell language is Hebrew, Arabic, or another language that
  4192. supports reading order alignment; otherwise, the style is
  4193. ignored and not treated as an error. <E>
  4194. <L WS_EX_RIGHTSCROLLBAR> Vertical scroll bar (if present) is to the
  4195. right of the client area. This is the default. <E>
  4196. <L WS_EX_RTLREADING> If the shell language is Hebrew, Arabic, or
  4197. another language that supports reading order alignment, the
  4198. window text is displayed using Right to Left reading-order
  4199. properties. For other languages, the style is ignored and not
  4200. treated as an error. <E>
  4201. <L WS_EX_STATICEDGE> Creates a window with a three-dimensional
  4202. border style intended to be used for items that do not accept
  4203. user input. <E>
  4204. <L WS_EX_TOOLWINDOW> Creates a tool window; that is, a window
  4205. intended to be used as a floating toolbar. A tool window has
  4206. a title bar that is shorter than a normal title bar, and the
  4207. window title is drawn using a smaller font. A tool window does
  4208. not appear in the taskbar or in the dialog that appears when
  4209. the user presses ALT+TAB. <E>
  4210. <L WS_EX_TOPMOST> Specifies that a window created with this style
  4211. should be placed above all non-topmost windows and should stay
  4212. above them, even when the window is deactivated. To add or remove
  4213. this style, use the SetWindowPos function. <E>
  4214. <L WS_EX_TRANSPARENT> Specifies that a window created with this
  4215. style is to be transparent. That is, any windows that are
  4216. beneath the window are not obscured by the window. A window
  4217. created with this style receives WM_PAINT messages only after
  4218. all sibling windows beneath it have been updated. <E>
  4219. <L WS_EX_WINDOWEDGE> Specifies that a window has a border with
  4220. a raised edge. <E>
  4221. |</table>
  4222. See also Win32.hlp (topic CreateWindowEx).
  4223. }
  4224. property Cursor: HCursor read fCursor write SetCursor;
  4225. {* Current cursor. For most of controls, sets initially to IDC_ARROW. See
  4226. also ScreenCursor. }
  4227. procedure CursorLoad( Inst: Integer; ResName: PChar );
  4228. {* Loads Cursor from the resource. See also comments for Icon property. }
  4229. property Icon: HIcon read GetIcon write SetIcon;
  4230. {* |<#appbutton>
  4231. |<#form>
  4232. Icon. By default, icon of the Applet is used. To load icon from the
  4233. resource, use IconLoad or IconLoadCursor method - this is more correct, because
  4234. in such case a special flag is set to prevent attempts to destroy
  4235. shared icon object in the destructor of the control. }
  4236. procedure IconLoad( Inst: Integer; ResName: PChar );
  4237. {* |<#appbutton>
  4238. |<#form>
  4239. See Icon property. }
  4240. procedure IconLoadCursor( Inst: Integer; ResName: PChar );
  4241. {* |<#appbutton>
  4242. |<#form>
  4243. Loads Icon from the cursor resource. See also Icon property. }
  4244. property Menu: HMenu read fMenu write SetMenu;
  4245. {* Menu (or ID of control - for standard GUI controls). }
  4246. property HelpContext: Integer read fHelpContext write SetHelpContext;
  4247. {* Help context. }
  4248. function AssignHelpContext( Context: Integer ): PControl;
  4249. {* Assigns HelpContext and returns @ Self (can be used in initialization
  4250. of a control in a chain of "transparent" calls). }
  4251. procedure CallHelp( Context: Integer; CtxCtl: PControl {; CtlID: Integer} );
  4252. {* Method of a form or Applet. Call it to show help with the given context
  4253. ID. If the Context = 0, help contents is displayed. By default,
  4254. WinHelp is used. To allow using HtmlHelp, call AssignHtmlHelp global
  4255. function. When WinHelp used, HelpPath variable can be assigned directly.
  4256. If HelpPath variable is not assigned, application name
  4257. (and path) is used, with extension replaced to '.hlp'. }
  4258. property HelpPath: String read GetHelpPath write SetHelpPath;
  4259. {* Property of a form or an Applet. Change it to provide custom path to
  4260. WinHelp format help file. If HtmlHelp used, call global procedure
  4261. AssignHtmlHelp instead. }
  4262. property OnHelp: TOnHelp read fOnHelp write fOnHelp;
  4263. {* An event of a form, it is called when F1 pressed or help topic requested
  4264. by any other way. To prevent showing help, nullify Sender. Set Popup to
  4265. TRUE to provide showing help in a pop-up window. It is also possible to
  4266. change Context dynamically. }
  4267. property Caption: String read GetCaption write SetCaption;
  4268. {* |<#appbutton>
  4269. |<#form>
  4270. |<#button>
  4271. |<#bitbtn>
  4272. |<#label>
  4273. |<#wwlabel>
  4274. |<#3dlabel>
  4275. Caption of a window. For standard Windows buttons, labels and so on
  4276. not a caption of a window, but text of the window. }
  4277. property Text: String read GetCaption write SetCaption;
  4278. {* |<#edit>
  4279. |<#memo>
  4280. The same as Caption. To make more convenient with Edit controls. For
  4281. Rich Edit control, use property RE_Text. }
  4282. property SelStart: Integer read GetSelStart write SetSelStart;
  4283. {* |<#edit>
  4284. |<#memo>
  4285. |<#richedit>
  4286. |<#listbox>
  4287. |<#combo>
  4288. Start of selection (editbox - character position, listbox and combobox -
  4289. index of [the first] selected item). }
  4290. property SelLength: Integer read GetSelLength write SetSelLength;
  4291. {* |<#edit>
  4292. |<#memo>
  4293. |<#richedit>
  4294. |<#listbox>
  4295. |<#listview>
  4296. Length of selection (editbox - number of characters selected, multiline
  4297. listbox - number of items selected). }
  4298. property Selection: String read GetSelection write SetSelection;
  4299. {* |<#edit>
  4300. |<#memo>
  4301. |<#richedit>
  4302. Selected text (editbox, richedit) as string. Can be useful to replace
  4303. selection. For rich edit, use RE_Text[ reText, TRUE ], if you want to
  4304. read correctly characters from another locale then ANSI only. }
  4305. procedure SelectAll;
  4306. {* |<#edit>
  4307. |<#memo>
  4308. |<#richedit>
  4309. Makes all the text in editbox or RichEdit, or all items in listbox
  4310. selected. }
  4311. procedure ReplaceSelection( const Value: String; aCanUndo: Boolean );
  4312. {* |<#edit>
  4313. |<#memo>
  4314. |<#richedit>
  4315. Replaces selection (in edit, RichEdit). Unlike assigning new value
  4316. to Selection property, it is possible to specify, if operation can
  4317. be undone. }
  4318. procedure DeleteLines( FromLine, ToLine: Integer );
  4319. {* |<#edit>
  4320. |<#memo>
  4321. |<#richedit>
  4322. Deletes lines from FromLine to ToLine (inclusively, i.e. 0 to 0 deletes
  4323. one line with index 0). Current selection is restored as possible. }
  4324. property CurIndex: Integer read GetCurIndex write SetCurIndex;
  4325. {* |<#listbox>
  4326. |<#combo>
  4327. |<#toolbar>
  4328. Index of current item (for listbox, combobox) or button index pressed
  4329. or dropped down (for toolbar button, and only in appropriate event
  4330. handler call).
  4331. |<br>
  4332. You cannot use it to set or remove a selection in a multiple-selection
  4333. list box, so you should set option loNoExtendSel to true.
  4334. |<br>
  4335. In OnClick event handler, CurIndex has not yet changed. Use OnSelChange
  4336. to respond to selection changes. }
  4337. property Count: Integer read GetItemsCount write SetItemsCount;
  4338. {* |<#listbox>
  4339. |<#combo>
  4340. |<#listview>
  4341. |<#treeview>
  4342. |<#edit>
  4343. |<#memo>
  4344. |<#richedit>
  4345. |<#toolbar>
  4346. Number of items (listbox, combobox, listview) or lines (multiline
  4347. editbox, richedit control) or buttons (toolbar). It is possible to
  4348. assign a value to this property only for listbox control with loNoData
  4349. style and for list view control with lvoOwnerData style (virtual list
  4350. box and list view). }
  4351. property Items[ Idx: Integer ]: String read GetItems write SetItems;
  4352. {* |<#edit>
  4353. |<#listbox>
  4354. |<#combo>
  4355. |<#memo>
  4356. |<#richedit>
  4357. Obvious. Used with editboxes, listbox, combobox. With list view, use
  4358. property LVItems instead. }
  4359. function Item2Pos( ItemIdx: Integer ): Integer;
  4360. {* |<#edit>
  4361. |<#memo>
  4362. Only for edit controls: converts line index to character position. }
  4363. function Pos2Item( Pos: Integer ): Integer;
  4364. {* |<#edit>
  4365. |<#memo>
  4366. Only for edit controls: converts character position to line index. }
  4367. function EditTabChar: PControl;
  4368. {* |<#edit>
  4369. |<#memo>
  4370. Call this method (once) to provide insertion of tab character (code #9)
  4371. when tab key is pressed on keyboard. }
  4372. function IndexOf( const S: String ): Integer;
  4373. {* |<#listbox>
  4374. |<#combobox>
  4375. |<#tabcontrol>
  4376. Works for the most of control types, though some of those
  4377. have its own methods to search given item. If a control is not
  4378. list box or combobox, item is finding by enumerating all
  4379. the Items one by one. See also SearchFor method. }
  4380. function SearchFor( const S: String; StartAfter: Integer; Partial: Boolean ): Integer;
  4381. {* |<#listbox>
  4382. |<#combobox>
  4383. |<#tabcontrol>
  4384. Works for the most of control types, though some of those
  4385. have its own methods to search given item. If a control is not
  4386. list box or combobox, item is finding by enumerating all
  4387. the Items one by one. See also IndexOf method. }
  4388. property ItemSelected[ ItemIdx: Integer ]: Boolean read GetItemSelected write SetItemSelected;
  4389. {* |<#edit>
  4390. |<#memo>
  4391. |<#listbox>
  4392. |<#combo>
  4393. Returns True, if a line (in editbox) or an item (in listbox, combobox) is
  4394. selected.
  4395. Can be set only for listboxes. For listboxes, which are not multiselect, and
  4396. for combo lists, it is possible only to set to True, to change selection. }
  4397. property ItemData[ Idx: Integer ]: DWORD read GetItemData write SetItemData;
  4398. {* |<#listbox>
  4399. |<#combo>
  4400. Access to user-defined data, associated with the item of a list box and
  4401. combo box. }
  4402. property OnDropDown: TOnEvent read fOnDropDown write fOnDropDown;
  4403. {* |<#combo>
  4404. |<#toolbar>
  4405. Is called when combobox is dropped down (or drop-down button of
  4406. toolbar is pressed - see also OnTBDropDown). }
  4407. property OnCloseUp: TOnEvent read fOnCloseUp write fOnCloseUp;
  4408. {* |<#combo>
  4409. Is called when combobox is closed up. When drop down list is closed
  4410. because user pressed "Escape" key, previous selection is restored.
  4411. To test if it is so, call GetKeyState( VK_ESCAPE ) and check, if
  4412. negative value is returned (i.e. Escape key is pressed when event
  4413. handler is calling). }
  4414. property DroppedWidth: Integer read FDroppedWidth write SetDroppedWidth;
  4415. {* |<#combo>
  4416. Allows to change width of dropped down items list for combobox (only!)
  4417. control. }
  4418. property DroppedDown: Boolean read fDropped write SetDroppedDown;
  4419. {* |<#combo>
  4420. Dropped down state for combo box. Set it to TRUE or FALSE to change
  4421. dropped down state. }
  4422. procedure AddDirList( const Filemask: String; Attrs: DWORD );
  4423. {* |<#listbox>
  4424. |<#combo>
  4425. Can be used only with listbox and combobox - to add directory list items,
  4426. filtered by given Filemask (can contain wildcards) and Attrs. Following
  4427. flags can be combined in Attrs:
  4428. |<table border=0>
  4429. |&L=<tr><td>%1</td><td>
  4430. <L DDL_ARCHIVE> Include archived files. <E>
  4431. <L DDL_DIRECTORY> Includes subdirectories. Subdirectory names are
  4432. enclosed in square brackets ([ ]). <E>
  4433. <L DDL_DRIVES> Includes drives. Drives are listed in the form [-x-],
  4434. where x is the drive letter. <E>
  4435. <L DDL_EXCLUSIVE> Includes only files with the specified attributes.
  4436. By default, read-write files are listed even if DDL_READWRITE is
  4437. not specified. Also, this flag needed to list directories only,
  4438. etc. <E>
  4439. <L DDL_HIDDEN> Includes hidden files. <E>
  4440. <L DDL_READONLY> Includes read-only files. <E>
  4441. <L DDL_READWRITE> Includes read-write files with no additional
  4442. attributes. <E>
  4443. <L DDL_SYSTEM> Includes system files. <E>
  4444. </table>
  4445. If the listbox is sorted, directory items will be sorted (alpabetically). }
  4446. property OnBitBtnDraw: TOnBitBtnDraw read fOnBitBtnDraw write fOnBitBtnDraw;
  4447. {* |<#bitbtn>
  4448. Special event for BitBtn. Using it, it is possible to provide
  4449. additional effects, such as highlighting button text (by changing
  4450. its Font and other properties). If the handler returns True, it is
  4451. supposed that it made all drawing and there are no further drawing
  4452. occure. }
  4453. property BitBtnDrawMnemonic: Boolean read FBitBtnDrawMnemonic write SetBitBtnDrawMnemonic;
  4454. {* |<#bitbtn>
  4455. Set this property to TRUE to provide correct drawing of bit btn control
  4456. caption with '&' characters (to remove such characters, and underline
  4457. follow ones). }
  4458. property TextShiftX: Integer read fTextShiftX write fTextShiftX;
  4459. {* |<#bitbtn>
  4460. Horizontal shift for bitbtn text when the bitbtn is pressed. }
  4461. property TextShiftY: Integer read fTextShiftY write fTextShiftY;
  4462. {* |<#bitbtn>
  4463. Vertical shift for bitbtn text when the bitbtn is pressed. }
  4464. property BitBtnImgIdx: Integer read GetBitBtnImgIdx write SetBitBtnImgIdx;
  4465. {* |<#bitbtn>
  4466. BitBtn image index for the first image in list view, used as bitbtn
  4467. image. It is used only in case when BitBtn is created with bboImageList
  4468. option. }
  4469. property BitBtnImgList: THandle read GetBitBtnImageList write SetBitBtnImageList;
  4470. {* |<#bitbtn>
  4471. BitBtn Image list. Assign image list handle to change it. }
  4472. function SetButtonIcon( aIcon: HIcon ): PControl;
  4473. {* |<#button>
  4474. Sets up button icon image and changes its styles. Returns button itself. }
  4475. function SetButtonBitmap( aBmp: HBitmap ): PControl;
  4476. {* |<#button>
  4477. Sets up button icon image and changes its styles. Returns button itself. }
  4478. property OnMeasureItem: TOnMeasureItem read fOnMeasureItem write SetOnMeasureItem;
  4479. {* |<#combo>
  4480. |<#listbox>
  4481. |<#listview>
  4482. This event is called for owner-drawn controls, such as list box, combo box,
  4483. list view with appropriate owner-drawn style. For fixed item height controls
  4484. (list box with loOwnerDrawFixed style, combobox with coOwnerDrawFixed and
  4485. list view with lvoOwnerDrawFixed option) this event is called once. For
  4486. list box with loOwnerDrawVariable style and for combobox with coOwnerDrawVariable
  4487. style this event is called for every item. }
  4488. property DefaultBtn: Boolean index 13
  4489. {$IFDEF F_P} read GetDefaultBtn
  4490. {$ELSE DELPHI} read fDefaultBtn
  4491. {$ENDIF F_P/DELPHI} write SetDefaultBtn;
  4492. {* |<#button>
  4493. |<#bitbtn>
  4494. Set this property to true to make control clicked when ENTER key is pressed.
  4495. This property uses OnMessage event of the parent form, storing it into
  4496. fOldOnMessage field and calling in chain. So, assign default button
  4497. after setting OnMessage event for the form. }
  4498. property CancelBtn: Boolean index 27
  4499. {$IFDEF F_P} read GetDefaultBtn
  4500. {$ELSE DELPHI} read fCancelBtn
  4501. {$ENDIF F_P/DELPHI} write SetDefaultBtn;
  4502. {* |<#button>
  4503. |<#bitbtn>
  4504. Set this property to true to make control clicked when escape key is pressed.
  4505. This property uses OnMessage event of the parent form, storing it into
  4506. fOldOnMessage field and calling in chain. So, assign cancel button
  4507. after setting OnMessage event for the form. }
  4508. function AllBtnReturnClick: PControl;
  4509. {* Call this method for a form or any its control to provide clicking
  4510. a focused button when ENTER pressed. By default, a button can be clicked
  4511. only by SPACE key from the keyboard, or by mouse. }
  4512. property IgnoreDefault: Boolean read fIgnoreDefault write fIgnoreDefault;
  4513. {* Change this property to TRUE to ignore default button reaction on
  4514. press ENTER key when a focus is grabbed of the control. Default
  4515. value is different for different controls. By default, DefaultBtn
  4516. ignored in memo, richedit (even if read-only). }
  4517. property Color: TColor read fColor write SetCtlColor;
  4518. {* Property Color is one of the most common for all visual
  4519. elements (like form, control etc.) Please note, that standard GUI button
  4520. can not change its color and the most characteristics of the Font. Also,
  4521. standard button can not become Transparent. Use bitbtn for such purposes.
  4522. Also, changing Color property for some kinds of control has no effect (rich edit,
  4523. list view, tree view, etc.). To solve this, use native (for such controls)
  4524. color property, or call Perform method with appropriate message to set the
  4525. background color. }
  4526. property Font: PGraphicTool read GetFont;
  4527. {* If the Font property is not accessed, correspondent TGraphicTool object
  4528. is not created and its methods are not included into executable. Leaving
  4529. properties Font and Brush untouched can economy executable size a lot. }
  4530. property Brush: PGraphicTool read GetBrush;
  4531. {* If not accessed, correspondent TGraphicTool object is not created
  4532. and its methods are not referenced. See also note on Font property. }
  4533. property Ctl3D: Boolean read fCtl3D write SetCtl3D;
  4534. {* Inheritable from parent controls to child ones. }
  4535. procedure Show;
  4536. {* |<#appbutton>
  4537. |<#form>
  4538. Makes control visible and activates it. }
  4539. function ShowModal: Integer;
  4540. {* |<#form>
  4541. Can be used only with a forms to show it modal. See also global function
  4542. ShowMsgModal.
  4543. |<br>
  4544. To use a form as a modal, it is possible to make it either auto-created
  4545. or dynamically created. For a first case, You (may be prefer to hide a
  4546. form after showing it as a modal:
  4547. !
  4548. ! procedure TForm1.Button1Click( Sender: PObj );
  4549. ! begin
  4550. ! Form2.Form.ShowModal;
  4551. ! Form2.Form.Hide;
  4552. ! end;
  4553. !
  4554. Another way is to create modal form just before showing it (this economies
  4555. system resources):
  4556. !
  4557. ! procedure TForm1.Button1Click( Sender: PObj );
  4558. ! begin
  4559. ! NewForm2( Form2, Applet );
  4560. ! Form2.Form.ShowModal;
  4561. ! Form2.Form.Free; // Never call Form2.Free or Form2.Form.Close
  4562. ! end; // but always Form2.Form.Free; (!)
  4563. !
  4564. In samples above, You certainly can place any wished code before and after
  4565. calling ShowModal method.
  4566. |<br>
  4567. Do not forget that if You have more than a single form in your project,
  4568. separate Applet object should be used.
  4569. |<br>
  4570. See also ShowModalEx.
  4571. }
  4572. function ShowModalParented( const AParent: PControl ): Integer;
  4573. {* by Alexander Pravdin. The same as ShowModal, but with a certain
  4574. form as a parent. }
  4575. function ShowModalEx: Integer;
  4576. {* The same as ShowModal, but all the windows of current thread are
  4577. disabled while showing form modal. This is useful if KOL form from
  4578. a DLL is used modally in non-KOL application. }
  4579. property ModalResult: Integer read fModalResult write
  4580. {$IFDEF USE_SETMODALRESULT}
  4581. SetModalResult;
  4582. {$ELSE}
  4583. fModalResult;
  4584. {$ENDIF}
  4585. {* |<#form>
  4586. Modal result. Set it to value<>0 to stop modal dialog. By agreement,
  4587. value 1 corresponds 'OK', 2 - 'Cancel'. But it is totally by decision
  4588. of yours how to interpret this value. }
  4589. property Modal: Boolean read GetModal;
  4590. {* |<#form>
  4591. TRUE, if the form is shown modal. }
  4592. property ModalForm: PControl read fModalForm write fModalForm;
  4593. {* |<#form>
  4594. |<#appbutton>
  4595. Form currently shown modal from this form or from Applet. }
  4596. procedure Hide;
  4597. {* |<#appbutton>
  4598. |<#form>
  4599. Makes control hidden. }
  4600. property OnShow: TOnEvent read FOnShow write SetOnShow;
  4601. {* Is called when a control or form is to be shown. This event is not fired
  4602. for a form, if its WindowState initially is set to wsMaximized or
  4603. wsMinimized. This behaviour is by design (the window does not receive
  4604. WM_SHOW message in such case). }
  4605. property OnHide: TOnEvent read FOnHide write SetOnHide;
  4606. {* Is called when a control or form becomes hidden. }
  4607. property WindowState: TWindowState read GetWindowState write SetWindowState;
  4608. {* |<#form>
  4609. Window state. }
  4610. property Canvas: PCanvas read GetCanvas;
  4611. {* |<#paintbox>
  4612. Placeholder for Canvas: PCanvas. But in KOL, it is possible to
  4613. create applets without canvases at all. To do so, avoid using
  4614. Canvas and use DC directly (which is passed in OnPaint event). }
  4615. function CallDefWndProc( var Msg: TMsg ): Integer;
  4616. {* Function to be called in WndProc method to redirect message handling
  4617. to default window procedure. }
  4618. function DoSetFocus: Boolean;
  4619. {* Sets focus for Enabled window. Returns True, if success. }
  4620. procedure MinimizeNormalAnimated;
  4621. {* |<#form>
  4622. Apply this method to a main form (not to another form or Applet,
  4623. even when separate Applet control is not used and main form matches it!).
  4624. This provides normal animated visual minimization for the application.
  4625. It therefore has no effect, if animation during minimize/resore is
  4626. turned off by user. }
  4627. property OnMessage: TOnMessage read fOnMessage write fOnMessage;
  4628. {* |<#appbutton>
  4629. |<#form>
  4630. Is called for every message processed by TControl object. And for
  4631. Applet window, this event is called also for all messages, handled by
  4632. all its child windows (forms). }
  4633. function IsMainWindow: Boolean;
  4634. {* |<#appbutton>
  4635. |<#form>
  4636. Returns True, if a window is the main in application (created first
  4637. after the Applet, or matches the Applet). }
  4638. property IsApplet: Boolean read FIsApplet;
  4639. {* Returns true, if the control is created using NewApplet (or CreateApplet).
  4640. }
  4641. property IsForm: Boolean read fIsForm;
  4642. {* Returns True, if the object is form window. }
  4643. property IsMDIChild: Boolean read fIsMDIChild;
  4644. {* Returns TRUE, if the object is MDI child form. In such case, IsForm also
  4645. returns TRUE. }
  4646. property IsControl: Boolean read fIsControl;
  4647. {* Returns True, is the control is control (not form or applet). }
  4648. property IsButton: Boolean read fIsButton;
  4649. {* Returns True, if the control is button-like or containing buttons (button,
  4650. bitbtn, checkbox, radiobox, toolbar). }
  4651. function ProcessMessage: Boolean;
  4652. {* |<#appbutton>
  4653. Processes one message. See also ProcessMessages. }
  4654. procedure ProcessMessages;
  4655. {* |<#appbutton>
  4656. Processes pending messages during long cycle of calculation,
  4657. allowing to window to be repainted if needed and to respond to other
  4658. messages. But if there are no such messages, your application can be
  4659. stopped until such one appear in messages queue. To prevent such
  4660. situation, use method ProcessPendingMessages instead. }
  4661. procedure ProcessMessagesEx;
  4662. {* Version of ProcessMessages, which works always correctly, even if
  4663. the application is minimized or background. }
  4664. procedure ProcessPendingMessages;
  4665. {* |<#appbutton>
  4666. Similar to ProcessMessages, but without waiting of
  4667. message in messages queue. I.e., if there are no pending
  4668. messages, this method immediately returns control to your
  4669. code. This method is better to call during long cycle of
  4670. calculation (then ProcessMessages). }
  4671. procedure ProcessPaintMessages;
  4672. {* }
  4673. function WndProc( var Msg: TMsg ): Integer; virtual;
  4674. {* Responds to all Windows messages, posted (sended) to the
  4675. window, before all other proceeding. You can override it in
  4676. derived controls, but in KOL there are several other ways
  4677. to control message flow of existing controls without deriving
  4678. another costom controls for only such purposes. See OnMessage,
  4679. AttachProc. }
  4680. property HasBorder: Boolean read GetHasBorder write SetHasBorder;
  4681. {* |<#form>
  4682. Obvious. Form-aware. }
  4683. property HasCaption: Boolean read GetHasCaption write SetHasCaption;
  4684. {* |<#form>
  4685. Obvious. Form-aware. }
  4686. property CanResize: Boolean read GetCanResize write SetCanResize;
  4687. {* |<#form>
  4688. Obvious. Form-aware. }
  4689. property StayOnTop: Boolean read GetStayOnTop write SetStayOnTop;
  4690. {* |<#form>
  4691. Obvious. Form-aware, but can be applied to controls. }
  4692. property Border: Integer read fMargin write fMargin;
  4693. {* |<#form>
  4694. Distance between edges and child controls and between child
  4695. controls by default (if methods PlaceRight, PlaceDown, PlaceUnder,
  4696. ResizeParent, ResizeParentRight, ResizeParentBottom are called).
  4697. |<br>
  4698. Originally was named Margin, now I recommend to use the name 'Border' to
  4699. avoid confusion with MarginTop, MarginBottom, MarginLeft and
  4700. MarginRight properties.
  4701. |<br>
  4702. Initial value is always 2. Border property is used in realigning
  4703. child controls (when its Align property is not caNone), and value
  4704. of this property determines size of borders between edges of children
  4705. and its parent and between aligned controls too.
  4706. |<br>
  4707. See also properties MarginLeft, MarginRight, MarginTop, MarginBottom. }
  4708. function SetBorder( Value: Integer ): PControl;
  4709. {* Assigns new Border value, and returns @ Self. }
  4710. property Margin: Integer read fMargin write fMargin;
  4711. {* |<#form>
  4712. Old name for property Border. }
  4713. property MarginTop: Integer index 1
  4714. {$IFDEF F_P} read GetClientMargin
  4715. {$ELSE DELPHI} read fClientTop
  4716. {$ENDIF F_P/DELPHI} write SetClientMargin;
  4717. {* Additional distance between true window client top and logical top of
  4718. client rectangle. This value is added to Top of rectangle, returning
  4719. by property ClientRect. Together with other margins and property Border,
  4720. this property allows to change view of form for case, that Align property
  4721. is used to align controls on parent (it is possible to provide some
  4722. distance from child controls to its parent, and between child controls.
  4723. |<br>
  4724. Originally this property was introduced to compensate incorrect
  4725. ClientRect property, calculated for some types of controls.
  4726. |<br>
  4727. See also properties Border, MarginBottom, MarginLeft, MarginRight. }
  4728. property MarginBottom: Integer index 2
  4729. {$IFDEF F_P} read GetClientMargin
  4730. {$ELSE DELPHI} read fClientBottom
  4731. {$ENDIF F_P/DELPHI} write SetClientMargin;
  4732. {* The same as MarginTop, but a distance between true window Bottom of
  4733. client rectangle and logical bottom one. Take in attention, that this value
  4734. should be POSITIVE to make logical bottom edge located above true edge.
  4735. |<br>
  4736. See also properties Border, MarginTop, MarginLeft, MarginRight. }
  4737. property MarginLeft: Integer index 3
  4738. {$IFDEF F_P} read GetClientMargin
  4739. {$ELSE DELPHI} read fClientLeft
  4740. {$ENDIF F_P/DELPHI} write SetClientMargin;
  4741. {* The same as MarginTop, but a distance between true window Left of
  4742. client rectangle and logical left edge.
  4743. |<br>
  4744. See also properties Border, MarginTop, MarginRight, MarginBottom. }
  4745. property MarginRight: Integer index 4
  4746. {$IFDEF F_P} read GetClientMargin
  4747. {$ELSE DELPHI} read fClientRight
  4748. {$ENDIF F_P/DELPHI} write SetClientMargin;
  4749. {* The same as MarginLeft, but a distance between true window Right of
  4750. client rectangle and logical bottom one. Take in attention, that this value
  4751. should be POSITIVE to make logical right edge located left of true edge.
  4752. |<br>
  4753. See also properties Border, MarginTop, MarginLeft, MarginBottom. }
  4754. property Tabstop: Boolean read fTabstop write fTabstop;
  4755. {* True, if control can be focused using tabulating between controls.
  4756. Set it to False to make control unavailable for keyboard, but only
  4757. for mouse. }
  4758. property TabOrder: Integer read fTabOrder write SetTabOrder;
  4759. {* Order of tabulating of controls. Initially, TabOrder is equal to
  4760. creation order of controls. If TabOrder changed, TabOrder of
  4761. all controls with not less value of one is shifted up. To place
  4762. control before another, assign TabOrder of one to another.
  4763. For example:
  4764. ! Button1.TabOrder := EditBox1.TabOrder;
  4765. In code above, Button1 is placed just before EditBox1 in tabulating
  4766. order (value of TabOrder of EditBox1 is incremented, as well as
  4767. for all follow controls). }
  4768. property Focused: Boolean read GetFocused write SetFocused;
  4769. {* True, if the control is current on form (but check also, what form
  4770. itself is focused). For form it is True, if the form is active (i.e.
  4771. it is foreground and capture keyboard). Set this value to True to make
  4772. control current and focused (if applicable). }
  4773. function BringToFront: PControl;
  4774. {* Changes z-order of the control, bringing it to the topmost level. }
  4775. function SendToBack: PControl;
  4776. {* Changes z-order of the control, sending it to the back of siblings. }
  4777. property TextAlign: TTextAlign read GetTextAlign write SetTextAlign;
  4778. {* |<#label>
  4779. |<#panel>
  4780. |<#button>
  4781. |<#bitbtn>
  4782. |<#edit>
  4783. |<#memo>
  4784. Text horizontal alignment. Applicable to labels, buttons,
  4785. multi-line edit boxes, panels. }
  4786. property VerticalAlign: TVerticalAlign read GetVerticalAlign write SetVerticalAlign;
  4787. {* |<#button>
  4788. |<#label>
  4789. |<#panel>
  4790. Text vertical alignment. Applicable to buttons, labels and panels. }
  4791. property WordWrap: Boolean read fWordWrap write fWordWrap;
  4792. {* TRUE, if this is a label, created using NewWordWrapLabel. }
  4793. property ShadowDeep: Integer read FShadowDeep write SetShadowDeep;
  4794. {* |<#3dlabel>
  4795. Deep of a shadow (for label effect only, created calling NewLabelEffect). }
  4796. property CannotDoubleBuf: Boolean read fCannotDoubleBuf write fCannotDoubleBuf;
  4797. {* }
  4798. property DoubleBuffered: Boolean read fDoubleBuffered write SetDoubleBuffered;
  4799. {* Set it to true for some controls, which are flickering in repainting
  4800. (like label effect). Slow, and requires additional code. This property
  4801. is inherited by all child controls.
  4802. |<br>&nbsp;&nbsp;&nbsp;
  4803. Note: RichEdit control can not become DoubleBuffered. }
  4804. //function IsSelfOrParentDblBuf: Boolean;
  4805. {* Returns true, if DoubleBuffered or one of parents is DoubleBuffered. }
  4806. function DblBufTopParent: PControl;
  4807. {* Returns the topmost DoubleBuffered Parent control. }
  4808. property Transparent: Boolean read fTransparent write SetTransparent;
  4809. {* Set it to true to get special effects. Transparency also uses
  4810. DoubleBuffered and inherited by child controls.
  4811. |<br>&nbsp;&nbsp;&nbsp;
  4812. Please note, that some controls can not be shown properly, when
  4813. Transparent is set to True for it. If You want to make edit control
  4814. transparent (e.g., over gradient filled panel), handle its OnChanged
  4815. property and call there Invalidate to provide repainting of edit
  4816. control content. Note also, that for RichEdit control property
  4817. Transparent has no effect (as well as DoubleBuffered). But special
  4818. property RE_Transparent is designed especially for RichEdit control
  4819. (it works fine, but with great number of flicks while resizing
  4820. of a control). Another note is about Edit control. To allow editing
  4821. of transparent edit box, it is necessary to invalidate it for
  4822. every pressed character. Or, use Ed_Transparent property instead. }
  4823. property Ed_Transparent: Boolean read fTransparent write EdSetTransparent;
  4824. {* |<#edit>
  4825. |<#memo>
  4826. Use this property for editbox to make it really Transparent. Remember,
  4827. that though Transparent property is inherited by child controls from
  4828. its parent, this is not so for Ed_Transparent. So, it is necessary to
  4829. set Ed_Transparent to True for every edit control explicitly. }
  4830. property AlphaBlend: Integer read fAlphaBlend write SetAlphaBlend;
  4831. {* |<#form>
  4832. If assigned to 0..254, makes window (form or control) semi-transparent
  4833. (Win2K only).
  4834. |<br>
  4835. Depending on value assigned, it is possible to adjust transparency
  4836. level ( 0 - totally transparent, 255 - totally opaque). }
  4837. property LookTabKeys: TTabKeys read fLookTabKeys write fLookTabKeys;
  4838. {* Set of keys which can be used as tabulation keys in a control. }
  4839. procedure GotoControl( Key: DWORD );
  4840. {* |<#form>
  4841. Emulates tabulation key press w/o sending message to current control.
  4842. Can be applied to a form or to any its control. If VK_TAB is used,
  4843. state of shift kay is checked in: if it is pressed, tabulate is in
  4844. backward direction. }
  4845. property SubClassName: String read get_ClassName write set_ClassName;
  4846. {* Name of window class - unique for every window class
  4847. in every run session of a program. }
  4848. property OnClose: TOnEventAccept read fOnClose write fOnClose;
  4849. {* |<#form>
  4850. |<#applet>
  4851. Called before closing the window. It is possible to set Accept
  4852. parameter to False to prevent closing the window. This event events
  4853. is not called when windows session is finishing (to handle this
  4854. event, handle WM_QUERYENDSESSION message, or assign OnQueryEndSession
  4855. event to another or the same event handler). }
  4856. property OnQueryEndSession: TOnEventAccept read fOnQueryEndSession write SetOnQueryEndSession;
  4857. {* |<#form>
  4858. |<#applet>
  4859. Called when WM_QUERYENDSESSION message come in. It is possible to set Accept
  4860. parameter to False to prevent closing the window (in such case session ending
  4861. is halted). It is possible to check CloseQueryReason property to find out,
  4862. why event occur. }
  4863. property CloseQueryReason: TCloseQueryReason read fCloseQueryReason;
  4864. {* Reason why OnClose or OnQueryEndSession called. }
  4865. property OnMinimize: TOnEvent index 0
  4866. {$IFDEF F_P} read GetOnMinMaxRestore
  4867. {$ELSE DELPHI} read fOnMinimize
  4868. {$ENDIF F_P/DELPHI} write SetOnMinMaxRestore;
  4869. {* |<#form>
  4870. Called when window is minimized. }
  4871. property OnMaximize: TOnEvent index 8
  4872. {$IFDEF F_P} read GetOnMinMaxRestore
  4873. {$ELSE DELPHI} read fOnMaximize
  4874. {$ENDIF F_P/DELPHI} write SetOnMinMaxRestore;
  4875. {* |<#form>
  4876. Called when window is maximized. }
  4877. property OnRestore: TOnEvent index 16
  4878. {$IFDEF F_P} read GetOnMinMaxRestore
  4879. {$ELSE DELPHI} read fOnRestore
  4880. {$ENDIF F_P/DELPHI} write SetOnMinMaxRestore;
  4881. {* |<#form>
  4882. Called when window is restored from minimized or maximized state. }
  4883. property UpdateRgn: HRgn read fUpdRgn;
  4884. {* A handle of update region. Valid only in OnPaint method. You
  4885. can use it to improve painting (for speed), if necessary. When
  4886. UpdateRgn is obtained in response to WM_PAINT message, value
  4887. of the property EraseBackground is used to pass it to the API
  4888. function GetUpdateRgn. If UpdateRgn = 0, this means that entire
  4889. window should be repainted. Otherwise, You (e.g.) can check
  4890. if the rectangle is in clipping region using API function
  4891. RectInRegion. }
  4892. property EraseBackground: Boolean read fEraseUpdRgn write fEraseUpdRgn;
  4893. {* This value is used to pass it to the API function GetUpdateRgn,
  4894. when UpadateRgn property is obtained first in responce to WM_PAINT
  4895. message. If EraseBackground is set to True, system is responsible
  4896. for erasing background of update region before painting. If not
  4897. (default), the entire region invalidated should be painted by your
  4898. event handler. }
  4899. property OnPaint: TOnPaint read fOnPaint write SetOnPaint;
  4900. {* Event to set to override standard control painting. Can be applied
  4901. to any control (though originally was designed only for paintbox
  4902. control). When an event handler is called, it is possible to use
  4903. UpdateRgn to examine what parts of window require painting to
  4904. improve performance of the painting operation. }
  4905. property OnPrePaint: TOnPaint read fOnPrePaint write fOnPrePaint;
  4906. {* Only for graphic controls. If you assign it, call Invalidate also. }
  4907. property OnPostPaint: TOnPaint read fOnPostPaint write fOnPostPaint;
  4908. {* Only for graphic controls. If you assign it, call Invalidate also. }
  4909. property OnEraseBkgnd: TOnPaint read fOnEraseBkgnd write SetOnEraseBkgnd;
  4910. {* This event allows to override erasing window background in response
  4911. to WM_ERASEBKGND message. This allows to add some decorations to
  4912. standard controls without overriding its painting in total.
  4913. Note: When erase background, remember, that property ClientRect can
  4914. return not true client rectangle of the window - use GetClientRect
  4915. API function instead. For example:
  4916. !
  4917. !var BkBmp: HBitmap;
  4918. !
  4919. !procedure TForm1.KOLForm1FormCreate(Sender: PObj);
  4920. !begin
  4921. ! Toolbar1.OnEraseBkgnd := DecorateToolbar;
  4922. ! BkBmp := LoadBitmap( hInstance, 'BK1' );
  4923. !end;
  4924. !
  4925. !procedure TForm1.DecorateToolbar(Sender: PControl; DC: HDC);
  4926. !var CR: TRect;
  4927. !begin
  4928. ! GetClientRect( Sender.Handle, CR );
  4929. ! Sender.Canvas.Brush.BrushBitmap := BkBmp;
  4930. ! Sender.Canvas.FillRect( CR );
  4931. !end;
  4932. !
  4933. }
  4934. property OnClick: TOnEvent read fOnClick write fOnClick;
  4935. {* |<#button>
  4936. |<#checkbox>
  4937. |<#radiobox>
  4938. |<#toolbar>
  4939. Called on click at control. For buttons, checkboxes and radioboxes
  4940. is called regadless if control clicked by mouse or keyboard. For toolbar,
  4941. the same event is used for all toolbar buttons and toolbar itself.
  4942. To determine which toolbar button is clicked, check CurIndex property.
  4943. And note, that all the buttons including separator buttons are enumerated
  4944. starting from 0. Though images are stored (and prepared) only for
  4945. non-separator buttons. And to determine, if toolbar button was clicked
  4946. with right mouse button, check RightClick property. }
  4947. property RightClick: Boolean read fRightClick;
  4948. {* |<#toolbar>
  4949. |<#listview>
  4950. Use this property to determine which mouse button was clicked
  4951. (applicable to toolbar in the OnClick event handler). }
  4952. property OnEnter: TOnEvent read fOnEnter write fOnEnter;
  4953. {* Called when control receives focus. }
  4954. property OnLeave: TOnEvent read fOnLeave write fOnLeave;
  4955. {* Called when control looses focus. }
  4956. property OnChange: TOnEvent read fOnChange write fOnChange;
  4957. {* |<#edit>
  4958. |<#memo>
  4959. |<#listbox>
  4960. |<#combo>
  4961. |<#tabcontrol>
  4962. Called when edit control is changed, or selection in listbox or
  4963. current index in combobox is changed (but if OnSelChanged assigned,
  4964. the last is called for change selection). To respond to check/uncheck
  4965. checkbox or radiobox events, use OnClick instead. }
  4966. property OnSelChange: TOnEvent read fOnSelChange write fOnSelChange;
  4967. {* |<#richedit>
  4968. |<#listbox>
  4969. |<#combo>
  4970. |<#treeview>
  4971. Called for rich edit control, listbox, combobox or treeview when current selection
  4972. (range, or current item) is changed. If not assigned, but OnChange is
  4973. assigned, OnChange is called instead. }
  4974. property OnResize: TOnEvent read FOnResize write SetOnResize;
  4975. {* Called whenever control receives message WM_SIZE (thus is, if
  4976. control is resized. }
  4977. property OnMove: TOnEvent read FOnMove write SetOnMove;
  4978. {* Called whenever control receives message WM_MOVE (i.e. when control is
  4979. moved over its parent). }
  4980. property MinSizePrev: Integer read fSplitMinSize1 write fSplitMinSize1;
  4981. {* |<#splitter>
  4982. Minimal allowed (while dragging splitter) size of previous control
  4983. for splitter (see NewSplitter). }
  4984. property SplitMinSize1: Integer read fSplitMinSize1 write fSplitMinSize1;
  4985. {* The same as MinSizePrev. }
  4986. property MinSizeNext: Integer read fSplitMinSize2 write fSplitMinSize2;
  4987. {* |<#splitter>
  4988. Minimal allowed (while dragging splitter) size of the rest of parent
  4989. of splitter or of SecondControl (see NewSplitter). }
  4990. property SplitMinSize2: Integer read fSplitMinSize2 write fSplitMinSize2;
  4991. {* The same as MinSizeNext. }
  4992. property SecondControl: PControl read fSecondControl write fSecondControl;
  4993. {* |<#splitter>
  4994. Second control to check (while dragging splitter) if its size not less
  4995. than SplitMinSize2 (see NewSplitter). By default, second control is
  4996. not necessary, and needed only in rare case when SecondControl can not
  4997. be determined automatically to restrict splitter right (bottom) position. }
  4998. property OnSplit: TOnSplit read fOnSplit write fOnSplit;
  4999. {* |<#splitter>
  5000. Called when splitter control is dragging - to allow for
  5001. your event handler to decide if to accept new size of
  5002. left (top) control, and new size of the rest area of parent. }
  5003. property Dragging: Boolean read FDragging;
  5004. {* |<#splitter>
  5005. True, if splitter control is dragging now by user with left
  5006. mouse button. Also, this property can be used to detect if the control
  5007. is dragging with mouse (after calling DragStartEx method). }
  5008. procedure DragStart;
  5009. {* Call this method for a form or control to drag it with left mouse button,
  5010. when mouse left button is already down. Dragging is stopped when left mouse
  5011. button is released. See also DragStartEx, DragStopEx. }
  5012. procedure DragStartEx;
  5013. {* Call this method to start dragging the form by mouse. To stop
  5014. dragging, call DragStopEx method. (Tip: to detect mouse up event,
  5015. use OnMouseUp event of the dragging control). This method can be used
  5016. to move any control with the mouse, not only entire form. State of
  5017. mouse button is not significant. Determine dragging state of the control
  5018. checking its Dragging property. }
  5019. procedure DragStopEx;
  5020. {* Call this method to stop dragging the form (started by DragStopEx). }
  5021. procedure DragItem( OnDrag: TOnDrag );
  5022. {* Starts dragging something with mouse. During the process,
  5023. callback function OnDrag is called, which allows to control
  5024. drop target, change cursor shape, etc. }
  5025. property OnKeyDown: TOnKey read fOnKeyDown write SetOnKeyDown;
  5026. {* Obvious. }
  5027. property OnKeyUp: TOnKey read fOnKeyUp write SetOnKeyUp;
  5028. {* Obvious. }
  5029. property OnChar: TOnChar read fOnChar write SetOnChar;
  5030. {* Obvious. }
  5031. property OnMouseDown: TOnMouse read fOnMouseDown write SetMouseDown;
  5032. {* Obvious. }
  5033. property OnMouseUp: TOnMouse read fOnMouseUp write SetMouseUp;
  5034. {* Obvious. }
  5035. property OnMouseMove: TOnMouse read fOnMouseMove write SetMouseMove;
  5036. {* Obvious. }
  5037. property OnMouseDblClk: TOnMouse read fOnMouseDblClk write SetMouseDblClk;
  5038. {* Obvious. }
  5039. property OnMouseWheel: TOnMouse read fOnMouseWheel write SetMouseWheel;
  5040. {* Obvious. }
  5041. property OnMouseEnter: TOnEvent read fOnMouseEnter write SetOnMouseEnter;
  5042. {* Is called when mouse is entered into control. See also OnMouseLeave. }
  5043. property OnMouseLeave: TOnEvent read fOnMouseLeave write SetOnMouseLeave;
  5044. {* Is called when mouse is leaved control. If this event is assigned,
  5045. then mouse is captured on mouse enter event to handle all other
  5046. mouse events until mouse cursor leaves the control. }
  5047. property OnTestMouseOver: TOnTestMouseOver read fOnTestMouseOver write SetOnTestMouseOver;
  5048. {* |<#bitbtn>
  5049. Special event, which allows to extend OnMouseEnter / OnMouseLeave
  5050. (and also Flat property for BitBtn control). If a handler is assigned
  5051. to this event, actual testing whether mouse is in control or not,
  5052. is occuring in the handler. So, it is possible to simulate more
  5053. careful hot tracking for controls with non-rectangular shape (such
  5054. as glyphed BitBtn control). }
  5055. property MouseInControl: Boolean read fMouseInControl;
  5056. {* |<#bitbtn>
  5057. This property can return True only if OnMouseEnter / OnMouseLeave
  5058. event handlers are set for a control (or, for BitBtn, property Flat
  5059. is set to True. Otherwise, False is returned always. }
  5060. property Flat: Boolean read fFlat write SetFlat;
  5061. {* |<#bitbtn>
  5062. Set it to True for BitBtn, to provide either flat border for a button
  5063. or availability of "highlighting" (correspondent to glyph index 4).
  5064. |<br>
  5065. Note: this can work incorrectly a bit under win95 without comctl32.dll
  5066. updated. Therefore, application will launch. To enforce correct working
  5067. even under Win95, use your own timer, which event handler checks for
  5068. mouse over bitbtn control, e.g.:
  5069. ! procedure TForm1.Timer1Timer(Sender: PObj);
  5070. ! var P: TPoint;
  5071. ! begin
  5072. ! if not BitBtn1.MouseInControl then Exit;
  5073. ! GetCursorPos( P );
  5074. ! P := BitBtn1.Screen2Client( P );
  5075. ! if not PtInRect( BitBtn1.ClientRect, P ) then
  5076. ! begin
  5077. ! BitBtn1.Flat := FALSE;
  5078. ! BitBtn1.Flat := TRUE;
  5079. ! end;
  5080. ! end;
  5081. }
  5082. property RepeatInterval: Integer read fRepeatInterval write fRepeatInterval;
  5083. {* |<#bitbtn>
  5084. If this property is set to non-zero, it is interpreted (for BitBtn
  5085. only) as an interval in milliseconds between repeat button down events,
  5086. which are generated after first mouse or button click and until
  5087. button is released. Though, if the button is pressed with keyboard (with
  5088. space key), RepeatInterval value is ignored and frequency of repeatitive
  5089. clicking is determined by user keyboard settings only. }
  5090. function LikeSpeedButton: PControl;
  5091. {* |<#button>
  5092. |<#bitbtn>
  5093. Transparent method (returns control itself). Makes button not focusable. }
  5094. function Add( const S: String ): Integer;
  5095. {* |<#listbox>
  5096. |<#combo>
  5097. Only for listbox and combobox. }
  5098. function Insert( Idx: Integer; const S: String ): Integer;
  5099. {* |<#listbox>
  5100. |<#combo>
  5101. Only for listbox and combobox. }
  5102. procedure Delete( Idx: Integer );
  5103. {* |<#listbox>
  5104. |<#combo>
  5105. Only for listbox and combobox. }
  5106. procedure Clear;
  5107. {* Clears object content. Has different sense for different controls.
  5108. E.g., for label, editbox, button and other simple controls it
  5109. assigns empty string to Caption property. For listbox, combobox,
  5110. listview it deletes all items. For toolbar, it deletes all buttons.
  5111. Et so on. }
  5112. property Progress: Integer index ((PBM_SETPOS or $8000) shl 16) or PBM_GETPOS
  5113. read GetIntVal write SetIntVal;
  5114. {* |<#progressbar>
  5115. Only for ProgressBar. }
  5116. property MaxProgress: Integer index ((PBM_SETRANGE32 or $8000) shl 16) or PBM_GETRANGE
  5117. read GetIntVal write SetMaxProgress;
  5118. {* |<#progressbar>
  5119. Only for ProgressBar. 100 is the default value. }
  5120. property ProgressColor: TColor read fTextColor write SetProgressColor;
  5121. {* |<#progressbar>
  5122. Only for ProgressBar. }
  5123. property ProgressBkColor: TColor read fColor write SetCtlColor; //SetProgressBkColor;
  5124. {* |<#progressbar>
  5125. Obsolete. Now the same as Color. }
  5126. property StatusText[ Idx: Integer ]: PChar read GetStatusText write SetStatusText;
  5127. {* |<#form>
  5128. Only for forms to set/retrieve status text to/from given status panel.
  5129. Panels are enumerated from 0 to 254, 255 is to indicate simple
  5130. status bar. Size grip in right bottom corner of status window is
  5131. displayed only if form still CanResize.
  5132. |<br>
  5133. When a status text is set first time, status bar window is created
  5134. (always aligned to bottom), and form is resizing to preset client height.
  5135. While status bar is showing, client height value is returned without
  5136. height of status bar. To remove status bar, call RemoveStatus method for
  5137. a form.
  5138. |<br>
  5139. By default, text is left-aligned within the specified part of a status
  5140. window. You can embed tab characters (#9) in the text to center or
  5141. right-align it. Text to the right of a single tab character is centered,
  5142. and text to the right of a second tab character is right-aligned.
  5143. |<br>
  5144. If You use separate status bar onto several panels, these automatically
  5145. align its widths to the same value (width divided to number of panels).
  5146. To adjust status panel widths for every panel, use property StatusPanelRightX.
  5147. }
  5148. property SimpleStatusText: PChar index 255 read GetStatusText write SetStatusText;
  5149. {* |<#form>
  5150. Only for forms to set/retrive status text to/from simple status bar.
  5151. Size grip in right bottom corner of status window is displayed only
  5152. if form CanResize.
  5153. |<br>
  5154. When status text set first time, (simple) status bar window is created
  5155. (always aligned to bottom), and form is resizing to preset client height.
  5156. While status bar is showing, client height value is returned without
  5157. height of status bar. To remove status bar, call RemoveStatus method for
  5158. a form.
  5159. |<br>
  5160. By default, text is left-aligned within the specified part of a status
  5161. window. You can embed tab characters (#9) in the text to center or
  5162. right-align it. Text to the right of a single tab character is centered,
  5163. and text to the right of a second tab character is right-aligned.
  5164. }
  5165. property StatusCtl: PControl read fStatusCtl;
  5166. {* Pointer to Status bar control. To "create" child controls on
  5167. the status bar, first create it as a child of form, for instance, and
  5168. then change its property Parent, e.g.:
  5169. ! var Progress1: PControl;
  5170. ! ...
  5171. ! Progress1 := NewProgressBar( Form1 );
  5172. ! Progress1.Parent := Form1.StatusCtl;
  5173. (If you use MCK, code should be another a bit, and in this case it is
  5174. possible to create and adjust the control at design-time, and at run-time
  5175. change its parent control. E.g. (Progress1 is created at run-time here too):
  5176. ! Progress1 := NewProgressBar( Form );
  5177. ! Progress1.Parent := Form.StatusCtl;
  5178. ).
  5179. Do not forget to provide StatusCtl to be existing first (e.g. assign
  5180. one-space string to SimpleStatusText property of the form, for MCK do
  5181. so using Object Inspector).
  5182. }
  5183. property SizeGrip: Boolean read fSizeGrip write fSizeGrip;
  5184. {* Size grip for status bar. Has effect only before creating window. }
  5185. procedure RemoveStatus;
  5186. {* |<#form>
  5187. Call it to remove status bar from a form (created in result of assigning
  5188. value(s) to StatusText[], SimpleStatusText properties). When status bar is
  5189. removed, form is resized to preset client height. }
  5190. function StatusPanelCount: Integer;
  5191. {* |<#form>
  5192. Returns number of status panels defined in status bar. }
  5193. property StatusPanelRightX[ Idx: Integer ]: Integer read GetStatusPanelX write SetStatusPanelX;
  5194. {* |<#form>
  5195. Use this property to adjust status panel right edges (if the status bar is
  5196. divided onto several subpanels). If the right edge for the last panel is
  5197. set to -1 (by default) it is expanded to the right edge of a form window.
  5198. Otherwise, status bar can be shorter then form width. }
  5199. property StatusWindow: HWND read fStatusWnd;
  5200. {* |<#form>
  5201. Provided for case if You want to use API direct message sending to
  5202. status bar. }
  5203. property Color1: TColor read fColor1 write SetColor1;
  5204. {* |<#gradient>
  5205. Top line color for GradientPanel. }
  5206. property Color2: TColor read fColor2 write SetColor2;
  5207. {* |<#gradient>
  5208. |<#3Dlabel>
  5209. Bottom line color for GradientPanel, or shadow color for LabelEffect.
  5210. (If clNone, shadow color for LabelEffect is calculated as a mix bitween
  5211. TextColor and clBlack). }
  5212. property GradientStyle: TGradientStyle read FGradientStyle write SetGradientStyle;
  5213. {* |<#gradient>
  5214. Styles other then gsVertical and gsHorizontal has effect only for
  5215. gradient panel, created by NewGradientPanelEx. }
  5216. property GradientLayout: TGradientLayout read FGradientLayout write SetGradientLayout;
  5217. {* |<#gradient>
  5218. Has only effect for gradient panel, created by NewGradientPanelEx.
  5219. Ignored for styles gsVertical and gsHorizontal. }
  5220. //======== Image lists (for ListView, TreeView, ToolBar and TabControl):
  5221. property ImageListSmall: PImageList index 16 read GetImgListIdx write SetImgListIdx;
  5222. {* |<#listview>
  5223. Image list with small icons used with List View control. If not set,
  5224. last added (i.e. created with a control as an owner) image list with
  5225. small icons is used. }
  5226. property ImageListNormal: PImageList index 32 read GetImgListIdx write SetImgListIdx;
  5227. {* |<#listview>
  5228. |<#treeview>
  5229. |<#tabcontrol>
  5230. |<#bitbtn>
  5231. Image list with normal size icons used with List View control (or with
  5232. icons for BitBtn, TreeView, ToolBar or TabControl). If not set,
  5233. last added (i.e. created with a control as an owner) image list is used.
  5234. }
  5235. property ImageListState: PImageList index 0 read GetImgListIdx write SetImgListIdx;
  5236. {* |<#listview>
  5237. |<#treeview>
  5238. Image list used as a state images list for ListView or TreeView control. }
  5239. //========
  5240. function SetUnicode( Unicode: Boolean ): PControl;
  5241. {* |<#listview>
  5242. |<#treeview>
  5243. |<#tabcontrol>
  5244. Sets control as Unicode or not. The control itself is returned as for
  5245. other "transparent" functions. A conditional define UNICODE_CTRLS must
  5246. be added to a project to provide handling unicode messages. }
  5247. //======== TabControl-specific properties and methods:
  5248. property Pages[ Idx: Integer ]: PControl read GetPages;
  5249. {* |<#tabcontrol>
  5250. Returns controls, which can be used as parent for controls, placed on
  5251. different pages of a tab control. Use it like in follows example:
  5252. | Label1 := NewLabel( TabControl1.Pages[ 0 ], 'Label1' );
  5253. To find number of pages available, check out Count property of the tab
  5254. control. Pages are enumerated from 0 to Count - 1, as usual. }
  5255. property TC_Pages[ Idx: Integer ]: PControl read GetPages;
  5256. {* |<#tabcontrol>
  5257. The same as above. }
  5258. function TC_Insert( Idx: Integer; const TabText: String; TabImgIdx: Integer ): PControl;
  5259. {* |<#tabcontrol>
  5260. Inserts new tab before given, returns correspondent page control
  5261. (which can be used as a parent for controls to place on the page). }
  5262. procedure TC_Delete( Idx: Integer );
  5263. {* |<#tabcontrol>
  5264. Removes tab from tab control, destroying all its child controls. }
  5265. property TC_Items[ Idx: Integer ]: String read TCGetItemText write TCSetItemText;
  5266. {* |<#tabcontrol>
  5267. Text, displayed on tab control tabs. }
  5268. property TC_Images[ Idx: Integer ]: Integer read TCGetItemImgIDx write TCSetItemImgIdx;
  5269. {* |<#tabcontrol>
  5270. Image index for a tab in tab control. }
  5271. property TC_ItemRect[ Idx: Integer ]: TRect read TCGetItemRect;
  5272. {* |<#tabcontrol>
  5273. Item rectangle for a tab in tab control. }
  5274. procedure TC_SetPadding( cx, cy: Integer );
  5275. {* |<#tabcontrol>
  5276. Sets space padding around tab text in a tab of tab control. }
  5277. function TC_TabAtPos( x, y: Integer ): Integer;
  5278. {* |<#tabcontrol>
  5279. Returns index of tab, found at the given position (relative to
  5280. a client rectangle of tab control). If no tabs found at the
  5281. position, -1 is returned. }
  5282. function TC_DisplayRect: TRect;
  5283. {* |<#tabcontrol>
  5284. Returns rectangle, occupied by a page rather then tab. }
  5285. function TC_IndexOf(const S: String): Integer;
  5286. {* |<#tabcontrol>
  5287. By Mr Brdo. Index of page by its Caption. }
  5288. function TC_SearchFor(const S: String; StartAfter: Integer; Partial: Boolean): Integer;
  5289. {* |<#tabcontrol>
  5290. By Mr Brdo. Index of page by its Caption. }
  5291. //======== ListView style and options:
  5292. property LVStyle: TListViewStyle read fLVStyle write SetLVStyle;
  5293. {* |<#listview>
  5294. ListView style of view. Can be changed at run time. }
  5295. property LVOptions: TListViewOptions read fLVOptions write SetLVOptions;
  5296. {* |<#listview>
  5297. ListView options. Can be changed at run time. }
  5298. property LVTextColor: TColor index LVM_GETTEXTCOLOR
  5299. {$IFDEF F_P} read LVGetColorByIdx
  5300. {$ELSE DELPHI} read fTextColor
  5301. {$ENDIF F_P/DELPHI} write LVSetColorByIdx;
  5302. {* |<#listview>
  5303. ListView text color. Use it instead of TextColor. }
  5304. property LVTextBkColor: TColor index LVM_GETTEXTBKCOLOR
  5305. {$IFDEF F_P} read LVGetColorByIdx
  5306. {$ELSE DELPHI} read fLVTextBkColor
  5307. {$ENDIF F_P/DELPHI} write LVSetColorByIdx;
  5308. {* |<#listview>
  5309. ListView background color for text. }
  5310. property LVBkColor: TColor read fColor write SetCtlColor; //LVSetBkColor;
  5311. {* |<#listview>
  5312. ListView background color. Use it instead of Color. }
  5313. //======== List View columns handling:
  5314. property LVColCount: Integer read fLVColCount;
  5315. {* |<#listview>
  5316. ListView (additional) column count. Value 0 means that there are
  5317. no columns (single item text / icon is used). If You want
  5318. to provide several columns, first call LVColAdd to "insert" column 0,
  5319. i.e. to provide header text for first column (with index 0).
  5320. If there are no column, nothing will be shown in lvsDetail /
  5321. lvsDetailNoHeader view style. }
  5322. procedure LVColAdd( const aText: String; aalign: TTextAlign; aWidth: Integer );
  5323. {* |<#listview>
  5324. Adds new column. Pass 'width' <= 0 to provide default column width.
  5325. 'text' is a column header text. }
  5326. {$IFNDEF _FPC}
  5327. {$IFNDEF _D2}
  5328. procedure LVColAddW( const aText: WideString; aalign: TTextAlign; aWidth: Integer );
  5329. {* |<#listview>
  5330. Adds new column (unicode version). }
  5331. {$ENDIF _D2}
  5332. {$ENDIF _FPC}
  5333. procedure LVColInsert( ColIdx: Integer; const aText: String; aAlign: TTextAlign; aWidth: Integer );
  5334. {* |<#listview>
  5335. Inserts new column at the Idx position (1-based column index). }
  5336. {$IFNDEF _FPC}
  5337. {$IFNDEF _D2}
  5338. procedure LVColInsertW( ColIdx: Integer; const aText: WideString; aAlign: TTextAlign; aWidth: Integer );
  5339. {* |<#listview>
  5340. Inserts new column at the Idx position (1-based column index). }
  5341. {$ENDIF _D2}
  5342. {$ENDIF _FPC}
  5343. procedure LVColDelete( ColIdx: Integer );
  5344. {* |<#listview>
  5345. Deletes column from List View }
  5346. property LVColWidth[ Item: Integer ]: Integer index LVM_GETCOLUMNWIDTH
  5347. read GetItemVal write SetItemVal;
  5348. {* |<#listview>
  5349. Retrieves or changes column width. For lvsList view style, the same width
  5350. is returned for all columns (ColIdx is ignored). It is possible to use
  5351. special values to assign to a property:
  5352. |<br> LVSCW_AUTOSIZE - Automatically sizes the column
  5353. |<br> LVSCW_AUTOSIZE_USEHEADER - Automatically sizes the column to fit
  5354. the header text
  5355. |<br>
  5356. To set coumn width in lvsList view mode, column index must be -1
  5357. (and Width to set must be in range 0..32767 always). }
  5358. property LVColText[ Idx: Integer ]: String read GetLVColText write SetLVColText;
  5359. {* |<#listview>
  5360. Allows to get/change column header text at run time. }
  5361. {$IFNDEF _FPC}
  5362. {$IFNDEF _D2}
  5363. property LVColTextW[ Idx: Integer ]: WideString read GetLVColTextW write SetLVColTextW;
  5364. {* |<#listview>
  5365. Allows to get/change column header text at run time. }
  5366. {$ENDIF _D2}
  5367. {$ENDIF _FPC}
  5368. property LVColAlign[ Idx: Integer ]: TTextAlign read GetLVColalign write SetLVColalign;
  5369. {* |<#listview>
  5370. Column text aligning. }
  5371. property LVColImage[ Idx: Integer ]: Integer index LVCF_IMAGE or (24 shl 16) read GetLVColEx write SetLVColEx;
  5372. {* |<#listview>
  5373. Only starting from comctrl32.dll of version 4.70 (IE4+). Allows to
  5374. set an image for list view column itself from the ImageListSmall.
  5375. }
  5376. property LVColOrder[ Idx: Integer ]: Integer index LVCF_ORDER or (28 shl 16) read GetLVColEx write SetLVColEx;
  5377. {* |<#listview>
  5378. Only starting from comctrl32.dll of version 4.70 (IE4+). Allows to
  5379. set visual order of the list view column from the ImageListSmall.
  5380. This value does not affect the index, by which the column is still
  5381. accessible in the column array.
  5382. }
  5383. //======== List View items handling:
  5384. property LVCount: Integer read GetItemsCount write SetItemsCount;
  5385. {* |<#listview>
  5386. Returns item count for ListView control. It is possible to use Count
  5387. property instead when obtaining of item count is needed only. But this this
  5388. property allows also to set actual count of list view items when a list
  5389. view is virtual. }
  5390. property LVCurItem: Integer read GetLVCurItem write SetLVCurItem;
  5391. {* |<#listview>
  5392. Returns first selected item index in a list view. See also LVNextSelected,
  5393. LVNextItem and LVFocusItem functions. }
  5394. property LVFocusItem: Integer read GetLVFocusItem;
  5395. {* |<#listview>
  5396. Returns focused item index in a list view. See also LVCurItem. }
  5397. function LVNextItem( IdxPrev: Integer; Attrs: DWORD ): Integer;
  5398. {* |<#listview>
  5399. Returns an index of the next after IdxPrev item with given attributes in
  5400. the list view. }
  5401. function LVNextSelected( IdxPrev: Integer ): Integer;
  5402. {* |<#listview>
  5403. Returns an index of next (after IdxPrev) selected item in a list view. }
  5404. function LVAdd( const aText: String; ImgIdx: Integer; State: TListViewItemState;
  5405. StateImgIdx, OverlayImgIdx: Integer; Data: DWORD ): Integer;
  5406. {* |<#listview>
  5407. Adds new line to the end of ListView control. Only content of item itself
  5408. is set (aText, ImgIdx). To change other column text and attributes of
  5409. item added, use appropriate properties / methods ().
  5410. |<br>
  5411. Returns an index of added item.
  5412. |<br>
  5413. There is no Unicode version defined, use LVItemAddW instead. }
  5414. function LVItemAdd( const aText: String ): Integer;
  5415. {* |<#listview>
  5416. Adds an item to the end of list view. Returns an index of the item added. }
  5417. {$IFNDEF _FPC}
  5418. {$IFNDEF _D2}
  5419. function LVItemAddW( const aText: WideString ): Integer;
  5420. {* |<#listview>
  5421. Adds an item to the end of list view. Returns an index of the item added. }
  5422. {$ENDIF _D2}
  5423. {$ENDIF _FPC}
  5424. function LVInsert( Idx: Integer; const aText: String; ImgIdx: Integer;
  5425. State: TListViewItemState; StateImgIdx, OverlayImgIdx: Integer; Data: DWORD ): Integer;
  5426. {* |<#listview>
  5427. Inserts new line before line with index Idx in ListView control. Only
  5428. content of item itself is set (aText, ImgIdx). To change other column
  5429. text and attributes of item added, use appropriate properties / methods ().
  5430. if ImgIdx = I_IMAGECALLBACK, event handler OnGetLVItemImgIdx is responsible
  5431. for returning image index for an item ( /// not implemented yet /// )
  5432. Pass StateImgIdx and OverlayImgIdx = 0 (ignored in that case) or 1..15 to
  5433. use correspondent icon from ImageListState image list.
  5434. |<br> Returns an index of item inserted.
  5435. |<br> There is no unicode version of this method, use LVItemInsertW. }
  5436. function LVItemInsert( Idx: Integer; const aText: String ): Integer;
  5437. {* |<#listview>
  5438. Inserts an item to Idx position. }
  5439. {$IFNDEF _FPC}
  5440. {$IFNDEF _D2}
  5441. function LVItemInsertW( Idx: Integer; const aText: WideString ): Integer;
  5442. {* |<#listview>
  5443. Inserts an item to Idx position. }
  5444. {$ENDIF _D2}
  5445. {$ENDIF _FPC}
  5446. procedure LVDelete( Idx: Integer );
  5447. {* |<#listview>
  5448. Deletes item of ListView with subitems (full row - in lvsDetail view style. }
  5449. procedure LVSetItem( Idx, Col: Integer; const aText: String; ImgIdx: Integer;
  5450. State: TListViewItemState; StateImgIdx, OverlayImgIdx: Integer; Data: DWORD );
  5451. {* |<#listview>
  5452. Use this method to set item data and item columns data for ListView control.
  5453. It is possible to pass I_SKIP as ImgIdx, StateImgIdx, OverlayImgIdx values to
  5454. skip setting this fields. But all other are set always. Like in LVInsert /
  5455. LVAdd, ImgIdx can be I_IMAGECALLBACK to determine that image will be
  5456. retrieved in OnGetItemImgIdx event handler when needed.
  5457. |<br>
  5458. If this method is called to set data for column > 0, parameters ImgIdx and
  5459. Data are ignored anyway.
  5460. |<br> There is no unicode version of this method, use other methods
  5461. to set up listed properties separately using correspondent W-functions. }
  5462. property LVItemState[ Idx: Integer ]: TListViewItemState read LVGetItemState write LVSetItemState;
  5463. {* |<#listview>
  5464. Access to list view item states set [lvisBlend, lvisHighlight, lvisFocus,
  5465. lvisSelect]. When assign new value to the property, it is possible to use
  5466. special index value -1 to change state for all items for a list view
  5467. (but only when lvoMultiselect style is applied to the list view, otherwise
  5468. index -1 is referring to the last item of the list view). }
  5469. property LVItemIndent[ Idx: Integer ]: Integer read LVGetItemIndent write LVSetItemIndent;
  5470. {* Item indentation. Indentation is calculated as this value multiplied to
  5471. image list ImgWidth value (Image list must be applied to list view).
  5472. Note: indentation supported only if IE3.0 or higher installed. }
  5473. property LVItemStateImgIdx[ Idx: Integer ]: Integer read LVGetSttImgIdx write LVSetSttImgIdx;
  5474. {* |<#listview>
  5475. Access to state image of the item. Use index -1 to assign the same state
  5476. image index to all items of the list view at once (fast).
  5477. Option lvoCheckBoxes just means, that control itself creates special inner
  5478. image list for two state images. Later it is possible to examine checked
  5479. state for items or set checked state programmatically by changing
  5480. LVItemStateImgIdx[ ] property. Value 1 corresponds to unchecked state,
  5481. 2 to checked. Value 0 allows to remove checkbox at all. So, to check all
  5482. added items by default (e.g.), do following:
  5483. ! ListView1.LVItemStateImgIdx[ -1 ] := 2;
  5484. |<br>Use 1-based index of the image
  5485. in image list ImageListState. Value 0 reserved to use as "no state image".
  5486. Values 1..15 can be used only - this is the Windows restriction on
  5487. state images. }
  5488. property LVItemOverlayImgIdx[ Idx: Integer ]: Integer read LVGetOvlImgIdx write LVSetOvlImgIdx;
  5489. {* |<#listview>
  5490. Access to overlay image of the item. Use index -1 to assign the same
  5491. overlay image to all items of the list view at once (fast). }
  5492. property LVItemData[ Idx: Integer ]: DWORD read LVGetItemData write LVSetItemData;
  5493. {* |<#listview>
  5494. Access to user defined data, assiciated with the item of the list view. }
  5495. procedure LVSelectAll;
  5496. {* |<#listview>
  5497. Call this method to select all the items of the list view control. }
  5498. property LVSelCount: Integer read GetSelLength write SetSelLength;
  5499. {* |<#listview>
  5500. Returns number of items selected in listview. }
  5501. property LVItemImageIndex[ Idx: Integer ]: Integer read LVGetItemImgIdx write LVSetItemImgIdx;
  5502. {* |<#listview>
  5503. Image index of items in listview. When an item is created (using LVItemAdd
  5504. or LVItemInsert), image index 0 is set by default (not -1 like in VCL!). }
  5505. property LVItems[ Idx, Col: Integer ]: String read LVGetItemText write LVSetItemText;
  5506. {* |<#listview>
  5507. Access to List View item text. }
  5508. {$IFNDEF _FPC}
  5509. {$IFNDEF _D2}
  5510. property LVItemsW[ Idx, Col: Integer ]: WideString read LVGetItemTextW write LVSetItemTextW;
  5511. {* |<#listview>
  5512. Access to List View item text. }
  5513. {$ENDIF _D2}
  5514. {$ENDIF _FPC}
  5515. function LVItemRect( Idx: Integer; Part: TGetLVItemPart ): TRect;
  5516. {* |<#listview>
  5517. Returns rectangle occupied by given item part(s) in ListView window.
  5518. Empty rectangle is returned, if the item is not viewing currently. }
  5519. function LVSubItemRect( Idx, ColIdx: Integer ): TRect;
  5520. {* |<#listview>
  5521. Returns rectangle occupied by given item's subitem in ListView window,
  5522. in lvsDetail or lvsDetailNoHeader style. Empty rectangle (0,0,0,0) is
  5523. returned if the item is not viewing currently. Left or/and right bounds
  5524. of the rectangle returned can be outbound item rectangle if only a part
  5525. of the subitem is visible or the subitem is not visible in the item,
  5526. which is visible itself. }
  5527. property LVItemPos[ Idx: Integer ]: TPoint read LVGetItemPos write LVSetItemPos;
  5528. {* |<#listview>
  5529. Position of List View item (can be changed in icon or small icon view). }
  5530. function LVItemAtPos( X, Y: Integer ): Integer;
  5531. {* |<#listview>
  5532. Return index of item at the given position. }
  5533. function LVItemAtPosEx( X, Y: Integer; var Where: TWherePosLVItem ): Integer;
  5534. {* |<#listview>
  5535. Retrieves index of item and sets in Where, what part of item is under
  5536. given coordinates. If there are no items at the specified position,
  5537. -1 is returned. }
  5538. procedure LVMakeVisible( Item: Integer; PartiallyOK: Boolean );
  5539. {* |<#listview>
  5540. Makes listview item visible. Ignred when Item passed < 0. }
  5541. procedure LVEditItemLabel( Idx: Integer );
  5542. {* |<#listview>
  5543. Begins in-place editing of item label (first column text). }
  5544. procedure LVSort;
  5545. {* |<#listview>
  5546. Initiates sorting of list view items. This sorting procedure is available only
  5547. for Win2K, WinNT4 with IE5, Win98 or Win95 with IE5. See also LVSortData. }
  5548. procedure LVSortData;
  5549. {* |<#listview>
  5550. Initiates sorting of list view items. This sorting procedure is always available
  5551. in Windows95/98, NT/2000. But OnCompareLVItems procedure receives not indexes of
  5552. items compared but its Data field associated instead. }
  5553. procedure LVSortColumn( Idx: Integer );
  5554. {* |<#listview>
  5555. This is a method to simplify sort by column. Just call it in your OnColumnClick
  5556. event passing column index and enjoy with your list view sorted automatically
  5557. when column header is clicked. Requieres Windows2000 or Winows98, not supported
  5558. under WinNT 4.0 and below and under Windows95.
  5559. |<br>
  5560. Either lvoSortAscending or lvoSortDescending option must be set in
  5561. LVOptions, otherwise no sorting is performed. }
  5562. function LVIndexOf( const S: String ): Integer;
  5563. {* Returns first list view item index with caption matching S.
  5564. The same as LVSearchFor( S, -1, FALSE ). }
  5565. {$IFNDEF _FPC}
  5566. {$IFNDEF _D2}
  5567. function LVIndexOfW( const S: WideString ): Integer;
  5568. {* Returns first list view item index with caption matching S.
  5569. The same as LVSearchForW( S, -1, FALSE ). }
  5570. {$ENDIF _D2}
  5571. {$ENDIF _FPC}
  5572. function LVSearchFor( const S: String; StartAfter: Integer; Partial: Boolean ): Integer;
  5573. {* Searches an item with Caption equal to S (or starting from S, if Partial = TRUE).
  5574. Searching is started after an item specified by StartAfter parameter. }
  5575. {$IFNDEF _FPC}
  5576. {$IFNDEF _D2}
  5577. function LVSearchForW( const S: WideString; StartAfter: Integer; Partial: Boolean ): Integer;
  5578. {* Searches an item with Caption equal to S (or starting from S, if Partial = TRUE).
  5579. Searching is started after an item specified by StartAfter parameter. }
  5580. {$ENDIF _D2}
  5581. {$ENDIF _FPC}
  5582. //======== List view page:
  5583. property LVTopItem: Integer index LVM_GETTOPINDEX read GetIntVal; //LVGetTopItem;
  5584. {* |<#listview>
  5585. Returns index of topmost visible item of ListView in lvsList view style. }
  5586. property LVPerPage: Integer index LVM_GETCOUNTPERPAGE read GetIntVal; //LVGetPerPage;
  5587. {* |<#listview>
  5588. Returns the number of fully-visible items if successful. If the current
  5589. view is icon or small icon view, the return value is the total number
  5590. of items in the list view control. }
  5591. //======== List View specific events:
  5592. property OnEndEditLVItem: TOnEditLVItem read fOnEditLVITem write SetOnEditLVItem;
  5593. {* |<#listview>
  5594. Called when edit of an item label in ListView control finished. Return
  5595. True to accept new label text, or false - to not accept it (item label
  5596. will not be changed). If handler not set to an event, all changes are
  5597. accepted. }
  5598. property OnDeleteLVItem: TOnDeleteLVItem read fOnDeleteLVItem write SetOnDeleteLVItem;
  5599. {* |<#listview>
  5600. Called for every deleted list view item. }
  5601. property OnDeleteAllLVItems: TOnEvent read fOnDeleteAllLVItems write SetOnDeleteAllLVItems;
  5602. {* |<#listview>
  5603. Called when all the items of the list view control are to be deleted. If after
  5604. returning from this event handler event OnDeleteLVItem is yet assigned,
  5605. an event OnDeleteLVItem will be called for every deleted item. }
  5606. property OnLVData: TOnLVData read fOnLVData write SetOnLVData;
  5607. {* |<#listview>
  5608. Called to provide virtual list view with actual data. To use list view as
  5609. virtaul list view, define also lvsOwnerData style and set Count property
  5610. to actual row count of the list view. This manner of working with list view
  5611. control can greatly improve performance of an application when working with
  5612. huge data sets represented in listview control. }
  5613. {$IFNDEF _FPC}
  5614. {$IFNDEF _D2}
  5615. property OnLVDataW: TOnLVDataW read fOnLVDataW write SetOnLVDataW;
  5616. {* |<#listview>
  5617. The same as OnLVData, but for unicode version of the list view allows
  5618. to return WideString text in the event handler. Though for unicode list
  5619. view it is still possible to use ordinary event OnLVData, it is
  5620. very recommended to use this event istead. }
  5621. {$ENDIF _D2}
  5622. {$ENDIF _FPC}
  5623. property OnCompareLVItems: TOnCompareLVItems read fOnCompareLVItems write fOnCompareLVItems;
  5624. {* |<#listview>
  5625. Event to compare two list view items during sort operation (initiated by
  5626. LVSort method call). Do not send any messages to the list view control
  5627. while it is sorting - results can be unpredictable! }
  5628. property OnColumnClick: TOnLVColumnClick read fOnColumnClick write SetOnColumnClick;
  5629. {* |<#listview>
  5630. This event handler is called when column of the list view control is clicked.
  5631. You can use this event to initiate sorting of list view items by this column. }
  5632. property OnLVStateChange: TOnLVStateChange read FOnLVStateChange write SetOnLVStateChange;
  5633. {* |<#listview>
  5634. This event occure when an item or items range in list view control are
  5635. changing its state (e.g. selected or unselected). }
  5636. property OnLVDelete: TOnLVDelete read FOnLVDelete write SetOnLVDelete;
  5637. {* |<#listview>
  5638. This event is called when an item is deleted in the listview.
  5639. Do not add, delete, or rearrange items in the list view while processing
  5640. this notification. }
  5641. property OnDrawItem: TOnDrawItem read fOnDrawItem write SetOnDrawItem;
  5642. {* |<#listview>
  5643. |<#listbox>
  5644. |<#combo>
  5645. This event can be used to implement custom drawing for list view, list box, dropped
  5646. list of a combobox. For a list view, custom drawing using this event is possible
  5647. only in lvsDetail and lvsDetailNoHeader styles, and OnDrawItem is called to draw
  5648. entire row at once only. See also OnLVCustomDraw event. }
  5649. property OnLVCustomDraw: TOnLVCustomDraw read FOnLVCustomDraw write SetOnLVCustomDraw;
  5650. {* |<#listview>
  5651. Custom draw event for listview. For every item to be drawn, this event
  5652. can be called several times during a single drawing cycle - depending on
  5653. a result, returned by an event handler. Stage can have one of following
  5654. values:
  5655. |<pre>
  5656. CDDS_PREERASE
  5657. CDDS_POSTERASE
  5658. CDDS_ITEMPREERASE
  5659. CDDS_PREPAINT
  5660. CDDS_ITEMPREPAINT
  5661. CDDS_ITEM
  5662. CDDS_SUBITEM + CDDS_ITEMPREPAINT
  5663. CDDS_SUBITEM + CDDS_ITEMPOSTPAINT
  5664. CDDS_ITEMPOSTPAINT
  5665. CDDS_POSTPAINT
  5666. </pre>
  5667. When called, see on Stage to get know, on what stage the event is
  5668. activated. And depend on the stage and on what you want to paint,
  5669. return a value as a result, which instructs the system, if to use
  5670. default drawing on this (and follows) stage(s) for the item, and if
  5671. to notify further about different stages of drawing the item during
  5672. this drawing cycle. Possible values to return are:
  5673. |<pre>
  5674. CDRF_DODEFAULT - perform default drawing. Do not notify further for this
  5675. item (subitem) (or for entire listview, if called with
  5676. flag CDDS_ITEM reset - ?);
  5677. CDRF_NOTIFYITEMDRAW - return this value, when the event is called the
  5678. first time in a cycle of drawing, with ItemIdx = -1 and
  5679. flag CDDS_ITEM reset in Stage parameter;
  5680. CDRF_NOTIFYPOSTERASE - usually can be used to provide default erasing,
  5681. if you want to perform drawing immediately after that;
  5682. CDRF_NOTIFYPOSTPAINT - return this value to provide calling the event
  5683. after performing default drawing. Useful when you wish
  5684. redraw only a part of the (sub)item;
  5685. CDRF_SKIPDEFAULT - return this value to inform the system that all
  5686. drawing is done and system should not peform any more
  5687. drawing for the (sub)item during this drawing cycle.
  5688. CDRF_NEWFONT - informs the system, that font is changed and default
  5689. drawing should be performed with changed font;
  5690. |</pre>
  5691. If you want to get notifications for each subitem, do not use option
  5692. lvoOwnerDrawFixed, because such style prevents system from notifying
  5693. the application for each subitem to be drawn in the listview and only
  5694. notifications will be sent about entire items.
  5695. |<br>
  5696. See also NM_CUSTOMDRAW in API Help.
  5697. }
  5698. procedure Set_LVItemHeight(Value: Integer);
  5699. function SetLVItemHeight(Value: Integer): PControl;
  5700. property LVItemHeight: Integer read fLVItemHeight write Set_LVItemHeight;
  5701. //======== TreeView specific properties and methods:
  5702. function TVInsert( nParent, nAfter: THandle; const Txt: String ): THandle;
  5703. {* |<#treeview>
  5704. Inserts item to a tree view. If nParent is 0 or TVI_ROOT, the item is
  5705. inserted at the root of tree view. It is possible to pass following special
  5706. values as nAfter parameter:
  5707. |<pre>
  5708. TVI_FIRST Inserts the item at the beginning of the list.
  5709. TVI_LAST Inserts the item at the end of the list.
  5710. TVI_SORT Inserts the item into the list in alphabetical order.
  5711. |</pre> }
  5712. {$IFNDEF _FPC}
  5713. {$IFNDEF _D2}
  5714. function TVInsertW( nParent, nAfter: THandle; const Txt: WideString ): THandle;
  5715. {* |<#treeview>
  5716. Inserts item to a tree view. If nParent is 0 or TVI_ROOT, the item is
  5717. inserted at the root of tree view. It is possible to pass following special
  5718. values as nAfter parameter:
  5719. |<pre>
  5720. TVI_FIRST Inserts the item at the beginning of the list.
  5721. TVI_LAST Inserts the item at the end of the list.
  5722. TVI_SORT Inserts the item into the list in alphabetical order.
  5723. |</pre><br>
  5724. This version of the method is Unicode. The tree view control should be
  5725. set up as unicode control calling Perform( TVM_SETUNICODEFORMAT, 1, 0 ),
  5726. and conditional symbol UNICODE_CTRLS must be defined to provide event
  5727. handling for such kind of tree view (and other Unicode) controls. }
  5728. {$ENDIF _D2}
  5729. {$ENDIF _FPC}
  5730. procedure TVDelete( Item: THandle );
  5731. {* |<#treeview>
  5732. Removes an item from the tree view. If value TVI_ROOT is passed, all items
  5733. are removed. }
  5734. property TVSelected: THandle index TVGN_CARET read TVGetItemIdx write TVSetItemIdx;
  5735. {* |<#treeview>
  5736. Returns or sets currently selected item handle in tree view. }
  5737. property TVDropHilighted: THandle index TVGN_DROPHILITE read TVGetItemIdx write TVSetItemIdx;
  5738. {* |<#treeview>
  5739. Returns or sets item, which is currently highlighted as a drop target. }
  5740. property TVDropHilited: THandle index TVGN_DROPHILITE read TVGetItemIdx write TVSetItemIdx;
  5741. {* The same as TVDropHilighted. }
  5742. property TVFirstVisible: THandle index TVGN_FIRSTVISIBLE read TVGetItemIdx write TVSetItemIdx;
  5743. {* |<#treeview>
  5744. Returns or sets given item to top of tree view. }
  5745. property TVIndent: Integer index TVM_GETINDENT read GetIntVal write SetIntVal;
  5746. {* |<#treeview>
  5747. The amount, in pixels, that child items are indented relative to their
  5748. parent items. }
  5749. property TVVisibleCount: Integer index TVM_GETVISIBLECOUNT read GetIntVal;
  5750. {* |<#treeview>
  5751. Returns number of fully (not partially) visible items in tree view. }
  5752. property TVRoot: THandle index TVGN_ROOT read TVGetItemIdx;
  5753. {* |<#treeview>
  5754. Returns handle of root item in tree view (or 0, if tree is empty). }
  5755. property TVItemChild[ Item: THandle ]: THandle index TVGN_CHILD read TVGetItemNext;
  5756. {* |<#treeview>
  5757. Returns first child item for given one. }
  5758. property TVItemHasChildren[ Item: THandle ]: Boolean read TV_GetItemHasChildren write TV_SetItemHasChildren;
  5759. {* |<#treeview>
  5760. TRUE, if an Item has children. Set this value to true if you want to
  5761. force [+] sign appearing left from the node, even if there are no
  5762. subnodes added to the node yet. }
  5763. property TVItemChildCount[ Item: THandle ]: Integer read TV_GetItemChildCount;
  5764. {* |<#treeview>
  5765. Returns number of node child items in tree view.
  5766. }
  5767. property TVItemNext[ Item: THandle ]: THandle index TVGN_NEXT read TVGetItemNext;
  5768. {* |<#treeview>
  5769. Returns next sibling item handle for given one (or 0, if passed item is
  5770. the last child for its parent node). }
  5771. property TVItemPrevious[ Item: THandle ]: THandle index TVGN_PREVIOUS read TVGetItemNext;
  5772. {* |<#treeview>
  5773. Returns previous sibling item (or 0, if the is no such item). }
  5774. property TVItemNextVisible[ Item: THandle ]: THandle index TVGN_NEXTVISIBLE read TVGetItemNext;
  5775. {* |<#treeview>
  5776. Returns next visible item (passed item must be visible too, to determine,
  5777. if it is really visible, use property TVItemRect or TVItemVisible. }
  5778. property TVItemPreviousVisible[ Item: THandle ]: THandle index TVGN_PREVIOUSVISIBLE read TVGetItemNext;
  5779. {* |<#treeview>
  5780. Returns previous visible item. }
  5781. property TVItemParent[ Item: THandle ]: THandle index TVGN_PARENT read TVGetItemNext;
  5782. {* |<#treeview>
  5783. Returns parent item for given one (or 0 for root item). }
  5784. property TVItemText[ Item: THandle ]: String read TVGetItemText write TVSetItemText;
  5785. {* |<#treeview>
  5786. Text of tree view item. }
  5787. {$IFNDEF _FPC}
  5788. {$IFNDEF _D2}
  5789. property TVItemTextW[ Item: THandle ]: WideString read TVGetItemTextW write TVSetItemTextW;
  5790. {* |<#treeview>
  5791. Text of tree view item. }
  5792. {$ENDIF _D2}
  5793. {$ENDIF _FPC}
  5794. function TVItemPath( Item: THandle; Delimiter: Char ): String;
  5795. {* |<#treeview>
  5796. Returns full path from the root item to given item. Path is calculated
  5797. as a concatenation of all parent nodes text strings, separated by
  5798. given delimiter character.
  5799. |<br>Please note, that returned path has no trailing delimiter, this
  5800. character is only separating different parts of the path.
  5801. |<br>If Item is not specified ( =0 ), path is returned
  5802. for Selected item. }
  5803. {$IFNDEF _FPC}
  5804. {$IFNDEF _D2}
  5805. function TVItemPathW( Item: THandle; Delimiter: WideChar ): WideString;
  5806. {* |<#treeview>
  5807. Returns full path from the root item to given item. Path is calculated
  5808. as a concatenation of all parent nodes text strings, separated by
  5809. given delimiter character. If Item is not specified ( =0 ), path is returned
  5810. for Selected item. }
  5811. {$ENDIF _D2}
  5812. {$ENDIF _FPC}
  5813. property TVItemRect[ Item: THandle; TextOnly: Boolean ]: TRect read TVGetItemRect;
  5814. {* |<#treeview>
  5815. Returns rectangle, occupied by an item in tree view. }
  5816. property TVItemVisible[ Item: THandle ]: Boolean read TVGetItemVisible write TVSetITemVisible;
  5817. {* |<#treeview>
  5818. Returs True, if item is visible in tree view. It is also possible to
  5819. assign True to this property to ensure that a tree view item is visible
  5820. (if False is assigned, this does nothing). }
  5821. function TVItemAtPos( x, y: Integer; var Where: DWORD ): THandle;
  5822. {* |<#treeview>
  5823. Returns handle of item found at specified position (relative to upper left
  5824. corener of client area of the tree view). If no item found, 0 is returned.
  5825. Variable Where receives additional flags combination, describing more
  5826. detailed, on which part of item or tree view given point is located,
  5827. such as:
  5828. |<pre>
  5829. TVHT_ABOVE Above the client area
  5830. TVHT_BELOW Below the client area
  5831. TVHT_NOWHERE In the client area, but below the last item
  5832. TVHT_ONITEM On the bitmap or label associated with an item
  5833. TVHT_ONITEMBUTTON On the button associated with an item
  5834. TVHT_ONITEMICON On the bitmap associated with an item
  5835. TVHT_ONITEMINDENT In the indentation associated with an item
  5836. TVHT_ONITEMLABEL On the label (string) associated with an item
  5837. TVHT_ONITEMRIGHT In the area to the right of an item
  5838. TVHT_ONITEMSTATEICON On the state icon for a tree-view item that is in a user-defined state
  5839. TVHT_TOLEFT To the right of the client area
  5840. TVHT_TORIGHT To the left of the client area
  5841. |</pre> }
  5842. property TVRightClickSelect: Boolean read fTVRightClickSelect write SetTVRightClickSelect;
  5843. {* |<#treeview>
  5844. Set this property to True to allow change selection to an item, clicked with right mouse button. }
  5845. property TVEditing: Boolean read fEditing;
  5846. {* |<#treeview>
  5847. Returns True, if tree view control is editing its item label. }
  5848. property TVItemBold[ Item: THandle ]: Boolean index TVIS_BOLD read TVGetItemStateFlg write TVSetItemStateFlg;
  5849. {* |<#treeview>
  5850. True, if item is bold. }
  5851. property TVItemCut[ Item: THandle ]: Boolean index TVIS_CUT read TVGetITemStateFlg write TVSetItemStateFlg;
  5852. {* |<#treeview>
  5853. True, if item is selected as part of "cut and paste" operation. }
  5854. property TVItemDropHighlighted[ Item: THandle ]: Boolean index TVIS_DROPHILITED read TVGetITemStateFlg write TVSetItemStateFlg;
  5855. {* |<#treeview>
  5856. True, if item is selected as drop target. }
  5857. property TVItemDropHilited[ Item: THandle ]: Boolean index TVIS_DROPHILITED read TVGetITemStateFlg write TVSetItemStateFlg;
  5858. {* The same as TVItemDropHighlighted. }
  5859. property TVItemExpanded[ Item: THandle ]: Boolean index TVIS_EXPANDED read TVGetITemStateFlg; // write TVSetItemStateFlg;
  5860. {* |<#treeview>
  5861. True, if item's list of child items is currently expanded. To change
  5862. expanded state, use method TVExpand. }
  5863. property TVItemExpandedOnce[ Item: THandle ]: Boolean index TVIS_EXPANDEDONCE read TVGetITemStateFlg; // write TVSetItemStateFlg;
  5864. {* |<#treeview>
  5865. True, if item's list of child items has been expanded at least once. }
  5866. property TVItemSelected[ Item: THandle ]: Boolean index TVIS_SELECTED read TVGetITemStateFlg write TVSetItemStateFlg;
  5867. {* |<#treeview>
  5868. True, if item is selected. }
  5869. procedure TVExpand( Item: THandle; Flags: DWORD );
  5870. {* |<#treeview>
  5871. Call it to expand/collapse item's child nodes. Possible values for Flags
  5872. parameter are:
  5873. <pre>
  5874. TVE_COLLAPSE Collapses the list.
  5875. TVE_COLLAPSERESET Collapses the list and removes the child items. Note
  5876. that TVE_COLLAPSE must also be specified.
  5877. TVE_EXPAND Expands the list.
  5878. TVE_TOGGLE Collapses the list if it is currently expanded or
  5879. expands it if it is currently collapsed.
  5880. </pre>
  5881. }
  5882. procedure TVSort( N: THandle );
  5883. {* |<#treeview>
  5884. By Alex Mokrov. Sorts treeview. If N = 0, entire treeview is sorted.
  5885. Otherwise, children of the given node only.
  5886. }
  5887. property TVItemImage[ Item: THandle ]: Integer index TVIF_IMAGE read TVGetItemImage write TVSetItemImage;
  5888. {* |<#treeview>
  5889. Image index for an item of tree view. To tell that there are no image
  5890. set, use index -2 (value -1 is reserved for callback image). }
  5891. property TVItemSelImg[ Item: THandle ]: Integer index TVIF_SELECTEDIMAGE read TVGetItemImage write TVSetItemImage;
  5892. {* |<#treeview>
  5893. Image index for an item of tree view in selected state. Use value -2 to
  5894. provide no image, -1 used for callback image. }
  5895. property TVItemOverlay[ Item: THandle ]: Integer index TVIS_OVERLAYMASK or $80000
  5896. read TVGetItemImage write TVSetItemImage;
  5897. {* |<#treeview>
  5898. Overlay image index for an item in tree view. }
  5899. property TVItemStateImg[ Item: THandle ]: Integer index TVIS_STATEIMAGEMASK or $C0000
  5900. read TVGetItemImage write TVSetItemImage;
  5901. {* |<#treeview>
  5902. State image index for an item in tree view. Use 1-based index of the image
  5903. in image list ImageListState. Value 0 reserved to use as "no state image".
  5904. Values 1..15 can be used only - this is the Windows restriction on
  5905. state images. }
  5906. property TVItemData[ Item: THandle ]: Pointer read TVGetItemData write TVSetItemData;
  5907. {* |<#treeview>
  5908. Stores any program-defined pointer with the item. }
  5909. procedure TVEditItem( Item: THandle );
  5910. {* |<#treeview>
  5911. Begins editing given item label in tree view. }
  5912. procedure TVStopEdit( Cancel: Boolean );
  5913. {* |<#treeview>
  5914. Ends editing item label, started by user or explicitly by TVEditItem method. }
  5915. property OnTVBeginDrag: TOnTVBeginDrag read fOnTVBeginDrag write fOnTVBeginDrag;
  5916. {* |<#treeview>
  5917. Is called for tree view, when its item is to be dragging. }
  5918. property OnTVBeginEdit: TOnTVBeginEdit read fOnTVBeginEdit write fOnTVBeginEdit;
  5919. {* |<#treeview>
  5920. Is called for tree view, when its item label is to be editing. }
  5921. property OnTVEndEdit: TOnTVEndEdit read fOnTVEndEdit write fOnTVEndEdit;
  5922. {* |<#treeview>
  5923. Is called when item label is edited. It is possible to cancel
  5924. edit, returning False as a result. }
  5925. property OnTVExpanding: TOnTVExpanding read fOnTVExpanding write fOnTVExpanding;
  5926. {* |<#treeview>
  5927. Is called just before expanding/collapsing item. It is possible to
  5928. return False to prevent expanding item. }
  5929. property OnTVExpanded: TOnTVExpanded read fOnTVExpanded write fOnTVExpanded;
  5930. {* |<#treeview>
  5931. Is called after expanding/collapsing item children. }
  5932. property OnTVDelete: TOnTVDelete read fOnTVDelete write SetOnTVDelete;
  5933. {* |<#treeview>
  5934. Is called just before deleting item. You may use this event to free
  5935. resources, associated with an item (see TVItemData property). }
  5936. //----------------- by Sergey Shisminzev:
  5937. property OnTVSelChanging: TOnTVSelChanging read fOnTVSelChanging write fOnTVSelChanging;
  5938. {* |<#treeview>
  5939. Is called before changing the selection. The handler can return FALSE
  5940. to prevent changing the selection. }
  5941. //--------------------------------------
  5942. //======== Toolbar specific methods:
  5943. procedure TBAddBitmap( Bitmap: HBitmap );
  5944. {* |<#toolbar>
  5945. Adds bitmaps to a toolbar. You can pass special values as Bitmap to
  5946. add one of predefined system button images bitmaps:
  5947. |<br> THandle(-1) to add standard small icons,
  5948. |<br> THandle(-2) to add standard large icons,
  5949. |<br> THandle(-5) to add standard small view icons,
  5950. |<br> THandle(-6) to add standard large view icons,
  5951. |<br> THandle(-9) to add standard small view icons,
  5952. |<br> THandle(-10) to add standard large view icons,
  5953. (in that case use following values as indexes to the standard and view
  5954. bitmaps:
  5955. |<br>
  5956. STD_COPY, STD_CUT, STD_DELETE, STD_FILENEW, STD_FILEOPEN, STD_FILESAVE,
  5957. STD_FIND, STD_HELP, STD_PASTE, STD_PRINT, STD_PRINTPRE, STD_PROPERTIES,
  5958. STD_REDO, STD_REPLACE, STD_UNDO,
  5959. |<br>
  5960. VIEW_LARGEICONS, VIEW_SMALLICONS,
  5961. VIEW_LIST, VIEW_DETAILS, VIEW_SORTNAME, VIEW_SORTSIZE, VIEW_SORTDATE,
  5962. VIEW_SORTTYPE (use it as parameters BtnImgIdxArray in TBAddButtons or
  5963. TBInsertButtons methods, and in assigning value to TBButtonImage[ ]
  5964. property).
  5965. Added bitmaps have indeces starting from previous count of images
  5966. (as these are appended to existing - if any).
  5967. |<br>
  5968. Note, that if You add your own (custom) bitmap, it is not transparent.
  5969. Do not assume that clSilver is always equal to clBtnFace. Use API
  5970. function CreateMappedBitmap to load bitmap from resource and map
  5971. desired colors as you wish (e.g., convert clTeal to clBtnFace). Or,
  5972. call defined in KOL function LoadMappedBitmap to do the same more easy.
  5973. Unfortunately, resource identifier for bitmap to pass it to LoadMappedBitmap
  5974. or to CreateMappedBitmap seems must be integer, so it is necessary to
  5975. create rc-file manually and compile using Borland Resource Compiler to
  5976. figure it out. }
  5977. function TBAddButtons( const Buttons: array of PChar; const BtnImgIdxArray: array
  5978. of Integer ): Integer;
  5979. {* |<#toolbar>
  5980. Adds buttons to toolbar. Last string in Buttons array *must* be empty
  5981. ('' or nil), so to add buttons without text, pass ' ' string (one space
  5982. char). It is not necessary to provide image indexes for all
  5983. buttons (it is sufficient to assign index for first button only).
  5984. But in place, correspondent to separator button (defined by string '-'),
  5985. any integer must be passed to assign follow image indexes correctly.
  5986. See example.
  5987. |*Toolbar adding buttons sample.
  5988. Code below shows how to call TBAddButtons method to add two buttons with
  5989. a separator between these buttons. idxNew and idxOld are integer
  5990. expressions assigning image indexes to buttons 'New' and 'Old'. This
  5991. indexes are zero-based and refer to bitmap images, added earlier (either
  5992. in creating toolbar by call of NewToolbar or later in call of TBAddBitmap).
  5993. !
  5994. ! TBAddButtons( [ '&New', '-', '&Old', '' ], [ idxNew, 0, idxOld ] );
  5995. !
  5996. |*
  5997. To add check buttons, use prefix '+' or '-' in button definition
  5998. string. If next character is '!', such buttons are grouped to a
  5999. radio-group. Also, it is possible to use '^' prefix (must be first) to
  6000. define button with small drop-down section (use also OnTBDropDown event
  6001. to respond to clicking drop down section of such buttons).
  6002. |<br>
  6003. This function returns command id for first added button (other
  6004. id's can be calculated incrementing the result by one for each
  6005. button, except separators, which have no command id).
  6006. |<br>
  6007. Note: for static toolbar (single in application and created
  6008. once) ids are started from value 100. }
  6009. function TBInsertButtons( BeforeIdx: Integer; Buttons: array of PChar;
  6010. BtnImgIdxArray: array of Integer ): Integer;
  6011. {* |<#toolbar>
  6012. Inserts buttons before button with given index on toolbar. Returns
  6013. command identifier for first button inserted (other can be calculated
  6014. incrementing returned value needed times. See also TBAddButtons. }
  6015. procedure TBDeleteButton( BtnID: Integer );
  6016. {* |<#toolbar>
  6017. Deletes single button given by its command id. To delete separator,
  6018. use TBDeleteBtnByIdx instead. }
  6019. procedure TBDeleteBtnByIdx( Idx: Integer );
  6020. {* |<#toolbar>
  6021. Deletes single button given by its index in toolbar (not by command ID). }
  6022. procedure TBAssignEvents( BtnID: Integer; Events: array of TOnToolbarButtonClick );
  6023. {* |<#toolbar>
  6024. Allows to assign separate OnClick events for every toolbar button.
  6025. BtnID should be toolbar button ID or index of the first button to
  6026. assign event. If it is an ID, events are assigned to buttons in
  6027. creation order. Otherwise, events are assigned in placement order.
  6028. Anyway, separator buttons are not skipped, so pass at least nil for such
  6029. button as an event.
  6030. |<br>
  6031. Please note, that though not all buttons should exist before
  6032. assigning events to it, therefore at least the first button
  6033. (specified by BtnID) must be already added before calling TBAssignEvents. }
  6034. procedure TBResetImgIdx( BtnID, BtnCount: Integer );
  6035. {* |<#toolbar>
  6036. Resets image index for BtnCount buttons starting from BtnID. }
  6037. property CurItem: Integer read fCurItem;
  6038. {* |<#toolbar>
  6039. For toolbar, in OnClick event this property can be used to determine
  6040. which button was clicked (100-based button id in toolbar). It is also
  6041. possible to use CurIndex property (zero-based) for this purpose as
  6042. well, but do not assume, that CurItem always equal to CurIndex+100.
  6043. At least, it is possible to call TBItem2Index function to convert
  6044. button ID to its index in toolbar.
  6045. |<br>
  6046. In case, when button (or toolbar itself) is clicked using right
  6047. mouse button, CurItem and CurIndex are always set to -1. To further
  6048. determine which button was clicked, get mouse coordinates on screen,
  6049. apply Screen2Client method of toolbar control to it and then use
  6050. TBButtonAtPos function to determine which button was under cursor.
  6051. }
  6052. property TBButtonCount: Integer read GetItemsCount; //TBGetButtonCount;
  6053. {* |<#toolbar>
  6054. Returns count of buttons on toolbar. The same as Count. }
  6055. property TBBtnImgWidth: Integer read fTBBtnImgWidth write fTBBtnImgWidth;
  6056. {* |<#toolbar>
  6057. Custom toolbar buttons width. Set it before assigning buttons bitmap.
  6058. Changing this property after assigning the bitmap has no effect. }
  6059. function TBItem2Index( BtnID: Integer ): Integer;
  6060. {* |<#toolbar>
  6061. Converts button command id to button index for tool bar. }
  6062. function TBIndex2Item( Idx: Integer ): Integer;
  6063. {* |<#toolbar>
  6064. Converts toolbar button index to its command ID. }
  6065. procedure TBConvertIdxArray2ID( const IdxVars: array of PDWORD );
  6066. {* |<#toolbar>
  6067. Converts toolbar button indexes to its command IDs for an array
  6068. of indexes (each item in the array passed is a pointer to
  6069. Integer, containing button index when the procedure is callled,
  6070. then all these indexes are relaced with a correspondent button ID).}
  6071. property TBButtonEnabled[ BtnID: Integer ]: Boolean index TB_ENABLEBUTTON
  6072. read TBGetBtnStt write TBSetBtnStt;
  6073. {* |<#toolbar>
  6074. Obvious. }
  6075. property TBButtonVisible[ BtnID: Integer ]: Boolean read TBGetButtonVisible
  6076. write TBSetButtonVisible;
  6077. {* |<#toolbar>
  6078. Allows to hide/show some of toolbar buttons. }
  6079. property TBButtonChecked[ BtnID: Integer ]: Boolean index TB_CHECKBUTTON
  6080. read TBGetBtnStt write TBSetBtnStt;
  6081. {* |<#toolbar>
  6082. Allows to determine 'checked' state of a button (e.g., radio-button),
  6083. and to check it programmatically. }
  6084. property TBButtonMarked[ BtnID: Integer ]: Boolean index TB_MARKBUTTON
  6085. read TBGetBtnStt write TBSetBtnStt;
  6086. {* |<#toolbar>
  6087. Returns True if toolbar button is marked (highlighted). Allows to
  6088. highlight buttons assigning True to this value. }
  6089. property TBButtonPressed[ BtnID: Integer ]: Boolean index TB_PRESSBUTTON
  6090. read TBGetBtnStt write TBSetBtnStt;
  6091. {* |<#toolbar>
  6092. Allows to detrmine if toolbar button (given by its command ID) pressed,
  6093. and press/unpress it programmatically. }
  6094. property TBButtonText[ BtnID: Integer ]: String read TBGetButtonText write TBSetButtonText;
  6095. {* |<#toolbar>
  6096. Obtains toolbar button text and allows to change it. Be sure that text
  6097. is not empty for all buttons, if You want for it to be shown (if at least
  6098. one button has empty text, no text labels will be shown at all). At
  6099. least set it to ' ' for buttons, which You do not want to show labels,
  6100. if You want from other ones to have it. }
  6101. property TBButtonImage[ BtnID: Integer ]: Integer read TBGetBtnImgIdx write TBSetBtnImgIdx;
  6102. {* |<#toolbar>
  6103. Allows to access/change button image. Do not read this property for
  6104. separator buttons, returning value is not proper. If you do not know,
  6105. is the button a separator, using function below. }
  6106. function TBButtonSeparator( BtnID: Integer ): Boolean;
  6107. {* |<#toolbar>
  6108. Returns TRUE, if a toolbar button is separator. }
  6109. property TBButtonRect[ BtnID: Integer ]: TRect read TBGetButtonRect;
  6110. {* |<#toolbar>
  6111. Obtains rectangle occupied by toolbar button in toolbar window.
  6112. (It is not possible to obtain rectangle for buttons, currently
  6113. not visible). }
  6114. property TBButtonWidth[ BtnID: Integer ]: Integer read TBGetBtnWidth write TBSetBtnWidth;
  6115. {* |<#toolbar>
  6116. Allows to obtain / change toolbar button width. }
  6117. property TBButtonsMinWidth: Integer index 0
  6118. {$IFDEF F_P} read TBGetBtMinMaxWidth
  6119. {$ELSE DELPHI} read FTBBtMinWidth
  6120. {$ENDIF F_P/DELPHI} write TBSetBtMinMaxWidth;
  6121. {* |<#toolbar>
  6122. Allows to set minimal width for all toolbar buttons. }
  6123. property TBButtonsMaxWidth: Integer index 1
  6124. {$IFDEF F_P} read TBGetBtMinMaxWidth
  6125. {$ELSE DELPHI} read FTBBtMaxWidth
  6126. {$ENDIF F_P/DELPHI} write TBSetBtMinMaxWidth;
  6127. {* |<#toolbar>
  6128. Allows to set maximal width for all toolbar buttons. }
  6129. function TBButtonAtPos( X, Y: Integer ): Integer;
  6130. {* |<#toolbar>
  6131. Returns command ID of button at the given position on toolbar,
  6132. or -1, if there are no button at the position. Value 0 is returned
  6133. for separators. }
  6134. function TBBtnIdxAtPos( X, Y: Integer ): Integer;
  6135. {* |<#toolbar>
  6136. Returns index of button at the given position on toolbar.
  6137. This also can be index of separator button. -1 is returned if
  6138. there are no buttons found at the position. }
  6139. function TBMoveBtn( FromIdx, ToIdx: Integer ): Boolean;
  6140. {* |<#toolbar>
  6141. By TR"]F. Moves button from one position to another. }
  6142. property TBRows: Integer read TBGetRows write TBSetRows;
  6143. {* |<#toolbar>
  6144. Returns number of rows for toolbar and allows to try to set
  6145. desired number of rows (but system can set another number of
  6146. rows in some cases). This property has no effect if tboWrapable
  6147. style not present in Options when toolbar is created. }
  6148. procedure TBSetTooltips( BtnID1st: Integer; Tooltips: array of PChar );
  6149. {* |<#toolbar>
  6150. Allows to assign tooltips to several buttons. Until this procedure
  6151. is not called, tooltips list is not created and no code is added
  6152. to executable. This method of tooltips maintainance for toolbar buttons
  6153. is useful both for static and dynamic toolbars (meaning "dynamic" -
  6154. toolbars with buttons, deleted and inserted at run-time). }
  6155. property OnTBDropDown: TOnEvent read fOnDropDown write fOnDropDown;
  6156. {* |<#toolbar>
  6157. This event is called for drop down buttons, when user click drop part
  6158. of drop down button. To determine for which button event is called,
  6159. look at CurItem or CurIndex property. It is also possible to use
  6160. common (with combobox) property OnDropDown. }
  6161. property OnTBClick: TOnEvent read fOnClick write fOnClick;
  6162. {* |<#toolbar>
  6163. The same as OnClick. }
  6164. //================== RichEdit specific: ==================
  6165. property MaxTextSize: DWORD read GetMaxTextSize write SetMaxTextSize;
  6166. {* |<#richedit>
  6167. This property valid also for simple edit control, not only for RichEdit.
  6168. But for usual edit control, maximum text size available is 32K. For
  6169. RichEdit, limit is 4Gb. By default, RichEdit is limited to
  6170. 32767 bytes (to set maximum size available to 2Gb, assign MaxInt value
  6171. to a property). Also, to get current text size of RichEdit, use property
  6172. TextSize or RE_TextSize[ ]. }
  6173. property TextSize: Integer read GetTextSize;
  6174. {* |<#richedit>
  6175. Common for edit and rich edit controls property, which returns size of
  6176. text in edit control. Also, for any other control (or form, or applet
  6177. window) returns size (in characters) of Caption or Text (what is, the
  6178. same property actually). }
  6179. property RE_TextSize[ Units: TRichTextSize ]: Integer read REGetTextSize;
  6180. {* |<#richedit>
  6181. For RichEdit control, it returns text size, measured in desired units
  6182. (rtsChars - characters, including OLE objects, counted as a single
  6183. character; rtsBytes - presize length of text image (if it would be stored
  6184. in file or stream). Please note, that for RichEdit1.0, only size in
  6185. characters can be obtained. }
  6186. function RE_TextSizePrecise: Integer;
  6187. {* |<#richedit>
  6188. By Savva. Returns length of rich edit text. }
  6189. property RE_CharFmtArea: TRichFmtArea read fRECharArea write fRECharArea;
  6190. {* |<#richedit>
  6191. By default, this property is raSelection. Changing it, You determine in
  6192. for which area characters format is applyed, when changing
  6193. character formatting properties below (not paragraph formatting).
  6194. |&A=<a href=#RE_CharFmtArea target=main>%0</a>
  6195. }
  6196. property RE_CharFormat: TCharFormat read REGetCharformat write RESetCharFormat;
  6197. {* |<#richedit>
  6198. In differ to follow properties, which allow to control certain formatting
  6199. attributes, this property provides low level access for formatting current
  6200. character area (see RE_CharFmtArea). It returns TCharFormat structure,
  6201. filled in with formatting attributes, and by assigning another value to
  6202. this property You can change desired attributes as You wish. Even if
  6203. RichEdit1.0 is used, TCharFormat2 is returned (but extended fields are
  6204. ignored for RichEdit1.0). }
  6205. property RE_Font: PGraphicTool read REGetFont write RESetFont;
  6206. {* |<#richedit>
  6207. Font of the first character in current selection (when retrieve).
  6208. When set (or subproperties of RE_Font are set), all font attributes are
  6209. applied to entire <A area>. To apply only needed attributes, use another
  6210. properties: RE_FmtBold, RE_FmtItalic, RE_FmtStrikeout, RE_FmtUnderline,
  6211. RE_FmtName, etc.
  6212. |<br>
  6213. Note, that font size is measured in twips, which is about 1/10 of pixel. }
  6214. property RE_FmtBold: Boolean index CFM_BOLD read REGetFontEffects write RESetFontEffect;
  6215. {* |<#richedit>
  6216. Formatting flag. When retrieve, returns True, if fsBold style RE_Font.FontStyle
  6217. is valid for a first character in the selection. When set, changes fsBold
  6218. style (True - set, False - reset) for all characters in <A area>. }
  6219. property RE_FmtBoldValid: Boolean index CFM_BOLD read REGetFontMask;
  6220. {* }
  6221. property RE_FmtItalic: Boolean index CFM_ITALIC read REGetFontEffects write RESetFontEffect;
  6222. {* |<#richedit>
  6223. Formatting flag. Like RE_FmtBold, when retrieving, shows, is fsItalic
  6224. style valid for the first character of the selection, and when set, changes
  6225. only fsItalic style for an <A area>. }
  6226. property RE_FmtItalicValid: Boolean index CFM_ITALIC read REGetFontMask;
  6227. {* }
  6228. property RE_FmtStrikeout: Boolean index CFM_STRIKEOUT read REGetFontEffects write RESetFontEffect;
  6229. {* |<#richedit>
  6230. Formatting flag. Like RE_FmtBold, when retrieving, shows, is fsStrikeout
  6231. style valid for the first selected character, and when set, changes only
  6232. fsStrikeout style for an <A area>. }
  6233. property RE_FmtStrikeoutValid: Boolean index CFM_STRIKEOUT read REGetFontMask;
  6234. {* }
  6235. property RE_FmtUnderline: Boolean index CFM_UNDERLINE read REGetFontEffects write RESetFontEffect;
  6236. {* |<#richedit>
  6237. Formatting flag. Like RE_FmtBold, when retrieving, shows, is fsUnderline
  6238. style valid for the first selected character, and when set, changes
  6239. fsUnderline style for an <A area>. }
  6240. property RE_FmtUnderlineValid: Boolean index CFM_UNDERLINE read REGetFontMask;
  6241. {* }
  6242. property RE_FmtUnderlineStyle: TRichUnderline
  6243. read REGetUnderlineEx write RESetUnderlineEx;
  6244. {* |<#richedit>
  6245. Extended underline style. To check, if this property is valid for
  6246. entire selection, examine RE_FmtUnderlineValid value. }
  6247. property RE_FmtProtected: Boolean index CFM_PROTECTED read REGetFontEffects write RESetFontEffect;
  6248. {* |<#richedit>
  6249. Formatting flag. When retrieving, shows, is the first character of the selection
  6250. is protected from changing it by user (True) or not (False). To get know,
  6251. if retrived value is valid for entire selection, check the property
  6252. RE_FmtProtectedValid. When set, makes all characters in <A area> protected (
  6253. True) or not (False). }
  6254. property RE_FmtProtectedValid: Boolean index CFM_PROTECTED read REGetFontMask;
  6255. {* |<#richedit>
  6256. True, if property RE_FmtProtected is valid for entire selection, when
  6257. retrieving it. }
  6258. property RE_FmtHidden: Boolean index CFM_HIDDEN read REGetFontEffects write RESetFontEffect;
  6259. {* |<#richedit>
  6260. For RichEdit3.0, makes text hidden (not displayed). }
  6261. property RE_FmtHiddenValid: Boolean index CFM_HIDDEN read REGetFontMask;
  6262. {* |<#richedit>
  6263. Returns True, if RE_FmtHidden style is valid for entire selection. }
  6264. property RE_FmtLink: Boolean index $20 {CFM_LINK} read REGetFontEffects write RESetFontEffect;
  6265. {* |<#richedit>
  6266. Returns True, if the first selected character is a part of link (URL). }
  6267. // by Sergey Shisminzev
  6268. property RE_FmtLinkValid: Boolean index $20 {CFM_LINK} read REGetFontMask;
  6269. {* }
  6270. property RE_FmtFontSize: Integer index (12 shl 16) or CFM_SIZE read REGetFontAttr write RESetFontAttr;
  6271. {* |<#richedit>
  6272. Formatting value: font size, in twips (1/1440 of an inch, or 1/20 of a
  6273. printer's point, or about 1/10 of pixel). When retrieving, returns
  6274. RE_Font.FontHeight.
  6275. When set, changes font size for entire <A area> (but does not change
  6276. other font attributes). }
  6277. property RE_FmtFontSizeValid: Boolean read REGetFontSizeValid;
  6278. {* |<#richedit>
  6279. Returns True, if property RE_FmtFontSize is valid for entire selection,
  6280. when retrieving it. }
  6281. //property RE_FmtBackColor: Integer index (62 shl 16) or CFM_BACKCOLOR read REGetFontAttr write RESetFontAttr1;
  6282. {* |<#richedit>
  6283. Background color for an <A area>. }
  6284. //property RE_FmtBackColorValid: Boolean index CFM_BACKCOLOR read REGetFontEffect;
  6285. {* |<#richedit>
  6286. True, if RE_FmtBackColor valid for entire <A area>. }
  6287. property RE_FmtAutoBackColor: Boolean index CFM_BACKCOLOR read REGetFontEffects write RESetFontEffect;
  6288. {* |<#richedit>
  6289. True, when automatic back color is used. }
  6290. property RE_FmtAutoBackColorValid: Boolean index CFM_BACKCOLOR read REGetFontMask;
  6291. {* }
  6292. property RE_FmtFontColor: Integer index (20 shl 16) or CFM_COLOR read REGetFontAttr write RESetFontAttr1;
  6293. {* |<#richedit>
  6294. Formatting value (font color). When retrieving, returns RE_Font.Color.
  6295. When set, changes font color for entire <A area> (but does not change
  6296. other font attributes). }
  6297. property RE_FmtFontColorValid: Boolean index CFM_COLOR read REGetFontMask;
  6298. {* |<#richedit>
  6299. Returns True, if property RE_FmtFontColor valid for entire selection,
  6300. when retrieving it. }
  6301. property RE_FmtAutoColor: Boolean index CFM_COLOR read REGetFontEffects write RESetFontEffect;
  6302. {* |<#richedit>
  6303. True, when automatic text color is used (in such case, RE_FmtFontColor
  6304. assignment is ignored for current area). }
  6305. property RE_FmtAutoColorValid: Boolean index CFM_COLOR read REGetFontMask;
  6306. {* }
  6307. property RE_FmtBackColor: Integer index (64 shl 16) or CFM_BACKCOLOR read REGetFontAttr write RESetFontAttr1;
  6308. {* |<#richedit>
  6309. Formatting value (back color). Only available for Rich Edit 2.0 and higher.
  6310. When set, changes background color for entire <A area> (but does not change
  6311. other font attributes). }
  6312. property RE_FmtBackColorValid: Boolean index CFM_BACKCOLOR read REGetFontMask;
  6313. {* }
  6314. property RE_FmtFontOffset: Integer index (16 shl 16) or CFM_OFFSET read REGetFontAttr write RESetFontAttr;
  6315. {* |<#richedit>
  6316. Formatting value (font vertical offset from baseline, positive values
  6317. correspond to subscript). When retrieving, returns offset for first
  6318. character in the selection. When set, changes font offset for entire
  6319. <A area>. To get know, is retrieved value valid for entire selction,
  6320. check RE_FmtFontOffsetValid property. }
  6321. property RE_FmtFontOffsetValid: Boolean index CFM_OFFSET read REGetFontMask;
  6322. {* |<#richedit>
  6323. Returns True, if property RE_FmtFontOffset is valid for entire selection,
  6324. when retrieving it. }
  6325. property RE_FmtFontCharset: Integer index (25 shl 16) or CFM_CHARSET read REGetFontAttr write RESetFontAttr;
  6326. {* |<#richedit>
  6327. Returns charset for first character in current selection, when retrieved
  6328. (and to get know, if this value is valid for entire selection, check
  6329. property RE_FmtFontCharsetValid). When set, changes charset for all
  6330. characters in <A area>, but does not alter other formatting attributes. }
  6331. property RE_FmtFontCharsetValid: Boolean index CFM_CHARSET read REGetFontMask;
  6332. {* |<#richedit>
  6333. Returns True, only if rerieved property RE_FmtFontCharset is valid for
  6334. entire selection. }
  6335. property RE_FmtFontName: String read REGetFontName write RESetFontName;
  6336. {* |<#richedit>
  6337. Returns font face name for first character in the selection, when retrieved,
  6338. and sets font name for entire <A area>, wnen assigned to (without
  6339. changing of other formatting attributes). To get know, if retrived
  6340. font name valid for entire selection, examine property RE_FmtFontNameValid. }
  6341. property RE_FmtFontNameValid: Boolean index CFM_FACE read REGetFontMask;
  6342. {* |<#richedit>
  6343. Returns True, only if the font name is the same for entire selection,
  6344. thus is, if rerieved property value RE_FmtFontName is valid for entire
  6345. selection. }
  6346. property RE_ParaFmt: TParaFormat read REGetParaFmt write RESetParaFmt;
  6347. {* |<#richedit>
  6348. Allows to retrieve or set paragraph formatting attributes for currently
  6349. selected paragraph(s) in RichEdit control. See also following properties,
  6350. which allow to do the same for certain paragraph format attributes
  6351. separately. }
  6352. property RE_TextAlign: TRichTextAlign read REGetTextAlign write RESetTextAlign;
  6353. {* |<#richedit>
  6354. Returns text alignment for current selection and allows to change it
  6355. (without changing other formatting attributes). }
  6356. property RE_TextAlignValid: Boolean index PFM_ALIGNMENT read REGetParaAttrValid;
  6357. {* |<#richedit>
  6358. Returns True, if property RE_TextAlign is valid for entire selection. If
  6359. False, it is concerning only start of selection. }
  6360. property RE_Numbering: Boolean read REGetNumbering write RESetNumbering;
  6361. {* |<#richedit>
  6362. Returns True, if selected text is numbered (or has style of list with
  6363. bullets). To get / change numbering style, see properties
  6364. RE_NumStyle and RE_NumBrackets. }
  6365. property RE_NumStyle: TRichNumbering read REGetNumStyle write RESetNumStyle;
  6366. {* |<#richedit>
  6367. Advanced numbering style, such as rnArabic etc. If You use it, do not
  6368. change RE_Numbering property simultaneously - this can cause changing
  6369. style to rnBullets only. }
  6370. property RE_NumStart: Integer read REGetNumStart write RESetNumStart;
  6371. {* |<#richedit>
  6372. Starting number for advanced numbering style. If this property is not
  6373. set, numbering is starting by default from 0. For rnLRoman and rnURoman
  6374. this cause, that first item has no number to be shown (ancient Roman
  6375. people did not invent '0'). }
  6376. property RE_NumBrackets: TRichNumBrackets read REGetNumBrackets write RESetNumBrackets;
  6377. {* |<#richedit>
  6378. Brackets style for advanced numbering. rnbPlain is default
  6379. brackets style, and every time, when RE_NumStyle is changed,
  6380. RE_NumBrackets is reset to rnbPlain. }
  6381. property RE_NumTab: Integer read REGetNumTab write RESetNumTab;
  6382. {* |<#richedit>
  6383. Tab between start of number and start of paragraph text. If too small too
  6384. view number, number is not displayed. (Default value seems to be sufficient
  6385. though). }
  6386. property RE_NumberingValid: Boolean index PFM_NUMBERING read REGetParaAttrValid;
  6387. {* |<#richedit>
  6388. Returns True, if RE_Numbering, RE_NumStyle, RE_NumBrackets, RE_NumTab,
  6389. RE_NumStart properties are valid for entire selection. }
  6390. property RE_Level: Integer read REGetLevel;
  6391. {* |<#richedit>
  6392. Outline level (for numbering paragraphs?). Read only. }
  6393. property RE_SpaceBefore: Integer index 0 or PFM_SPACEBEFORE read REGetSpacing write RESetSpacing;
  6394. {* |<#richedit>
  6395. Spacing before paragraph. }
  6396. property RE_SpaceBeforeValid: Boolean index PFM_SPACEBEFORE read REGetParaAttrValid;
  6397. {* |<#richedit>
  6398. True, if RE_SpaceBefore value is valid for all selected paragraph (if
  6399. False, this value is valid only for first paragraph. }
  6400. property RE_SpaceAfter: Integer index 4 or PFM_SPACEAFTER read REGetSpacing write RESetSpacing;
  6401. {* |<#richedit>
  6402. Spacing after paragraph. }
  6403. property RE_SpaceAfterValid: Boolean index PFM_SPACEAFTER read REGetParaAttrValid;
  6404. {* |<#richedit>
  6405. True, only if RE_SpaceAfter value is valid for all selected paragraphs. }
  6406. property RE_LineSpacing: Integer index 8 or PFM_LINESPACING read REGetSpacing write RESetSpacing;
  6407. {* |<#richedit>
  6408. Linespacing in paragraph (this value is based on RE_SpacingRule property). }
  6409. property RE_SpacingRule: Integer read REGetSpacingRule write RESetSpacingRule;
  6410. {* |<#richedit>
  6411. Linespacing rule. Do not know what is it. }
  6412. property RE_LineSpacingValid: Boolean index PFM_LINESPACING read REGetParaAttrValid;
  6413. {* |<#richedit>
  6414. True, only if RE_LineSpacing and RE_SpacingRule values are valid for
  6415. entire selection. }
  6416. property RE_Indent: Integer index (20 shl 16) or PFM_OFFSET read REGetParaAttr write RESetParaAttr;
  6417. {* |<#richedit>
  6418. Returns left indentation for paragraph in current selection and allows
  6419. to change it (without changing other formatting attributes). }
  6420. property RE_IndentValid: Boolean index PFM_OFFSET read REGetParaAttrValid;
  6421. {* |<#richedit>
  6422. Returns True, if RE_Indent property is valid for entire selection. }
  6423. property RE_StartIndent: Integer index (12 shl 16) or PFM_OFFSETINDENT read REGetParaAttr write RESetParaAttr;
  6424. {* |<#richedit>
  6425. Returns left indentation for first line in paragraph for current
  6426. selection, and allows to change it (without changing other formatting
  6427. attributes). }
  6428. property RE_StartIndentValid: Boolean read REGetStartIndentValid;
  6429. {* |<#richedit>
  6430. Returns True, if property RE_StartIndent is valid for entire selection. }
  6431. property RE_RightIndent: Integer index (16 shl 16) or PFM_RIGHTINDENT read REGetParaAttr write RESetParaAttr;
  6432. {* |<#richedit>
  6433. Returns right indent for paragraph in current selection, and allow to
  6434. change it (without changing other formatting attributes). }
  6435. property RE_RightIndentValid: Boolean index PFM_RIGHTINDENT read REGetParaAttrValid;
  6436. {* |<#richedit>
  6437. Returns True, if property RE_RightIndent is valid for entire selection only. }
  6438. property RE_TabCount: Integer read REGetTabCount write RESetTabCount;
  6439. {* |<#richedit>
  6440. Number of tab stops in current selection. This value can not be set greater
  6441. then MAX_TAB_COUNT (32). }
  6442. property RE_Tabs[ Idx: Integer ]: Integer read REGetTabs write RESetTabs;
  6443. {* |<#richedit>
  6444. Tab stops for RichEdit control. }
  6445. property RE_TabsValid: Boolean index PFM_TABSTOPS read REGetParaAttrValid;
  6446. {* |<#richedit>
  6447. Returns True, if properties RE_Tabs[ ] and RE_TabCount are valid for
  6448. entire selection. }
  6449. // following does not work now :
  6450. property RE_BorderWidth[ Side: TBorderEdge ]: Integer index 2 read REGetBorder write RESetBorder;
  6451. { * |<#richedit>
  6452. Border width. }
  6453. property RE_BorderSpace[ Side: TBorderEdge ]: Integer index 0 read REGetBorder write RESetBorder;
  6454. { * |<#richedit>
  6455. Border space. }
  6456. property RE_BorderStyle[ Side: TBorderEdge ]: Integer index 4 read REGetBorder write RESetBorder;
  6457. { * |<#richedit>
  6458. Border style. }
  6459. property RE_BorderValid: Boolean index PFM_BORDER read REGetParaAttrValid;
  6460. { * |<#richedit>
  6461. Returns True, if border style, space and width are the same for all
  6462. paragraphs in selection. }
  6463. property RE_Table: Boolean index $C000 read REGetParaEffect write RESetParaEffect;
  6464. { * |<#richedit>
  6465. True, if current paragraph is a part of table (row, cell or cell end).
  6466. seems working as read only property. }
  6467. // end of experiment section
  6468. function RE_FmtStandard: PControl;
  6469. {* |<#richedit>
  6470. "Transparent" method (returns @Self as a result), which (when called)
  6471. provides "standard" keyboard interface for formatting Rich text (just
  6472. call this method, for example:
  6473. ! RichEd1 := NewRichEdit( Panel1, [ ] ).SetAlign( caClient ).RE_FmtStandard;
  6474. Following keys will be maintained additionally:
  6475. |<pre>
  6476. CTRL+I - switch "Italic",
  6477. CTRL+B - switch "Bold",
  6478. CTRL+U - switch "Underline",
  6479. CTRL+SHIFT+U - swith underline type
  6480. and turn underline on (note, that some of underline styles
  6481. can not be shown properly in RichEdit v2.0 and lower,
  6482. though RichEdit2.0 stores data successfully).
  6483. CTRL+O - switch "StrikeOut",
  6484. CTRL+'gray+' - increase font size,
  6485. CTRL+'gray-' - decrease font size,
  6486. CTRL+SHIFT+'gray+' - superscript,
  6487. CTRL+SHIFT+'gray-' - subscript.
  6488. CTRL+SHIFT+Z - ReDo
  6489. |</pre>
  6490. And, though following standard formatting keys are provided by RichEdit
  6491. control itself in Windows2000, some of these are not functioning
  6492. automatically in earlier Windows versions, even for RichEdit2.0. So,
  6493. functionality of some of these (marked with (*) ) are added here too:
  6494. |<pre>
  6495. CTRL+L - align paragraph left, (*)
  6496. CTRL+R - align paragraph right, (*)
  6497. CTRL+E - align paragraph center, (*)
  6498. CTRL+A - select all, (*)
  6499. double-click on word - select word,
  6500. CTRL+Right - to next word,
  6501. CTRL+Left - to previous word,
  6502. CTRL+Home - to the beginning of text,
  6503. CTRL+End - to the end of text.
  6504. CTRL+Z - UnDo
  6505. |</pre>
  6506. If You originally assign some (plain) text to Text property, switching "underline"
  6507. can also change other font attributes, e.g., "bold" - if fsBold style is
  6508. in default Font. To prevent such behavior, select entire text first (see
  6509. SelectAll) and make assignment to RE_Font property, e.g.:
  6510. ! RichEd1.SelectAll;
  6511. ! RichEd1.RE_Font := RichEd1.RE_Font;
  6512. ! RichEd1.SelLength := 0;
  6513. |<br>
  6514. And, some other notices about formatting. Please remember, that only True
  6515. Type fonts can be succefully scaled and transformed to get desired effects
  6516. (e.g., bold). By default, RichEdit uses System font face name, which can
  6517. even have problems with fsBold style. Please remember also, that assigning
  6518. RE_Font to RE_Font just initializying formatting attributes, making all
  6519. those valid in entire text, but does not change font attributes. To use
  6520. True Type font, directly assign face name You wish, e.g.:
  6521. ! RichEd1.SelectAll;
  6522. ! RichEd1.RE_Font := RichEd1.RE_Font;
  6523. ! RichEd1.RE_Font.FontName := 'Arial';
  6524. ! RichEd1.SelLength := 0;
  6525. }
  6526. property RE_AutoKeyboard: Boolean index 1 read REGetLangOptions write RESetLangOptions;
  6527. {* |<#richedit>
  6528. True if autokeyboard on (lovely "feature" of automatic switching keyboard
  6529. language when caret is over another language text). For older RichEdit,
  6530. is 'on' always, for newest - 'off' by default. }
  6531. property RE_OverwriteMode: Boolean read REGetOverwite write RESetOverwrite;
  6532. {* |<#richedit>
  6533. This property allows to control insert/overwrite mode. First, to examine, if
  6534. insert or overwrite mode is current (but it is necessary either to
  6535. access this property, at least once, immediately after creating RichEdit
  6536. control, or to assign event OnRE_InsOvrMode_Change to your handler).
  6537. Second, to set desired mode programmatically - by assigning value to
  6538. this property (You also have to initialize monitoring procedure by either
  6539. reading RE_OverwriteMode property or assigning handler to event
  6540. OnRE_InsOvrMode_Change immediately following RichEdit control creation). }
  6541. property OnRE_InsOvrMode_Change: TOnEvent read fOnREInsModeChg write fOnREInsModeChg;
  6542. {* |<#richedit>
  6543. This event is called, whenever key INSERT is pressed in control (and for
  6544. RichEdit, this means, that insert mode is changed). }
  6545. property RE_DisableOverwriteChange: Boolean read fReOvrDisable write RESetOvrDisable;
  6546. {* |<#richedit>
  6547. It is possible to disable switching between "insert" and "overwrite" mode
  6548. by user (therefore, event OnRE_InsOvrMode_Change continue works, but it
  6549. just called when key INSERT is pressed, though RE_OverwriteMode property
  6550. is not actually changed if switching is disabled). }
  6551. function RE_LoadFromStream( Stream: PStream; Length: Integer;
  6552. Format: TRETextFormat; SelectionOnly: Boolean ): Boolean;
  6553. {* |<#richedit>
  6554. Use this method rather then assignment to RE_Text property, if
  6555. source is stored in file or stream (to minimize resources during
  6556. loading of RichEdit content). Data is loading starting from current
  6557. position in stream and no more then Length bytes are loaded (use -1
  6558. value to load to the end of stream). Loaded data replaces entire
  6559. content of RichEdit control, or selection only, depending on SelectionOnly
  6560. flag.
  6561. |<br>&nbsp;&nbsp;&nbsp;
  6562. If You want to provide progress (e.g. in form of progress bar), assign
  6563. OnProgress event to your handler - and to examine current position of
  6564. loading, read TSream.Position property of soiurce stream). }
  6565. function RE_SaveToStream( Stream: PStream; Format: TRETextFormat; SelectionOnly: Boolean ): Boolean;
  6566. {* |<#richedit>
  6567. Use this method rather then RE_TextProperty to store data to file
  6568. or stream (to minimize resources during saving of RichEdit content).
  6569. Data is saving starting from current position in a stream (until
  6570. end of RichEdit data). If SelectionOnly flag is True, only selected
  6571. part of RichEdit text is saved.
  6572. |<br>&nbsp;&nbsp;&nbsp;
  6573. Like for RE_LoadFromStream, it is possible to assign your method to
  6574. OnProgress event (but to calculate progress of save-to-stream operation,
  6575. compare current stream position with RE_Size[ rsBytes ] property
  6576. value). }
  6577. property OnProgress: TOnEvent read fOnProgress write fOnProgress;
  6578. {* |<#richedit>
  6579. This event is called during RE_SaveToStream, RE_LoadFromStream (and also
  6580. during RE_SaveToFile, RE_LoadFromFile and while accessing or changing
  6581. RE_Text property). To calculate relative progress, it is possible to
  6582. examine current position in stream/file with its total size while reading,
  6583. or with rich edit text size, while writing (property RE_TextSize[ rsBytes ]).
  6584. }
  6585. function RE_LoadFromFile( const Filename: String; Format: TRETextFormat;
  6586. SelectionOnly: Boolean ): Boolean;
  6587. {* |<#richedit>
  6588. Use this method rather then other assignments to RE_Text property,
  6589. if a source for RichEdit is the file. See also RE_LoadFromStream. }
  6590. function RE_SaveToFile( const Filename: String; Format: TRETextFormat;
  6591. SelectionOnly: Boolean ): Boolean;
  6592. {* |<#richedit>
  6593. Use this method rather then other similar, if You want to store
  6594. entire content of RichEdit or selection only of RichEdit to a file. }
  6595. property RE_Text[ Format: TRETextFormat; SelectionOnly: Boolean ]: String read REReadText write REWriteText;
  6596. {* |<#richedit>
  6597. This property allows to get / replace content of RichEdit control
  6598. (entire text or selection only). Using different formats, it is
  6599. possible to exclude or replace undesired formatting information
  6600. (see TRETextFormat specification). To get or replace entire text
  6601. in reText mode (plain text only), it is possible to use habitual
  6602. for edit controls Text property.
  6603. |<br>&nbsp;&nbsp;&nbsp;
  6604. Note: it is possible to append text to the end of RichEdit control
  6605. using method Add, but only if property RE_Text is accessed at least
  6606. once:
  6607. ! RichEdit1.RE_Text[ reText, True ];
  6608. (This line can be written immediatelly after creating RichEdit control). }
  6609. procedure RE_Append( const S: String; ACanUndo: Boolean );
  6610. {* }
  6611. procedure RE_InsertRTF( const S: String );
  6612. {* }
  6613. property RE_Error: Integer read fREError;
  6614. {* |<#richedit>
  6615. Contains error code, if access to RE_Text failed. }
  6616. procedure RE_HideSelection( aHide: Boolean );
  6617. {* |<#richedit>
  6618. Allows to hide / show selection in RichEdit. }
  6619. function RE_SearchText( const Value: String; MatchCase, WholeWord, ScanForward: Boolean;
  6620. SearchFrom, SearchTo: Integer ): Integer;
  6621. {* |<#richedit>
  6622. Searches given string starting from SearchFrom position up to SearchTo
  6623. position (to the end of text, if SearchTo is -1). Returns zero-based
  6624. character position of the next match, or -1 if there are no more matches.
  6625. To search in bacward direction, set ScanForward to False, and pass
  6626. SearchFrom > SearchTo (or even SearchFrom = -1 and SearchTo = 0). }
  6627. property RE_AutoURLDetect: Boolean read REGetAutoURLDetect write RESetAutoURLDetect;
  6628. {* |<#richedit>
  6629. If set to True, automatically detects URLs (and highlights it with
  6630. blue color, applying fsItalic and fsUnderline font styles (while
  6631. typing and loading). Default value is False. Note: if event OnRE_URLClick
  6632. or event OnRE_OverURL are set, property RE_AutoURLDetect is set to True
  6633. automatically. }
  6634. property RE_URL: String read fREUrl;
  6635. {* |<#richedit>
  6636. Detected URL (valid in OnRE_OverURL and OnRE_URLClick event handlers). }
  6637. property OnRE_OverURL: TOnEvent index 0
  6638. {$IFDEF F_P} read REGetOnURL
  6639. {$ELSE DELPHI} read fOnREOverURL
  6640. {$ENDIF F_P/DELPHI} write RESetOnURL;
  6641. {* |<#richedit>
  6642. Is called when mouse is moving over URL. This can be used to set
  6643. cursor, for example, depending on type of URL (to determine URL type
  6644. read property RE_URL). }
  6645. property OnRE_URLClick: TOnEvent index 8
  6646. {$IFDEF F_P} read REGetOnURL
  6647. {$ELSE DELPHI} read fOnREURLClick
  6648. {$ENDIF F_P/DELPHI} write RESetOnURL;
  6649. {* |<#richedit>
  6650. Is called when click on URL detected. }
  6651. //property RE_SelectionBar: Boolean read REGetSelectionBar write RESetSelectionBar;
  6652. //{* ??? - don't know that is this... }
  6653. function RE_NoOLEDragDrop: PControl;
  6654. {* |<#richedit>
  6655. Just prevents drop OLE objects to the rich edit control. Seems not
  6656. working for some cases. }
  6657. //function RE_Wyswig: PControl;
  6658. function RE_Bottomless: PControl;
  6659. // not finished
  6660. property RE_Transparent: Boolean read REGetTransparent write RESetTransparent;
  6661. {* |<#richedit>
  6662. Use this property to make richedit control transparent, instead of
  6663. Ed_Transparent or Transparent. But do not place such transparent
  6664. richedit control directly on form - it can be draw incorrectly when
  6665. form is activated and rich editr control is not current active control.
  6666. Use at least panel as a parent instead.
  6667. }
  6668. //========== both for Edit and RichEdit: =====================
  6669. function CanUndo: Boolean;
  6670. {* |<#richedit>
  6671. |<#edit>
  6672. |<#memo>
  6673. Returns True, if the edit (or RichEdit) control can correctly process
  6674. the EM_UNDO message. }
  6675. procedure EmptyUndoBuffer;
  6676. {* |<#richedit>
  6677. |<#edit>
  6678. |<#memo>
  6679. Reset the undo flag of an edit control, preventing undoing all previous
  6680. changes. }
  6681. function Undo: Boolean;
  6682. {* |<#richedit>
  6683. |<#edit>
  6684. |<#memo>
  6685. For a single-line edit control, the return value is always TRUE. For a
  6686. multiline edit control and RichEdit control, the return value is TRUE if
  6687. the undo operation is successful, or FALSE if the undo operation fails. }
  6688. function RE_Redo: Boolean;
  6689. {* |<#richedit>
  6690. Only for RichEdit control: Returns True if successful. }
  6691. //----------------------------------------------------------------------
  6692. // DateTimePicker
  6693. property OnDTPUserString: TDTParseInputEvent read FOnDTPUserString
  6694. write FOnDTPUserString;
  6695. {* Special event to parse input from the application. Option dtpoParseInput
  6696. must be set when control is created. }
  6697. property DateTime: TDateTime read GetDateTime write SetDateTime;
  6698. {* DateTime for DateTimePicker control only. }
  6699. property Date: TDateTime read GetDate write SetDate;
  6700. {* Date only for DateTimePicker control only. }
  6701. property Time: TDateTime read GetTime write SetTime;
  6702. {* Time only for DateTimePicker control only. }
  6703. property DateTimeRange: TDateTimeRange read GetDateTimeRange
  6704. write SetDateTimeRange;
  6705. {* DateTimePicker range. If first date in the agrument assigned is NAN,
  6706. minimum system allowed value is used as the left bound, and if the second is
  6707. NAN, maximum system allowed is used as the right one. }
  6708. property DateTimePickerColors[ Index: TDateTimePickerColor ]: TColor
  6709. read GetDateTimePickerColor write SetDateTimePickerColor;
  6710. property DateTimeFormat: String write SetDateTimeFormat;
  6711. //----------------------------------------------------------------------
  6712. //----------------------------------------------------------------------
  6713. // ScrollBar
  6714. property SBMin: Longint read fSBMinMax.X write SetSBMin;
  6715. property SBMax: Longint read fSBMinMax.Y write SetSBMax;
  6716. property SBMinMax: TPoint read fSBMinMax write SetSBMinMax;
  6717. property SBPosition: Integer read fSBPosition write SetSBPosition;
  6718. property SBPageSize: Integer read fSBPageSize write SetSBPageSize;
  6719. property OnSBBeforeScroll: TOnSBBeforeScroll read FOnSBBeforeScroll write FOnSBBeforeScroll;
  6720. property OnSBScroll: TOnSBScroll read FOnSBScroll write FOnSBScroll;
  6721. function SBSetScrollInfo(const SI: TScrollInfo): Integer;
  6722. function SBGetScrollInfo(var SI: TScrollInfo): Boolean;
  6723. function GetSBMinMax: TPoint;
  6724. function GetSBPageSize: Integer;
  6725. function GetSBPosition: Integer;
  6726. //----------------------------------------------------------------------
  6727. // "Through", or "transparent" methods to simplify initial
  6728. // adjustment of controls and make non-visual designing of
  6729. // forms more easy. All these functions return @Self as a
  6730. // result, so, it is possible to use such methods immediately
  6731. // in constructing statement, concatenating it with dots, e.g.:
  6732. //
  6733. // NewButton( MyForm, 'Click here' ).PlaceUnder.ResizeParentBottom;
  6734. //
  6735. function PlaceRight: PControl;
  6736. {* Places control right (to previously created on the same parent). }
  6737. function PlaceDown: PControl;
  6738. {* Places control below (to previously created on the same parent).
  6739. Left position is not changed (thus is, kept equal to Parent.Margin). }
  6740. function PlaceUnder: PControl;
  6741. {* Places control below (to previously created one, aligning its
  6742. Left position to Left position of previous control). }
  6743. function SetSize( W, H: Integer ): PControl;
  6744. {* Changes size of a control. If W or H less or equal to 0,
  6745. correspondent size is not changed. }
  6746. function Size( W, H: Integer ): PControl;
  6747. {* Like SetSize, but provides automatic resizing of parent control
  6748. (recursively). Especially useful for aligned controls. }
  6749. function SetClientSize( W, H: Integer ): PControl;
  6750. {* Like SetSize, but works setting W = ClientWidth, H = ClientHeight.
  6751. Use this method for forms, which can not be resized (dialogs). }
  6752. function AutoSize( AutoSzOn: Boolean ): PControl;
  6753. function MakeWordWrap: PControl;
  6754. {* Determines if to autosize control (like label, button, etc.) }
  6755. function IsAutoSize: Boolean;
  6756. {* TRUE, if a control is autosizing. }
  6757. function AlignLeft( P: PControl ): PControl;
  6758. {* assigns Left := P.Left }
  6759. function AlignTop( P: PControl ): PControl;
  6760. {* assigns Top := P.Top }
  6761. function ResizeParent: PControl;
  6762. {* Resizes parent, calling ResizeParentRight and ResizeParentBottom. }
  6763. function ResizeParentRight: PControl;
  6764. {* Resizes parent right edge (Margin of parent is added to right
  6765. coordinate of a control). If called second time (for the same
  6766. parent), resizes only for increasing of right edge of parent. }
  6767. function ResizeParentBottom: PControl;
  6768. {* Resizes parent bottom edge (Margin of parent is added to
  6769. bottom coordinate of a control). }
  6770. function CenterOnParent: PControl;
  6771. {* Centers control on parent, or if applied to a form, centers
  6772. form on screen. }
  6773. function Shift( dX, dY : Integer ): PControl;
  6774. {* Moves control respectively to current position (Left := Left + dX,
  6775. Top := Top + dY). }
  6776. function SetPosition( X, Y: Integer ): PControl;
  6777. {* Moves control directly to the specified position. }
  6778. function Tabulate: PControl;
  6779. {* Call it once for form/applet to provide tabulation between controls on
  6780. form/on all forms using TAB / SHIFT+TAB and arrow keys. }
  6781. function TabulateEx: PControl;
  6782. {* Call it once for form/applet to provide tabulation between controls on
  6783. form/on all forms using TAB / SHIFT+TAB and arrow keys. Arrow keys are
  6784. used more smart, allowing go to nearest control in certain direction. }
  6785. function SetAlign( AAlign: TControlAlign ): PControl;
  6786. {* Assigns passed value to property Align, aligning control on parent,
  6787. and returns @Self (so it is "transparent" function, which can be
  6788. used to adjust control at the creation, e.g.:
  6789. ! MyLabel := NewLabel( MyForm, 'Label1' ).SetAlign( caBottom );
  6790. See also property Align. }
  6791. function PreventResizeFlicks: PControl;
  6792. {* If called, prevents resizing flicks for child controls, aligned to
  6793. right and bottom (but with a lot of code added to executable - about 3,5K).
  6794. There is sensible to set DoubleBuffered to True also to eliminate the
  6795. most of flicks.
  6796. |<br>&nbsp;&nbsp;&nbsp;
  6797. This method been applied to a form, prevents, resizing flicks for
  6798. form and all controls on the form. If it is called for applet window,
  6799. all forms are affected. And if You want, You can apply it for certain
  6800. control only - in such case only given control and its children will
  6801. be resizing without flicks (e.g., using splitter control). }
  6802. property Checked: Boolean read GetChecked write Set_Checked;
  6803. {* |<#checkbox>
  6804. |<#radiobox>
  6805. For checkbox and radiobox - if it is checked. Do not assign
  6806. value for radiobox - use SetRadioChecked instead. }
  6807. function SetChecked(const Value: Boolean): PControl;
  6808. {* |<#checkbox>
  6809. Use it to check/uncheck check box control or push button.
  6810. Do not apply it to check radio buttons - use SetRadioChecked
  6811. method below. }
  6812. function SetRadioChecked : PControl;
  6813. {* |<#radiobox>
  6814. Use it to check radio button item correctly (unchecking all
  6815. alternative ones). Actually, method Click is called, and control
  6816. itself is returned. }
  6817. function SetRadioCheckedOld: PControl;
  6818. {* |<#radiobox>
  6819. Old version of SetRadioChecked (implemented using recommended API
  6820. call. It does not work properly, if control is not visible
  6821. (together with its form). }
  6822. property Check3: TTriStateCheck read GetCheck3 write SetCheck3;
  6823. {* |<#checkbox>
  6824. State of checkbox with BS_AUTO3STATE style. }
  6825. procedure Click;
  6826. {* |<#button>
  6827. |<#checkbox>
  6828. |<#radiobox>
  6829. Emulates click on control programmatically, sending WM_COMMAND
  6830. message with BN_CLICKED code. This method is sensible only for
  6831. buttons, checkboxes and radioboxes. }
  6832. function Perform( msgcode: DWORD; wParam, lParam: Integer): Integer; stdcall;
  6833. {* Sends message to control's window (created if needed). }
  6834. function Postmsg( msgcode: DWORD; wParam, lParam: Integer): Boolean; stdcall;
  6835. {* Sends message to control's window (created if needed). }
  6836. procedure AttachProc( Proc: TWindowFunc );
  6837. {* It is possible to attach dynamically any message handler to window
  6838. procedure using this method. Last attached procedure is called first.
  6839. If procedure returns True, further processing of a message is stopped.
  6840. Attached procedure can be detached using DetachProc (but do not
  6841. attach/detach procedures during handling of attached procedure -
  6842. this can hang application). }
  6843. procedure AttachProcEx( Proc: TWindowFunc; ExecuteAfterAppletTerminated: Boolean );
  6844. {* The same as AttachProc, but a handler is executed even after terminating
  6845. the main message loop processing (i.e. after assigning true to
  6846. AppletTerminated global variable. }
  6847. function IsProcAttached( Proc: TWindowFunc ): Boolean;
  6848. {* Returns True, if given procedure is already in chain of attached
  6849. ones for given control window proc. }
  6850. procedure DetachProc( Proc: TWindowFunc );
  6851. {* Detaches procedure attached earlier using AttachProc. }
  6852. property OnDropFiles: TOnDropFiles read FOnDropFiles write SetOnDropFiles;
  6853. {* Assign this event to your handler, if You want to accept drag and drop
  6854. files from other applications such as explorer onto your control. When
  6855. this event is assigned to a control or form, this has effect also for
  6856. all its child controls too. }
  6857. property CustomData: Pointer read fCustomData write fCustomData;
  6858. {* Can be used to exend the object when new type of control added. Memory,
  6859. pointed by this pointer, released automatically in the destructor. }
  6860. property CustomObj: PObj read fCustomObj write fCustomObj;
  6861. {* Can be used to exend the object when new type of control added. Object,
  6862. pointed by this pointer, released automatically in the destructor. }
  6863. procedure SetAutoPopupMenu( PopupMenu: PObj );
  6864. {* To assign a popup menu to the control, call SetAutoPopupMenu method of
  6865. the control with popup menu object as a parameter. }
  6866. function SupportMnemonics: PControl;
  6867. {* This method provides supporting mnemonic keys in menus, buttons, checkboxes,
  6868. toolbar buttons. }
  6869. property OnScroll: TOnScroll read FOnScroll write SetOnScroll;
  6870. {* }
  6871. protected
  6872. {$IFDEF USE_DROPDOWNCOUNT}
  6873. fDropDownCount: Cardinal;
  6874. {$ENDIF}
  6875. fGraphCtlMouseEvent: TOnGraphCtlMouse;
  6876. public
  6877. {$IFDEF USE_DROPDOWNCOUNT}
  6878. property DropDownCount: Cardinal read fDropDownCount write fDropDownCount;
  6879. {$ENDIF}
  6880. protected
  6881. fPushedBtn: PControl;
  6882. fFocused: Boolean;
  6883. fEditOptions: TEditOptions;
  6884. fEditCtl: PControl;
  6885. fSetFocus: procedure of object;
  6886. fSaveCursor: HCursor;
  6887. fLeave: TOnEvent;
  6888. fKeyboardProcess: TOnMessage;
  6889. fHot: Boolean;
  6890. fHotCtl: PControl;
  6891. fMouseLeaveProc: TOnEvent;
  6892. fIsGroupBox: Boolean;
  6893. fErasingBkgnd: Boolean;
  6894. fButtonIcon: HIcon;
  6895. procedure GraphicLabelPaint( DC: HDC );
  6896. procedure GraphicCheckBoxPaint( DC: HDC );
  6897. procedure GraphicCheckBoxMouse( var Msg: TMsg );
  6898. procedure GraphicRadioBoxPaint( DC: HDC );
  6899. procedure GraphicButtonPaint( DC: HDC );
  6900. procedure GraphicButtonMouse( var Msg: TMsg );
  6901. procedure GraphButtonSetFocus;
  6902. function GraphButtonKeyboardProcess( var Msg: TMsg; var Rslt: Integer ): Boolean;
  6903. procedure LeaveGraphButton( Sender: PObj );
  6904. procedure GraphicEditPaint( DC: HDC );
  6905. procedure GraphicEditMouse( var Msg: TMsg );
  6906. function EditGraphEdit: PControl;
  6907. procedure DestroyGraphEdit( Sender: PObj );
  6908. procedure LeaveGraphEdit( Sender: PObj );
  6909. procedure ChangeGraphEdit( Sender: PObj );
  6910. procedure GraphEditboxSetFocus;
  6911. procedure GraphCtlDrawFocusRect( DC: HDC; const R: TRect );
  6912. {$IFDEF GRAPHCTL_HOTTRACK}
  6913. procedure MouseLeaveFromParentOfGraphCtl( Sender: PObj );
  6914. {$ENDIF GRAPHCTL_HOTTRACK}
  6915. procedure GroupBoxPaint( DC: HDC );
  6916. {$IFDEF KEY_PREVIEW}
  6917. protected
  6918. fKeyPreview: Boolean;
  6919. public
  6920. property KeyPreview: Boolean read fKeyPreview write fKeyPreview;
  6921. {$ENDIF KEY_PREVIEW}
  6922. public
  6923. {$IFDEF USE_CONSTRUCTORS}
  6924. //------------------------------------------------------------
  6925. // constructors here:
  6926. constructor CreateWindowed( AParent: PControl; AClassName: PChar; ACtl3D: Boolean );
  6927. constructor CreateApplet( const ACaption: String );
  6928. constructor CreateForm( AParent: PControl; const ACaption: String );
  6929. constructor CreateControl( AParent: PControl; AClassName: PChar; AStyle: DWORD;
  6930. ACtl3D: Boolean; Actions: PCommandActions );
  6931. constructor CreateButton( AParent: PControl; const ACaption: String );
  6932. constructor CreateBitBtn( AParent: PControl; const ACaption: String;
  6933. AOptions: TBitBtnOptions; ALayout: TGlyphLayout; AGlyphBitmap: HBitmap;
  6934. AGlyphCount: Integer);
  6935. constructor CreateLabel( AParent: PControl; const ACaption: String );
  6936. constructor CreateWordWrapLabel( AParent: PControl; const ACaption: String );
  6937. constructor CreateLabelEffect( AParent: PControl; ACaption: String; AShadowDeep: Integer );
  6938. constructor CreatePaintBox( AParent: PControl );
  6939. constructor CreateGradientPanel( AParent: PControl; AColor1, AColor2: TColor );
  6940. constructor CreateGradientPanelEx( AParent: PControl; AColor1, AColor2: TColor;
  6941. AStyle: TGradientStyle; ALayout: TGradientLayout );
  6942. constructor CreateGroupbox( AParent: PControl; const ACaption: String );
  6943. constructor CreateCheckbox( AParent: PControl; const ACaption: String );
  6944. constructor CreateRadiobox( AParent: PControl; const ACaption: String );
  6945. constructor CreateEditbox( AParent: PControl; AOptions: TEditOptions );
  6946. constructor CreatePanel( AParent: PControl; AStyle: TEdgeStyle );
  6947. constructor CreateSplitter( AParent: PControl; AMinSizePrev, AMinSizeNext: Integer;
  6948. EdgeStyle: TEdgeStyle );
  6949. constructor CreateListbox( AParent: PControl; AOptions: TListOptions );
  6950. constructor CreateCombobox( AParent: PControl; AOptions: TComboOptions );
  6951. constructor CreateCommonControl( AParent: PControl; AClassName: PChar; AStyle: DWORD;
  6952. ACtl3D: Boolean; Actions: PCommandActions );
  6953. constructor CreateRichEdit( AParent: PControl; AOptions: TEditOptions );
  6954. constructor CreateRichEdit1( AParent: PControl; AOptions: TEditOptions );
  6955. constructor CreateProgressbar( AParent: PControl );
  6956. constructor CreateProgressbarEx( AParent: PControl; AOptions: TProgressbarOptions );
  6957. constructor CreateListView( AParent: PControl; AStyle: TListViewStyle; AOptions: TListViewOptions;
  6958. AImageListSmall, AImageListNormal, AImageListState: PImageList );
  6959. constructor CreateTreeView( AParent: PControl; AOptions: TTreeViewOptions;
  6960. AImgListNormal, AImgListState: PImageList );
  6961. constructor CreateTabControl( AParent: PControl; ATabs: array of String;
  6962. AOptions: TTabControlOptions; AImgList: PImageList; AImgList1stIdx: Integer );
  6963. constructor CreateToolbar( AParent: PControl; AAlign: TControlAlign; AOptions: TToolbarOptions;
  6964. ABitmap: HBitmap; AButtons: array of PChar;
  6965. ABtnImgIdxArray: array of Integer );
  6966. {$ENDIF USE_CONSTRUCTORS}
  6967. {$IFDEF USE_CUSTOMEXTENSIONS}
  6968. {$I CUSTOM_TCONTROL_EXTENSION.inc}
  6969. {$ENDIF}
  6970. // If an option USE_CUSTOMEXTENSIONS is enabled (at the beginning of this
  6971. // unit), You can freely extend TControl definition by your own fields,
  6972. // methods and properties. This provides You with capability to extend
  6973. // TControl implementing another kinds of visual controls without deriving
  6974. // new descendant objects from TControl. This way is provided to avoid too
  6975. // large grow of executable size. You also can derive your own controls
  6976. // from TControl using standard OOP capabilities. In such case an option
  6977. // USE_CONSTRUCTORS should be turned on (see it at the start of this unit).
  6978. // If You choose this "flat" model of extending the TControl with your
  6979. // own properties, fieds, methods, events, etc. You should provide three
  6980. // inc-files: CUSTOM_TCONTROL_EXTENSION.inc, containing such definitions
  6981. // for TControl, CUSTOM_KOL_EXTENSION.inc, containing needed global
  6982. // declarations, and CUSTOM_CODE_EXTENSION.inc, the implementation of those
  6983. // two.
  6984. // Because KOL is always grow and constantly is extending by me, I also can
  6985. // add my own complements for TControl. To avoid naming conflicts, I suggest
  6986. // to use the same naming rule for all of You. Name your fields, properies, etc.
  6987. // using a form idx_SomeName, where idx is a prefix, containing several
  6988. // (at least one) letters and digits. E.g. ZK65_OnSomething.
  6989. end;
  6990. //[END OF TControl DEFINITION]
  6991. {$IFDEF USE_MHTOOLTIP}
  6992. {$DEFINE interface}
  6993. {$I KOLMHToolTip}
  6994. {$UNDEF interface}
  6995. {$ENDIF}
  6996. //[Paint Background PROCEDURE]
  6997. type
  6998. TOnPaintBkgnd = procedure( Sender: PControl; DC: HDC; Rect: PRect );
  6999. {* Global event definition. Used to define Global_OnPaintBackground
  7000. event placeholder. }
  7001. procedure DefaultPaintBackground( Sender: PControl; DC: HDC; Rect: PRect );
  7002. var
  7003. Global_OnPaintBkgnd: TOnPaintBkgnd = DefaultPaintBackground;
  7004. {* Global event. It is assigned in XBackgounds.pas add-on to replace
  7005. PaintBackground method for all TVisual objects, allowing great
  7006. visualization effect: transparent controls over [animated] bitmap
  7007. background. Idea:
  7008. | <a href=mailto:"bw@sunv.com">Wei&nbsp;Bao</a>. Implementation:
  7009. | <a href=mailto:"bonanzas@xcl.cjb.net">Kladov&nbsp;Vladimir</a>. }
  7010. procedure DummyPaintProc( Sender: PControl; DC: HDC );
  7011. //[GetShiftState DECLARATION]
  7012. function GetShiftState: DWORD;
  7013. //[WndProcXXX DECLARATIONS]
  7014. function WndProcMouse( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7015. function WndProcKeybd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7016. function WndProcDummy( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7017. function WndProcBufferedDraw( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7018. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  7019. function WndProcBtnReturnClick( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  7020. {$ENDIF}
  7021. function AutoMinimizeApplet(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  7022. {* By Sergey Shishmintzev.
  7023. Attach this handler to your modal dialog form handle to provide automatic
  7024. minimization of all other forms in the application together with the dialog. }
  7025. //[InitCommonXXXX DECLARATIONS]
  7026. procedure InitCommonControlSizeNotify( Ctrl: PControl );
  7027. procedure InitCommonControlCommonNotify( Ctrl: PControl );
  7028. //[Buffered Draw DECLARATIONS]
  7029. var
  7030. Global_OnBufferedDraw: function( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean
  7031. = WndProcDummy;
  7032. Global_DblBufCreateWnd: procedure( Sender: PObj ) = DummyObjProc;
  7033. Global_Invalidate: procedure( Sender: PObj ) = DummyObjProc;
  7034. {* Is called in TControl.Invalidate to extend it in case when DoubleBuffered
  7035. painting used. }
  7036. Global_TranspDrawBkgnd: procedure( DC: HDC; Sender: PControl );
  7037. //Global_OnCreateWindow: procedure( Sender: PObj ) = DummyObjProc;
  7038. //{* Is called when TControl object is created. }
  7039. //Global_OnDestroyWindow: procedure( Sender: PObj ) = DummyObjProc;
  7040. //{* Is called before destroying TControl object (after accepting it,
  7041. // if event OnClose is defined). }
  7042. Global_OnBeginPaint: procedure( Sender: PControl; DC: HDC ) = DummyPaintProc;
  7043. {* Is called before painting a window. }
  7044. Global_OnEndPaint: procedure( Sender: PControl; DC: HDC ) = DummyPaintProc;
  7045. {* Is called after painting a window. }
  7046. HelpFilePath: PChar;
  7047. {* Path to application help file. If not assigned, application path with
  7048. extension replaced to '.hlp' used. To use '.chm' file (HtmlHelp),
  7049. call AssignHtmlHelp with a path to a html help file (or a name). }
  7050. //[Html Help DECLARATIONS]
  7051. procedure AssignHtmlHelp( const HtmlHelpPath: String );
  7052. procedure HtmlHelpCommand( Wnd: HWnd; const HelpFilePath: String; Cmd, Data: Integer );
  7053. {* Use this wrapper procedure to call HtmlHelp API function. }
  7054. //+++++++++++ HTML HELP DEFINITIONS SECTION:
  7055. // this section is from
  7056. // HTML Help API Interface Unit
  7057. // Copyright (c) 1999 The Helpware Group
  7058. // provided for KOL by Alexey Babenko
  7059. const
  7060. HH_DISPLAY_TOPIC = $0000; {**}
  7061. HH_HELP_FINDER = $0000; // WinHelp equivalent
  7062. HH_DISPLAY_TOC = $0001; // not currently implemented
  7063. HH_DISPLAY_INDEX = $0002; // not currently implemented
  7064. HH_DISPLAY_SEARCH = $0003; // not currently implemented
  7065. HH_SET_WIN_TYPE = $0004;
  7066. HH_GET_WIN_TYPE = $0005;
  7067. HH_GET_WIN_HANDLE = $0006;
  7068. HH_ENUM_INFO_TYPE = $0007; // Get Info type name, call repeatedly to enumerate, -1 at end
  7069. HH_SET_INFO_TYPE = $0008; // Add Info type to filter.
  7070. HH_SYNC = $0009;
  7071. HH_RESERVED1 = $000A;
  7072. HH_RESERVED2 = $000B;
  7073. HH_RESERVED3 = $000C;
  7074. HH_KEYWORD_LOOKUP = $000D;
  7075. HH_DISPLAY_TEXT_POPUP = $000E; // display string resource id or text in a popup window
  7076. HH_HELP_CONTEXT = $000F; {**}// display mapped numeric value in dwData
  7077. HH_TP_HELP_CONTEXTMENU = $0010; // text popup help, same as WinHelp HELP_CONTEXTMENU
  7078. HH_TP_HELP_WM_HELP = $0011; // text popup help, same as WinHelp HELP_WM_HELP
  7079. HH_CLOSE_ALL = $0012; // close all windows opened directly or indirectly by the caller
  7080. HH_ALINK_LOOKUP = $0013; // ALink version of HH_KEYWORD_LOOKUP
  7081. HH_GET_LAST_ERROR = $0014; // not currently implemented // See HHERROR.h
  7082. HH_ENUM_CATEGORY = $0015; // Get category name, call repeatedly to enumerate, -1 at end
  7083. HH_ENUM_CATEGORY_IT = $0016; // Get category info type members, call repeatedly to enumerate, -1 at end
  7084. HH_RESET_IT_FILTER = $0017; // Clear the info type filter of all info types.
  7085. HH_SET_INCLUSIVE_FILTER = $0018; // set inclusive filtering method for untyped topics to be included in display
  7086. HH_SET_EXCLUSIVE_FILTER = $0019; // set exclusive filtering method for untyped topics to be excluded from display
  7087. HH_INITIALIZE = $001C; // Initializes the help system.
  7088. HH_UNINITIALIZE = $001D; // Uninitializes the help system.
  7089. HH_PRETRANSLATEMESSAGE = $00fd; // Pumps messages. (NULL, NULL, MSG*).
  7090. HH_SET_GLOBAL_PROPERTY = $00fc; // Set a global property. (NULL, NULL, HH_GPROP)
  7091. { window properties }
  7092. const
  7093. HHWIN_PROP_TAB_AUTOHIDESHOW = $00000001; // (1 << 0) Automatically hide/show tri-pane window
  7094. HHWIN_PROP_ONTOP = $00000002; // (1 << 1) Top-most window
  7095. HHWIN_PROP_NOTITLEBAR = $00000004; // (1 << 2) no title bar
  7096. HHWIN_PROP_NODEF_STYLES = $00000008; // (1 << 3) no default window styles (only HH_WINTYPE.dwStyles)
  7097. HHWIN_PROP_NODEF_EXSTYLES = $00000010; // (1 << 4) no default extended window styles (only HH_WINTYPE.dwExStyles)
  7098. HHWIN_PROP_TRI_PANE = $00000020; // (1 << 5) use a tri-pane window
  7099. HHWIN_PROP_NOTB_TEXT = $00000040; // (1 << 6) no text on toolbar buttons
  7100. HHWIN_PROP_POST_QUIT = $00000080; // (1 << 7) post WM_QUIT message when window closes
  7101. HHWIN_PROP_AUTO_SYNC = $00000100; // (1 << 8) automatically ssync contents and index
  7102. HHWIN_PROP_TRACKING = $00000200; // (1 << 9) send tracking notification messages
  7103. HHWIN_PROP_TAB_SEARCH = $00000400; // (1 << 10) include search tab in navigation pane
  7104. HHWIN_PROP_TAB_HISTORY = $00000800; // (1 << 11) include history tab in navigation pane
  7105. HHWIN_PROP_TAB_FAVORITES = $00001000; // (1 << 12) include favorites tab in navigation pane
  7106. HHWIN_PROP_CHANGE_TITLE = $00002000; // (1 << 13) Put current HTML title in title bar
  7107. HHWIN_PROP_NAV_ONLY_WIN = $00004000; // (1 << 14) Only display the navigation window
  7108. HHWIN_PROP_NO_TOOLBAR = $00008000; // (1 << 15) Don't display a toolbar
  7109. HHWIN_PROP_MENU = $00010000; // (1 << 16) Menu
  7110. HHWIN_PROP_TAB_ADVSEARCH = $00020000; // (1 << 17) Advanced FTS UI.
  7111. HHWIN_PROP_USER_POS = $00040000; // (1 << 18) After initial creation, user controls window size/position
  7112. HHWIN_PROP_TAB_CUSTOM1 = $00080000; // (1 << 19) Use custom tab #1
  7113. HHWIN_PROP_TAB_CUSTOM2 = $00100000; // (1 << 20) Use custom tab #2
  7114. HHWIN_PROP_TAB_CUSTOM3 = $00200000; // (1 << 21) Use custom tab #3
  7115. HHWIN_PROP_TAB_CUSTOM4 = $00400000; // (1 << 22) Use custom tab #4
  7116. HHWIN_PROP_TAB_CUSTOM5 = $00800000; // (1 << 23) Use custom tab #5
  7117. HHWIN_PROP_TAB_CUSTOM6 = $01000000; // (1 << 24) Use custom tab #6
  7118. HHWIN_PROP_TAB_CUSTOM7 = $02000000; // (1 << 25) Use custom tab #7
  7119. HHWIN_PROP_TAB_CUSTOM8 = $04000000; // (1 << 26) Use custom tab #8
  7120. HHWIN_PROP_TAB_CUSTOM9 = $08000000; // (1 << 27) Use custom tab #9
  7121. HHWIN_TB_MARGIN = $10000000; // (1 << 28) the window type has a margin
  7122. { window parameters }
  7123. const
  7124. HHWIN_PARAM_PROPERTIES = $00000002; // (1 << 1) valid fsWinProperties
  7125. HHWIN_PARAM_STYLES = $00000004; // (1 << 2) valid dwStyles
  7126. HHWIN_PARAM_EXSTYLES = $00000008; // (1 << 3) valid dwExStyles
  7127. HHWIN_PARAM_RECT = $00000010; // (1 << 4) valid rcWindowPos
  7128. HHWIN_PARAM_NAV_WIDTH = $00000020; // (1 << 5) valid iNavWidth
  7129. HHWIN_PARAM_SHOWSTATE = $00000040; // (1 << 6) valid nShowState
  7130. HHWIN_PARAM_INFOTYPES = $00000080; // (1 << 7) valid apInfoTypes
  7131. HHWIN_PARAM_TB_FLAGS = $00000100; // (1 << 8) valid fsToolBarFlags
  7132. HHWIN_PARAM_EXPANSION = $00000200; // (1 << 9) valid fNotExpanded
  7133. HHWIN_PARAM_TABPOS = $00000400; // (1 << 10) valid tabpos
  7134. HHWIN_PARAM_TABORDER = $00000800; // (1 << 11) valid taborder
  7135. HHWIN_PARAM_HISTORY_COUNT = $00001000; // (1 << 12) valid cHistory
  7136. HHWIN_PARAM_CUR_TAB = $00002000; // (1 << 13) valid curNavType
  7137. { button constants }
  7138. const
  7139. HHWIN_BUTTON_EXPAND = $00000002; // (1 << 1) Expand/contract button
  7140. HHWIN_BUTTON_BACK = $00000004; // (1 << 2) Back button
  7141. HHWIN_BUTTON_FORWARD = $00000008; // (1 << 3) Forward button
  7142. HHWIN_BUTTON_STOP = $00000010; // (1 << 4) Stop button
  7143. HHWIN_BUTTON_REFRESH = $00000020; // (1 << 5) Refresh button
  7144. HHWIN_BUTTON_HOME = $00000040; // (1 << 6) Home button
  7145. HHWIN_BUTTON_BROWSE_FWD = $00000080; // (1 << 7) not implemented
  7146. HHWIN_BUTTON_BROWSE_BCK = $00000100; // (1 << 8) not implemented
  7147. HHWIN_BUTTON_NOTES = $00000200; // (1 << 9) not implemented
  7148. HHWIN_BUTTON_CONTENTS = $00000400; // (1 << 10) not implemented
  7149. HHWIN_BUTTON_SYNC = $00000800; // (1 << 11) Sync button
  7150. HHWIN_BUTTON_OPTIONS = $00001000; // (1 << 12) Options button
  7151. HHWIN_BUTTON_PRINT = $00002000; // (1 << 13) Print button
  7152. HHWIN_BUTTON_INDEX = $00004000; // (1 << 14) not implemented
  7153. HHWIN_BUTTON_SEARCH = $00008000; // (1 << 15) not implemented
  7154. HHWIN_BUTTON_HISTORY = $00010000; // (1 << 16) not implemented
  7155. HHWIN_BUTTON_FAVORITES = $00020000; // (1 << 17) not implemented
  7156. HHWIN_BUTTON_JUMP1 = $00040000; // (1 << 18)
  7157. HHWIN_BUTTON_JUMP2 = $00080000; // (1 << 19)
  7158. HHWIN_BUTTON_ZOOM = $00100000; // (1 << 20)
  7159. HHWIN_BUTTON_TOC_NEXT = $00200000; // (1 << 21)
  7160. HHWIN_BUTTON_TOC_PREV = $00400000; // (1 << 22)
  7161. HHWIN_DEF_BUTTONS = (HHWIN_BUTTON_EXPAND
  7162. OR HHWIN_BUTTON_BACK
  7163. OR HHWIN_BUTTON_OPTIONS
  7164. OR HHWIN_BUTTON_PRINT);
  7165. { Button IDs }
  7166. const
  7167. IDTB_EXPAND = 200;
  7168. IDTB_CONTRACT = 201;
  7169. IDTB_STOP = 202;
  7170. IDTB_REFRESH = 203;
  7171. IDTB_BACK = 204;
  7172. IDTB_HOME = 205;
  7173. IDTB_SYNC = 206;
  7174. IDTB_PRINT = 207;
  7175. IDTB_OPTIONS = 208;
  7176. IDTB_FORWARD = 209;
  7177. IDTB_NOTES = 210; // not implemented
  7178. IDTB_BROWSE_FWD = 211;
  7179. IDTB_BROWSE_BACK = 212;
  7180. IDTB_CONTENTS = 213; // not implemented
  7181. IDTB_INDEX = 214; // not implemented
  7182. IDTB_SEARCH = 215; // not implemented
  7183. IDTB_HISTORY = 216; // not implemented
  7184. IDTB_FAVORITES = 217; // not implemented
  7185. IDTB_JUMP1 = 218;
  7186. IDTB_JUMP2 = 219;
  7187. IDTB_CUSTOMIZE = 221;
  7188. IDTB_ZOOM = 222;
  7189. IDTB_TOC_NEXT = 223;
  7190. IDTB_TOC_PREV = 224;
  7191. { Notification codes }
  7192. const
  7193. HHN_FIRST = (0-860);
  7194. HHN_LAST = (0-879);
  7195. HHN_NAVCOMPLETE = (HHN_FIRST-0);
  7196. HHN_TRACK = (HHN_FIRST-1);
  7197. HHN_WINDOW_CREATE = (HHN_FIRST-2);
  7198. type
  7199. {*** Used by command HH_GET_LAST_ERROR
  7200. NOTE: Not part of the htmlhelp.h but documented in HH Workshop help
  7201. You must call SysFreeString(xx.description) to free BSTR
  7202. }
  7203. tagHH_LAST_ERROR = packed record
  7204. cbStruct: Integer; // sizeof this structure
  7205. hr: Integer; // Specifies the last error code.
  7206. description: PWideChar; // (BSTR) Specifies a Unicode string containing a description of the error.
  7207. end;
  7208. HH_LAST_ERROR = tagHH_LAST_ERROR;
  7209. THHLastError = tagHH_LAST_ERROR;
  7210. type
  7211. {*** Notify event info for HHN_NAVCOMPLETE, HHN_WINDOW_CREATE }
  7212. PHHNNotify = ^THHNNotify;
  7213. tagHHN_NOTIFY = packed record
  7214. hdr: TNMHdr;
  7215. pszUrl: PChar; //PCSTR: Multi-byte, null-terminated string
  7216. end;
  7217. HHN_NOTIFY = tagHHN_NOTIFY;
  7218. THHNNotify = tagHHN_NOTIFY;
  7219. {** Use by command HH_DISPLAY_TEXT_POPUP}
  7220. PHHPopup = ^THHPopup;
  7221. tagHH_POPUP = packed record
  7222. cbStruct: Integer; // sizeof this structure
  7223. hinst: HINST; // instance handle for string resource
  7224. idString: cardinal; // string resource id, or text id if pszFile is specified in HtmlHelp call
  7225. pszText: PChar; // used if idString is zero
  7226. pt: TPOINT; // top center of popup window
  7227. clrForeground: COLORREF; // use -1 for default
  7228. clrBackground: COLORREF; // use -1 for default
  7229. rcMargins: TRect; // amount of space between edges of window and text, -1 for each member to ignore
  7230. pszFont: PChar; // facename, point size, char set, BOLD ITALIC UNDERLINE
  7231. end;
  7232. HH_POPUP = tagHH_POPUP;
  7233. THHPopup = tagHH_POPUP;
  7234. {** Use by commands - HH_ALINK_LOOKUP, HH_KEYWORD_LOOKUP}
  7235. PHHAKLink = ^THHAKLink;
  7236. tagHH_AKLINK = packed record
  7237. cbStruct: integer; // sizeof this structure
  7238. fReserved: BOOL; // must be FALSE (really!)
  7239. pszKeywords: PChar; // semi-colon separated keywords
  7240. pszUrl: PChar; // URL to jump to if no keywords found (may be NULL)
  7241. pszMsgText: PChar; // Message text to display in MessageBox if pszUrl is NULL and no keyword match
  7242. pszMsgTitle: PChar; // Message text to display in MessageBox if pszUrl is NULL and no keyword match
  7243. pszWindow: PChar; // Window to display URL in
  7244. fIndexOnFail: BOOL; // Displays index if keyword lookup fails.
  7245. end;
  7246. HH_AKLINK = tagHH_AKLINK;
  7247. THHAKLink = tagHH_AKLINK;
  7248. const
  7249. HHWIN_NAVTYPE_TOC = 0;
  7250. HHWIN_NAVTYPE_INDEX = 1;
  7251. HHWIN_NAVTYPE_SEARCH = 2;
  7252. HHWIN_NAVTYPE_FAVORITES = 3;
  7253. HHWIN_NAVTYPE_HISTORY = 4; // not implemented
  7254. HHWIN_NAVTYPE_AUTHOR = 5;
  7255. HHWIN_NAVTYPE_CUSTOM_FIRST = 11;
  7256. const
  7257. IT_INCLUSIVE = 0;
  7258. IT_EXCLUSIVE = 1;
  7259. IT_HIDDEN = 2;
  7260. type
  7261. PHHEnumIT = ^THHEnumIT;
  7262. tagHH_ENUM_IT = packed record //tagHH_ENUM_IT, HH_ENUM_IT, *PHH_ENUM_IT
  7263. cbStruct: Integer; // size of this structure
  7264. iType: Integer; // the type of the information type ie. Inclusive, Exclusive, or Hidden
  7265. pszCatName: PAnsiChar; // Set to the name of the Category to enumerate the info types in a category; else NULL
  7266. pszITName: PAnsiChar; // volitile pointer to the name of the infotype. Allocated by call. Caller responsible for freeing
  7267. pszITDescription: PAnsiChar; // volitile pointer to the description of the infotype.
  7268. end;
  7269. THHEnumIT = tagHH_ENUM_IT;
  7270. type
  7271. PHHEnumCat = ^THHEnumCat;
  7272. tagHH_ENUM_CAT = packed record //tagHH_ENUM_CAT, HH_ENUM_CAT, *PHH_ENUM_CAT
  7273. cbStruct: Integer; // size of this structure
  7274. pszCatName: PAnsiChar; // volitile pointer to the category name
  7275. pszCatDescription: PAnsiChar; // volitile pointer to the category description
  7276. end;
  7277. THHEnumCat = tagHH_ENUM_CAT;
  7278. type
  7279. PHHSetInfoType = ^THHSetInfoType;
  7280. tagHH_SET_INFOTYPE = packed record //tagHH_SET_INFOTYPE, HH_SET_INFOTYPE, *PHH_SET_INFOTYPE
  7281. cbStruct: Integer; // the size of this structure
  7282. pszCatName: PAnsiChar; // the name of the category, if any, the InfoType is a member of.
  7283. pszInfoTypeName: PAnsiChar; // the name of the info type to add to the filter
  7284. end;
  7285. THHSetInfoType = tagHH_SET_INFOTYPE;
  7286. type
  7287. HH_INFOTYPE = DWORD;
  7288. THHInfoType = HH_INFOTYPE;
  7289. PHHInfoType = ^THHInfoType; //PHH_INFOTYPE
  7290. const
  7291. HHWIN_NAVTAB_TOP = 0;
  7292. HHWIN_NAVTAB_LEFT = 1;
  7293. HHWIN_NAVTAB_BOTTOM = 2;
  7294. const
  7295. HH_MAX_TABS = 19; // maximum number of tabs
  7296. const
  7297. HH_TAB_CONTENTS = 0;
  7298. HH_TAB_INDEX = 1;
  7299. HH_TAB_SEARCH = 2;
  7300. HH_TAB_FAVORITES = 3;
  7301. HH_TAB_HISTORY = 4;
  7302. HH_TAB_AUTHOR = 5;
  7303. HH_TAB_CUSTOM_FIRST = 11;
  7304. HH_TAB_CUSTOM_LAST = HH_MAX_TABS;
  7305. HH_MAX_TABS_CUSTOM = (HH_TAB_CUSTOM_LAST - HH_TAB_CUSTOM_FIRST + 1);
  7306. { HH_DISPLAY_SEARCH Command Related Structures and Constants }
  7307. const
  7308. HH_FTS_DEFAULT_PROXIMITY = (-1);
  7309. type
  7310. {** Used by command HH_DISPLAY_SEARCH}
  7311. PHHFtsQuery = ^THHFtsQuery;
  7312. tagHH_FTS_QUERY = packed record //tagHH_FTS_QUERY, HH_FTS_QUERY
  7313. cbStruct: integer; // Sizeof structure in bytes.
  7314. fUniCodeStrings: BOOL; // TRUE if all strings are unicode.
  7315. pszSearchQuery: PChar; // String containing the search query.
  7316. iProximity: LongInt; // Word proximity.
  7317. fStemmedSearch: Bool; // TRUE for StemmedSearch only.
  7318. fTitleOnly: Bool; // TRUE for Title search only.
  7319. fExecute: Bool; // TRUE to initiate the search.
  7320. pszWindow: PChar; // Window to display in
  7321. end;
  7322. THHFtsQuery = tagHH_FTS_QUERY;
  7323. { HH_WINTYPE Structure }
  7324. type
  7325. {** Used by commands HH_GET_WIN_TYPE, HH_SET_WIN_TYPE}
  7326. PHHWinType = ^THHWinType;
  7327. tagHH_WINTYPE = packed record //tagHH_WINTYPE, HH_WINTYPE, *PHH_WINTYPE;
  7328. cbStruct: Integer; // IN: size of this structure including all Information Types
  7329. fUniCodeStrings: BOOL; // IN/OUT: TRUE if all strings are in UNICODE
  7330. pszType: PChar; // IN/OUT: Name of a type of window
  7331. fsValidMembers: DWORD; // IN: Bit flag of valid members (HHWIN_PARAM_)
  7332. fsWinProperties: DWORD; // IN/OUT: Properties/attributes of the window (HHWIN_)
  7333. pszCaption: PChar; // IN/OUT: Window title
  7334. dwStyles: DWORD; // IN/OUT: Window styles
  7335. dwExStyles: DWORD; // IN/OUT: Extended Window styles
  7336. rcWindowPos: TRect; // IN: Starting position, OUT: current position
  7337. nShowState: Integer; // IN: show state (e.g., SW_SHOW)
  7338. hwndHelp: HWND; // OUT: window handle
  7339. hwndCaller: HWND; // OUT: who called this window
  7340. paInfoTypes: PHHInfoType; // IN: Pointer to an array of Information Types
  7341. { The following members are only valid if HHWIN_PROP_TRI_PANE is set }
  7342. hwndToolBar: HWND; // OUT: toolbar window in tri-pane window
  7343. hwndNavigation: HWND; // OUT: navigation window in tri-pane window
  7344. hwndHTML: HWND; // OUT: window displaying HTML in tri-pane window
  7345. iNavWidth: Integer; // IN/OUT: width of navigation window
  7346. rcHTML: TRect; // OUT: HTML window coordinates
  7347. pszToc: PChar; // IN: Location of the table of contents file
  7348. pszIndex: PChar; // IN: Location of the index file
  7349. pszFile: PChar; // IN: Default location of the html file
  7350. pszHome: PChar; // IN/OUT: html file to display when Home button is clicked
  7351. fsToolBarFlags: DWORD; // IN: flags controling the appearance of the toolbar (HHWIN_BUTTON_)
  7352. fNotExpanded: BOOL; // IN: TRUE/FALSE to contract or expand, OUT: current state
  7353. curNavType: Integer; // IN/OUT: UI to display in the navigational pane
  7354. tabpos: Integer; // IN/OUT: HHWIN_NAVTAB_TOP, HHWIN_NAVTAB_LEFT, or HHWIN_NAVTAB_BOTTOM
  7355. idNotify: Integer; // IN: ID to use for WM_NOTIFY messages
  7356. tabOrder: packed array[0..HH_MAX_TABS] of Byte; // IN/OUT: tab order: Contents, Index, Search, History, Favorites, Reserved 1-5, Custom tabs
  7357. cHistory: Integer; // IN/OUT: number of history items to keep (default is 30)
  7358. pszJump1: PChar; // Text for HHWIN_BUTTON_JUMP1
  7359. pszJump2: PChar; // Text for HHWIN_BUTTON_JUMP2
  7360. pszUrlJump1: PChar; // URL for HHWIN_BUTTON_JUMP1
  7361. pszUrlJump2: PChar; // URL for HHWIN_BUTTON_JUMP2
  7362. rcMinSize: TRect; // Minimum size for window (ignored in version 1)
  7363. cbInfoTypes: Integer; // size of paInfoTypes;
  7364. pszCustomTabs: PChar; // multiple zero-terminated strings
  7365. end;
  7366. HH_WINTYPE = tagHH_WINTYPE;
  7367. THHWinType = tagHH_WINTYPE;
  7368. const
  7369. HHACT_TAB_CONTENTS = 0;
  7370. HHACT_TAB_INDEX = 1;
  7371. HHACT_TAB_SEARCH = 2;
  7372. HHACT_TAB_HISTORY = 3;
  7373. HHACT_TAB_FAVORITES = 4;
  7374. HHACT_EXPAND = 5;
  7375. HHACT_CONTRACT = 6;
  7376. HHACT_BACK = 7;
  7377. HHACT_FORWARD = 8;
  7378. HHACT_STOP = 9;
  7379. HHACT_REFRESH = 10;
  7380. HHACT_HOME = 11;
  7381. HHACT_SYNC = 12;
  7382. HHACT_OPTIONS = 13;
  7383. HHACT_PRINT = 14;
  7384. HHACT_HIGHLIGHT = 15;
  7385. HHACT_CUSTOMIZE = 16;
  7386. HHACT_JUMP1 = 17;
  7387. HHACT_JUMP2 = 18;
  7388. HHACT_ZOOM = 19;
  7389. HHACT_TOC_NEXT = 20;
  7390. HHACT_TOC_PREV = 21;
  7391. HHACT_NOTES = 22;
  7392. HHACT_LAST_ENUM = 23;
  7393. type
  7394. {*** Notify event info for HHN_TRACK }
  7395. PHHNTrack = ^THHNTrack;
  7396. tagHHNTRACK = packed record //tagHHNTRACK, HHNTRACK;
  7397. hdr: TNMHdr;
  7398. pszCurUrl: PChar; // Multi-byte, null-terminated string
  7399. idAction: Integer; // HHACT_ value
  7400. phhWinType: PHHWinType; // Current window type structure
  7401. end;
  7402. HHNTRACK = tagHHNTRACK;
  7403. THHNTrack = tagHHNTRACK;
  7404. ///////////////////////////////////////////////////////////////////////////////
  7405. //
  7406. // Global Control Properties.
  7407. //
  7408. const
  7409. HH_GPROPID_SINGLETHREAD = 1; // VARIANT_BOOL: True for single thread
  7410. HH_GPROPID_TOOLBAR_MARGIN = 2; // long: Provides a left/right margin around the toolbar.
  7411. HH_GPROPID_UI_LANGUAGE = 3; // long: LangId of the UI.
  7412. HH_GPROPID_CURRENT_SUBSET = 4; // BSTR: Current subset.
  7413. HH_GPROPID_CONTENT_LANGUAGE = 5; // long: LandId for desired content.
  7414. type
  7415. tagHH_GPROPID = HH_GPROPID_SINGLETHREAD..HH_GPROPID_CONTENT_LANGUAGE; //tagHH_GPROPID, HH_GPROPID
  7416. HH_GPROPID = tagHH_GPROPID;
  7417. THHGPropID = HH_GPROPID;
  7418. ///////////////////////////////////////////////////////////////////////////////
  7419. //
  7420. // Global Property structure
  7421. //
  7422. {type
  7423. PHHGlobalProperty = ^THHGlobalProperty;
  7424. tagHH_GLOBAL_PROPERTY = record //tagHH_GLOBAL_PROPERTY, HH_GLOBAL_PROPERTY
  7425. id: THHGPropID;
  7426. Dummy: Integer; // Added to enforce 8-byte packing
  7427. var_: VARIANT;
  7428. end;
  7429. HH_GLOBAL_PROPERTY = tagHH_GLOBAL_PROPERTY;
  7430. THHGlobalProperty = tagHH_GLOBAL_PROPERTY;}
  7431. //[END OF HTMLHELP DECLARATIONS]
  7432. //[GetCtlBrush DECLARATIONS]
  7433. function SimpleGetCtlBrushHandle( Sender: PControl ): HBrush; //forward;
  7434. var
  7435. Global_GetCtlBrushHandle: function( Sender: PControl ): HBrush = SimpleGetCtlBrushHandle;
  7436. {* Is called to obtain brush handle. }
  7437. Global_Align: procedure( Sender: PObj ) = DummyObjProc;
  7438. {* Is set to perform aligning of control, and only if property Align
  7439. is changed for TControl, or SetAlign method is called for it. }
  7440. //[WndFunc DECLARATION]
  7441. function WndFunc( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  7442. : Integer; stdcall;
  7443. {* Global message handler for window. Redirects all messages to
  7444. destination windows, obtaining target TControl object address from
  7445. window itself, using GetProp API call. }
  7446. //[Applet VARIABLES]
  7447. var AppletRunning: Boolean;
  7448. {* Is set to True while message loop is processing (in Run procedure). }
  7449. AppletTerminated: Boolean;
  7450. {* Is set to True when message loop is terminated. }
  7451. Applet: PControl;
  7452. {* Applet window object. Actually, can be set to main form if program
  7453. not needed in special applet button window (useful to make applet
  7454. button invisible on taskbar, or to have several forms with single
  7455. applet button - crete it in that case using NewApplet). }
  7456. AppButtonUsed: Boolean;
  7457. {* True if special window to represent applet button (may be invisible)
  7458. is used. If no, every form is represented with its own taskbar button
  7459. (always visible). }
  7460. //[Screen DECLARATIONS]
  7461. ScreenCursor: HCursor;
  7462. {* Set this global variable to override any cursor settings of current
  7463. form or control. }
  7464. function ScreenWidth: Integer;
  7465. {* Returns screen width in pixels. }
  7466. function ScreenHeight: Integer;
  7467. {* Returns screen height in pixels. }
  7468. //[Status DECLARATIONS]
  7469. type
  7470. TStatusOption = ( soNoSizeGrip, soTop );
  7471. {* Options available for status bars. }
  7472. TStatusOptions = Set of TStatusOption;
  7473. {* Status bar options. }
  7474. procedure DrawFormattedText( Ctl: PControl; DC: HDC; var R: TRect; Flags: DWORD {EditCtl: Boolean} );
  7475. {* This procedure can be useful to draw control's text in custom-defined controls. }
  7476. {$IFDEF GRAPHCTL_XPSTYLES}
  7477. var DoNotDrawGraphCtlsUsingXPStyles: Boolean;
  7478. procedure DrawFormattedTextXP( Theme: THandle; Ctl: PControl; DC: HDC;
  7479. var R: TRect; CtlType, CtlStates, Flags1, Flags2: Integer );
  7480. {* This procedure can be useful to draw control's text in custom-defined controls. }
  7481. {$ENDIF}
  7482. function _NewGraphCtl( AParent: PControl; ATabStop: Boolean ): PControl;
  7483. {* Creates graphic control basics. }
  7484. function NewGraphLabel( AParent: PControl; const ACaption: String ): PControl;
  7485. {* Creates graphic label, which does not require a window handle. }
  7486. function NewWordWrapGraphLabel( AParent: PControl; const ACaption: String ): PControl;
  7487. {* Creates graphic label, which does not require a window handle. }
  7488. function NewGraphPaintBox( AParent: PControl ): PControl;
  7489. {* Creates graphic paint box (just the same as graphic label, but with empty Caption). }
  7490. function NewGraphCheckBox( AParent: PControl; const ACaption: String ): PControl;
  7491. {* Creates graphic checkbox. }
  7492. function NewGraphRadioBox( AParent: PControl; const ACaption: String ): PControl;
  7493. {* Creates graphic radiobox. }
  7494. function NewGraphButton( AParent: PControl; const ACaption: String ): PControl;
  7495. {* Creates graphic button. }
  7496. function NewGraphEditbox( AParent: PControl; Options: TEditOptions ): PControl;
  7497. {* Creates graphic edit box. To do editing, this box should be replaced with
  7498. real edit box with a handle (actually, it is enough to place an edit box
  7499. on the same Parent having the same BoundsRect). }
  7500. //[Run DECLARATION]
  7501. procedure Run( var AppletWnd: PControl );
  7502. {* |<#appbutton>
  7503. Call this procedure to process messages loop of your program.
  7504. Pass here pointer to applet button object (if You have created it
  7505. - see NewApplet) or your main form object of type PControl (created
  7506. using NewForm).
  7507. |<br><br>
  7508. |<h1 align=center><font color=#FF8040><a name="visual_objects_constructors"></a>
  7509. Visual objects constructing functions
  7510. |</font></h1>
  7511. Following constructing functions for visual controls are available:
  7512. |#control
  7513. }
  7514. procedure TerminateExecution( var AppletWnd: PControl );
  7515. //[Applet FUNCTIONS DECLARATIONS]
  7516. procedure AppletMinimize;
  7517. {* Minimizes the application (Applet should be assigned to have effect). }
  7518. procedure AppletHide;
  7519. {* Minimizes and hides application. }
  7520. procedure AppletRestore;
  7521. {* Restores Applet when minimized. }
  7522. //[Idle handler DECALRATIONS]
  7523. {YS+}
  7524. procedure RegisterIdleHandler( const OnIdle: TOnEvent );
  7525. {* Registers new Idle handler. Idle handler is called each time when
  7526. message queue becomes empty. }
  7527. procedure UnRegisterIdleHandler( const OnIdle: TOnEvent );
  7528. {* Unregisters Idle handler. }
  7529. {YS-}
  7530. //[InitCommonXXXX ANOTHER DECLARATIONS]
  7531. {* ComCtrl32 controls initialization. }
  7532. procedure InitCommonControls; stdcall;
  7533. procedure DoInitCommonControls( dwICC: DWORD );
  7534. {* Calls extended initialization for Common Controls (from ComCtrl32).
  7535. Pass one of following constants:
  7536. |<pre>
  7537. ICC_LISTVIEW_CLASSES = $00000001; // listview, header
  7538. ICC_TREEVIEW_CLASSES = $00000002; // treeview, tooltips
  7539. ICC_BAR_CLASSES = $00000004; // toolbar, statusbar, trackbar, tooltips
  7540. ICC_TAB_CLASSES = $00000008; // tab, tooltips
  7541. ICC_UPDOWN_CLASS = $00000010; // updown
  7542. ICC_PROGRESS_CLASS = $00000020; // progress
  7543. ICC_HOTKEY_CLASS = $00000040; // hotkey
  7544. ICC_ANIMATE_CLASS = $00000080; // animate
  7545. ICC_WIN95_CLASSES = $000000FF;
  7546. ICC_DATE_CLASSES = $00000100; // month picker, date picker, time picker, updown
  7547. ICC_USEREX_CLASSES = $00000200; // comboex
  7548. ICC_COOL_CLASSES = $00000400; // rebar (coolbar) control
  7549. ICC_INTERNET_CLASSES = $00000800;
  7550. ICC_PAGESCROLLER_CLASS = $00001000; // page scroller
  7551. ICC_NATIVEFNTCTL_CLASS = $00002000; // native font control
  7552. |</pre>
  7553. }
  7554. const
  7555. ICC_LISTVIEW_CLASSES = $00000001; // listview, header
  7556. ICC_TREEVIEW_CLASSES = $00000002; // treeview, tooltips
  7557. ICC_BAR_CLASSES = $00000004; // toolbar, statusbar, trackbar, tooltips
  7558. ICC_TAB_CLASSES = $00000008; // tab, tooltips
  7559. ICC_UPDOWN_CLASS = $00000010; // updown
  7560. ICC_PROGRESS_CLASS = $00000020; // progress
  7561. ICC_HOTKEY_CLASS = $00000040; // hotkey
  7562. ICC_ANIMATE_CLASS = $00000080; // animate
  7563. ICC_WIN95_CLASSES = $000000FF;
  7564. ICC_DATE_CLASSES = $00000100; // month picker, date picker, time picker, updown
  7565. ICC_USEREX_CLASSES = $00000200; // comboex
  7566. ICC_COOL_CLASSES = $00000400; // rebar (coolbar) control
  7567. ICC_INTERNET_CLASSES = $00000800;
  7568. ICC_PAGESCROLLER_CLASS = $00001000; // page scroller
  7569. ICC_NATIVEFNTCTL_CLASS = $00002000; // native font control
  7570. //[Ole DECLARATIONS]
  7571. function OleInit: Boolean;
  7572. {* Calls OleInitialize (once - all other calls are simulated by incrementing
  7573. call counter. Every OleInit shoud be complemented with correspondent OleUninit.
  7574. (Though, it is possible to call API function OleUnInitialize once to
  7575. cancel all OleInit calls). }
  7576. procedure OleUnInit;
  7577. {* Decrements counter and calls OleUnInitialize when it is zeroed. }
  7578. var OleInitCount: Integer;
  7579. {-}
  7580. function StringToOleStr(const Source: string): PWideChar;
  7581. {* }
  7582. {+}
  7583. function SysAllocStringLen(psz: PWideChar; len: Integer): PWideChar; stdcall;
  7584. procedure SysFreeString( psz: PWideChar ); stdcall;
  7585. { -- Contructors for visual controls -- }
  7586. //[NewXXXX DECLARATIONS]
  7587. //[_NewWindowed DECLARATION]
  7588. function _NewWindowed( AParent: PControl; ControlClassName: PChar; Ctl3D: Boolean ): PControl;
  7589. //[NewApplet DECLARATION]
  7590. function NewApplet( const Caption: String ): PControl;
  7591. {* |<#control>
  7592. Creates applet button window, which has to be parent of all other forms
  7593. in your project (but this is *not must*). See also comments about NewForm.
  7594. |<br>
  7595. Following methods, properties and events are useful to work with applet
  7596. control:
  7597. |#appbutton }
  7598. //[NewForm DECLARATION]
  7599. function NewForm( AParent: PControl; const Caption: String ): PControl;
  7600. {* |<#control>
  7601. Creates form window object and returns pointer to it. If You use only one form,
  7602. and You are not going to do applet button on task bar invisible, it is not
  7603. necessary to create also special applet button window - just pass
  7604. your (main) form object to Run procedure. In that case, it is a good
  7605. idea to assign pointer to your main form object to Applet variable
  7606. immediately following creating it - because some objects (e.g. TTimer)
  7607. want to have Applet assigned to something.
  7608. |<br>
  7609. |&D=<a href="tcontrol.htm#%1" target=_top> %0 </a>
  7610. Following methods, properties and events are useful to work with forms
  7611. (ones common for all visual objects, such as <D Left>, <D Top>, <D Width>,
  7612. <D Height>, etc. are not listed here - look TControl for it):
  7613. |#form }
  7614. //[_NewControl DECLARATION]
  7615. function _NewControl( AParent: PControl; ControlClassName: PChar;
  7616. Style: DWORD; Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  7617. //[NewButton DECLARATION]
  7618. function NewButton( AParent: PControl; const Caption: String ): PControl;
  7619. {* |<#control>
  7620. Creates button on given parent control or form.
  7621. Please note, that in Windows, buttons can not change its <D Font> color
  7622. and to be <D Transparent>.
  7623. |<br> Following methods, properies and events are (especially) useful with
  7624. a button:
  7625. |#button }
  7626. //[NewBitBtn DECLARATION]
  7627. function NewBitBtn( AParent: PControl; const Caption: String;
  7628. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap; GlyphCount: Integer ): PControl;
  7629. {* |<#control>
  7630. Creates image button (actually implemented as owner-drawn). In Options,
  7631. it is possible to determine, whether bitmap or image list used to contain
  7632. one or more (up to 5) images, correspondent to certain BitBtn state.
  7633. |<br>&nbsp;&nbsp;&nbsp;
  7634. For case of imagelist (option bboImageList), it is possible to use a
  7635. number of glyphs from the image list, starting from image index given
  7636. by GlyphCount parameter. Number of used glyphs is passed in that case
  7637. in high word of GlyphCount parameter (if 0, one image is used therefore).
  7638. For bboImageList, BitBtn can be Transparent (and in that case bboNoBorder
  7639. style can be useful to draw custom buttons of non-rectangular shape).
  7640. |<br>&nbsp;&nbsp;&nbsp;
  7641. For case of bitmap BitBtn, image is stretched down (if too big), but can
  7642. not be transparent. It is not necessary for bitmap BitBtn to pass correct
  7643. GlyphCount - it is calculated on base of bitmap size, if 0 is passed.
  7644. |<br>&nbsp;&nbsp;&nbsp;
  7645. And, certainly, BitBtn can be without glyph image (text only). For that
  7646. case, it is therefore is more flexible and power than usual Button (but
  7647. requires more code). E.g., BitBtn can change its <D Font>, <D Color>,
  7648. and to be totally <D Transparent>.
  7649. Moreover, BitBtn can be <D Flat>, bboFixed, <D SpeedButton> and
  7650. have property <D RepeatInterval>.
  7651. |<br>&nbsp;&nbsp;&nbsp;
  7652. Note: if You use bboFixed Style, use OnChange event instead of OnClick,
  7653. because <D Checked> state is changed immediately however OnClick occure
  7654. only when mouse or space key released (and can be not called at all if
  7655. mouse button is released out of BitBtn bounds). Also, bboFixed defines
  7656. only which glyph to show (the border if it is not turned off behaves as
  7657. usual for a button, i.e. it becomes lowered and then raised again at any click).
  7658. Here You can find references to other properties, events and methods
  7659. applicable to BitBtn:
  7660. |#bitbtn }
  7661. //[NewLabel DECLARATION]
  7662. function NewLabel( AParent: PControl; const Caption: String ): PControl;
  7663. {* |<#control>
  7664. Creates static text control (native Windows STATIC control).
  7665. Use property <D Caption> at run time to change label text. Also
  7666. it is possible to adjust label <D Font>, <D Brush> or <D Color>.
  7667. Label can be <D Transparent>. If You want to have rotated text
  7668. label, call NewLabelEffect instead and change its <D Font>.FontOrientation.
  7669. Other references certain for a label:
  7670. |#label }
  7671. //[NewWordWrapLabel DECLARATION]
  7672. function NewWordWrapLabel( AParent: PControl; const Caption: String ): PControl;
  7673. {* |<#control>
  7674. Creates multiline static text control (native Windows STATIC control),
  7675. which can wrap long text onto several lines. See also NewLabel.
  7676. See also:
  7677. |#wwlabel
  7678. |#label }
  7679. //[NewLabelEffect DECLARATION]
  7680. function NewLabelEffect( AParent: PControl; const Caption: String; ShadowDeep: Integer ): PControl;
  7681. {* |<#control>
  7682. Creates 3D-label with capability to rotate its text <D Caption>, which
  7683. is controlled by changing <D Font>.FontOrientation property. If You want
  7684. to get flat effect label (e.g. to rotate it only), pass <D ShadowDeep> = 0.
  7685. Please note, that drawing procedure uses <D Canvas> property, so using of
  7686. LabelEffect leads to increase size of executable.
  7687. See also:
  7688. |#3dlabel
  7689. |#label }
  7690. //[NewPaintbox DECLARATION]
  7691. function NewPaintbox( AParent: PControl ): PControl;
  7692. {* |<#control>
  7693. Creates owner-drawn STATIC control. Set its <D OnPaint> event to
  7694. perform custom painting.
  7695. |#paintbox }
  7696. //[NewImageShow DECLARATION]
  7697. function NewImageShow( AParent: PControl; AImgList: PImageList; ImgIdx: Integer ): PControl;
  7698. {* |<#control>
  7699. Creates an image show control, implemented as a paintbox which is used to
  7700. draw an image from the imagelist. At run-time, use property CurIndex to
  7701. select another image from the imagelist, and a property ImageListNormal to
  7702. use another image list. When the control is created, its size becomes
  7703. equal to dimensions of imagelist (if any). }
  7704. //[NewScrollBar DECLARATION]
  7705. function NewScrollBar( AParent: PControl; BarSide: TScrollerBar ): PControl;
  7706. { * not yet finished... }
  7707. //[NewScrollBox DECLARATION]
  7708. function NewScrollBox( AParent: PControl; EdgeStyle: TEdgeStyle;
  7709. Bars: TScrollerBars ): PControl;
  7710. {* |<#control>
  7711. Creates simple scrolling box, which can be used any way you wish, e.g. to scroll
  7712. certain large image. To provide automatic scrolling of a set of child controls,
  7713. use advanced scroll box, created with NewScrollBoxEx. }
  7714. procedure NotifyScrollBox( Self_, Child: PControl );
  7715. function NewScrollBoxEx( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  7716. {* |<#control>
  7717. Creates extended scrolling box control, which automatically scrolls child
  7718. controls (if any). }
  7719. //[NewGradientPanel DECLARATION]
  7720. function NewGradientPanel( AParent: PControl; Color1, Color2: TColor ): PControl;
  7721. {* |<#control>
  7722. Creates gradient-filled STATIC control. To adjust colors at the
  7723. run time, change <D Color1> and <D Color2> properties (which initially are
  7724. assigned from Color1, Color2 parameters), and call <D Invalidate> method
  7725. to repaint control. }
  7726. function NewGradientPanelEx( AParent: PControl; Color1, Color2: TColor;
  7727. Style: TGradientStyle; Layout: TGradientLayout ): PControl;
  7728. {* |<#control>
  7729. Creates gradient-filled STATIC control. To adjust colors at the
  7730. run time, change <D Color1> and <D Color2> properties (which initially are
  7731. assigned from Color1, Color2 parameters), and call <D Invalidate> method
  7732. to repaint control. Depending on style and first line/point layout, can
  7733. looking different. Idea: Vladimir Stojiljkovic. }
  7734. //[NewPanel DECLARATION]
  7735. function NewPanel( AParent: PControl; EdgeStyle: TEdgeStyle ): PControl;
  7736. {* |<#control>
  7737. Creates panel, which can be parent for other controls (though, any
  7738. control can be used as a parent for other ones, but panel is specially
  7739. designed for such purpose). }
  7740. //[NewMDIxxx DECLARATIONS]
  7741. function NewMDIClient( AParent: PControl; WindowMenu: THandle ): PControl;
  7742. {* |<#control>
  7743. Creates MDI client window, which is a special type of child window,
  7744. containing all MDI child windows, created calling NewMDIChild function.
  7745. On a form, MDI client behaves like a panel, so it can be placed and sized
  7746. (or aligned) like any other controls. To minimize flick during resizing
  7747. main form having another aligned controls, place MDI client window on
  7748. a panel and align it caClient in the panel.
  7749. |<br>Note:
  7750. MDI client must be a single on the form. }
  7751. function NewMDIChild( AParent: PControl; const ACaption: String ): PControl;
  7752. {* |<#control>
  7753. Creates MDI client window. AParent should be a MDI client window,
  7754. created with NewMDIClient function. }
  7755. //[NewSplitter DECLARATIONS]
  7756. function NewSplitter( AParent: PControl; MinSizePrev, MinSizeNext: Integer ): PControl;
  7757. {* |<#control>
  7758. Creates splitter control, which will separate previous one (i.e. last
  7759. created one before splitter on the same parent) from created
  7760. next, allowing to user to adjust size of separated controls by dragging
  7761. the splitter in desired direction. Created splitter becomes vertical
  7762. or horizontal depending on Align style of previous control on the same
  7763. parent (if caLeft/caRight then vertical, if caTop/caBottom then horizontal).
  7764. |<br>&nbsp;&nbsp;&nbsp;
  7765. Please note, what if previous control has no Align equal to caLeft/caRight
  7766. or caTop/caBottom, splitter will not be able to function normally. If
  7767. previous control does not exist, it is yet possible to use splitter as
  7768. a resizeable panel (but set its initial Align value first - otherwise it
  7769. is not set by default. Also, change Cursor property as You wish in that
  7770. case, since it is not set too in case, when previous control does not
  7771. exist).
  7772. |<br>&nbsp;&nbsp;&nbsp;
  7773. Additional parameters determine, which minimal size (width or height -
  7774. correspondently to split direction) is allowed for left (top) control
  7775. and to rest of client area of parent, correspondently. (It is possible
  7776. later to set second control for checking its size with MinSizeNext
  7777. value - using TControl.SecondControl property). If -1 passed,
  7778. correspondent control size is not checked during dragging of splitter.
  7779. Usually 0 is more suitable value (with this value, it is garantee, that
  7780. splitter will be always available even if mouse was released far from the
  7781. edge of form).
  7782. |<br>&nbsp;&nbsp;&nbsp;
  7783. It is possible for user to press Escape any time while dragging splitter
  7784. to abort all adjustments made starting from left mouse button push and
  7785. begin of drag the splitter. But remember please, that such event is
  7786. controlled using timer, and therefore correspondent keyboard events
  7787. are received by currently focused control. Be sure, that pressing Escape
  7788. will not affect to any control on form, which could be focused, otherwise
  7789. filter keyboard messages (by yourself) to prevent undesired handling of
  7790. Escape key by certain controls while splitting. (Use Dragging property
  7791. to check if splitter is dragging by user with mouse).
  7792. |<br>&nbsp;&nbsp;&nbsp;
  7793. See also:
  7794. NewSplitterEx
  7795. |#splitter }
  7796. function NewSplitterEx( AParent: PControl; MinSizePrev, MinSizeNext: Integer;
  7797. EdgeStyle: TEdgeStyle ): PControl;
  7798. {* |<#control>
  7799. Creates splitter control. Difference from NewSplitter is what it is possible
  7800. to determine if a splitter will be beveled or not. See also NewSplitter. }
  7801. //[NewGroupbox DECLARATION]
  7802. function NewGroupbox( AParent: PControl; const Caption: String ): PControl;
  7803. {* |<#control>
  7804. Creates group box control. Note, that to group radio items, group
  7805. box is not necessary - any parent can play role of group for radio items.
  7806. See also NewPanel. }
  7807. //[NewCheckbox DECLARATION]
  7808. function NewCheckbox( AParent: PControl; const Caption: String ): PControl;
  7809. {* |<#control>
  7810. Creates check box control. Special properties, methods, events:
  7811. |#checkbox }
  7812. function NewCheckBox3State( AParent: PControl; const Caption: String ): PControl;
  7813. {* |<#control>
  7814. Creates check box control with 3 states. Special properties, methods,
  7815. events:
  7816. |#checkbox }
  7817. //[NewRadiobox DECLARATION]
  7818. function NewRadiobox( AParent: PControl; const Caption: String ): PControl;
  7819. {* |<#control>
  7820. Creates radio box control. Alternative radio items must have the
  7821. same parent window (regardless of its kind, either groupbox (NewGroupbox),
  7822. panel (NewPanel) or form itself). Following properties, methods and events
  7823. are specially for radiobox controls:
  7824. |#radiobox }
  7825. //[NewEditbox DECLARATION]
  7826. function NewEditbox( AParent: PControl; Options: TEditOptions ): PControl;
  7827. {* |<#control>
  7828. Creates edit box control. To create multiline edit box, similar to
  7829. TMemo in VCL, apply eoMultiline in Options. Following properties, methods,
  7830. events are special for edit controls:
  7831. |#edit }
  7832. //[NewRichEdit DECLARATION]
  7833. function NewRichEdit( AParent: PControl; Options: TEditOptions ): PControl;
  7834. {* |<#control>
  7835. Creates rich text edit control. A rich edit control is a window in which
  7836. the user can enter and edit text. The text can be assigned character and
  7837. paragraph formatting, and can include embedded OLE objects. Rich edit
  7838. controls provide a programming interface for formatting text. However, an
  7839. application must implement any user interface components necessary to make
  7840. formatting operations available to the user.
  7841. |<br>&nbsp;&nbsp;&nbsp;
  7842. Note: eoPassword, eoMultiline options have no effect for RichEdit control.
  7843. Some operations are supersided with special versions of those, created
  7844. especially for RichEdit, but in some cases it is necessary to use
  7845. another properties and methods, specially designed for RichEdit (see
  7846. methods and properties, which names are starting from RE_...).
  7847. |<br>&nbsp;&nbsp;&nbsp;
  7848. Following properties, methods, events are special for edit controls:
  7849. |#richedit
  7850. }
  7851. function NewRichEdit1( AParent: PControl; Options: TEditOptions ): PControl;
  7852. {* |<#control>
  7853. Like NewRichEdit, but to work with older RichEdit control version 1.0
  7854. (window class 'RichEdit' forced to use instead of 'RichEdit20A', even
  7855. if library RICHED20.DLL found and loaded successfully). One more
  7856. difference - OleInit is not called, so the most of OLE capabilities
  7857. of RichEdit could not working. }
  7858. //[NewListbox DECLARATION]
  7859. function NewListbox( AParent: PControl; Options: TListOptions ): PControl;
  7860. {* |<#control>
  7861. Creates list box control. Following properties, methods and events are
  7862. special for Listbox:
  7863. |#listbox }
  7864. //[NewCombobox DECLARATION]
  7865. function NewCombobox( AParent: PControl; Options: TComboOptions ): PControl;
  7866. {* |<#control>
  7867. Creates new combo box control. Note, that it is not possible to align
  7868. combobox caLeft or caRight: this can cause infinit recursion in the
  7869. application.
  7870. |<br>Following properties, methods and events are
  7871. special for Combobox:
  7872. |#combo }
  7873. //[_NewCommonControl DECLARATION]
  7874. function _NewCommonControl( AParent: PControl; ClassName: PChar; Style: DWORD;
  7875. Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  7876. //[NewProgressbar DECLARATION]
  7877. function NewProgressbar( AParent: PControl ): PControl;
  7878. {* |<#control>
  7879. Creates progress bar control. Following properties are special for
  7880. progress bar:
  7881. |#progressbar
  7882. See also NewProgressEx. }
  7883. function NewProgressbarEx( AParent: PControl; Options: TProgressbarOptions ): PControl;
  7884. {* |<#control>
  7885. Can create progress bar with smooth style (progress is not segmented
  7886. onto bricks) or/and vertical progress bar - using additional parameter.
  7887. For list of properties, suitable for progress bars, see NewProgressbar. }
  7888. //[NewListVew DECLARATION]
  7889. function NewListView( AParent: PControl; Style: TListViewStyle; Options: TListViewOptions;
  7890. ImageListSmall, ImageListNormal, ImageListState: PImageList ): PControl;
  7891. {* |<#control>
  7892. Creates list view control. It is very powerful control, which can partially
  7893. compensate absence of grid controls (in lvsDetail view mode). Properties,
  7894. methods and events, special for list view control are:
  7895. |#listview }
  7896. //[NewTreeView DECLARATION]
  7897. function NewTreeView( AParent: PControl; Options: TTreeViewOptions;
  7898. ImgListNormal, ImgListState: PImageList ): PControl;
  7899. {* |<#control>
  7900. Creates tree view control. See tree view methods and properties:
  7901. |#treeview }
  7902. //[NewTabControl DECLARATION]
  7903. function NewTabControl( AParent: PControl; Tabs: array of String; Options: TTabControlOptions;
  7904. ImgList: PImageList; ImgList1stIdx: Integer ): PControl;
  7905. {* |<#control>
  7906. Creates new tab control (like notebook). To place child control on a certain
  7907. page of TabControl, use property Pages[ Idx ], for example:
  7908. ! Label1 := NewLabel( TabControl1.Pages[ 0 ], 'Label1' );
  7909. | &nbsp;&nbsp;&nbsp;
  7910. To determine number of pages at run time, use property <D Count>;
  7911. |<br> to determine which page is currently selected (or to change
  7912. selection), use property <D CurrentIndex>;
  7913. |<br> to feedback to switch between tabs assign your handler to OnSelChange
  7914. event;
  7915. |<br>Note, that by default, tab control is created with a border lowered to
  7916. tab control's parent. To remove it, you can apply WS_EX_TRANSPARENT extended
  7917. style (see TControl.ExStyle property), but painting of some child controls
  7918. can be strange a bit in this case (no border drawing for edit controls was
  7919. found, but not always...). You can also apply style WS_THICKFRAME (TControl.Style
  7920. property) to make the border raised.
  7921. |<br> Other methods and properties, suitable for tab control, are:
  7922. |#tabcontrol }
  7923. //[NewToolbar DECLARATION]
  7924. function NewToolbar( AParent: PControl; Align: TControlAlign; Options: TToolbarOptions;
  7925. Bitmap: HBitmap; Buttons: array of PChar;
  7926. BtnImgIdxArray: array of Integer ) : PControl;
  7927. {* |<#control>
  7928. Creates toolbar control. Bitmap must contain images for all buttons
  7929. excluding separators (defined by string '-' in Buttons array), otherwise
  7930. last buttons will no have images at all. Image width for every button
  7931. is assumed to be equal to Bitmap height (if last of "squares" has
  7932. insufficient width, it will not be used). To define fixed buttons, use
  7933. characters '+' or '-' as a prefix for button string (even empty). To
  7934. create groups of (radio-)buttons, use also '!' follow '+' or '-'. (These rules
  7935. are similar used in menu creation). To define drop down button, use (as
  7936. first) prefix '^'. (Do not forget to set <D OnTBDropDown> event for this
  7937. case). If You want to assign images to buttons not in the same order
  7938. how these are placed in Bitmap (or You use system bitmap), define for every
  7939. button (in BtnImgIdxArray array) indexes for every button (excluding
  7940. separator buttons). Otherwise, it is possible to define index only for first
  7941. button (e.g., [0]). It is also possible to change TBImages[ ] property
  7942. for such purpose, or do the same in method TBSetBtnImgIdx).
  7943. |<br>
  7944. Following properties, methods and event are specially designed to work with
  7945. toolbar control:
  7946. |#toolbar
  7947. |<br>&nbsp;&nbsp;&nbsp;
  7948. If your project uses Align property to align controls, this can conflict with
  7949. toolbar native aligning. To solve such problem, place toolbar to parent panel,
  7950. which has its own Align property assigned to desired value.
  7951. |<br>
  7952. To create toolbar with buttons, drawn from top to bottom, instead from left
  7953. to right, combine caLeft / caRight in Align parameter and style tboWrapable
  7954. when create toolbar. To adjust width of vertically aligned toolbar, it is
  7955. possible to call ResizeParentLeft for it. E.g.:
  7956. ! P0 := NewPanel( W, esRaised ) .SetSize( 30, 0 ) .SetAlign( caLeft );
  7957. ! // ^^^^^^^^^^^^^^^^^ //////
  7958. !TB := NewToolbar( P0, caLeft, [ tboNoDivider, tboWrapable ], DWORD(-1),
  7959. ! // ////// ///////////
  7960. ! [ ' ', ' ', ' ', '-', ' ', ' ' ],
  7961. ! [ STD_FILEOPEN ] ).ResizeParentRight;
  7962. !//Note, that caLeft is *must*, and tboWrapable style too. SetSize for
  7963. !//parent panel is not necessary, but only if ResizeParentRight is called
  7964. !//than for Toolbar.
  7965. |<br><br>
  7966. One more note: if You create toolbar without text labels (passing ' ' for
  7967. each button You add), include also option tboTextRight to fix incorrect
  7968. sizing of buttons under Windows9x.
  7969. }
  7970. //[NewDateTimePicker DECLARATION]
  7971. function NewDateTimePicker( AParent: PControl; Options: TDateTimePickerOptions )
  7972. : PControl;
  7973. {* |<#control>
  7974. Creates date and time picker common control.
  7975. }
  7976. { -- Constructor for Image List objet -- }
  7977. //[NewImageList DECLARATION]
  7978. function NewImageList( AOwner: PControl ): PImageList;
  7979. {* Constructor of TImageList object. Unlike other non-visual objects, image list
  7980. can be parented by TControl object (but this does not *must*), and in that
  7981. case it is destroyed automatically when its parent control is destroyed.
  7982. Every control can have several TImageList objects, linked to a simple list.
  7983. But if any TImageList object is destroyed, all following ones are destroyed
  7984. too (at least, now I implemented it so). }
  7985. //[TIMER]
  7986. type
  7987. {++}(*TTimer = class;*){--}
  7988. PTimer = {-}^{+}TTimer;
  7989. { ----------------------------------------------------------------------
  7990. TTimer object
  7991. ----------------------------------------------------------------------- }
  7992. //[TTimer DEFINITION]
  7993. TTimer = object( TObj )
  7994. {* Easy timer incapsulation object. Uses applet window to
  7995. receive timer events. So, either assign your main form
  7996. to Applet variable or create applet button object (and
  7997. assign it to Applet) before enabling timer. }
  7998. protected
  7999. fHandle : Integer;
  8000. fEnabled: Boolean;
  8001. fInterval: Integer;
  8002. fOnTimer: TOnEvent;
  8003. procedure SetEnabled(const Value: Boolean); virtual;
  8004. procedure SetInterval(const Value: Integer);
  8005. protected
  8006. {++}(*public*){--}
  8007. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  8008. {* Destructor. }
  8009. public
  8010. property Handle : Integer read fHandle;
  8011. {* Windows timer object handle. }
  8012. property Enabled : Boolean read fEnabled write SetEnabled;
  8013. {* True, is timer is on. Initially, always False. Before assigning True,
  8014. make sure, that Applet global variable is assigned to applet object
  8015. (NewApplet) or to form (NewForm). }
  8016. property Interval : Integer read fInterval write SetInterval;
  8017. {* Interval in milliseconds (1000 is default and means 1 second). }
  8018. property OnTimer : TOnEvent read fOnTimer write fOnTimer;
  8019. {* Event, which is called when time interval is over. }
  8020. end;
  8021. //[END OF TTimer DEFINITION]
  8022. //[NewTimer DECLARATION]
  8023. function NewTimer( Interval: Integer ): PTimer;
  8024. {* Constructs initially disabled timer with interval 1000 (1 second). }
  8025. //[MULTIMEDIA TIMER]
  8026. type
  8027. {++}(*TMMTimer = class;*){--}
  8028. PMMTimer = {-}^{+}TMMTimer;
  8029. //[TMMTimer DEFINITION]
  8030. TMMTimer = object( TTimer )
  8031. {* Multimedia timer incapsulation object. Does not require Applet or special
  8032. window to handle it. System creates a thread for each high resolution
  8033. timer, so using many such objects can degrade total PC performance. }
  8034. protected
  8035. FResolution: Integer;
  8036. FPeriodic: Boolean;
  8037. procedure SetEnabled(const Value: Boolean); {-}virtual;{+}{++}(*override;*){--}
  8038. public
  8039. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  8040. {* }
  8041. property Resolution: Integer read FResolution write FResolution;
  8042. {* Minimum timer resolution. The less the more accuracy (0 is exactly
  8043. Interval milliseconds between timer shots). It is recommended to set
  8044. this property greater to prevent entire system from reducing overhead.
  8045. If you change this value, reset and then set Enabled again to apply
  8046. changes. }
  8047. property Periodic: Boolean read FPeriodic write FPeriodic;
  8048. {* TRUE, if timer is periodic (default). Otherwise, timer is one-shot
  8049. (set it Enabled every time in such case for each shot). If you change
  8050. this property, reset and set Enabled property again to get effect. }
  8051. end;
  8052. //[END OF TMMTimer DEFINITION]
  8053. //[NewMMTimer DECLARATION]
  8054. function NewMMTimer( Interval: Integer ): PMMTimer;
  8055. {* Creates multimedia timer object. Initially, it has Resolution = 0,
  8056. Periodic = TRUE and Enabled = FALSE. Do not forget also to assign your
  8057. event handler to OnTimer to do something on timer shot. }
  8058. { -- TTrayIcon object -- }
  8059. //[TRAYICON]
  8060. type
  8061. TOnTrayIconMouse = procedure( Sender: PObj; Message : Word ) of object;
  8062. {* Event type to be called when Applet receives a message from an icon,
  8063. added to the taskbar tray. }
  8064. {++}(*TTrayIcon = class;*){--}
  8065. PTrayIcon = {-}^{+}TTrayIcon;
  8066. { ----------------------------------------------------------------------
  8067. TTrayIcon - icon in tray area of taskbar
  8068. ----------------------------------------------------------------------- }
  8069. //[TTrayIcon DEFINITION]
  8070. TTrayIcon = object(TObj)
  8071. {* Object to place (and change) a single icon onto taskbar tray. }
  8072. protected
  8073. FIcon: HIcon;
  8074. FActive: Boolean;
  8075. FTooltip: String;
  8076. FOnMouse: TOnTrayIconMouse;
  8077. FControl: PControl;
  8078. fAutoRecreate: Boolean;
  8079. FNoAutoDeactivate: Boolean;
  8080. FWnd: HWnd;
  8081. procedure SetIcon(const Value: HIcon);
  8082. procedure SetActive(const Value: Boolean);
  8083. procedure SetTrayIcon( const Value : DWORD );
  8084. procedure SetTooltip(const Value: String);
  8085. procedure SetAutoRecreate(const Value: Boolean);
  8086. protected
  8087. {++}(*public*){--}
  8088. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  8089. {* Destructor. Use Free method instead (as usual). }
  8090. public
  8091. property Icon : HIcon read FIcon write SetIcon;
  8092. {* Icon to be shown on taskbar tray. If not set, value of Active
  8093. property has no effect. It is also possible to assign a value
  8094. to Icon property after assigning True to Active to install
  8095. icon first time or to replace icon with another one (e.g. to
  8096. get animation effect).
  8097. |<br>&nbsp;&nbsp;&nbsp;
  8098. Previously allocated icon (if any) is not deleted using
  8099. DeleteObject. This is normal for icons, loaded from resource
  8100. (e.g., by LoadIcon API call). But if icon was created (e.g.) by
  8101. CreateIconIndirect, your code is responsible for destroying
  8102. of it). }
  8103. property Active : Boolean read FActive write SetActive;
  8104. {* Set it to True to show assigned Icon on taskbar tray. Default
  8105. is False. Has no effect if Icon property is not assigned.
  8106. TrayIcon is deactivated automatically when Applet is finishing
  8107. (but only if Applet window is used as a "parent" for tray
  8108. icon object). }
  8109. property Tooltip : String read FTooltip write SetTooltip;
  8110. {* Tooltip string, showing automatically when mouse is moving
  8111. over installed icon. Though "huge string" type is used, only
  8112. first 63 characters are considered. Also note, that only in
  8113. most recent versions of Windows multiline tooltips are supported. }
  8114. property OnMouse : TOnTrayIconMouse read FOnMouse write FOnMouse;
  8115. {* Is called then mouse message is taking place concerning installed
  8116. icon. Only type of message can be obtained (e.g. WM_MOUSEMOVE,
  8117. WM_LBUTTONDOWN etc.) }
  8118. property AutoRecreate: Boolean read fAutoRecreate write SetAutoRecreate;
  8119. {* If set to TRUE, auto-recreating of tray icon is proveded in case,
  8120. when Explorer is restarted for some (unpredictable) reasons. Otherwise,
  8121. your tray icon is disappeared forever, and if this is the single way
  8122. to communicate with your application, the user nomore can achieve it. }
  8123. property NoAutoDeactivate: Boolean read FNoAutoDeactivate write FNoAutoDeactivate;
  8124. {* If set to true, tray icon is not removed from tray automatically on
  8125. WM_CLOSE message receive by owner control. Set Active := FALSE in
  8126. your code for such case before accepting closing the form. }
  8127. property Wnd: HWnd read FWnd write FWnd;
  8128. {* A window to use as a base window for tray icon messages. Overrides
  8129. parent Control handle is assigned. Note, that if Wnd property used,
  8130. message handling is not done automatically, and you should do this in
  8131. your code, or at least for one tray icon object, call AttachProc2Wnd. }
  8132. procedure AttachProc2Wnd;
  8133. {* Call this method for a tray icon object in case if Wnd used rather then
  8134. control. It is enough to call this method once for each Wnd used, even
  8135. if several other tray icons are also based on the same Wnd. See also
  8136. DetachProc2Wnd method. }
  8137. procedure DetachProc2Wnd;
  8138. {* Call this method to detach window procedure attached via AttachProc2Wnd.
  8139. Do it once for a Wnd, used as a base to handle tray icon messages.
  8140. Caution! If you do not call this method before destroying Wnd, the
  8141. application will not functioning normally. }
  8142. end;
  8143. {* When You create invisible application, which should be represented by
  8144. only the tray icon, prepare a handle for the window, resposible for
  8145. messages handling. Remember, that window handle is created automatically
  8146. only when a window is showing first time. If window's property Visible is
  8147. set to False, You should to call CreateWindow manually.
  8148. <br>
  8149. There is a known bug exist with similar invisible tray-iconized applications.
  8150. When a menu is activated in response to tray mouse event, if there was
  8151. not active window, belonging to the application, the menu is not disappeared
  8152. when mouse is clicked anywhere else. This bug is occure in Windows9x/ME.
  8153. To avoid it, activate first your form window. This last window shoud have
  8154. status visible (but, certainly, there are no needs to place it on visible
  8155. part of screen - change its position, so it will not be visible for user,
  8156. if You wish).
  8157. <br>
  8158. Also, to make your application "invisible" but until special event is occure,
  8159. use Applet separate from the main form, and make for both Visible := False.
  8160. This allows for You to make your form visible any time You wish, and without
  8161. making application button visible if You do not wish.
  8162. }
  8163. {= Êîãäà Âû äåëàåòå íåâèäèìîå ïðèëîæåíèå, êîòîðîå äîëæíî áûòü ïðåäñòàâëåíî
  8164. òîëüêî èêîíêîé â òðåå, îáåñïå÷üòå íåíóëåâîé Handle äëÿ îêíà, îòâå÷àþùåãî
  8165. çà îáðàáîòêó ñîîáùåíèé. Ïîìíèòå, ÷òî Handle îêíà ñîçäàåòñÿ àâòîìàòè÷åñêè
  8166. òîëüêî â òîò ìîìåíò, êîãäà îíî äîëæíî ïîÿâèòüñÿ â ïåðâûé ðàç. Åñëè ñâîéñòâî
  8167. îêíà Visible óñòàíîâëåíî â FALSE, íåîáõîäèìî âûçâàòü CreateWindow ñàìîñòîÿòåëüíî.
  8168. <br>
  8169. Ñóùåñòâóåò èçâåñòíûé BUG ñ ïîäîáíûìè íåâèäèìûìè ìèíèìèçèðîâàííûìè â òðåé
  8170. ïðèëîæåíèÿìè. Êîãäà â îòâåò íà ñîáûòèå ìûøè àêòèâèçèðâàíî âûïàäàþùåå ìåíþ,
  8171. îíî íå èñ÷åçàåò ïî ùåë÷êó ìûøè âíå ýòîãî ìåíþ. Ïðîèñõîäèò ýòî â Windows9x/ME.
  8172. ÷òîáû ðåøèòü ýòó ïðîáëåìó, ñíà÷àëà àêòèâèçèðóéòå ñâîå îêíî (ôîðìó). Ýòî îêíî
  8173. äîëæíî áûòü âèäèìûì (íî, êîíå÷íî, åãî ìîæíî ðàçìåñòèòü âíå ïðåäåëîâ âèäèìîé
  8174. ÷àñòè ýêðàíà, òàê ÷òî ïîëüçîâàòåëþ åãî âèäíî íå áóäåò).
  8175. <br>
  8176. Òàê æå, ÷òîáû ñäåëàòü ïðèëîæåíèå íåâèäèìûì, ïî êðàéíåé ìåðå, ïîêà ýòî íå
  8177. ïîòðåáóåòñÿ, èñïîëüçóéòå îòäåëüíûé ïðåäñòàâèòåëü êëàññà TControl - ãëîáàëüíóþ
  8178. ïåðåìåííóþ Applet, è ïðèñâîéòå FALSE åå ñâîéñòâó Visible.
  8179. }
  8180. //[END OF TTrayIcon DEFINITION]
  8181. //[NewTrayIcon DECLARATION]
  8182. function NewTrayIcon( Wnd: PControl; Icon: HIcon ): PTrayIcon;
  8183. {* Constructor of TTrayIcon object. Pass main form or applet as Wnd
  8184. parameter. }
  8185. //[JUST ONE]
  8186. { -- JustOne -- }
  8187. type
  8188. TOnAnotherInstance = procedure( const CmdLine: String ) of object;
  8189. {* Event type to use in JustOneNotify function. }
  8190. function JustOne( Wnd: PControl; const Identifier : String ) : Boolean;
  8191. {* Returns True, if this is a first instance. For all other instances
  8192. (application is already running), False is returned. }
  8193. function JustOneNotify( Wnd: PControl; const Identifier : String;
  8194. const aOnAnotherInstance: TOnAnotherInstance ) : Boolean;
  8195. {* Returns True, if this is a first instance. For all other instances
  8196. (application is already running), False is returned. If handler
  8197. aOnAnotherInstance passed, it is called (in first instance) every time
  8198. when another instance of an application is started, receiving command
  8199. line used to run it. }
  8200. { -- string (mainly) utility procedures and functions. -- }
  8201. //[Message Box DECLARATIONS]
  8202. function MsgBox( const S: String; Flags: DWORD ): DWORD;
  8203. {* Displays message box with the same title as Applet.Caption. If applet
  8204. is not running, and Applet global variable is not assigned, caption
  8205. 'Error' is displayed (but actually this is not an error - the system
  8206. does so, if nil is passed as a title).
  8207. |<br>&nbsp;&nbsp;&nbsp;
  8208. Returns ID_... result (correspondently to flags passed (MB_OK, MBYESNO,
  8209. etc. -> ID_OK, ID_YES, ID_NO, etc.) }
  8210. procedure MsgOK( const S: String );
  8211. {* Displays message box with the same title as Applet.Caption (or 'Error',
  8212. if Applet is not running). }
  8213. function ShowMsg( const S: String; Flags: DWORD ): DWORD;
  8214. {* Displays message box like MsgBox, but uses Applet.Handle as a parent
  8215. (so the message has no button on a task bar). }
  8216. procedure ShowMessage( const S: String );
  8217. {* Like ShowMsg, but has only styles MB_OK and MB_SETFOREGROUND. }
  8218. procedure ShowMsgModal( const S: String );
  8219. {* This message function can be used out of a message loop (e.g., after
  8220. finishing the application). It is always modal.
  8221. Actually, a form with word-wrap label (decorated as borderless edit
  8222. box with btnFace color) and with OK button is created and shown modal.
  8223. When a dialog is called from outside message loop, caption 'Information'
  8224. is always displayed.
  8225. Dialog form is automatically resized vertically to fit message text
  8226. (but until screen height is achieved) and shown always centered on
  8227. screen. The width is fixed (400 pixels).
  8228. |<br>
  8229. Do not use this function outside the message loop for case, when the
  8230. Applet variable is not used in an application. }
  8231. function ShowQuestion( const S: String; Answers: String ): Integer;
  8232. {* Modal dialog like ShowMsgModal. It is based on KOL form, so it can
  8233. be called also out of message loop, e.g. after finishing the
  8234. application. Also, this function *must* be used in MDI applications
  8235. in place of any dialog functions, based on MessageBox.
  8236. |<br>
  8237. The second parameter should be empty string or several possible
  8238. answers separated by '/', e.g.: 'Yes/No/Cancel'. Result is
  8239. a number answered, starting from 1. For example, if 'Cancel'
  8240. was pressed, 3 will be returned.
  8241. |<br>
  8242. User can also press ESCAPE key, or close modal dialog. In such case
  8243. -1 is returned. }
  8244. function ShowQuestionEx( const S: String; Answers: String; CallBack: TOnEvent ): Integer;
  8245. {* Like ShowQuestion, but with CallBack function, called just before showing
  8246. the dialog. }
  8247. procedure SpeakerBeep( Freq: Word; Duration: DWORD );
  8248. {* On Windows NT, calls Windows.Beep. On Windows 9x, produces beep on speaker
  8249. of desired frequency during given duration time (in milliseconds). }
  8250. {++}(*
  8251. function FormatMessage(dwFlags: DWORD; lpSource: Pointer; dwMessageId: DWORD; dwLanguageId: DWORD;
  8252. lpBuffer: PChar; nSize: DWORD; Arguments: Pointer): DWORD; stdcall;
  8253. *){--}
  8254. function SysErrorMessage(ErrorCode: Integer): string;
  8255. {* Creates and returns a string containing formatted system error message.
  8256. It is possible then to display this message or write it to a log
  8257. file, e.g.:
  8258. ! ShowMsg( SysErrorMessage( GetLastError ) );
  8259. |&R=<a name="%0"></a><font color=#FF8040><h1>%0</h1></font>
  8260. <R 64-bit integer numbers>
  8261. }
  8262. //[I64 TYPE]
  8263. type
  8264. I64 = record
  8265. {* 64 bit integer record. Use it and correspondent functions below in KOL
  8266. projects to avoid dependancy from Delphi version (earlier versions of
  8267. Delphi had no Int64 type). }
  8268. Lo, Hi: DWORD;
  8269. end;
  8270. PI64 = ^I64;
  8271. {* }
  8272. {-}
  8273. {$IFNDEF _D4orHigher}
  8274. Int64 = I64;
  8275. PInt64 = PI64;
  8276. {$ENDIF}
  8277. function MakeInt64( Lo, Hi: DWORD ): I64;
  8278. {* }
  8279. function Int2Int64( X: Integer ): I64;
  8280. {* }
  8281. procedure IncInt64( var I64: I64; Delta: Integer );
  8282. {* I64 := I64 + Delta; }
  8283. procedure DecInt64( var I64: I64; Delta: Integer );
  8284. {* I64 := I64 - Delta; }
  8285. function Add64( const X, Y: I64 ): I64;
  8286. {* Result := X + Y; }
  8287. function Sub64( const X, Y: I64 ): I64;
  8288. {* Result := X - Y; }
  8289. function Neg64( const X: I64 ): I64;
  8290. {* Result := -X; }
  8291. function Mul64i( const X: I64; Mul: Integer ): I64;
  8292. {* Result := X * Mul; }
  8293. function Div64i( const X: I64; D: Integer ): I64;
  8294. {* Result := X div D; }
  8295. function Mod64i( const X: I64; D: Integer ): Integer;
  8296. {* Result := X mod D; }
  8297. function Sgn64( const X: I64 ): Integer;
  8298. {* Result := sign( X ); i.e.:
  8299. |<br>
  8300. if X < 0 then -1
  8301. |<br>
  8302. if X = 0 then 0
  8303. |<br>
  8304. if X > 0 then 1 }
  8305. function Cmp64( const X, Y: I64 ): Integer;
  8306. {* Result := sign( X - Y ); i.e.
  8307. |<br>
  8308. if X < Y then -1
  8309. |<br>
  8310. if X = Y then 0
  8311. |<br>
  8312. if X > Y then 1 }
  8313. function Int64_2Str( X: I64 ): String;
  8314. {* }
  8315. function Str2Int64( const S: String ): I64;
  8316. {* }
  8317. function Int64_2Double( const X: I64 ): Double;
  8318. {* }
  8319. function Double2Int64( D: Double ): I64;
  8320. {*
  8321. <R Floating point numbers>
  8322. }
  8323. const
  8324. NAN = 0.0 / 0.0;
  8325. {+}
  8326. {++}(*const NAN = 1e-100;*){--}
  8327. function IsNan(const AValue: Double): Boolean;
  8328. {* Checks is an argument passed is NAN. }
  8329. function IntPower(Base: Extended; Exponent: Integer): Extended;
  8330. {* Result := Base ^ Exponent; }
  8331. //[String<->Double DECLARATIONS]
  8332. function Str2Double( const S: String ): Double;
  8333. {* }
  8334. function Double2Str( D: Double ): String;
  8335. {* }
  8336. function Extended2Str( E: Extended ): String;
  8337. {* }
  8338. function Double2StrEx( D: Double ): String;
  8339. {* experimental, do not use }
  8340. function TruncD( D: Double ): Double;
  8341. {* Result := trunc( D ) as Double;
  8342. |<hr>
  8343. <R Small bit arrays (max 32 bits in array)>
  8344. See also TBits object.
  8345. }
  8346. //[SMALL BIT ARRAYS DECLARATIONS]
  8347. function GetBits( N: DWORD; first, last: Byte ): DWord;
  8348. {* Retuns bits straing from <first> and to <last> inclusively. }
  8349. function GetBitsL( N: DWORD; from, len: Byte ): DWord;
  8350. {* Retuns len bits starting from index <from>.
  8351. |<hr>
  8352. <R Arithmetics, geometry and other utility functions>
  8353. See also units KolMath.pas, CplxMath.pas and Err.pas.
  8354. }
  8355. //[MulDiv DECLARATION]
  8356. {$IFNDEF FPC}
  8357. function MulDiv( A, B, C: Integer ): Integer;
  8358. {* Returns A * B div C. Small and fast. }
  8359. {$ENDIF}
  8360. //[TMethod TYPE]
  8361. type
  8362. ///////////////////////////////////////////
  8363. {$ifndef _D6orHigher} //
  8364. ///////////////////////////////////////////
  8365. TMethod = packed record
  8366. {* Is defined here because using of VCL classes.pas unit is
  8367. not recommended in XCL. This record type is used often
  8368. to set/access event handlers, referring to a procedure
  8369. of object (usually to set such event to an ordinal
  8370. procedure setting Data field to nil. }
  8371. Code: Pointer; // Pointer to method code.
  8372. {* If used to fake assigning to event handler of type 'procedure
  8373. of object' with ordinal procedure pointer, use symbol '@'
  8374. before method:
  8375. |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Courier"><b>
  8376. | Method.Code := @MyProcedure;
  8377. |</b></font> }
  8378. Data: Pointer; // Pointer to object, owning the method.
  8379. {* To fake event of type 'procedure of object' with setting it to
  8380. ordinal procedure assign here NIL; }
  8381. end;
  8382. {* When assigning TMethod record to event handler, typecast it with
  8383. desired event type, e.g.:
  8384. |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Courier"><b>
  8385. | SomeObject.OnSomeEvent := TOnSomeEvent( Method );
  8386. |</b></font><br> }
  8387. ///////////////////////////////////////////
  8388. {$endif} //
  8389. ///////////////////////////////////////////
  8390. PMethod = ^TMethod;
  8391. {* }
  8392. function MakeMethod( Data, Code: Pointer ): TMethod;
  8393. {* Help function to construct TMethod record. Can be useful to
  8394. assign regular type procedure/function as event handler for
  8395. event, defined as object method (do not forget, that in that
  8396. case it must have first dummy parameter to replace @Self,
  8397. passed in EAX to methods of object). }
  8398. //[Rectangles&Points DECLARATIONS]
  8399. function MakeRect( Left, Top, Right, Bottom: Integer ): TRect; stdcall;
  8400. {* Use it instead of VCL Rect function }
  8401. function RectsEqual( const R1, R2: TRect ): Boolean;
  8402. {* Returns True if rectangles R1 and R2 have the same bounds }
  8403. function RectsIntersected( const R1, R2: TRect ): Boolean;
  8404. {* Returns TRUE if rectangles R1 and R2 have at least one common point.
  8405. Note, that right and bottom bounds of rectangles are not their part,
  8406. so, if such points are lying on that bounds, FALSE is returned. }
  8407. function PointInRect( const P: TPoint; const R: TRect ): Boolean;
  8408. {* Returns True if point P is located in rectangle R (including
  8409. left and top bounds but without right and bottom bounds of the
  8410. rectangle). }
  8411. function MakePoint( X, Y: Integer ): TPoint;
  8412. {* Use instead of VCL function Point }
  8413. //[MakeFlags DECLARATION]
  8414. function MakeFlags( FlgSet: PDWORD; FlgArray: array of Integer): Integer;
  8415. {* }
  8416. function MakeDateTimeRange( D1, D2: TDateTime ): TDateTimeRange;
  8417. {* Returns TDateTimeRange from two TDateTime bounds. }
  8418. //[Integer FUNCTIONS DECLARATIONS]
  8419. procedure Swap( var X, Y: Integer );
  8420. {* exchanging values }
  8421. function Min( X, Y: Integer ): Integer;
  8422. {* minimum of two integers }
  8423. function Max( X, Y: Integer ): Integer;
  8424. {* maximum of two integers }
  8425. {$IFDEF REDEFINE_ABS}
  8426. function Abs( X: Integer ): Integer;
  8427. {* absolute value }
  8428. {$ENDIF}
  8429. function Sgn( X: Integer ): Integer;
  8430. {* sign of X: if X < 0, -1 is returned, if > 0, then +1, otherwise 0. }
  8431. function iSqrt( X: Integer ): Integer;
  8432. {* square root
  8433. |<hr>
  8434. <R String to number and number to string conversions>
  8435. }
  8436. //[Integer<->String DECLARATIONS]
  8437. function Int2Hex( Value : DWord; Digits : Integer ) : String;
  8438. {* Converts integer Value into string with hex number. Digits parameter
  8439. determines minimal number of digits (will be completed by adding
  8440. necessary number of leading zeroes). }
  8441. function Int2Str( Value : Integer ) : String;
  8442. {* Obvious. }
  8443. function UInt2Str( Value: DWORD ): String;
  8444. {* The same as Int2Str, but for unsigned integer value. }
  8445. function Int2StrEx( Value, MinWidth: Integer ): String;
  8446. {* Like Int2Str, but resulting string filled with leading spaces to provide
  8447. at least MinWidth characters. }
  8448. function Int2Rome( Value: Integer ): String;
  8449. {* Represents number 1..8999 to Rome numer. }
  8450. function Int2Ths( I : Integer ) : String;
  8451. {* Converts integer into string, separating every three digits from each
  8452. other by character ThsSeparator. (Convert to thousands). You }
  8453. function Int2Digs( Value, Digits : Integer ) : String;
  8454. {* Converts integer to string, inserting necessary number of leading zeroes
  8455. to provide desired length of string, given by Digits parameter. If
  8456. resulting string is greater then Digits, string is not truncated anyway. }
  8457. function Num2Bytes( Value : Double ) : String;
  8458. {* Converts double float to string, considering it as a bytes count.
  8459. If Value is sufficiently large, number is represented in kilobytes (with
  8460. following letter K), or in megabytes (M), gigabytes (G) or terabytes (T).
  8461. Resulting string number is truncated to two decimals (.XX) or to one (.X),
  8462. if the second is 0. }
  8463. function S2Int( S: PChar ): Integer;
  8464. {* Converts null-terminated string to Integer. Scanning stopped when any
  8465. non-digit character found. Even empty string or string not containing
  8466. valid integer number silently converted to 0. }
  8467. function Str2Int(const Value : String) : Integer;
  8468. {* Converts string to integer. First character, which can not be
  8469. recognized as a part of number, regards as a separator. Even
  8470. empty string or string without number silently converted to 0. }
  8471. function Hex2Int( const Value : String) : Integer;
  8472. {* Converts hexadecimal number to integer. Scanning is stopped
  8473. when first non-hexadicimal character is found. Leading dollar ('$')
  8474. character is skept (if present). Minus ('-') is not concerning as
  8475. a sign of number and also stops scanning.}
  8476. function cHex2Int( const Value : String) : Integer;
  8477. {* As Hex2Int, but also checks for leading '0x' and skips it. }
  8478. function Octal2Int( const Value: String ) : Integer;
  8479. {* Converts octal number to integer. Scanning is stopped on first
  8480. non-octal digit (any char except 0..7). There are no checking if
  8481. there octal numer in the parameter. If the first char is not octal
  8482. digit, 0 is returned. }
  8483. function Binary2Int( const Value: String ) : Integer;
  8484. {* Converts binary number to integer. Like Octal2Int, but only digits
  8485. 0 and 1 are allowed. }
  8486. {$IFNDEF _FPC}
  8487. function Format( const fmt: string; params: array of const ): String;
  8488. {* Uses API call to wvsprintf, so does not understand extra formats,
  8489. such as floating point, date/time, currency conversions. See list of
  8490. available formats in win32.hlp (topic wsprintf).
  8491. |<hr>
  8492. <R Working with null-terminated and ansi strings>
  8493. }
  8494. {$ENDIF _FPC}
  8495. //[String FUNCTIONS DECLARATIONS]
  8496. function StrComp(const Str1, Str2: PChar): Integer;
  8497. {* Compares two strings fast. -1: Str1<Str2; 0: Str1=Str2; +1: Str1>Str2 }
  8498. function StrComp_NoCase(const Str1, Str2: PChar): Integer;
  8499. {* Compares two strings fast without case sensitivity.
  8500. Returns: -1 when Str1<Str2; 0 when Str1=Str2; +1 when Str1>Str2 }
  8501. function StrLComp(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  8502. {* Compare two strings (fast). Terminating 0 is not considered, so if
  8503. strings are equal, comparing is continued up to MaxLen bytes.
  8504. Since this, pass minimum of lengths as MaxLen. }
  8505. function StrLComp_NoCase(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  8506. {* Compare two strings fast without case sensitivity.
  8507. Terminating 0 is not considered, so if strings are equal,
  8508. comparing is continued up to MaxLen bytes.
  8509. Since this, pass minimum of lengths as MaxLen. }
  8510. function StrCopy( Dest, Source: PChar ): PChar;
  8511. {* Copy source string to destination (fast). Pointer to Dest is returned. }
  8512. function StrCat( Dest, Source: PChar ): PChar;
  8513. {* Append source string to destination (fast). Pointer to Dest is returned. }
  8514. function StrLen(const Str: PChar): Cardinal;
  8515. {* StrLen returns the number of characters in Str, not counting the null
  8516. terminator. }
  8517. function StrScanLen(Str: PChar; Chr: Char; Len: Integer): PChar;
  8518. {* Fast scans string Str of length Len searching character Chr.
  8519. Pointer to a character next to found or to Str[Len] (if no one found)
  8520. is returned. }
  8521. function StrScan(Str: PChar; Chr: Char): PChar;
  8522. {* Fast search of given character in a string. Pointer to found character
  8523. (or nil) is returned. }
  8524. function StrRScan(const Str: PChar; Chr: Char): PChar;
  8525. {* StrRScan returns a pointer to the last occurrence of Chr in Str. If Chr
  8526. does not occur in Str, StrRScan returns NIL. The null terminator is
  8527. considered to be part of the string. }
  8528. function StrIsStartingFrom( Str, Pattern: PChar ): Boolean;
  8529. {* Returns True, if string Str is starting from Pattern, i.e. if
  8530. Copy( Str, 1, StrLen( Pattern ) ) = Pattern. Str must not be nil! }
  8531. function StrIsStartingFromNoCase( Str, Pattern: PChar ): Boolean;
  8532. {* Like StrIsStartingFrom above, but without case sensitivity. }
  8533. function TrimLeft(const S: string): string;
  8534. {* Removes spaces, tabulations and control characters from the starting
  8535. of string S. }
  8536. function TrimRight(const S: string): string;
  8537. {* Removes spaces, tabulates and other control characters from the
  8538. end of string S. }
  8539. function Trim( const S : string): string;
  8540. {* Makes TrimLeft and TrimRight for given string. }
  8541. function RemoveSpaces( const S: String ): String;
  8542. {* Removes all characters less or equal to ' ' in S and returns it. }
  8543. procedure Str2LowerCase( S: PChar );
  8544. {* Converts null-terminated string to lowercase (inplace). }
  8545. function LowerCase(const S: string): string;
  8546. {* Obvious. }
  8547. function UpperCase(const S: string): string;
  8548. {* Obvious. }
  8549. function AnsiUpperCase(const S: string): string;
  8550. {* Obvious. }
  8551. function AnsiLowerCase(const S: string): string;
  8552. {* Obvious. }
  8553. {$IFNDEF _D2}
  8554. {$IFNDEF _FPC}
  8555. function WAnsiUpperCase(const S: WideString): WideString;
  8556. {* Obvious. }
  8557. function WAnsiLowerCase(const S: WideString): WideString;
  8558. {* Obvious. }
  8559. {$ENDIF _FPC}
  8560. {$ENDIF _D2}
  8561. function AnsiCompareStr(const S1, S2: string): Integer;
  8562. {* AnsiCompareStr compares S1 to S2, with case-sensitivity. The compare
  8563. operation is controlled by the current Windows locale. The return value
  8564. is the same as for CompareStr. }
  8565. function _AnsiCompareStr(S1, S2: PChar): Integer;
  8566. {* The same, but for PChar ANSI strings }
  8567. function AnsiCompareStrNoCase(const S1, S2: string): Integer;
  8568. {* AnsiCompareStr compares S1 to S2, with case-sensitivity. The compare
  8569. operation is controlled by the current Windows locale. The return value
  8570. is the same as for CompareStr. }
  8571. function _AnsiCompareStrNoCase(S1, S2: PChar): Integer;
  8572. {* The same, but for PChar ANSI strings }
  8573. function AnsiCompareText( const S1, S2: String ): Integer;
  8574. {* }
  8575. {$IFNDEF _FPC}
  8576. function LStrFromPWCharLen(Source: PWideChar; Length: Integer): String;
  8577. {* from Delphi5 - because D2 does not contain it. }
  8578. function LStrFromPWChar(Source: PWideChar): String;
  8579. {* from Delphi5 - because D2 does not contain it. }
  8580. {$ENDIF _FPC}
  8581. function CopyEnd( const S : String; Idx : Integer ) : String;
  8582. {* Returns copy of source string S starting from Idx up to the end of
  8583. string S. Works correctly for case, when Idx > Length( S ) (returns
  8584. empty string for such case). }
  8585. function CopyTail( const S : String; Len : Integer ) : String;
  8586. {* Returns last Len characters of the source string. If Len > Length( S ),
  8587. entire string S is returned. }
  8588. procedure DeleteTail( var S : String; Len : Integer );
  8589. {* Deletes last Len characters from string. }
  8590. function IndexOfChar( const S : String; Chr : Char ) : Integer;
  8591. {* Returns index of given character (1..Length(S)), or
  8592. -1 if a character not found. }
  8593. function IndexOfCharsMin( const S, Chars : String ) : Integer;
  8594. {* Returns index (in string S) of those character, what is taking place
  8595. in Chars string and located nearest to start of S. If no such
  8596. characters in string S found, -1 is returned. }
  8597. {$IFNDEF _D2}
  8598. {$IFNDEF _FPC}
  8599. function IndexOfWideCharsMin( const S, Chars : WideString ) : Integer;
  8600. {* Returns index (in wide string S) of those wide character, what
  8601. is taking place in Chars wide string and located nearest to start of S.
  8602. If no such characters in string S found, -1 is returned. }
  8603. {$ENDIF _FPC}
  8604. {$ENDIF _D2}
  8605. function IndexOfStr( const S, Sub : String ) : Integer;
  8606. {* Returns index of given substring in source string S. If found,
  8607. 1..Length(S)-Length(Sub), if not found, -1. }
  8608. function Parse( var S : String; const Separators : String ) : String;
  8609. {* Returns first characters of string S, separated from others by
  8610. one of characters, taking place in Separators string, assigning
  8611. a tail of string (after found separator) to source string. If
  8612. no separator characters found, source string S is returned, and
  8613. source string itself becomes empty. }
  8614. {$IFNDEF _FPC}
  8615. {$IFNDEF _D2}
  8616. function WParse( var S : WideString; const Separators : WideString ) : WideString;
  8617. {* Returns first wide characters of wide string S, separated from others
  8618. by one of wide characters, taking place in Separators wide string,
  8619. assigning a tail of wide string (following found separator) to the
  8620. source one. If there are no separator characters found, source wide
  8621. string S is returned, and source wide string itself becomes empty. }
  8622. {$ENDIF _D2}
  8623. {$ENDIF _FPC}
  8624. function ParsePascalString( var S : String; const Separators : String ) : String;
  8625. {* Returns first characters of string S, separated from others by
  8626. one of characters, taking place in Separators string, assigning
  8627. a tail of string (after the found separator) to source string. If
  8628. there are no separator characters found, the source string S is returned,
  8629. and the source string itself becomes empty. Additionally: if the first (after
  8630. a blank space) is the quote "'" or '#', pascal string is assumung first
  8631. and is converted to usual string (without quotas) before analizing
  8632. of other separators. }
  8633. function String2PascalStrExpr( const S : String ) : String;
  8634. {* Converts string to Pascal-like string expression (concatenation of
  8635. strings with quotas and characters with leading '#'). }
  8636. function StrEq( const S1, S2 : String ) : Boolean;
  8637. {* Returns True, if LowerCase(S1) = LowerCase(S2). I.e., if strings
  8638. are equal to each other without caring of characters case sensitivity
  8639. (ASCII only). }
  8640. function AnsiEq( const S1, S2 : String ) : Boolean;
  8641. {* Returns True, if AnsiLowerCase(S1) = AnsiLowerCase(S2). I.e., if ANSI
  8642. stringsare equal to each other without caring of characters case
  8643. sensitivity. }
  8644. {$IFNDEF _D2}
  8645. {$IFNDEF _FPC}
  8646. function WAnsiEq( const S1, S2 : WideString ) : Boolean;
  8647. {* Returns True, if AnsiLowerCase(S1) = AnsiLowerCase(S2). I.e., if ANSI
  8648. stringsare equal to each other without caring of characters case
  8649. sensitivity. }
  8650. {$ENDIF _FPC}
  8651. {$ENDIF _D2}
  8652. function StrIn( const S : String; const A : array of String ) : Boolean;
  8653. {* Returns True, if S is "equal" to one of strings, taking place
  8654. in A array. To check equality, StrEq function is used, i.e.
  8655. comaprison is taking place without case sensitivity. }
  8656. {$IFNDEF _FPC}
  8657. {$IFNDEF _D2}
  8658. function WStrIn( const S : WideString; const A : array of WideString ) : Boolean;
  8659. {* Returns True, if S is "equal" to one of strings, taking place
  8660. in A array. To check equality, WAnsiEq function is used, i.e.
  8661. comaprison is taking place without case sensitivity. }
  8662. {$ENDIF _D2}
  8663. {$ENDIF _FPC}
  8664. function StrIs( const S : String; const A : array of String; var Idx: Integer ) : Boolean;
  8665. {* Returns True, if S is "equal" to one of strings, taking place
  8666. in A array, and in such Case Idx also is assigned to an index of A element
  8667. equal to S. To check equality, StrEq function is used, i.e.
  8668. comaprison is taking place without case sensitivity. }
  8669. function IntIn( Value: Integer; const List: array of Integer ): Boolean;
  8670. {* Returns TRUE, if Value is found in a List. }
  8671. function _StrSatisfy( S, Mask : PChar ) : Boolean;
  8672. {* }
  8673. function _2StrSatisfy( S, Mask: PChar ): Boolean;
  8674. {* }
  8675. function StrSatisfy( const S, Mask : String ) : Boolean;
  8676. {* Returns True, if S is satisfying to a given Mask (which can contain
  8677. wildcard symbols '*' and '?' interpeted correspondently as 'any
  8678. set of characters' and 'single any character'. If there are no
  8679. such wildcard symbols in a Mask, result is True only if S is maching
  8680. to Mask string.) }
  8681. function StrReplace( var S: String; const From, ReplTo: String ): Boolean;
  8682. {* Replaces first occurance of From to ReplTo in S, returns True,
  8683. if pattern From was found and replaced. }
  8684. {$IFNDEF _FPC}
  8685. {$IFNDEF _D2}
  8686. function WStrReplace( var S: WideString; const From, ReplTo: WideString ): Boolean;
  8687. {* Replaces first occurance of From to ReplTo in S, returns True,
  8688. if pattern From was found and replaced. See also function StrReplace.
  8689. This function is not available in Delphi2 (this version of Delphi
  8690. does not support WideString type). }
  8691. {$ENDIF _D2}
  8692. {$ENDIF _FPC}
  8693. function StrRepeat( const S: String; Count: Integer ): String;
  8694. {* Repeats given string Count times. E.g., StrRepeat( 'A', 5 ) gives 'AAAAA'. }
  8695. {$IFNDEF _FPC}
  8696. {$IFNDEF _D2}
  8697. function WStrRepeat( const S: WideString; Count: Integer ): WideString;
  8698. {* Repeats given wide string Count times. E.g., StrRepeat( 'A', 5 ) gives 'AAAAA'. }
  8699. {$ENDIF _D2}
  8700. {$ENDIF _FPC}
  8701. procedure NormalizeUnixText( var S: String );
  8702. {* In the string S, replaces all occurances of character #10 (without leading #13)
  8703. to the character #13. }
  8704. function StrPCopy(Dest: PChar; const Source: string): PChar;
  8705. {* Copyes Pascal-style string into null-terminaed one. }
  8706. function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar;
  8707. {* Copyes first MaxLen characters of Pascal-style string into
  8708. null-terminated one. }
  8709. function DelimiterLast( const Str, Delimiters: String ): Integer;
  8710. {* Returns index of the last of delimiters given by same named parameter
  8711. among characters of Str. If there are no delimiters found, length of
  8712. Str is returned. This function is intended mainly to use in filename
  8713. parsing functions. }
  8714. function __DelimiterLast( Str, Delimiters: PChar ): PChar;
  8715. {* Returns address of the last of delimiters given by Delimiters parameter
  8716. among characters of Str. If there are no delimeters found, position of
  8717. the null terminator in Str is returned. This function is intended
  8718. mainly to use in filename parsing functions. }
  8719. function SkipSpaces( P: PChar ): PChar;
  8720. {* Skips all characters #1..' ' in a string.
  8721. }
  8722. {$IFDEF F_P}
  8723. function DummyStrFun( const S: String ): String;
  8724. {$ENDIF}
  8725. //[Memory FUNCTIONS DECLARATIONS]
  8726. function CompareMem(P1, P2: Pointer; Length: Integer): Boolean;
  8727. {* Fast compare of two memory blocks. }
  8728. function AllocMem( Size : Integer ) : Pointer;
  8729. {* Allocates global memory and unlocks it. }
  8730. procedure DisposeMem( var Addr : Pointer );
  8731. {* Locks global memory block given by pointer, and frees it.
  8732. Does nothing, if the pointer is nil.
  8733. |<hr>
  8734. <R Text in clipboard operations>
  8735. }
  8736. //[clipboard FUNCTIONS DECLARATIONS]
  8737. function Clipboard2Text: String;
  8738. {* If clipboard contains text, this function returns it for You. }
  8739. {$IFNDEF _FPC}
  8740. {$IFNDEF _D2}
  8741. function Clipboard2WText: WideString;
  8742. {* If clipboard contains text, this function returns it for You (as Unicode string). }
  8743. {$ENDIF _D2}
  8744. {$ENDIF _FPC}
  8745. function Text2Clipboard( const S: String ): Boolean;
  8746. {* Puts given string to a clipboard. }
  8747. {$IFNDEF _FPC}
  8748. {$IFNDEF _D2}
  8749. function WText2Clipboard( const WS: WideString ): Boolean;
  8750. {* Puts given Unicode string to a clipboard.
  8751. |<hr>
  8752. }
  8753. {$ENDIF _D2}
  8754. {$ENDIF _FPC}
  8755. //[Mnemonics FUNCTIONS DECLARATIONS]
  8756. var SearchMnemonics: function ( const S: String ): String
  8757. = {$IFDEF F_P} DummyStrFun {$ELSE} UpperCase {$ENDIF};
  8758. MnemonicsLocale: Integer;
  8759. procedure SupportAnsiMnemonics( LocaleID: Integer );
  8760. {* Provides encoding to work with given locale. Call this global function to
  8761. extend TControl.SupportMnemonics capability (also should be called for a form
  8762. or for Applet variable).
  8763. <R Date and time handling>
  8764. }
  8765. //[TDateTime TYPE DEFINITION]
  8766. type
  8767. //TDateTime = Double; // well, it is already defined so in System.pas
  8768. {* Basic date and time type. Integer part represents year and days (as is,
  8769. i.e. 1-Jan-2000 is representing by value 730141, which is a number of
  8770. days from 1-Jan-0001 to 1-Jan-2000 inclusively). Fractional part is
  8771. representing hours, minutes, seconds and milliseconds of a day
  8772. proportionally (like in VCL TDateTime type, e.g. 0.5 = 12:00, 0.25 = 6:00,
  8773. etc.). }
  8774. PDayTable = ^TDayTable;
  8775. TDayTable = array[1..12] of Word;
  8776. TDateFormat = ( dfShortDate, dfLongDate );
  8777. {* Date formats available to use in formatting date/time to string. }
  8778. TTimeFormatFlag = ( tffNoMinutes, tffNoSeconds, tffNoMarker, tffForce24 );
  8779. {* Additional flags, used for formatting time. }
  8780. TTimeFormatFlags = Set of TTimeFormatFlag;
  8781. {* Set of flags, used for formatting time. }
  8782. const
  8783. MonthDays: array [Boolean] of TDayTable =
  8784. ((31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
  8785. (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));
  8786. {* The MonthDays array can be used to quickly find the number of
  8787. days in a month: MonthDays[IsLeapYear(Y), M]. }
  8788. SecsPerDay = 24 * 60 * 60;
  8789. {* Seconds per day. }
  8790. MSecsPerDay = SecsPerDay * 1000;
  8791. {* Milliseconds per day. }
  8792. VCLDate0 = 693594;
  8793. {* Value to convert VCL "date 0" to KOL "date 0" and back.
  8794. This value corresponds to 30-Dec-1899, 0:00:00. So,
  8795. to convert VCL date to KOL date, just subtract this
  8796. value from VCL date. And to convert back from KOL date
  8797. to VCL date, add this value to KOL date.}
  8798. {++}(*
  8799. procedure GetLocalTime(var lpSystemTime: TSystemTime); stdcall;
  8800. procedure GetSystemTime(var lpSystemTime: TSystemTime); stdcall;
  8801. *){--}
  8802. //[Date&Time FUNCTIONS DECLARATIONS]
  8803. function Now : TDateTime;
  8804. {* Returns local date and time on running PC. }
  8805. function Date: TDateTime;
  8806. {* Returns todaylocal date. }
  8807. procedure DecodeDateFully( DateTime: TDateTime; var Year, Month, Day, DayOfWeek: WORD );
  8808. {* Decodes date. }
  8809. procedure DecodeDate( DateTime: TDateTime; var Year, Month, Day: WORD );
  8810. {* Decodes date. }
  8811. function EncodeDate( Year, Month, Day: WORD; var DateTime: TDateTime ): Boolean;
  8812. {* Encodes date. }
  8813. function CompareSystemTime(const D1, D2 : TSystemTime) : Integer;
  8814. {* Compares to TSystemTime records. Returns -1, 0, or 1 if, correspondantly,
  8815. D1 < D2, D1 = D2 and D1 > D2. }
  8816. procedure IncDays( var SystemTime : TSystemTime; DaysNum : Integer );
  8817. {* Increases/decreases day in TSystemTime record onto given days count
  8818. (can be negative). }
  8819. procedure IncMonths( var SystemTime : TSystemTime; MonthsNum : Integer );
  8820. {* Increases/decreases month number in TSystemTime record onto given
  8821. months count (can be negative). Correct result is not garantee if
  8822. day number is incorrect for newly obtained month. }
  8823. function IsLeapYear(Year: Word): Boolean;
  8824. {* Returns True, if given year is "leap" (i.e. has 29 days in the February). }
  8825. function DayOfWeek(Date: TDateTime): Integer;
  8826. {* Returns day of week (0..6) for given date. }
  8827. function SystemTime2DateTime(const SystemTime : TSystemTime; var DateTime : TDateTime ) : Boolean;
  8828. {* Converts TSystemTime record to XDateTime variable. }
  8829. function DateTime2SystemTime(const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;
  8830. {* Converts TDateTime variable to TSystemTime record. }
  8831. function DateTime_System2Local( DTSys: TDateTime ): TDateTime;
  8832. {* Converts DTSys representing system time (+0 Grinvich) to local time. }
  8833. function DateTime_Local2System( DTLoc: TDateTime ): TDateTime;
  8834. {* Converts DTLoc representing local time to system time (+0 Grinvich) }
  8835. function CatholicEaster( nYear: Integer ): TDateTime;
  8836. {* Returns date of catholic easter for given year. }
  8837. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
  8838. {* Dividing of integer onto divisor with obtaining both result of division
  8839. and remainder. }
  8840. function SystemDate2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  8841. const DfltDateFormat : TDateFormat; const DateFormat : PChar ) : String;
  8842. {* Formats date, stored in TSystemTime record into string, using given locale
  8843. and date/time formatting flags. (E.g.: GetUserDefaultLangID). }
  8844. function SystemTime2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  8845. const Flags : TTimeFormatFlags; const TimeFormat : PChar ) : String;
  8846. {* Formats time, stored in TSystemTime record into string, using given locale
  8847. and date/time formatting flags. }
  8848. function Date2StrFmt( const Fmt: String; D: TDateTime ): String;
  8849. {* Represents date as a string correspondently to Fmt formatting string.
  8850. See possible pictures in definition of the function Str2DateTimeFmt
  8851. (the first part). If Fmt string is empty, default system date format
  8852. for short date string used. }
  8853. function Time2StrFmt( const Fmt: String; D: TDateTime ): String;
  8854. {* Represents time as a string correspondently to Fmt formatting string.
  8855. See possible pictures in definition of the function Str2DateTimeFmt
  8856. (the second part). If Fmt string is empty, default system time format
  8857. for short date string used. }
  8858. function DateTime2StrShort( D: TDateTime ): String;
  8859. {* Formats date and time to string in short date format using current user
  8860. locale. }
  8861. function Str2DateTimeFmt( const sFmtStr, sS: String ): TDateTime;
  8862. {* Restores date or/and time from string correspondently to a format string.
  8863. Date and time formatting string can contain following pictures (case
  8864. sensitive):
  8865. |<pre>
  8866. DATE PICTURES
  8867. d Day of the month as digits without leading zeros for single digit days.
  8868. dd Day of the month as digits with leading zeros for single digit days
  8869. ddd Day of the week as a 3-letter abbreviation as specified by a
  8870. LOCALE_SABBREVDAYNAME value.
  8871. dddd Day of the week as specified by a LOCALE_SDAYNAME value.
  8872. M Month as digits without leading zeros for single digit months.
  8873. MM Month as digits with leading zeros for single digit months
  8874. MMM Month as a three letter abbreviation as specified by a LOCALE_SABBREVMONTHNAME value.
  8875. MMMM Month as specified by a LOCALE_SMONTHNAME value.
  8876. y Year represented only be the last digit.
  8877. yy Year represented only be the last two digits.
  8878. yyyy Year represented by the full 4 digits.
  8879. gg Period/era string as specified by the CAL_SERASTRING value. The gg
  8880. format picture in a date string is ignored if there is no associated era
  8881. string. In Enlish locales, usual values are BC or AD.
  8882. TIME PICTURES
  8883. h Hours without leading zeros for single-digit hours (12-hour clock).
  8884. hh Hours with leading zeros for single-digit hours (12-hour clock).
  8885. H Hours without leading zeros for single-digit hours (24-hour clock).
  8886. HH Hours with leading zeros for single-digit hours (24-hour clock).
  8887. m Minutes without leading zeros for single-digit minutes.
  8888. mm Minutes with leading zeros for single-digit minutes.
  8889. s Seconds without leading zeros for single-digit seconds.
  8890. ss Seconds with leading zeros for single-digit seconds.
  8891. t One charactertime marker string (usually P or A, in English locales).
  8892. tt Multicharactertime marker string (usually PM or AM, in English locales).
  8893. |</pre>
  8894. E.g., 'D, yyyy/MM/dd h:mm:ss'.
  8895. See also Str2DateTimeShort function.
  8896. }
  8897. function Str2DateTimeShort( const S: String ): TDateTime;
  8898. {* Restores date and time from string correspondently to current user locale. }
  8899. function Str2DateTimeShortEx( const S: String ): TDateTime;
  8900. {* Like Str2DateTimeShort above, but uses locale defined date and time
  8901. separators to avoid recognizing time as a date in some cases.
  8902. |<hr>
  8903. <R File and directory routines>
  8904. }
  8905. //[OpenFile CONSTANTS]
  8906. const
  8907. ofOpenRead = $80000000;
  8908. {* Use this flag (in combination with others) to open file for "read" only. }
  8909. ofOpenWrite = $40000000;
  8910. {* Use this flag (in combination with others) to open file for "write" only. }
  8911. ofOpenReadWrite = $C0000000;
  8912. {* Use this flag (in combination with others) to open file for "read" and "write". }
  8913. ofShareExclusive = $00;
  8914. {* Use this flag (in combination with others) to open file for exclusive use. }
  8915. ofShareDenyWrite = $01;
  8916. {* Use this flag (in combination with others) to open file in share mode, when
  8917. only attempts to open it in other process for "write" will be impossible.
  8918. I.e., other processes could open this file simultaneously for read only
  8919. access. }
  8920. ofShareDenyRead = $02;
  8921. {* Use this flag (in combination with others) to open file in share mode, when
  8922. only attempts to open it for "read" in other processes will be disabled.
  8923. I.e., other processes could open it for "write" only access. }
  8924. ofShareDenyNone = $03;
  8925. {* Use this flag (in combination with others) to open file in full sharing mode.
  8926. I.e. any process will be able open this file using the same share flag. }
  8927. ofCreateNew = $100;
  8928. {* Default creation disposition. Use this flag for creating new file (usually
  8929. for write access. }
  8930. ofCreateAlways = $200;
  8931. {* Use this flag (in combination with others) to open existing or creating new
  8932. file. If existing file is opened, it is truncated to size 0. }
  8933. ofOpenExisting = $300;
  8934. {* Use this flag (in combination with others) to open existing file only. }
  8935. ofOpenAlways = $400;
  8936. {* Use this flag (in combination with others) to open existing or create new
  8937. (if such file is not yet exists). }
  8938. ofTruncateExisting = $500;
  8939. {* Use this flag (in combination with others) to open existing file and truncate
  8940. it to size 0. }
  8941. ofAttrReadOnly = $10000;
  8942. {* Use this flag to create Read-Only file (?). }
  8943. ofAttrHidden = $20000;
  8944. {* Use this flag to create hidden file. }
  8945. ofAttrSystem = $40000;
  8946. {* Use this flag to create system file. }
  8947. ofAttrTemp = $1000000;
  8948. {* Use this flag to create temp file. }
  8949. ofAttrArchive = $200000;
  8950. {* Use this flag to create archive file. }
  8951. ofAttrCompressed = $8000000;
  8952. {* Use this flag to create compressed file. Has effect only on NTFS, and
  8953. only if ofAttrCompressed is not specified also. }
  8954. ofAttrOffline = $10000000;
  8955. {* Use this flag to create offline file. }
  8956. //[END OF OpenFileConstants]
  8957. //[File FUNCTIONS DECLARATIONS]
  8958. function FileCreate(const FileName: string; OpenFlags: DWord): THandle;
  8959. {* Call this function to open existing or create new file. OpenFlags
  8960. parameter can be a combination of up to three flags (by one from
  8961. each group:
  8962. |<table border=0>
  8963. |&L=<tr><td valign=top>%0</td><td valign=top>
  8964. |&E=</td></tr>
  8965. <L ofOpenRead, ofOpenWrite, ofOpenReadWrite> - 1st group. Here You decide
  8966. wish You open file for read, write or read-and-write operations; <E>
  8967. <L ofShareExclusive, ofShareDenyWrite, ofShareDenyRead, ofShareDenyNone> -2nd
  8968. group - sharing. Here You can mark out sharing mode, which is used to
  8969. open file. <E>
  8970. <L ofCreateNew, ofCreateAlways, ofOpenExisting, ofOpenAlways, ofTruncateExisting>
  8971. - 3rd group - creation disposition. Here You determine, either to create new
  8972. or open existing file and if to truncate existing or not.
  8973. |</table> }
  8974. function FileClose(Handle: THandle): Boolean;
  8975. {* Call it to close opened earlier file. }
  8976. function FileExists( const FileName: String ) : Boolean;
  8977. {* Returns True, if given file exists.
  8978. |<br>Note (by Dod):
  8979. It is not documented in a help for GetFileAttributes, but it seems that
  8980. under NT-based Windows systems, FALSE is always returned for files
  8981. opened for excluseve use like pagefile.sys. }
  8982. function FileRead(Handle: THandle; var Buffer; Count: DWord): DWord;
  8983. {* Reads bytes from current position in file to buffer. Returns number of
  8984. read bytes. }
  8985. function File2Str(Handle: THandle): String;
  8986. {* Reads file from current position to the end and returns result as ansi string. }
  8987. function FileSeek(Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  8988. {* Changes current position in file. }
  8989. function FileWrite(Handle: THandle; const Buffer; Count: DWord): DWord;
  8990. {* Writes bytes from buffer to file from current position, extending its
  8991. size if needed. }
  8992. function FileEOF( Handle: THandle ) : Boolean;
  8993. {* Returns True, if EOF is achieved during read operations or last byte is
  8994. overwritten or append made to extend file during last write operation. }
  8995. function FileFullPath( const FileName : String ) : String;
  8996. {* Returns full path name for given file. Validness of source FileName path
  8997. is not checked at all. }
  8998. function FileShortPath( const FileName: String ): String;
  8999. {* Returns short path to the file or directory. }
  9000. function FileIconSystemIdx( const Path: String ): Integer;
  9001. {* Returns index of the index of the system icon correspondent to the file or
  9002. directory in system icon image list. }
  9003. function FileIconSysIdxOffline( const Path: String ): Integer;
  9004. {* The same as FileIconSystemIdx, but an icon is calculated for the file
  9005. as it were offline (it is possible to get an icon for file even if
  9006. it is not existing, on base of its extension only). }
  9007. procedure LogFileOutput( const filepath, str: String );
  9008. {* Debug function. Use it to append given string to the end of the given file. }
  9009. function StrSaveToFile( const Filename, Str: String ): Boolean;
  9010. {* Saves a string to a file without any changes. If file does not exists, it is
  9011. created. If it exists, it is overriden. If operation failed, FALSE is returned. }
  9012. function StrLoadFromFile( const Filename: String ): String;
  9013. {* Reads entire file and returns its content as a string. If operation failed,
  9014. an empty strinng is returned.
  9015. |<br>by Sergey Shishmintzev: it is possible to pass Filename = 'CON' to
  9016. read input from redirected console output. }
  9017. function Mem2File( Filename: PChar; Mem: Pointer; Len: Integer ): Integer;
  9018. {* Saves memory block to a file (if file exists it is overriden, created new if
  9019. not exists). }
  9020. function File2Mem( Filename: PChar; Mem: Pointer; MaxLen: Integer ): Integer;
  9021. {* Loads file content to memory. }
  9022. function FileSize( const Path: String ) : Integer;
  9023. {* Returns file size in bytes without opening it. If file too large
  9024. to represent its size as Integer, -1 is returned. }
  9025. function GetUniqueFilename( PathName: string ) : String;
  9026. {* If file given by PathName exists, modifies it to create unique
  9027. filename in target folder and returns it. Modification is performed
  9028. by incrementing last number in name (if name part of file does not
  9029. represent a number, such number is generated and concatenated to
  9030. it). E.g., if file aaa.aaa is already exist, the function checks
  9031. names aaa1.aaa, aaa2.aaa, ..., aaa10.aaa, etc. For name abc123.ext,
  9032. names abc124.ext, abc125.ext, etc. will be checked. }
  9033. function FileTimeCompare( const FT1, FT2 : TFileTime ) : Integer;
  9034. {* Compares time of file (createing, writing, accessing. Returns
  9035. -1, 0, 1 if correspondantly FT1<FT2, FT1=FT2, FT1>FT2. }
  9036. //[Directory FUNCTIONS DECLARATIONS]
  9037. function GetStartDir: String;
  9038. {* Returns path to directory where executable is located (regardless
  9039. of current directory). }
  9040. function DirectoryExists(const Name: string): Boolean;
  9041. {* Returns True if given directory (folder) exists. }
  9042. function DirectoryEmpty(const Name: String): Boolean;
  9043. {* Returns True if given directory is not exists or empty. }
  9044. {
  9045. function DirectorySize( const Path: String ): I64;
  9046. -- moved after PDirList
  9047. }
  9048. function DirectoryHasSubdirs( const Path: String ): Boolean;
  9049. {* Returns TRUE if given directory exists and has subdirectories. }
  9050. function CheckDirectoryContent( const Name: String; SubDirsOnly: Boolean; const Mask: String ): Boolean;
  9051. {* Returns TRUE if directory does not contain files (or directories only)
  9052. satisfying given mask. }
  9053. //---------------------------------------------------------
  9054. // Following functions/procedures are created by Edward Aretino:
  9055. // IncludeTrailingPathDelimiter, ExcludeTrailingPathDelimiter,
  9056. // ForceDirectories, CreateDir, ChangeFileExt
  9057. //---------------------------------------------------------
  9058. function IncludeTrailingPathDelimiter(const S: string): string;
  9059. {* by Edward Aretino. Adds '\' to the end if it is not present. }
  9060. function ExcludeTrailingPathDelimiter(const S: string): string;
  9061. {* by Edward Aretino. Removes '\' at the end if it is present. }
  9062. function ForceDirectories(Dir: String): Boolean;
  9063. {* by Edward Aretino. Creates given directory if not present. All needed
  9064. subdirectories are created if necessary. }
  9065. function CreateDir(const Dir: string): Boolean;
  9066. {* by Edward Aretino. Creates given directory. }
  9067. function ChangeFileExt(FileName: String; const Extension: string): string;
  9068. {* by Edward Aretino. Changes file extention. }
  9069. function ExcludeTrailingChar( const S: String; C: Char ): String;
  9070. {* If S is finished with character C, it is excluded. }
  9071. function IncludeTrailingChar( const S: String; C: Char ): String;
  9072. {* If S is not finished with character C, it is added. }
  9073. function ExtractFilePath( const Path: String ) : String;
  9074. {* Returns only path part from exact path to file. }
  9075. function ExtractFileName( const Path: String ) : String;
  9076. {* Extracts file name from exact path to file. }
  9077. function ExtractFileNameWOext( const Path: String ) : String;
  9078. {* Extracts file name from path to file or from filename. }
  9079. function ExtractFileExt( const Path: String ) : String;
  9080. {* Extracts extention from file name (returns it with dot '.' first) }
  9081. function ReplaceFileExt( const Path, NewExt: String ): String;
  9082. {* Returns a path with extension replaced to a given one. }
  9083. function ExtractShortPathName( const Path: String ): String;
  9084. {* }
  9085. function FilePathShortened( const Path: String; MaxLen: Integer ): String;
  9086. {* Returns shortened file path to fit MaxLen characters. }
  9087. function FilePathShortenPixels( const Path: String; DC: HDC; MaxPixels: Integer ): String;
  9088. {* Returns shortened file path to fit MaxPixels for a given DC. If you pass
  9089. Canvas.Handle of any control or bitmap object, ensure that font is valid
  9090. for it (or call TCanvas.RequiredState( FontValid ) method before. If DC passed
  9091. = 0, call is equivalent to call FilePathShortened, and MaxPixels means in such
  9092. case maximum number of characters. }
  9093. function MinimizeName( const Path: String; DC: HDC; MaxPixels: Integer ): String;
  9094. {* Exactly the same as MinimizeName in FileCtrl.pas (VCL). }
  9095. function GetSystemDir: String;
  9096. {* Returns path to windows system directory. }
  9097. function GetWindowsDir : string;
  9098. {* Returns path to Windows directory. }
  9099. function GetWorkDir : string;
  9100. {* Returns path to application's working directory. }
  9101. function GetTempDir : string;
  9102. {* Returns path to default temp folder (directory to place temporary files). }
  9103. function CreateTempFile( const DirPath, Prefix: String ): String;
  9104. {* Returns path to just created temporary file. }
  9105. function GetFileListStr(FPath{e.g.'c:\tmp\'}, FMask{e.g.'*.*'}: string): string;
  9106. {* List of files in string, separating each path from others with semicolon (';').
  9107. E.g.: 'c:\tmp\unit1.dcu;c:\tmp\unit1.~pa' (for use with DeleteFile2Recycle())}
  9108. function DeleteFiles( const DirPath: String ): Boolean;
  9109. {* Deletes files by file mask (given with wildcards '*' and '?'). }
  9110. function DeleteFile2Recycle( const Filename : String ) : Boolean;
  9111. {* Deletes file to recycle bin. This operation can be very slow, when
  9112. called for a single file. To delete group of files at once (fast),
  9113. pass a list of paths to files to be deleted, separating each path
  9114. from others with semicolon (';'). E.g.: 'unit1.dcu;unit1.~pa'
  9115. |<br>
  9116. FALSE is returned only in case when at least one file was not deleted
  9117. successfully.
  9118. |<br>
  9119. Note, that files are deleted not to recycle bin, if wildcards are
  9120. used or not fully qualified paths to files. }
  9121. function CopyMoveFiles( const FromList, ToList: String; Move: Boolean ): Boolean;
  9122. {* }
  9123. {-}
  9124. function DiskFreeSpace( const Path: String ): I64; {+}
  9125. {* Returns disk free space in bytes. Pass a path to root directory,
  9126. e.g. 'C:\'.
  9127. |<hr>
  9128. <R Wrappers to registry API functions>
  9129. These functions can be used independently to simplify access to Windows
  9130. registry. }
  9131. //[Registry FUNCTIONS DECLARATIONS]
  9132. {++}(*
  9133. function RegSetValueEx(hKey: HKEY; lpValueName: PChar;
  9134. Reserved: DWORD; dwType: DWORD; lpData: Pointer; cbData: DWORD): Longint; stdcall;
  9135. *){--}
  9136. function RegKeyOpenRead( Key: HKey; const SubKey: String ): HKey;
  9137. {* Opens registry key for read operations (including enumerating of subkeys).
  9138. Pass either handle of opened earlier key or one of constans
  9139. HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS
  9140. as a first parameter. If not successful, 0 is returned. }
  9141. function RegKeyOpenWrite( Key: HKey; const SubKey: String ): HKey;
  9142. {* Opens registry key for write operations (including adding new values or
  9143. subkeys), as well as for read operations too. See also RegKeyOpenRead. }
  9144. function RegKeyOpenCreate( Key: HKey; const SubKey: String ): HKey;
  9145. {* Creates and opens key. }
  9146. function RegKeyGetStr( Key: HKey; const ValueName: String ): String;
  9147. {* Reads key, which must have type REG_SZ (null-terminated string). If
  9148. not successful, empty string is returned. This function as well as all
  9149. other registry manipulation functions, does nothing, if Key passed is 0
  9150. (without producing any error). }
  9151. function RegKeyGetStrEx( Key: HKey; const ValueName: String ): String;
  9152. {* Like RegKeyGetStr, but accepts REG_EXPAND_SZ type, expanding all
  9153. environment variables in resulting string.
  9154. |<br>
  9155. Code provided by neuron, e-mailto:neuron@hollowtube.mine.nu }
  9156. function RegKeyGetDw( Key: HKey; const ValueName: String ): DWORD;
  9157. {* Reads key value, which must have type REG_DWORD. If ValueName passed
  9158. is '' (empty string), unnamed (default) value is reading. If not
  9159. successful, 0 is returned. }
  9160. function RegKeySetStr(Key: HKey; const ValueName: String; const Value: String ): Boolean;
  9161. {* Writes new key value as null-terminated string (type REG_SZ). If not
  9162. successful, returns False. }
  9163. function RegKeySetStrEx( Key: HKey; const ValueName: string; const Value: string;
  9164. expand: boolean): Boolean;
  9165. {* Writes new key value as REG_SZ or REG_EXPAND_SZ. - by neuron, e-mailto:neuron@hollowtube.mine.nu }
  9166. function RegKeySetDw( Key: HKey; const ValueName: String; Value: DWORD ): Boolean;
  9167. {* Writes new key value as dword (with type REG_DWORD). Returns False,
  9168. if not successful. }
  9169. procedure RegKeyClose( Key: HKey );
  9170. {* Closes key, opened using RegKeyOpenRead or RegKeyOpenWrite. (But does
  9171. nothing, if Key passed is 0). }
  9172. function RegKeyDelete( Key: HKey; const SubKey: String ): Boolean;
  9173. {* Deletes key. Does nothing if key passed is 0 (returns FALSE). }
  9174. function RegKeyDeleteValue( Key: HKey; const SubKey: String ): Boolean;
  9175. {* Deletes value. - by neuron, e-mailto:neuron@hollowtube.mine.nu }
  9176. function RegKeyExists( Key: HKey; const SubKey: String ): Boolean;
  9177. {* Returns TRUE, if given subkey exists under given Key. }
  9178. function RegKeyValExists( Key: HKey; const ValueName: String ): Boolean;
  9179. {* Returns TRUE, if given value exists under the Key.
  9180. }
  9181. function RegKeyValueSize( Key: HKey; const ValueName: String ): Integer;
  9182. {* Returns a size of value. This is a size of buffer needed to store
  9183. registry key value. For string value, size returned is equal to a
  9184. length of string plus 1 for terminated null character. }
  9185. function RegKeyGetBinary( Key: HKey; const ValueName: String; var Buffer; Count: Integer ): Integer;
  9186. {* Reads binary data from a registry, writing it to the Buffer.
  9187. It is supposed that size of Buffer provided is at least Count bytes.
  9188. Returned value is actul count of bytes read from the registry and written
  9189. to the Buffer.
  9190. |<br>
  9191. This function can be used to get data of any type from the registry, not
  9192. only REG_BINARY. }
  9193. function RegKeySetBinary( Key: HKey; const ValueName: String; const Buffer; Count: Integer ): Boolean;
  9194. {* Stores binary data in the registry. }
  9195. function RegKeyGetDateTime(Key: HKey; const ValueName: String): TDateTime;
  9196. {* Returns datetime variable stored in registry in binary format. }
  9197. function RegKeySetDateTime(Key: HKey; const ValueName: String; DateTime: TDateTime): Boolean;
  9198. {* Stores DateTime variable in the registry. }
  9199. //-------------------------------------------------------
  9200. // registry functions by Valerian Luft <luft@valerian.de>
  9201. //-------------------------------------------------------
  9202. function RegKeyGetSubKeys( const Key: HKEY; List: PStrList): Boolean;
  9203. {* The function enumerates subkeys of the specified open registry key.
  9204. True is returned, if successful.
  9205. }
  9206. function RegKeyGetValueNames(const Key: HKEY; List: PStrList): Boolean;
  9207. {* The function enumerates value names of the specified open registry key.
  9208. True is returned, if successful.
  9209. }
  9210. function RegKeyGetValueTyp (const Key:HKEY; const ValueName: String) : DWORD;
  9211. {* The function receives the type of data stored in the specified value.
  9212. |<br>
  9213. If the function fails, the return value is the Key value.
  9214. |<br>
  9215. If the function succeeds, the return value return will be one of the following:
  9216. |<br>
  9217. REG_BINARY , REG_DWORD, REG_DWORD_LITTLE_ENDIAN,
  9218. REG_DWORD_BIG_ENDIAN, REG_EXPAND_SZ, REG_LINK , REG_MULTI_SZ,
  9219. REG_NONE, REG_RESOURCE_LIST, REG_SZ
  9220. |<hr>
  9221. <R Data sorting (quicksort implementation)>
  9222. This part contains implementation of 'quick sort' algorithm,
  9223. based on following code:
  9224. |<pre>
  9225. | TQSort by Mike Junkin 10/19/95.
  9226. | DoQSort routine adapted from Peter Szymiczek's QSort procedure which
  9227. | was presented in issue#8 of The Unofficial Delphi Newsletter.
  9228. | TQSort changed by Vladimir Kladov (Mr.Bonanzas) to allow 32-bit
  9229. | sorting (of big arrays with more than 64K elements).
  9230. |</pre>
  9231. Finally, this sort procedure is adapted to XCL (and then to KOL)
  9232. requirements (no references to SysUtils, Classes etc. TQSort object
  9233. is transferred to a single procedure call and DoQSort method is
  9234. renamed to SortData - which is a regular procedure now). }
  9235. //[Sorting TYPES]
  9236. type
  9237. TCompareEvent = function (const Data: Pointer; const e1,e2 : Dword) : Integer;
  9238. {* Event type to define comparison function between two elements of an array.
  9239. This event handler must return -1 or +1 (correspondently for cases e1<e2
  9240. and e2>e2). Items are enumerated from 0 to uNElem. }
  9241. TSwapEvent = procedure (const Data : Pointer; const e1,e2 : Dword);
  9242. {* Event type to define swap procedure which is swapping two elements of an
  9243. array. }
  9244. //[SortData FUNCTIONS DECLARATIONS]
  9245. procedure SortData( const Data: Pointer; const uNElem: Dword;
  9246. const CompareFun: TCompareEvent;
  9247. const SwapProc: TSwapEvent );
  9248. {* Call it to sort any array of data of any kind, passing total
  9249. number of items in an array and two defined (regular) function
  9250. and procedure to perform custom compare and swap operations.
  9251. First procedure parameter is to pass it to callback function
  9252. CompareFun and procedure SwapProc. Items are enumerated from
  9253. 0 to uNElem-1. }
  9254. procedure SortIntegerArray( var A : array of Integer );
  9255. {* procedure to sort array of integers. }
  9256. procedure SortDwordArray( var A : array of DWORD );
  9257. {* Procedure to sort array of unsigned 32-bit integers.
  9258. |<hr>
  9259. }
  9260. { -- directory list object -- }
  9261. //[DirList Object]
  9262. type
  9263. TDirItemAction = ( diSkip, diAccept, diCancel );
  9264. TOnDirItem = procedure( Sender: PObj; var DirItem: TWin32FindData; var Accept: TDirItemAction )
  9265. of object;
  9266. TSortDirRules = ( sdrNone, sdrFoldersFirst, sdrCaseSensitive, sdrByName, sdrByExt,
  9267. sdrBySize, sdrBySizeDescending, sdrByDateCreate, sdrByDateChanged,
  9268. sdrByDateAccessed );
  9269. {* List of rules (options) to sort directories. Rules are passed to Sort
  9270. method in an array, and first placed rules are applied first. }
  9271. {++}(*TDirList = class;*){--}
  9272. PDirList = {-}^{+}TDirList;
  9273. { ----------------------------------------------------------------------
  9274. TDirList - Directory scanning
  9275. ----------------------------------------------------------------------- }
  9276. //[TDirList DEFINITION]
  9277. TDirList = object( TObj )
  9278. {* Allows easy directory scanning. This is not visual object, but
  9279. storage to simplify working with directory content. }
  9280. protected
  9281. FList : PList;
  9282. FPath: string;
  9283. fFilters: PStrList;
  9284. fOnItem: TOnDirItem;
  9285. function Get(Idx: Integer): PWin32FindData;
  9286. function GetCount: Integer;
  9287. function GetNames(Idx: Integer): string;
  9288. function GetIsDirectory(Idx: Integer): Boolean;
  9289. protected
  9290. function SatisfyFilter( FileName : PChar; FileAttr, FindAttr : DWord ) : Boolean;
  9291. {++}(*public*){--}
  9292. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9293. {* Destructor. As usual, call Free method to destroy an object. }
  9294. public
  9295. property Items[ Idx : Integer ] : PWin32FindData read Get; default;
  9296. {* Full access to scanned items (files and subdirectories). }
  9297. property IsDirectory[ Idx: Integer ]: Boolean read GetIsDirectory;
  9298. {* Returns TRUE, if specified item represents a directory, not a file. }
  9299. property Count : Integer read GetCount;
  9300. {* Number of items. }
  9301. property Names[ Idx : Integer ] : string read GetNames;
  9302. {* Full long names of directory items. }
  9303. property Path : string read FPath;
  9304. {* Path of scanned directory. }
  9305. procedure Clear;
  9306. {* Call it to clear list of files. }
  9307. procedure ScanDirectory( const DirPath, Filter : String; Attr : DWord );
  9308. {* Call it to rescan directory or to scan another directory content
  9309. (method Clear is called first). Pass path to directory, file filter
  9310. and attributes to scan directory immediately.
  9311. |<br>&nbsp;&nbsp;&nbsp;
  9312. Note: Pass FILE_ATTRIBUTE_... constants or-combination as Attr
  9313. parameter. If 0 passed, both files and directories are listed. }
  9314. procedure ScanDirectoryEx( const DirPath, Filters : String; Attr : DWord );
  9315. {* Call it to rescan directory or to scan another directory content
  9316. (method Clear is called first). Pass path to directory, file filter
  9317. and attributes to scan directory immediately.
  9318. |<br>&nbsp;&nbsp;&nbsp;
  9319. Note: Pass FILE_ATTRIBUTE_... constants or-combination as Attr
  9320. parameter. }
  9321. procedure Sort( Rules : array of TSortDirRules );
  9322. {* Sorts directory entries. If empty rules array passed, default rules
  9323. array DefSortDirRules is used. }
  9324. function FileList( const Separator {e.g.: ';', or #13}: String;
  9325. Dirs, FullPaths: Boolean ): String;
  9326. {* Returns a string containing all names separated with Separator.
  9327. If Dirs=FALSE, only files are returned. }
  9328. property OnItem: TOnDirItem read fOnItem write fOnItem;
  9329. {* This event is called on reading each item while scanning directory.
  9330. To use it, first create PDirList object with empty path to scan, then
  9331. assign OnItem event and call ScanDirectory with correct path. }
  9332. end;
  9333. //[END OF TDirList DEFINITION]
  9334. //[NewDirList DECLARATIONS]
  9335. function NewDirList( const DirPath, Filter: String; Attr: DWORD ): PDirList;
  9336. {* Creates directory list object using easy one-string filter. If Attr = FILE_ATTRIBUTE_NORMAL,
  9337. only files are scanned without directories. If Attr = 0, both files and
  9338. directories are listed. }
  9339. function NewDirListEx( const DirPath, Filters: String; Attr: DWORD ): PDirList;
  9340. {* Creates directory list object using several filters, separated by ';'.
  9341. Filters starting from '^' consider to be anti-filters, i.e. files,
  9342. satisfying to those masks, are skept during scanning. }
  9343. const DefSortDirRules : array[ 0..3 ] of TSortDirRules = ( sdrFoldersFirst,
  9344. sdrByName, sdrBySize, sdrByDateCreate );
  9345. {* Default rules to sort directory entries. }
  9346. //[DirectorySize DECLARATION]
  9347. {-}
  9348. function DirectorySize( const Path: String ): I64;
  9349. {* Returns directory size in bytes as large 64 bit integer. }
  9350. {+}
  9351. //[OpenSaveDialog OPTIONS]
  9352. type
  9353. TOpenSaveOption = ( OSCreatePrompt,
  9354. OSExtensionDiffent,
  9355. OSFileMustExist,
  9356. OSHideReadonly,
  9357. OSNoChangedir,
  9358. OSNoReferenceLinks,
  9359. OSAllowMultiSelect,
  9360. OSNoNetworkButton,
  9361. OSNoReadonlyReturn,
  9362. OSOverwritePrompt,
  9363. OSPathMustExist,
  9364. OSReadonly,
  9365. OSNoValidate
  9366. //{$IFDEF OpenSaveDialog_Extended}
  9367. ,
  9368. OSTemplate,
  9369. OSHook
  9370. //{$ENDIF}
  9371. );
  9372. TOpenSaveOptions = set of TOpenSaveOption;
  9373. {* Options available for TOpenSaveDialog. }
  9374. {++}(*TOpenSaveDialog = class;*){--}
  9375. POpenSaveDialog = {-}^{+}TOpenSaveDialog;
  9376. { ----------------------------------------------------------------------
  9377. TOpenSaveDialog
  9378. ----------------------------------------------------------------------- }
  9379. //[TOpenSaveDialog DEFINITION]
  9380. TOpenSaveDialog = object( TObj )
  9381. {* Object to show standard Open/Save dialog. Initially provided
  9382. for XCL by Carlo Kok. }
  9383. protected
  9384. FFilter : String;
  9385. fFilterIndex : Integer;
  9386. fOpenDialog : Boolean;
  9387. FInitialDir : String;
  9388. FDefExtension : String;
  9389. FFilename : string;
  9390. FTitle : string;
  9391. FOptions : TOpenSaveOptions;
  9392. fWnd: THandle;
  9393. public
  9394. {$IFDEF OpenSaveDialog_Extended}
  9395. TemplateName: String;
  9396. HookProc: Pointer;
  9397. {$ENDIF}
  9398. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9399. {* destructor }
  9400. Function Execute : Boolean;
  9401. {* Call it after creating to perform selecting of file by user. }
  9402. property Filename : String read FFilename write FFileName;
  9403. {*
  9404. Filename is seperated by #13 when multiselect is true and the first
  9405. file, is the path of the files selected.
  9406. |<pre>
  9407. | C:\Projects
  9408. | Test1.Dpr
  9409. | Test2.Dpr
  9410. |</pre>
  9411. If only one file is selected, it is provided as (e.g.)
  9412. C:\Projects\Test1.dpr
  9413. |<br> For case when OSAllowMultiselect option used, after each
  9414. call initial value for a Filename containing several files prevents
  9415. system from opening the dialog. To fix this, assign another initial
  9416. value to Filename property in your code, when you use multiselect.
  9417. }
  9418. property InitialDir : string read FInitialDir write FInitialDir;
  9419. {* Initial directory path. If not set, current directory (usually
  9420. directory when program is started) is used. }
  9421. property Filter : String read FFilter write FFilter;
  9422. {* A list of pairs of filter names and filter masks, separated with '|'.
  9423. If a mask contains more than one mask, it should be separated with ';'.
  9424. E.g.:
  9425. ! 'All files|*.*|Text files|*.txt;*.1st;*.diz' }
  9426. property FilterIndex : Integer read FFilterIndex write FFilterIndex;
  9427. {* Index of default filter mask (0 by default, which means "first"). }
  9428. property OpenDialog : Boolean read FOpenDialog write FOpenDialog;
  9429. {* True, if "Open" dialog. False, if "Save" dialog. True is default. }
  9430. property Title : String read Ftitle write Ftitle;
  9431. {* Title for dialog. }
  9432. property Options : TOpenSaveOptions read FOptions write FOptions;
  9433. {* Options. }
  9434. property DefExtension : String read FDefExtension write FDefExtension;
  9435. {* Default extention. Set it to desired extension without leading period,
  9436. e.g. 'txt', but not '.txt'. }
  9437. property WndOwner: THandle read fWnd write fWnd;
  9438. {* Owner window handle. If not assigned, Applet.Handle is used (whenever
  9439. possible). Assign it, if your application has stay-on-top forms, and
  9440. a separate Applet object is used. }
  9441. end;
  9442. //[END OF TOpenSaveDialog DEFINITION]
  9443. //[Default OpenSaveDialog OPTIONS]
  9444. const DefOpenSaveDlgOptions: TOpenSaveOptions = [ OSHideReadonly,
  9445. OSOverwritePrompt, OSFileMustExist, OSPathMustExist ];
  9446. //[NewOpenSaveDialog DECLARATION]
  9447. function NewOpenSaveDialog( const Title, StrtDir: String;
  9448. Options: TOpenSaveOptions ): POpenSaveDialog;
  9449. {* Creates object, which can be used (several times) to open file(s)
  9450. selecting dialog. }
  9451. //[OpenDirectory Object]
  9452. type
  9453. {++}(*TOpenDirDialog = class;*){--}
  9454. POpenDirDialog = {-}^{+}TOpenDirDialog;
  9455. TOpenDirOption = ( odBrowseForComputer, odBrowseForPrinter, odDontGoBelowDomain,
  9456. odOnlyFileSystemAncestors, odOnlySystemDirs, odStatusText,
  9457. odBrowseIncludeFiles, odEditBox, odNewDialogStyle );
  9458. {* Flags available for TOpenDirDialog object. }
  9459. // odfStatusText - do not support status callback
  9460. TOpenDirOptions = set of TOpenDirOption;
  9461. {* Set of all flags used to control ZOpenDirDialog class. }
  9462. TOnODSelChange = procedure( Sender: POpenDirDialog; NewSelDir: PChar;
  9463. var EnableOK: Integer; var StatusText: String )
  9464. of object;
  9465. {* Event type to be called when user select another directory in OpenDirDialog.
  9466. Set EnableOK to -1 to disable OK button, or to +1 to enable it.
  9467. It is also possible to set new StatusText string. }
  9468. { ----------------------------------------------------------------------
  9469. TOpenDirDialog
  9470. ----------------------------------------------------------------------- }
  9471. //[TOpenDirDialog DEFINITION]
  9472. TOpenDirDialog = object( TObj )
  9473. {* Dialog for open directories, uses SHBrowseForFolder. }
  9474. protected
  9475. FTitle: String;
  9476. FOptions: TOpenDirOptions;
  9477. FCallBack: Pointer;
  9478. FCenterProc: procedure( Wnd: HWnd );
  9479. FBuf : array[ 0..MAX_PATH ] of Char;
  9480. FInitialPath: String;
  9481. FCenterOnScreen: Boolean;
  9482. FDoSelChanged: procedure( Wnd: HWnd; Msg: DWORD; lParam, lpData: LParam ); stdcall;
  9483. FOnSelChanged: TOnODSelChange;
  9484. FStatusText: String;
  9485. FWnd: HWnd;
  9486. function GetPath: String;
  9487. procedure SetInitialPath(const Value: String);
  9488. procedure SetCenterOnScreen(const Value: Boolean);
  9489. procedure SetOnSelChanged(const Value: TOnODSelChange);
  9490. function GetInitialPath: String;
  9491. public
  9492. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9493. {* destructor }
  9494. function Execute : Boolean;
  9495. {* Call it to select directory by user. Returns True, if operation was
  9496. not cancelled by user. }
  9497. property Title : String read FTitle write FTitle;
  9498. {* Title for a dialog. }
  9499. property Options : TOpenDirOptions read FOptions write FOptions;
  9500. {* Option flags. }
  9501. property Path : String read GetPath;
  9502. {* Resulting (selected by user) path. }
  9503. property InitialPath: String read GetInitialPath write SetInitialPath;
  9504. {* Set this property to a path of directory to be selected initially
  9505. in a dialog. }
  9506. property CenterOnScreen: Boolean read FCenterOnScreen write SetCenterOnScreen;
  9507. {* Set it to True to center dialog on screen. }
  9508. property OnSelChanged: TOnODSelChange read FOnSelChanged write SetOnSelChanged;
  9509. {* This event is called every time, when user selects another directory.
  9510. It is possible to eneble/disable OK button in dialog and/or change
  9511. dialog status text in responce to event. }
  9512. property WndOwner: HWnd read FWnd write FWnd;
  9513. {* Owner window. If you want to provide your dialog visible over stay-on-top
  9514. form, fire it as a child of the form, assigning the handle of form window
  9515. to this property first. }
  9516. end;
  9517. //[END OF TOpenDirDialog DEFINITION]
  9518. //[NewOpenSaveDialog DECLARATION]
  9519. function NewOpenDirDialog( const Title: String; Options: TOpenDirOptions ):
  9520. POpenDirDialog;
  9521. {* Creates object, which can be used (several times) to open directory
  9522. selecting dialog (using SHBrowseForFolder API call). }
  9523. //[Color Dialog Object]
  9524. type
  9525. TColorCustomOption = ( ccoFullOpen, ccoShortOpen, ccoPreventFullOpen );
  9526. {++}(*TColorDialog = class;*){--}
  9527. PColorDialog = {-}^{+}TColorDialog;
  9528. { ----------------------------------------------------------------------
  9529. TColorDialog
  9530. ----------------------------------------------------------------------- }
  9531. //[TColorDialog DEFINITION]
  9532. TColorDialog = object( TObj )
  9533. {* Color choosing dialog. }
  9534. protected
  9535. public
  9536. OwnerWindow: HWnd;
  9537. {* Owner window (can be 0). }
  9538. CustomColors: array[ 1..16 ] of TColor;
  9539. {* Array of stored custom colors. }
  9540. ColorCustomOption: TColorCustomOption;
  9541. {* Options (how to open a dialog). }
  9542. Color: TColor;
  9543. {* Returned color (if the result of Execute is True). }
  9544. function Execute: Boolean;
  9545. {* Call this method to open a dialog and wait its result. }
  9546. end;
  9547. //[END OF TColorDialog DEFINITION]
  9548. //[NewColorDialog DECLARATION]
  9549. function NewColorDialog( FullOpen: TColorCustomOption ): PColorDialog;
  9550. {* Creates color choosing dialog object. }
  9551. //[Ini files]
  9552. type
  9553. TIniFileMode = ( ifmRead, ifmWrite );
  9554. {* ifmRead is default mode (means "read" data from ini-file.
  9555. Set mode to ifmWrite to write data to ini-file, correspondent to
  9556. TIniFile. }
  9557. {++}(*TIniFile = class;*){--}
  9558. PIniFile = {-}^{+}TIniFile;
  9559. { ----------------------------------------------------------------------
  9560. TIniFile - store/load data to ini-files
  9561. ----------------------------------------------------------------------- }
  9562. //[TIniFile DEFINITION]
  9563. TIniFile = object( TObj )
  9564. {* Ini file incapsulation. The main feature is what the same block of
  9565. read-write operations could be defined (difference must be only in
  9566. Mode value).
  9567. |*Ini file sample.
  9568. This sample shows how the same Pascal operators can be used both
  9569. for read and write for the same variables, when working with TIniFile:
  9570. ! procedure ReadWriteIni( Write: Boolean );
  9571. ! var Ini: PIniFile;
  9572. ! begin
  9573. ! Ini := OpenIniFile( 'MyIniFile.ini' );
  9574. ! Ini.Section := 'Main';
  9575. ! if Write then // if Write, the same operators will save
  9576. ! Ini.Mode := ifmWrite; // data rather then load.
  9577. ! MyForm.Left := Ini.ValueInteger( 'Left', MyForm.Left );
  9578. ! MyForm.Top := Ini.ValueInteger( 'Top', MyForm.Top );
  9579. ! Ini.Free;
  9580. ! end;
  9581. !
  9582. |* }
  9583. protected
  9584. fMode: TIniFileMode;
  9585. fFileName: String;
  9586. fSection: String;
  9587. protected
  9588. public
  9589. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9590. {* destructor }
  9591. property Mode: TIniFileMode read fMode write fMode;
  9592. {* ifmWrite, if write data to ini-file rather than read it. }
  9593. property FileName: String read fFileName;
  9594. {* Ini file name. }
  9595. property Section: String read fSection write fSection;
  9596. {* Current ini section. }
  9597. function ValueInteger( const Key: String; Value: Integer ): Integer;
  9598. {* Reads or writes integer data value. }
  9599. function ValueString( const Key: String; const Value: String ): String;
  9600. {* Reads or writes string data value. }
  9601. function ValueBoolean( const Key: String; Value: Boolean ): Boolean;
  9602. {* Reads or writes boolean data value. }
  9603. function ValueData( const Key: String; Value: Pointer; Count: Integer ): Boolean;
  9604. {* Reads or writes data from/to buffer. Returns True, if success. }
  9605. procedure ClearAll;
  9606. {* Clears all sections of ini-file. }
  9607. procedure ClearSection;
  9608. {* Clears current Section of ini-file. }
  9609. procedure ClearKey( const Key: String );
  9610. {* Clears given key in current section. }
  9611. /////////////// + by Vyacheslav A. Gavrik:
  9612. procedure GetSectionNames(Names:PStrList);
  9613. {* Retrieves section names, storing it in string list passed as a parameter.
  9614. String list does not cleared before processing. Section names are added
  9615. to the end of the string list. }
  9616. procedure SectionData(Names:PStrList);
  9617. {* Read/write current section content to/from string list. (Depending on
  9618. current Mode value). }
  9619. ///////////////
  9620. end;
  9621. //[END OF TIniFile DEFINITION]
  9622. //[OpenIniFile DECLARATION]
  9623. function OpenIniFile( const FileName: String ): PIniFile;
  9624. {* Opens ini file, creating TIniFile object instance to work with it. }
  9625. //[MENU OBJECT]
  9626. type
  9627. TMenuitemInfo = packed record
  9628. cbSize: UINT;
  9629. fMask: UINT;
  9630. fType: UINT; { used if MIIM_TYPE}
  9631. fState: UINT; { used if MIIM_STATE}
  9632. wID: UINT; { used if MIIM_ID}
  9633. hSubMenu: HMENU; { used if MIIM_SUBMENU}
  9634. hbmpChecked: HBITMAP; { used if MIIM_CHECKMARKS}
  9635. hbmpUnchecked: HBITMAP; { used if MIIM_CHECKMARKS}
  9636. dwItemData: DWORD; { used if MIIM_DATA}
  9637. dwTypeData: PAnsiChar; { used if MIIM_TYPE}
  9638. cch: UINT; { used if MIIM_TYPE}
  9639. hbmpItem: HBITMAP; { used if MIIM_BITMAP - not exists under Windows95 }
  9640. end;
  9641. type
  9642. {++}(*TMenu = class;*){--}
  9643. PMenu = {-}^{+}TMenu;
  9644. TOnMenuItem = procedure( Sender : PMenu; Item : Integer ) of object;
  9645. {* Event type to define OnMenuItem event. }
  9646. TMenuAccelerator = packed Record
  9647. {* Menu accelerator record. Use MakeAccelerator function to combine desired
  9648. attributes into a record, describing the accelerator. }
  9649. fVirt: Byte; // or-combination of FSHIFT, FCONTROL, FALT, FVIRTKEY, FNOINVERT
  9650. Key: Word; // character or virtual key code (FVIRTKEY flag is present above)
  9651. NotUsed: Byte; // not used
  9652. end;
  9653. // by Sergey Shisminzev:
  9654. TMenuOption = (moDefault, moDisabled, moChecked,
  9655. moCheckMark, moRadioMark, moSeparator, moBitmap, moSubMenu,
  9656. moBreak, moBarBreak);
  9657. {* Options to add menu items dynamically. }
  9658. TMenuOptions = set of TMenuOption;
  9659. {* Set of options for menu item to use it in TMenu.AddItem method. }
  9660. TMenuBreak = ( mbrNone, mbrBreak, mbrBarBreak );
  9661. {* Possible menu item break types. }
  9662. { ----------------------------------------------------------------------
  9663. TMenu - main, popup menu and menu item
  9664. ----------------------------------------------------------------------- }
  9665. //[TMenu DEFINITION]
  9666. TMenu = object( TObj )
  9667. {* Dynamic menu incapsulation object. Can play role of form main menu or popup
  9668. menu, depending on kind of parent window (form or control) and order of
  9669. creation (created first (for a form) become main menu). Does not allow
  9670. merging menus, but items can be hidden. Additionally checkmark bitmaps,
  9671. shortcut key accelerators and other features are available. }
  9672. protected
  9673. FHandle: HMenu;
  9674. FId: Integer;
  9675. FParent: PMenu;
  9676. FControl: PControl;
  9677. fNextMenu : PMenu;
  9678. FRadioGroup: Integer;
  9679. FIsCheckItem: Boolean;
  9680. FIsSeparator: Boolean;
  9681. FMenuBreak: TMenuBreak;
  9682. FItems: PList;
  9683. FOnMenuItem : TOnMenuItem;
  9684. FOnRadioOff : TOnMenuItem;
  9685. fOnPopup: TOnEvent;
  9686. fByAccel: Boolean;
  9687. FPopupFlags: DWORD;
  9688. //fAutoPopup: Boolean;
  9689. FVisible: Boolean;
  9690. FSavedState: DWORD;
  9691. FData: Pointer;
  9692. FOwnerDraw: Boolean;
  9693. FCaption: String;
  9694. FBitmap: HBitmap;
  9695. FBmpChecked: HBitmap;
  9696. FBmpItem: HBitmap;
  9697. ClearBitmapsProc: procedure( Sender: PMenu );
  9698. FClearBitmaps: Boolean;
  9699. FNotPopup: Boolean;
  9700. FAccelerator: TMenuAccelerator;
  9701. FHelpContext: Integer;
  9702. FOnMeasureItem: TOnMeasureItem;
  9703. FOnDrawItem: TOnDrawItem;
  9704. {$IFDEF USE_MENU_CURCTL}
  9705. fCurCtl: PControl;
  9706. {$ENDIF USE_MENU_CURCTL}
  9707. function GetItems( Id: HMenu ): PMenu;
  9708. function GetCount: Integer;
  9709. function GetTopParent: PMenu;
  9710. function GetState( const Index: Integer ): Boolean;
  9711. procedure SetState( const Index: Integer; Value: Boolean );
  9712. procedure SetVisible( Value: Boolean );
  9713. procedure SetData( Value: Pointer );
  9714. procedure SetMenuItemCaption( const Value: String );
  9715. function FillMenuItems(AHandle: HMenu; StartIdx: Integer;
  9716. const Template: array of PChar): Integer;
  9717. procedure SetMenuBreak( Value: TMenuBreak );
  9718. function GetControl: PControl;
  9719. function GetInfo( var MII: TMenuItemInfo ): Boolean;
  9720. function SetInfo( var MII: TMenuItemInfo ): Boolean;
  9721. function SetTypeInfo( var MII: TMenuItemInfo ): Boolean;
  9722. procedure SetBitmap( Value: HBitmap );
  9723. procedure SetBmpChecked( Value: HBitmap );
  9724. procedure SetBmpItem( Value: HBitmap );
  9725. procedure ClearBitmaps;
  9726. procedure SetAccelerator( const Value: TMenuAccelerator );
  9727. procedure SetHelpContext( Value: Integer );
  9728. procedure SetSubmenu( Value: HMenu );
  9729. procedure SetOnMeasureItem( const Value: TOnMeasureItem );
  9730. procedure SetOnDrawItem( const Value: TOnDrawItem );
  9731. procedure SetOwnerDraw( Value: Boolean );
  9732. protected
  9733. function GetItemChecked( Item : Integer ) : Boolean;
  9734. procedure SetItemChecked( Item : Integer; Value : Boolean );
  9735. function GetItemBitmap(Idx: Integer): HBitmap;
  9736. procedure SetItemBitmap(Idx: Integer; const Value: HBitmap);
  9737. function GetItemText(Idx: Integer): String;
  9738. procedure SetItemText(Idx: Integer; const Value: String);
  9739. function GetItemEnabled(Idx: Integer): Boolean;
  9740. procedure SetItemEnabled(Idx: Integer; const Value: Boolean);
  9741. function GetItemVisible(Idx: Integer): Boolean;
  9742. procedure SetItemVisible(Idx: Integer; const Value: Boolean);
  9743. function GetItemAccelerator(Idx: Integer): TMenuAccelerator;
  9744. procedure SetItemAccelerator(Idx: Integer; const Value: TMenuAccelerator);
  9745. function GetItemSubMenu( Idx: Integer ): HMenu;
  9746. public
  9747. destructor Destroy; {-}virtual;{+}{++}(*override;*){--}
  9748. {* To release menu dynamically, call Free method instead. All (popup)
  9749. menus created after this (for the same control) are destroyed in
  9750. that case too.
  9751. |<br>
  9752. It is not necessary to release menu object manually: all menus,
  9753. created with given form (or control), are automatically released,
  9754. when owner form (or control) is destroyed.
  9755. }
  9756. property Handle : HMenu read FHandle;
  9757. {* Handle of Windows menu object. }
  9758. property MenuId: Integer read FId;
  9759. {* Id of the menu item object. If menu item has subitems, it has
  9760. also submenu Handle. Top parent menu object itself has no Id.
  9761. Id-s areassigned automatically starting from 4096. Do not
  9762. (re)create menu items instantly, because such values are not
  9763. reused, and maximum possible Id value must not exceed 65535. }
  9764. property Parent: PMenu read FParent;
  9765. {* Parent menu item (or parent menu). }
  9766. property TopParent: PMenu read GetTopParent;
  9767. {* Top parent menu, owning all nested subitems. }
  9768. property Owner: PControl read GetControl;
  9769. {* Parent control or form. }
  9770. property Caption: String read FCaption write SetMenuItemCaption;
  9771. {* Menu item caption text (including '&' indicating mnemonic characters,
  9772. and keyboard accelerator representation string, usually following
  9773. tabulation character). }
  9774. property Items[ Id: HMenu ]: PMenu read GetItems;
  9775. {* Returns menu item object by its index or by menu id. Since menu id
  9776. values are starting from 4096, values from 0 to 4095 are interpreted
  9777. as absolute index of menu item. Be careful accessing menu items or
  9778. submenus by index, if you dynamically insert or delete items or
  9779. submenus. In this version, separators are enumerating too, like
  9780. all other items. Use index -1 to access object itself. The first
  9781. item of a menu (or the first subitem of submenu item) has index 0.
  9782. Children are enumerating before all siblings. The maximum available
  9783. index is (Count - 1), when accessing menu items by index. }
  9784. property Count: Integer read GetCount;
  9785. {* Count of items together with all its nested subitems. }
  9786. function IndexOf( Item: PMenu ): Integer;
  9787. {* Returns index of an item. This index can be used to access
  9788. menu item. Value -2 is returned, if the Item is not a child for menu
  9789. or menu item, and has no parents, which are children for it, etc.
  9790. Menu object itself always has index -1. }
  9791. property OnMenuItem : TOnMenuItem read FOnMenuItem write FOnMenuItem;
  9792. {* Is called when menu item is clicked. Absolute index of menu item
  9793. clicked is passed as the second parameter. TopParent always is
  9794. passed as a Sender parameter. }
  9795. property ByAccel: Boolean read fByAccel;
  9796. {* True, when OnMenuItem is called not by mouse, but by accelerator key.
  9797. Check this flag for entire menu (TopParent), not for item itself.
  9798. (Note, that Sender in OnMenuItem always is TopParent menu object). )
  9799. }
  9800. property IsSeparator: Boolean read FIsSeparator;
  9801. {* TRUE, if a separator menu item. }
  9802. property MenuBreak: TMenuBreak read FMenuBreak write SetMenuBreak;
  9803. {* Menu item break type. }
  9804. property OnUncheckRadioItem : TOnMenuItem read FOnRadioOff write FOnRadioOff;
  9805. {* Is called when radio item becomes unchecked in menu in result of
  9806. checking another radio item of the same radio group. }
  9807. property RadioGroup: Integer read FRadioGroup write FRadioGroup;
  9808. {* Radio group index. Several neighbour items with the same radio group
  9809. index form radio group. Only single item from the same group can be
  9810. checked at a time. }
  9811. property IsCheckItem: Boolean read FIsCheckItem;
  9812. {* If menu item is defined as check item, it is checked automatically
  9813. when clicked. }
  9814. procedure RadioCheckItem;
  9815. {* Call this method to check radio item. (Calling this method for
  9816. an item, which is not belonging to a radio group, just sets its
  9817. Checked state to TRUE). }
  9818. property Checked: Boolean index MFS_CHECKED read GetState write SetState;
  9819. {* Checked state of the item. }
  9820. property Enabled: Boolean
  9821. {$IFDEF F_P}
  9822. index $80000000 or MFS_DISABLED
  9823. {$ELSE DELPHI}
  9824. index Integer( $80000000 or MFS_DISABLED )
  9825. {$ENDIF F_P/DELPHI}
  9826. read GetState write SetState;
  9827. {* Enabled state of the item. Whaen assigned, Grayed state also is
  9828. set to arbitrary value (i.e., when Enabled is set to true, Grayed
  9829. is set to FALSE. }
  9830. property DefaultItem: Boolean index MFS_DEFAULT read GetState write SetState;
  9831. {* Set this property to TRUE to make menu item default. Default item
  9832. is drawn with bold.
  9833. |<br>If you change DefaultItem at run-time and whant
  9834. to provide changing its visual state, recreate the item first resetting
  9835. Visible property, then setting it again. }
  9836. property Highlight: Boolean index MFS_HILITE read GetState write SetState;
  9837. {* Highlight state of the item. }
  9838. property Visible: Boolean read FVisible write SetVisible;
  9839. {* Visibility of menu item. }
  9840. property Data: Pointer read FData write SetData;
  9841. {* Data pointer, associated with the menu item. }
  9842. property Bitmap: HBitmap read FBitmap write SetBitmap;
  9843. {* Bitmap used for unchecked state of the menu item. }
  9844. property BitmapChecked: HBitmap read FBmpChecked write SetBmpChecked;
  9845. {* Bitmap used for checked state of the menu item. }
  9846. property BitmapItem: HBitmap read FBmpItem write SetBmpItem;
  9847. {* Bitmap used for item itself. In addition, following special values
  9848. are possible:
  9849. HBMMENU_CALLBACK, HBMMENU_MBAR_CLOSE, HBMMENU_MBAR_CLOSE_D,
  9850. HBMMENU_MBAR_MINIMIZE, HBMMENU_MBAR_MINIMIZE_D, HBMMENU_MBAR_RESTORE,
  9851. HBMMENU_POPUP_CLOSE, HBMMENU_POPUP_MAXIMIZE, HBMMENU_POPUP_MINIMIZE,
  9852. HBMMENU_POPUP_RESTORE, HBMMENU_SYSTEM. }
  9853. property Accelerator: TMenuAccelerator read FAccelerator write SetAccelerator;
  9854. {* Accelerator for menu item. }
  9855. property HelpContext: Integer read FHelpContext write SetHelpContext;
  9856. {* Help context for entire menu (help context can not be assigned to
  9857. individual menu items). }
  9858. procedure AssignEvents( StartIdx: Integer; Events: array of TOnMenuItem );
  9859. {* It is possible to assign its own event handler to every menu item
  9860. using this call. This procedure also is called automatically in
  9861. a constructor NewMenuEx. }
  9862. function Popup( X, Y : Integer ): Integer; {!ecm}
  9863. {* Only for popup menu - to popup it at the given position on screen.
  9864. Return: If you specify TPM_RETURNCMD in the uFlags parameter, the return
  9865. value is the menu-item identifier of the item that the user selected.
  9866. If the user cancels the menu without making a selection, or if an error
  9867. occurs, then the return value is zero.
  9868. If you do not specify TPM_RETURNCMD in the uFlags parameter, the return
  9869. value is nonzero if the function succeeds and zero if it fails. }
  9870. function PopupEx( X, Y: Integer ): Integer; {!ecm}
  9871. {* This version of popup command is very useful, when popup menu is activated
  9872. when its parent window is not visible (e.g., for a kind of applications,
  9873. which always are invisible, and can be activated only using tray icon).
  9874. PopupEx method provides correct tracking of menu disappearing when mouse
  9875. is clicked anywhere else on screen, fixing strange menu behavior in some
  9876. Windows versions (NT).
  9877. |<br>
  9878. Actually, when PopupEx used, parent form is shown but below of visible
  9879. screen, and when menu is disappearing, previous state of the form (visibility
  9880. and position) are restored. If such solvation is not satisfying You,
  9881. You can do something else (e.g., use region clipping, etc.) }
  9882. property OnPopup: TOnEvent read fOnPopup write fOnPopup;
  9883. {* This event occurs before the popup menu is shown. }
  9884. property NotPopup: Boolean read FNotPopup write FNotPopup;
  9885. {* Set this property to true to prevent popup of popup menu, e.g. in
  9886. OnPopup event handler. }
  9887. property Flags: DWORD read FPopupFlags write FPopupFlags;
  9888. {* Pop-up flags, which are used to call TrackPopupMenuEx, when Popup or
  9889. PopupEx method is called. Can be a combination of following values:
  9890. |<br>
  9891. TPM_CENTERALIGN or TPM_LEFTALIGN or TPM_RIGHTALIGN
  9892. |<br>
  9893. TPM_BOTTOMALIGN or TPM_TOPALIGN or TPM_VCENTERALIGN
  9894. |<br>
  9895. TPM_NONOTIFY or TPM_RETURNCMD
  9896. |<br>
  9897. TPM_LEFTBUTTON or TPM_RIGHTBUTTON
  9898. |<br>
  9899. TPM_HORNEGANIMATION or TPM_HORPOSANIMATION or TPM_NOANIMATION or
  9900. TPM_VERNEGANIMATION or TPM_VERPOSANIMATION
  9901. |<br>
  9902. TPM_HORIZONTAL or TPM_VERTICAL.
  9903. |<br>
  9904. By default, a combination TPM_LEFTALIGN or TPM_LEFTBUTTON is used. }
  9905. function Insert(InsertBefore: Integer; ACaption: PChar; Event: TOnMenuItem;
  9906. Options: TMenuOptions): PMenu;
  9907. {* Inserts new menu item before item, given by Id (>=4096) or index
  9908. value InsertBefore. Pointer to an object created is returned. }
  9909. property SubMenu: HMenu read FHandle; // write SetSubMenu;
  9910. {* Submenu associated with the menu item. The same as Handle. It was possible
  9911. in ealier versions to change this value, replacing (removing, assigning)
  9912. entire popup menu as a submenu for menu item.
  9913. But in modern version of TMenu, this is not possible.
  9914. Instead, entire menu object should be added or removed using
  9915. InsertSubmenu or RemoveSubmenu methods. }
  9916. procedure InsertSubMenu( SubMenuToInsert: PMenu; InsertBefore: Integer );
  9917. {* Inserts existing menu item (together with its subitems if any present)
  9918. into given position. See also RemoveSubMenu. }
  9919. function RemoveSubMenu( ItemToRemove: Integer ): PMenu;
  9920. {* Removes menu item from the menu, returning TMenu object, representing it,
  9921. if submenu item, having its own children, detached. If an individual menu
  9922. item is removed, nil is returned.
  9923. This function can be useful to add or remove dynamically entire submenus
  9924. (created together with its subitems). }
  9925. property OnMeasureItem: TOnMeasureItem read FOnMeasureItem write SetOnMeasureItem;
  9926. {* This event is called for owner-drawn menu items. Event handler should return
  9927. menu item height in lower word of a result and item width (for menu) in
  9928. high word of result. If either for height or for width returned value is 0,
  9929. a default one is used. }
  9930. property OnDrawItem: TOnDrawItem read FOnDrawItem write SetOnDrawItem;
  9931. {* This event is called for owner-drawn menu items. }
  9932. property OwnerDraw: Boolean read FOwnerDraw write SetOwnerDraw;
  9933. {* Set this property to true for some items to make it owner-draw. }
  9934. // For compatibility with old code (be sure that item with given index
  9935. // actually exists):
  9936. function GetMenuItemHandle( Idx : Integer ): DWORD;
  9937. {* Returns Id of menu item with given index. }
  9938. property ItemHandle[ Idx: Integer ]: DWORD read GetMenuItemHandle;
  9939. {* Returns handle for item given by index. }
  9940. property ItemChecked[ Idx : Integer ] : Boolean read GetItemChecked write SetItemChecked;
  9941. {* True, if correspondent menu item is checked. }
  9942. procedure RadioCheck( Idx : Integer );
  9943. {* Call this method to check radio item. For radio items, do not
  9944. use assignment to ItemChecked or Checked properties. }
  9945. property ItemBitmap[ Idx: Integer ]: HBitmap read GetItemBitmap write SetItemBitmap;
  9946. {* This property allows to assign bitmap to menu item (for unchecked state
  9947. only - for checked menu items default checkmark bitmap is used). }
  9948. procedure AssignBitmaps( StartIdx: Integer; Bitmaps: array of HBitmap );
  9949. {* Can be used to assign bitmaps to several menu items during one call. }
  9950. property ItemText[ Idx: Integer ]: String read GetItemText write SetItemText;
  9951. {* This property allows to get / modify menu item text at run time. }
  9952. property ItemEnabled[ Idx: Integer ]: Boolean read GetItemEnabled write SetItemEnabled;
  9953. {* Controls enabling / disabling menu items. Disabled menu items are
  9954. displayed (grayed) but inaccessible to click. }
  9955. property ItemVisible[ Idx: Integer ]: Boolean read GetItemVisible write SetItemVisible;
  9956. {* This property allows to simulate visibility of menu items (implementing
  9957. it by removing or inserting again if needed. For items of submenu, which
  9958. is made invisible, True is returned. If such item made Visible, entire
  9959. submenu with all its parent menu items becomes visible. To release menu
  9960. properly it is necessary to make before all its items visible again.
  9961. This does not matter, if menu is released at the end of execution, but
  9962. can be sensible if owner form is destroyed and re-created at run time
  9963. dynamically. }
  9964. function ParentItem( Idx: Integer ): Integer;
  9965. {* Returns index of parent menu item (for submenu item). If there are no
  9966. such item (Idx corresponds to root level menu item), -1 is returned. }
  9967. property ItemAccelerator[ Idx: Integer ]: TMenuAccelerator read GetItemAccelerator write SetItemAccelerator;
  9968. {* Allows to get / change accelerator key kodes assigned to menu items.
  9969. Has no effect unless SupportMnemonics called for a form. }
  9970. property ItemSubmenu[ Idx: Integer ]: HMenu read GetItemSubmenu; // write SetItemSubmenu;
  9971. {* Retrieves submenu item dynamically. See also SubMenu property. }
  9972. // by Sergey Shisminzev:
  9973. function AddItem(ACaption: PChar; Event: TOnMenuItem; Options: TMenuOptions): Integer;
  9974. {* Adds menu item dynamically. Returns ID of the added item. }
  9975. function InsertItem(InsertBefore: Integer; ACaption: PChar; Event: TOnMenuItem; Options: TMenuOptions): Integer;
  9976. {* Inserts menu item before an item with ID, given by InsertBefore parameter. }
  9977. function InsertItemEx(InsertBefore: Integer; ACaption: PChar; Event: TOnMenuItem; Options: TMenuOptions;
  9978. ByPosition: Boolean): Integer;
  9979. {* Inserts menu item by command or by position, dependant on ByPosition parameter }
  9980. procedure RedrawFormMenuBar;
  9981. {* }
  9982. {$IFDEF USE_MENU_CURCTL}
  9983. property CurCtl: PControl read fCurCtl;
  9984. {* By Alexander Pravdin. This property is assigned to a control which were
  9985. initiated a pop-up, for popup menu. }
  9986. {$ENDIF USE_MENU_CURCTL}
  9987. end;
  9988. //[END OF TMenu DEFINITION]
  9989. //[MenuStructSize VARIABLE]
  9990. function MenuStructSize: Integer;
  9991. {* Returns 44 under Windows95, and 48 (=sizeof(TMenuItemInfo) under all other
  9992. Windows versions. }
  9993. //[NewMenu DECLARATION]
  9994. function NewMenu( AParent : PControl; MaxCmdReserve: DWORD; const Template : array of PChar;
  9995. aOnMenuItem: TOnMenuItem ): PMenu;
  9996. {* Menu constructor. First created menu becomes main menu of form (if AParent
  9997. is a form). All other menus becomes popup (can be activated using Popup
  9998. method). To provide dynamic replacing of main menu, create all popup
  9999. menus as children of any other control, not form itself.
  10000. When Menu is created, pass FirstCmd integer value to set it
  10001. as ID of first menu item (all other ID's obtained by incrementing this value),
  10002. and Template, which is an array of PChar (usually array of string constants),
  10003. containing list of menu item identifiers and/or formatting characters.
  10004. |<br>&nbsp;&nbsp;&nbsp;
  10005. FirstCmd value is assigned to first menu item created as its ID,
  10006. all follow menu items are assigned to ID's obtained from FirstCmd incrementing
  10007. it by 1. It is desirable to provide not intersected ranges of ID's for
  10008. defferent menus in the applet.
  10009. |<br>&nbsp;&nbsp;&nbsp;
  10010. Following formatting characters can be used in menu template strings:
  10011. |&L=<br><b>%1</b>
  10012. <L &amp; (in identifier)> - to underline next character and use it as a shortcut character
  10013. when possible;
  10014. <L + (in front of identifier)> - to make item checked. If also
  10015. |<b>!</b> is used before <b>
  10016. &
  10017. |</b> than radioitem is defined;
  10018. <L - (in front of identifier)> - item not checked;
  10019. <L - (separate)> - separator (between two items);
  10020. <L ( (separate)> - start of submenu;
  10021. <L ) (separate)> - end of submenu;
  10022. |<br>&nbsp;&nbsp;&nbsp;
  10023. To get access to menu items, use constants 0, 1, etc. It is a good idea
  10024. to create special enumerated type to index correspondent menu items
  10025. using Ord( ) operator. Note in that case, that it is necessary only to
  10026. define constants correspondent to identifiers (positions, correspondent
  10027. to separators or submenu brackets are not identified by numbers).
  10028. |<br>&nbsp;&nbsp;&nbsp;
  10029. }
  10030. function NewMenuEx( AParent : PControl; FirstCmd : Integer; const Template : array of PChar;
  10031. aOnMenuItems: array of TOnMenuItem ): PMenu;
  10032. {* Creates menu, assigning its own event handler for every (enough) menu item. }
  10033. //[MakeAccelerator DECLARATION]
  10034. function MakeAccelerator( fVirt: Byte; Key: Word ): TMenuAccelerator;
  10035. {* Creates accelerator item to assign it to TMenu.ItemAccelerator[ ] property
  10036. easy.}
  10037. //[GetAcceleratorText DECLARATION]
  10038. // {YS} added 7 Aug 2004
  10039. function GetAcceleratorText( const Accelerator: TMenuAccelerator ): string;
  10040. {* Returns text representation of accelerator. }
  10041. {|<hr>
  10042. <R System functions and working with windows>
  10043. }
  10044. //[Window FUNCTIONS DECLARATIONS]
  10045. type
  10046. TWindowChildKind = ( wcActive, wcFocus, wcCapture, wcMenuOwner,
  10047. wcMoveSize, wcCaret );
  10048. {* Type of window child kind. Used in function GetWindowChild. }
  10049. function GetWindowChild( Wnd: HWnd; Kind: TWindowChildKind ): HWnd;
  10050. {* Returns child of given top-level window, having given characteristics.
  10051. For example, it is possible to get know for foreground window,
  10052. which of its child window has focus. This function does not work in old
  10053. Windows 95 (returns Wnd in that case). But for Windows 98, Windows NT/2000
  10054. this function works fine. To obtain focused child of the window,
  10055. use GetFocusedWindow, which is independant from Windows version. }
  10056. function GetFocusedChild( Wnd: HWnd ): HWnd;
  10057. {* Returns focused child of given window (which should be foreground
  10058. and active, certainly). 0 is returned either if Wnd is not active
  10059. or Wnd has no focused child window. }
  10060. function Stroke2Window( Wnd: HWnd; const S: String ): Boolean;
  10061. {* Posts characters from string S to those child window of Wnd, which
  10062. has focus now (top-level window Wnd must be foreground, and have
  10063. focused edit-aware control to receive the stroke).
  10064. |<br>
  10065. This function allows only to post typeable characters (including
  10066. such special symbols as #13 (Enter), #9 (Tab), #8 (BackSpace), etc.
  10067. |<br>
  10068. See also function Stroke2WindowEx, which allows to post any key down
  10069. and up events, simulating keyboard for given (automated) application. }
  10070. function Stroke2WindowEx( Wnd: HWnd; const S: String; Wait: Boolean ): Boolean;
  10071. {* In addition to function Stroke2Window, this one can send special keys
  10072. to given window, including functional keys and navigation keys. To
  10073. post special key to target window, place a combination of names of
  10074. such key together with keys, which should be passed simultaneously,
  10075. between square or figure brackets. For example, [Ctrl F1], [Alt Shift Home],
  10076. [Ctrl E]. For letters and usual characters, it is not necessary to
  10077. simulate pressing it with determining all Shift combinations and it is
  10078. sufficient to pass characters as is. (E.g., not '[Shift 1]', but '!'). }
  10079. function FindWindowByThreadID( ThreadID : DWORD ) : HWnd;
  10080. {* Searches for window, belonging to a given thread. }
  10081. function GetDesktopRect : TRect;
  10082. {* Returns rectangle of screen, free of taskbar and other
  10083. similar app-bars, which reduces size of available desktop
  10084. when created. }
  10085. function GetWorkArea: TRect;
  10086. {* The same as GetDesktopRect, but obtained calling SystemParametersInfo. }
  10087. function ExecuteWait( const AppPath, CmdLine, DfltDirectory: String;
  10088. Show: DWORD; TimeOut: DWORD; ProcID: PDWORD ): Boolean;
  10089. {* Allows to execute an application and wait when it is finished. Pass
  10090. INFINITE constant as TimeOut, if You sure that application is finished
  10091. anyway. If another value passed as a TimeOut (in milliseconds), and
  10092. application was not finished for that time, ExecuteWait is returning
  10093. FALSE, and if ProcID is not nil, than ProcID^ contains started process
  10094. handle (it can be used to wait it more, or to terminate it using
  10095. TerminateProcess API function).
  10096. |<br>
  10097. Launching application can be console or GUI - it does not matter.
  10098. Pass SW_SHOW, SW_HIDE or other SW_XXX constant as Show parameter
  10099. as appropriate.
  10100. |<br>
  10101. Trie is returned only in case when application specified was launched
  10102. successfully and finished for TimeOut specified. Otherwise, check
  10103. ProcID^ variable: if it is 0, process could not be launched (and it
  10104. is possible to get information about error using GetLastError API
  10105. function in a such case). You can freely pass nil in place of ProcID
  10106. parameter, but this is acually correct only when TimeOut is INFINITE. }
  10107. function ExecuteIORedirect( const AppPath, CmdLine, DfltDirectory: String;
  10108. Show: DWORD; ProcID: PDWORD; InPipe, OutPipeWr, OutPipeRd: PHandle ): Boolean;
  10109. {* Executes an application with its console input and output redirection.
  10110. Terminating of the application is not waiting, but if ProcID pointer
  10111. is defined, it receives process Id launched, so it is possible to
  10112. call WaitForSingleObject for it. InPipe is a pointer to THandle variable
  10113. which receives a handle to input pipe of the console redirected. The same
  10114. is for OutPipeWr and OutPipeRd, but for output of the console redirected.
  10115. Before reading from OutPipeRd^, first close OutPipeWr^. If you run
  10116. simple console application, for which you want to read results after its
  10117. termination, you can use ExecuteConsoleAppIORedirect instead.
  10118. |<br>&nbsp;&nbsp;&nbsp;
  10119. Notes: if your application is not console and it does not create console
  10120. using AllocConsole, this function will fail to redirect input-output. }
  10121. function ExecuteConsoleAppIORedirect( const AppPath, CmdLine, DfltDirectory: String;
  10122. Show: DWORD; const InStr: String; var OutStr: String; WaitTimeout: DWORD )
  10123. : Boolean;
  10124. {* Executes an application, redirecting its console input and output.
  10125. After redirecting input and output and launching the application,
  10126. content of InStr is written to input stream of the application, then
  10127. the application is waiting for its termination (WaitTimeout milliseconds
  10128. or INFINITE, as passed) and console output of the application is read to
  10129. OutStr. TRUE is returned only in case, when all these tasks are
  10130. completed successfully.
  10131. |<br>&nbsp;&nbsp;&nbsp;
  10132. Notes: if your application is not console and it does not create console
  10133. using AllocConsole, this function will fail to redirect input-output. }
  10134. function WindowsShutdown( const Machine : String; Force, Reboot : Boolean ) : Boolean;
  10135. {* Shut down of Windows NT. Pass Machine = '' to shutdown this PC.
  10136. Pass Reboot = True to reboot immediatelly after shut down. }
  10137. type
  10138. TWindowsVersion = ( wv31, wv95, wv98, wvNT, wvY2K, wvXP, wvLongHorn );
  10139. {* Windows versions constants. }
  10140. TWindowsVersions = Set of TWindowsVersion;
  10141. {* Set of Windows version (e.g. to define a range of versions supported by the
  10142. application). }
  10143. function WinVer : TWindowsVersion;
  10144. {* Returns Windows version. }
  10145. function IsWinVer( Ver : TWindowsVersions ) : Boolean;
  10146. {* Returns True if Windows version is in given range of values. }
  10147. //[Parameters FUNCTIONS DECLARATIONS]
  10148. function ParamStr( Idx: Integer ): String;
  10149. {* Returns command-line parameter by index. This function supersides
  10150. standard ParamStr function. }
  10151. function ParamCount: Integer;
  10152. {* Returns number of parameters in command line.
  10153. |<hr>
  10154. }
  10155. //{$DEFINE CHK_BITBLT}
  10156. procedure Chk_BitBlt;
  10157. {$IFDEF ASM_VERSION}
  10158. procedure StartDC;
  10159. procedure FinishDC;
  10160. {$ENDIF ASM_VERSION}
  10161. //[WndProcXXX OTHER DECLARATIONS]
  10162. function WndProcCtrl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  10163. function WndProcDoEraseBkgnd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  10164. var CreatingWindow: PControl;
  10165. //ActiveWindow: HWnd;
  10166. //[Assert OPERATOR DECLARATION]
  10167. {-}
  10168. {$IFDEF _D2}
  10169. // Assert operator was not available in Delphi2. Provide here easy Assert
  10170. // procedure for Delphi2.
  10171. procedure Assert( Cond: Boolean; const Msg: String );
  10172. var AssertErrorProc: procedure( const Message, Filename: AnsiString; LineNumber: Integer );
  10173. {$ENDIF}
  10174. {+}
  10175. //[CUSTOM EXTENSIONS]
  10176. {$IFDEF USE_CUSTOMEXTENSIONS}
  10177. {$I CUSTOM_KOL_EXTENSION.inc} // See comments in TControl
  10178. {$ENDIF}
  10179. {$IFDEF DEBUG_ENDSESSION}
  10180. var EndSession_Initiated: Boolean;
  10181. {$ENDIF}
  10182. //[FMMNotify VARIABLE]
  10183. var
  10184. FMMNotify: procedure( var Msg: TMsg );
  10185. //[procedure ClearText forward declaration]
  10186. procedure ClearText( Sender: PControl );
  10187. //[procedure ClearListbox forward declaration]
  10188. procedure ClearListbox( Sender: PControl );
  10189. //[procedure ClearCombobox forward declaration]
  10190. procedure ClearCombobox( Sender: PControl );
  10191. //[procedure ClearListView forward declaration]
  10192. procedure ClearListView( Sender: PControl );
  10193. //[procedure ClearTreeView forward declaration]
  10194. procedure ClearTreeView( TV: PControl );
  10195. //[START OF ACTIONS]
  10196. const
  10197. ButtonActions: TCommandActions = (
  10198. aClear: ClearText;
  10199. aAddText: nil;
  10200. aClick: BN_CLICKED;
  10201. aEnter: BN_SETFOCUS;
  10202. aLeave: BN_KILLFOCUS;
  10203. aChange: 0; //BN_CLICKED;
  10204. aSelChange: 0;
  10205. aGetCount: 0;
  10206. aSetCount: 0;
  10207. aGetItemLength: 0;
  10208. aGetItemText: 0;
  10209. aSetItemText: 0;
  10210. aGetItemData: 0;
  10211. aSetItemData: 0;
  10212. aAddItem: 0;
  10213. aDeleteItem: 0;
  10214. aInsertItem: 0;
  10215. aFindItem: 0;
  10216. aFindPartial: 0;
  10217. aItem2Pos: 0;
  10218. aPos2Item: 0;
  10219. aGetSelCount: 0;
  10220. aGetSelected: 0;
  10221. aGetSelRange: 0;
  10222. aExGetSelRange: 0;
  10223. aGetCurrent: 0;
  10224. aSetSelected: 0;
  10225. aSetCurrent: 0;
  10226. aSetSelRange: 0;
  10227. aExSetSelRange: 0;
  10228. aGetSelection: 0;
  10229. aReplaceSel: 0;
  10230. aTextAlignLeft: BS_LEFT;
  10231. aTextAlignRight: BS_RIGHT;
  10232. aTextAlignCenter: BS_CENTER;
  10233. aTextAlignMask: 0;
  10234. aVertAlignCenter: BS_VCENTER shr 8;
  10235. aVertAlignTop: BS_TOP shr 8;
  10236. aVertAlignBottom: BS_BOTTOM shr 8;
  10237. aDir: 0;
  10238. aSetLimit: 0;
  10239. aSetImgList: 0;
  10240. aAutoSzX: 14;
  10241. aAutoSzY: 6;
  10242. aSetBkColor: 0;
  10243. );
  10244. const
  10245. LabelActions: TCommandActions = (
  10246. aClear: ClearText;
  10247. aAddText: nil;
  10248. aClick: 0;
  10249. aEnter: 0;
  10250. aLeave: 0;
  10251. aChange: 0;
  10252. aSelChange: 0;
  10253. aGetCount: 0;
  10254. aSetCount: 0;
  10255. aGetItemLength: 0;
  10256. aGetItemText: 0;
  10257. aSetItemText: 0;
  10258. aGetItemData: 0;
  10259. aSetItemData: 0;
  10260. aAddItem: 0;
  10261. aDeleteItem: 0;
  10262. aInsertItem: 0;
  10263. aFindItem: 0;
  10264. aFindPartial: 0;
  10265. aItem2Pos: 0;
  10266. aPos2Item: 0;
  10267. aGetSelCount: 0;
  10268. aGetSelected: 0;
  10269. aGetSelRange: 0;
  10270. aExGetSelRange: 0;
  10271. aGetCurrent: 0;
  10272. aSetSelected: 0;
  10273. aSetCurrent: 0;
  10274. aSetSelRange: 0;
  10275. aExSetSelRange: 0;
  10276. aGetSelection: 0;
  10277. aReplaceSel: 0;
  10278. aTextAlignLeft: SS_LEFT;
  10279. aTextAlignRight: SS_RIGHT;
  10280. aTextAlignCenter: SS_CENTER;
  10281. aTextAlignMask: SS_LEFTNOWORDWRAP;
  10282. aVertAlignCenter: SS_CENTERIMAGE shr 8;
  10283. aVertAlignTop: 0;
  10284. aVertAlignBottom: 0;
  10285. aDir: 0;
  10286. aSetLimit: 0;
  10287. aSetImgList: 0;
  10288. aAutoSzX: 1;
  10289. aAutoSzY: 1;
  10290. aSetBkColor: 0;
  10291. );
  10292. const
  10293. EN_LINK = $070b;
  10294. EditActions: TCommandActions = (
  10295. aClear: ClearText;
  10296. aAddText: nil;
  10297. aClick: 0;
  10298. aEnter: EN_SETFOCUS;
  10299. aLeave: EN_KILLFOCUS;
  10300. aChange: EN_CHANGE;
  10301. aSelChange: 0;
  10302. aGetCount: EM_GETLINECOUNT;
  10303. aSetCount: 0;
  10304. aGetItemLength: EM_LINELENGTH;
  10305. aGetItemText: EM_GETLINE;
  10306. aSetItemText: EM_REPLACESEL;
  10307. aGetItemData: 0;
  10308. aSetItemData: 0;
  10309. aAddItem: 0;
  10310. aDeleteItem: 0;
  10311. aInsertItem: 0;
  10312. aFindItem: 0;
  10313. aFindPartial: 0;
  10314. aItem2Pos: EM_LINEINDEX;
  10315. aPos2Item: EM_LINEFROMCHAR;
  10316. aGetSelCount: EM_GETSEL;
  10317. aGetSelected: 0;
  10318. aGetSelRange: EM_GETSEL;
  10319. aExGetSelRange: 0;
  10320. aGetCurrent: EM_LINEINDEX;
  10321. aSetSelected: 0;
  10322. aSetCurrent: 0;
  10323. aSetSelRange: EM_SETSEL;
  10324. aExSetSelRange: 0;
  10325. aGetSelection: 0;
  10326. aReplaceSel: EM_REPLACESEL;
  10327. aTextAlignLeft: ES_LEFT;
  10328. aTextAlignRight: ES_RIGHT;
  10329. aTextAlignCenter: ES_CENTER;
  10330. aTextAlignMask: 0;
  10331. aVertAlignCenter: 0;
  10332. aVertAlignTop: 0;
  10333. aVertAlignBottom: 0;
  10334. aDir: 0;
  10335. aSetLimit: EM_SETLIMITTEXT;
  10336. aSetImgList: 0;
  10337. aAutoSzX: 0;
  10338. aAutoSzY: 6;
  10339. aSetBkColor: 0;
  10340. aItem2XY: EM_POSFROMCHAR;
  10341. );
  10342. const
  10343. ListActions: TCommandActions = (
  10344. aClear: ClearListbox;
  10345. aAddText: nil;
  10346. aClick: LBN_DBLCLK;
  10347. aEnter: LBN_SETFOCUS;
  10348. aLeave: LBN_KILLFOCUS;
  10349. aChange: 0;
  10350. aSelChange: LBN_SELCHANGE;
  10351. aGetCount: LB_GETCOUNT;
  10352. aSetCount: LB_SETCOUNT;
  10353. aGetItemLength: LB_GETTEXTLEN;
  10354. aGetItemText: LB_GETTEXT;
  10355. aSetItemText: 0;
  10356. aGetItemData: LB_GETITEMDATA;
  10357. aSetItemData: LB_SETITEMDATA;
  10358. aAddItem: LB_ADDSTRING;
  10359. aDeleteItem: LB_DELETESTRING;
  10360. aInsertItem: LB_INSERTSTRING;
  10361. aFindItem: LB_FINDSTRINGEXACT;
  10362. aFindPartial: LB_FINDSTRING;
  10363. aItem2Pos: 0;
  10364. aPos2Item: 0;
  10365. aGetSelCount: LB_GETSELCOUNT;
  10366. aGetSelected: LB_GETSEL;
  10367. aGetSelRange: 0;
  10368. aExGetSelRange: 0;
  10369. aGetCurrent: LB_GETCURSEL;
  10370. aSetSelected: LB_SETSEL;
  10371. aSetCurrent: LB_SETCURSEL;
  10372. aSetSelRange: 0;
  10373. aExSetSelRange: 0;
  10374. aGetSelection: 0;
  10375. aReplaceSel: 0;
  10376. aTextAlignLeft: 0;
  10377. aTextAlignRight: 0;
  10378. aTextAlignCenter: 0;
  10379. aTextAlignMask: 0;
  10380. aVertAlignCenter: 0;
  10381. aVertAlignTop: 0;
  10382. aVertAlignBottom: 0;
  10383. aDir: LB_DIR;
  10384. aSetLimit: 0;
  10385. aSetImgList: 0;
  10386. aAutoSzX: 0;
  10387. aAutoSzY: 0;
  10388. aSetBkColor: 0;
  10389. aItem2XY: LB_GETITEMRECT;
  10390. );
  10391. const
  10392. ComboActions: TCommandActions = (
  10393. aClear: ClearCombobox;
  10394. aAddText: nil;
  10395. aClick: CBN_DBLCLK;
  10396. aEnter: CBN_SETFOCUS;
  10397. aLeave: CBN_KILLFOCUS;
  10398. aChange: CBN_EDITCHANGE;
  10399. aSelChange: CM_CBN_SELCHANGE; // CBN_SELCHANGE;
  10400. aGetCount: CB_GETCOUNT;
  10401. aSetCount: 0;
  10402. aGetItemLength: CB_GETLBTEXTLEN;
  10403. aGetItemText: CB_GETLBTEXT;
  10404. aSetItemText: 0;
  10405. aGetItemData: CB_GETITEMDATA;
  10406. aSetItemData: CB_SETITEMDATA;
  10407. aAddItem: CB_ADDSTRING;
  10408. aDeleteItem: CB_DELETESTRING;
  10409. aInsertItem: CB_INSERTSTRING;
  10410. aFindItem: CB_FINDSTRINGEXACT;
  10411. aFindPartial: CB_FINDSTRING;
  10412. aItem2Pos: 0;
  10413. aPos2Item: 0;
  10414. aGetSelCount: 0;
  10415. aGetSelected: CB_GETCURSEL;
  10416. aGetSelRange: 0;
  10417. aExGetSelRange: 0;
  10418. aGetCurrent: CB_GETCURSEL;
  10419. aSetSelected: 0;
  10420. aSetCurrent: CB_SETCURSEL;
  10421. aSetSelRange: 0;
  10422. aExSetSelRange: 0;
  10423. aGetSelection: 0;
  10424. aReplaceSel: 0;
  10425. aTextAlignLeft: 0; //ES_LEFT;
  10426. aTextAlignRight: 0; //ES_RIGHT;
  10427. aTextAlignCenter: 0; //ES_CENTER;
  10428. aTextAlignMask: 0;
  10429. aVertAlignCenter: 0;
  10430. aVertAlignTop: 0;
  10431. aVertAlignBottom: 0;
  10432. aDir: CB_DIR;
  10433. aSetLimit: 0;
  10434. aSetImgList: 0;
  10435. aAutoSzX: 0;
  10436. aAutoSzY: 6;
  10437. aSetBkColor: 0;
  10438. );
  10439. const
  10440. ListViewActions: TCommandActions = (
  10441. aClear: ClearListView;
  10442. aAddText: nil;
  10443. aClick: 0;
  10444. aEnter: 0;
  10445. aLeave: 0;
  10446. aChange: LVN_ITEMCHANGED;
  10447. aSelChange: 0;
  10448. aGetCount: LVM_GETITEMCOUNT;
  10449. aSetCount: LVM_SETITEMCOUNT;
  10450. aGetItemLength: 0;
  10451. aGetItemText: 0;
  10452. aSetItemText: 0;
  10453. aGetItemData: 0;
  10454. aSetItemData: 0;
  10455. aAddItem: 0;
  10456. aDeleteItem: 0;
  10457. aInsertItem: 0;
  10458. aFindItem: 0;
  10459. aFindPartial: 0;
  10460. aItem2Pos: 0;
  10461. aPos2Item: 0;
  10462. aGetSelCount: $8000 or LVM_GETSELECTEDCOUNT;
  10463. aGetSelected: 0;
  10464. aGetSelRange: 0;
  10465. aExGetSelRange: 0;
  10466. aGetCurrent: LVM_GETNEXTITEM;
  10467. aSetSelected: 0;
  10468. aSetCurrent: 0;
  10469. aSetSelRange: 0;
  10470. aExSetSelRange: 0;
  10471. aGetSelection: 0;
  10472. aReplaceSel: 0;
  10473. aTextAlignLeft: 0;
  10474. aTextAlignRight: 0;
  10475. aTextAlignCenter: 0;
  10476. aTextAlignMask: 0;
  10477. aVertAlignCenter: 0;
  10478. aVertAlignTop: 0;
  10479. aVertAlignBottom: 0;
  10480. aDir: 0;
  10481. aSetLimit: 0;
  10482. aSetImgList: LVM_SETIMAGELIST;
  10483. aAutoSzX: 0;
  10484. aAutoSzY: 0;
  10485. aSetBkColor: LVM_SETBKCOLOR;
  10486. aItem2XY: LVM_GETITEMRECT;
  10487. );
  10488. const
  10489. TreeViewActions: TCommandActions = (
  10490. aClear: ClearTreeView;
  10491. aAddText: nil;
  10492. aClick: 0;
  10493. aEnter: 0;
  10494. aLeave: 0;
  10495. aChange: TVN_ENDLABELEDIT;
  10496. aSelChange: TVN_SELCHANGED;
  10497. aGetCount: TVM_GETCOUNT;
  10498. aSetCount: 0;
  10499. aGetItemLength: 0;
  10500. aGetItemText: 0;
  10501. aSetItemText: 0;
  10502. aGetItemData: 0;
  10503. aSetItemData: 0;
  10504. aAddItem: 0;
  10505. aDeleteItem: 0;
  10506. aInsertItem: 0;
  10507. aFindItem: 0;
  10508. aFindPartial: 0;
  10509. aItem2Pos: 0;
  10510. aPos2Item: 0;
  10511. aGetSelCount: 0;
  10512. aGetSelected: 0;
  10513. aGetSelRange: 0;
  10514. aExGetSelRange: 0;
  10515. aGetCurrent: 0;
  10516. aSetSelected: 0;
  10517. aSetCurrent: 0;
  10518. aSetSelRange: 0;
  10519. aExSetSelRange: 0;
  10520. aGetSelection: 0;
  10521. aReplaceSel: 0;
  10522. aTextAlignLeft: 0;
  10523. aTextAlignRight: 0;
  10524. aTextAlignCenter: 0;
  10525. aTextAlignMask: 0;
  10526. aVertAlignCenter: 0;
  10527. aVertAlignTop: 0;
  10528. aVertAlignBottom: 0;
  10529. aDir: CB_DIR;
  10530. aSetLimit: 0;
  10531. aSetImgList: TVM_SETIMAGELIST;
  10532. aAutoSzX: 0;
  10533. aAutoSzY: 0;
  10534. aSetBkColor: TVM_SETBKCOLOR;
  10535. aItem2XY: TVM_GETITEMRECT;
  10536. );
  10537. const
  10538. TabControlActions: TCommandActions = (
  10539. aClear: ClearText;
  10540. aAddText: nil;
  10541. aClick: 0;
  10542. aEnter: 0;
  10543. aLeave: 0;
  10544. aChange: TCN_SELCHANGE;
  10545. aSelChange: TCN_SELCHANGE;
  10546. aGetCount: TCM_GETITEMCOUNT;
  10547. aSetCount: 0;
  10548. aGetItemLength: 0;
  10549. aGetItemText: 0;
  10550. aSetItemText: 0;
  10551. aGetItemData: 0;
  10552. aSetItemData: 0;
  10553. aAddItem: 0;
  10554. aDeleteItem: 0;
  10555. aInsertItem: 0;
  10556. aFindItem: 0;
  10557. aFindPartial: 0;
  10558. aItem2Pos: 0;
  10559. aPos2Item: 0;
  10560. aGetSelCount: 0;
  10561. aGetSelected: 0;
  10562. aGetSelRange: 0;
  10563. aExGetSelRange: 0;
  10564. aGetCurrent: TCM_GETCURSEL;
  10565. aSetSelected: 0;
  10566. aSetCurrent: TCM_SETCURSEL; //TCM_SETCURFOCUS;
  10567. aSetSelRange: 0;
  10568. aExSetSelRange: 0;
  10569. aGetSelection: 0;
  10570. aReplaceSel: 0;
  10571. aTextAlignLeft: 0;
  10572. aTextAlignRight: 0;
  10573. aTextAlignCenter: 0;
  10574. aTextAlignMask: 0;
  10575. aVertAlignCenter: 0;
  10576. aVertAlignTop: 0;
  10577. aVertAlignBottom: 0;
  10578. aDir: CB_DIR;
  10579. aSetLimit: 0;
  10580. aSetImgList: TCM_SETIMAGELIST;
  10581. aAutoSzX: 0;
  10582. aAutoSzY: 0;
  10583. aSetBkColor: 0;
  10584. aItem2XY: TCM_GETITEMRECT;
  10585. );
  10586. const
  10587. RichEditActions: TCommandActions = (
  10588. aClear: ClearText;
  10589. aAddText: nil;
  10590. aClick: 0;
  10591. aEnter: EN_SETFOCUS;
  10592. aLeave: EN_KILLFOCUS;
  10593. aChange: EN_CHANGE;
  10594. aSelChange: EN_SELCHANGE;
  10595. aGetCount: EM_GETLINECOUNT;
  10596. aSetCount: 0;
  10597. aGetItemLength: EM_LINELENGTH;
  10598. aGetItemText: EM_GETLINE;
  10599. aSetItemText: EM_REPLACESEL;
  10600. aGetItemData: 0;
  10601. aSetItemData: 0;
  10602. aAddItem: 0;
  10603. aDeleteItem: 0;
  10604. aInsertItem: 0;
  10605. aFindItem: 0;
  10606. aFindPartial: 0;
  10607. aItem2Pos: EM_LINEINDEX;
  10608. aPos2Item: EM_LINEFROMCHAR;
  10609. aGetSelCount: 0; //EM_EXGETSEL;
  10610. aGetSelected: 0;
  10611. aGetSelRange: 0;
  10612. aExGetSelRange: EM_EXGETSEL;
  10613. aGetCurrent: EM_LINEINDEX;
  10614. aSetSelected: 0;
  10615. aSetCurrent: 0;
  10616. aSetSelRange: 0;
  10617. aExSetSelRange: EM_EXSETSEL;
  10618. aGetSelection: EM_GETSELTEXT;
  10619. aReplaceSel: EM_REPLACESEL;
  10620. aTextAlignLeft: ES_LEFT;
  10621. aTextAlignRight: ES_RIGHT;
  10622. aTextAlignCenter: ES_CENTER;
  10623. aTextAlignMask: 0;
  10624. aVertAlignCenter: 0;
  10625. aVertAlignTop: 0;
  10626. aVertAlignBottom: 0;
  10627. aDir: 0;
  10628. aSetLimit: EM_EXLIMITTEXT;
  10629. aSetImgList: 0;
  10630. aAutoSzX: 0;
  10631. aAutoSzY: 0;
  10632. aSetBkColor: EM_SETBKGNDCOLOR;
  10633. aItem2XY: EM_POSFROMCHAR;
  10634. );
  10635. //[IMPLEMENTATION]
  10636. implementation
  10637. //[USES-2]
  10638. uses
  10639. ShellAPI,
  10640. commdlg
  10641. ; //, commctrl;
  10642. // in Delphi3, including of commctrl.pas increases executable
  10643. // onto about 30K. So, all needed definitions are copied here
  10644. // (see commctrl.inc).
  10645. //[END OF USES-2]
  10646. {$IFDEF _D2orD3}
  10647. const
  10648. OFN_ENABLESIZING = $00800000;
  10649. {$ENDIF}
  10650. //[procedure Chk_BitBlt_ShowError]
  10651. procedure Chk_BitBlt_ShowError;
  10652. var Rslt: Integer;
  10653. begin
  10654. Rslt := GetLastError;
  10655. ShowMessage( 'BitBlt ERROR: ' + Int2Str( Rslt )
  10656. + ' ' + SysErrorMessage( Rslt ) );
  10657. end;
  10658. //[ENDe Chk_BitBlt_ShowError]
  10659. //[procedure Chk_BitBlt]
  10660. procedure Chk_BitBlt;
  10661. var Rslt: Integer;
  10662. begin
  10663. asm
  10664. MOV Rslt, EAX
  10665. end;
  10666. if Rslt = 0 then
  10667. begin
  10668. Chk_BitBlt_ShowError;
  10669. asm
  10670. int 3;
  10671. end;
  10672. end;
  10673. end;
  10674. //[ENDe Chk_BitBlt]
  10675. //[FUNCTION MulDiv]
  10676. {$IFNDEF FPC}
  10677. function MulDiv( A, B, C: Integer ): Integer;
  10678. asm
  10679. IMUL EDX
  10680. IDIV ECX
  10681. end;
  10682. {$ENDIF}
  10683. //[END MulDiv]
  10684. {-}
  10685. {$ifdef _D2}
  10686. //[PROCEDURE Assert]
  10687. procedure Assert( Cond: Boolean; const Msg: String );
  10688. begin
  10689. if not Cond then
  10690. begin
  10691. AssertErrorProc( Msg, '', 0 );
  10692. //MsgOK( Msg );
  10693. asm
  10694. int 3;
  10695. end;
  10696. end;
  10697. end;
  10698. //[API CreateDIBSection]
  10699. function CreateDIBSection(DC: HDC; const p2: TBitmapInfo; p3: UINT;
  10700. var p4: Pointer; p5: THandle; p6: DWORD): HBITMAP; stdcall;
  10701. external gdi32 name 'CreateDIBSection';
  10702. //[PROCEDURE _LStrFromPCharLen]
  10703. procedure _LStrFromPCharLen(var Dest: AnsiString; Source: PAnsiChar; Length: Integer);
  10704. asm
  10705. { -> EAX pointer to dest }
  10706. { EDX source }
  10707. { ECX length }
  10708. PUSH EBX
  10709. PUSH ESI
  10710. PUSH EDI
  10711. MOV EBX,EAX
  10712. MOV ESI,EDX
  10713. MOV EDI,ECX
  10714. { allocate new string }
  10715. MOV EAX,EDI
  10716. CALL System.@NewAnsiString
  10717. MOV ECX,EDI
  10718. MOV EDI,EAX
  10719. TEST ESI,ESI
  10720. JE @@noMove
  10721. MOV EDX,EAX
  10722. MOV EAX,ESI
  10723. CALL Move
  10724. { assign the result to dest }
  10725. @@noMove:
  10726. MOV EAX,EBX
  10727. CALL System.@LStrClr
  10728. MOV [EBX],EDI
  10729. POP EDI
  10730. POP ESI
  10731. POP EBX
  10732. end;
  10733. {$endif}
  10734. {+}
  10735. //[API InitCommonControls]
  10736. procedure InitCommonControls; external cctrl name 'InitCommonControls';
  10737. type
  10738. TInitCommonControlsEx = packed record
  10739. dwSize: DWORD;
  10740. dwICC: DWORD;
  10741. end;
  10742. PInitCommonControlsEx = ^TInitCommonControlsEx;
  10743. var ComCtl32_Module: HModule;
  10744. //[procedure DoInitCommonControls]
  10745. procedure DoInitCommonControls( dwICC: DWORD );
  10746. var Proc: procedure( ICC: PInitCommonControlsEx ); stdcall;
  10747. ICC: TInitCommonControlsEx;
  10748. begin
  10749. InitCommonControls;
  10750. if ComCtl32_Module = 0 then
  10751. ComCtl32_Module := LoadLibrary( 'comctl32.dll' );
  10752. @ Proc := GetProcAddress( ComCtl32_Module, 'InitCommonControlsEx' );
  10753. if Assigned( Proc ) then
  10754. begin
  10755. ICC.dwSize := Sizeof( ICC );
  10756. ICC.dwICC := dwICC;
  10757. Proc( @ ICC );
  10758. end;
  10759. end;
  10760. //[END DoInitCommonControls]
  10761. const size_TRect = 16; // used often in assembler versions of code
  10762. {-}
  10763. {$IFDEF ASM_VERSION}
  10764. const
  10765. EmptyString: String = '';
  10766. //[PROCEDURE EAX2PChar]
  10767. procedure EAX2PChar;
  10768. asm
  10769. TEST EAX, EAX
  10770. JNZ @@exit
  10771. MOV EAX, offset[EmptyString]
  10772. @@exit:
  10773. end;
  10774. //[PROCEDURE EDX2PChar]
  10775. procedure EDX2PChar;
  10776. asm
  10777. TEST EDX, EDX
  10778. JNZ @@exit
  10779. MOV EDX, offset[EmptyString]
  10780. @@exit:
  10781. end;
  10782. //[PROCEDURE ECX2PChar]
  10783. procedure ECX2PChar;
  10784. asm
  10785. JECXZ @@convert
  10786. RET
  10787. @@convert:
  10788. MOV ECX, offset[EmptyString]
  10789. @@exit:
  10790. end;
  10791. //[PROCEDURE RemoveStr]
  10792. procedure RemoveStr;
  10793. asm
  10794. { <- [ESP+4] = string to remove
  10795. -> ESP := ESP + 4
  10796. EAX = 0
  10797. }
  10798. POP EAX
  10799. XCHG EAX, [ESP]
  10800. PUSH EAX
  10801. MOV EAX, ESP
  10802. CALL System.@LStrClr
  10803. POP EAX
  10804. end;
  10805. {$ELSE ASM_VERSION}
  10806. {$ENDIF ASM_VERSION}
  10807. {+}
  10808. //[PROCEDURE MsgOK]
  10809. procedure MsgOK( const S: String );
  10810. begin
  10811. MsgBox( S, MB_OK );
  10812. end;
  10813. {$IFDEF ASM_VERSION}
  10814. //[function MsgBox]
  10815. function MsgBox( const S: String; Flags: DWORD ): DWORD;
  10816. asm
  10817. PUSH EDX
  10818. PUSH EAX
  10819. MOV ECX, [Applet]
  10820. XOR EAX, EAX
  10821. JECXZ @@1
  10822. MOV EAX, [ECX].TControl.fCaption
  10823. @@1:
  10824. XCHG EAX, [ESP]
  10825. PUSH EAX
  10826. PUSH 0
  10827. CALL MessageBox
  10828. end;
  10829. {$ELSE ASM_VERSION} //Pascal
  10830. function MsgBox( const S: String; Flags: DWORD ): DWORD;
  10831. var Title: PChar;
  10832. begin
  10833. Title := nil;
  10834. if assigned( Applet ) then
  10835. begin
  10836. Title := PChar( Applet.fCaption );
  10837. end;
  10838. Result := MessageBox( 0 {Wnd}, PChar( S ), Title, Flags );
  10839. end;
  10840. //[END MsgBox]
  10841. {$ENDIF ASM_VERSION}
  10842. //[function ShowMsg]
  10843. function ShowMsg( const S: String; Flags: DWORD ): DWORD;
  10844. var Title: PChar;
  10845. Wnd: HWnd;
  10846. begin
  10847. Title := nil;
  10848. Wnd := 0;
  10849. if assigned( Applet ) then
  10850. begin
  10851. Title := PChar( Applet.fCaption );
  10852. Wnd := Applet.Handle;
  10853. end;
  10854. Result := MessageBox( Wnd, PChar( S ), Title, Flags );
  10855. end;
  10856. //[END ShowMsg]
  10857. //[procedure ShowMessage]
  10858. procedure ShowMessage( const S: String );
  10859. begin
  10860. ShowMsg( S, MB_OK or MB_SETFOREGROUND );
  10861. end;
  10862. //[ENDe ShowMessage]
  10863. //[procedure OKClick]
  10864. procedure OKClick( Dialog, Btn: PControl );
  10865. var Rslt: Integer;
  10866. begin
  10867. Rslt := -1;
  10868. if Btn <> nil then
  10869. Rslt := Btn.Tag;
  10870. Dialog.ModalResult := Rslt;
  10871. Dialog.Close;
  10872. end;
  10873. //[END OKClick]
  10874. //[procedure KeyClick]
  10875. procedure KeyClick( Dialog, Btn: PControl; var Key: Longint; Shift: DWORD );
  10876. begin
  10877. if (Key = VK_RETURN) or (Key = VK_ESCAPE) then
  10878. begin
  10879. if Key = VK_ESCAPE then
  10880. Btn := nil;
  10881. OKClick( Dialog, Btn );
  10882. end;
  10883. end;
  10884. //[ENDe KeyClick]
  10885. //[procedure CloseMsg]
  10886. procedure CloseMsg( Dummy, Dialog: PControl; var Accept: Boolean );
  10887. begin
  10888. Accept := FALSE;
  10889. Dialog.ModalResult := -1;
  10890. end;
  10891. //[ENDe CloseMsg]
  10892. //[function ShowQuestionEx]
  10893. function ShowQuestionEx( const S: String; Answers: String; CallBack: TOnEvent ): Integer;
  10894. {$IFDEF F_P105ORBELOW}
  10895. type POnEvent = ^TOnEvent;
  10896. PONKey = ^TOnKey;
  10897. var M: TMethod;
  10898. {$ENDIF F_P105ORBELOW}
  10899. var Dialog: PControl;
  10900. Buttons: PList;
  10901. Btn: PControl;
  10902. AppTermFlag: Boolean;
  10903. Lab: PControl;
  10904. Y, W, I: Integer;
  10905. Title: String;
  10906. DlgWnd: HWnd;
  10907. AppCtl: PControl;
  10908. begin
  10909. AppTermFlag := AppletTerminated;
  10910. AppCtl := Applet;
  10911. AppletTerminated := FALSE;
  10912. Title := 'Information';
  10913. if pos( '/', Answers ) > 0 then
  10914. Title := 'Question';
  10915. if Applet <> nil then
  10916. Title := Applet.Caption;
  10917. Dialog := NewForm( Applet, Title ).SetSize( 300, 40 );
  10918. Dialog.Style := Dialog.Style and not (WS_MINIMIZEBOX or WS_MAXIMIZEBOX);
  10919. Dialog.OnClose := TOnEventAccept( MakeMethod( Dialog, @CloseMsg ) );
  10920. Dialog.Margin := 8;
  10921. Lab := NewEditbox( Dialog, [ eoMultiline, eoReadonly, eoNoHScroll, eoNoVScroll ] ).SetSize( 278, 20 );
  10922. Lab.HasBorder := FALSE;
  10923. Lab.Color := clBtnFace;
  10924. Lab.Caption := S;
  10925. Lab.Style := Lab.Style and not WS_TABSTOP;
  10926. Lab.TabStop := FALSE;
  10927. //Lab.LikeSpeedButton;
  10928. //Lab.CreateWindow; //virtual!!! -- not needed, window created in Perform
  10929. while TRUE do
  10930. begin
  10931. Y := HiWord( Lab.Perform( EM_POSFROMCHAR, Length( S ) - 1, 0 ) );
  10932. if Y < Lab.Height - 20 then break;
  10933. Lab.Height := Lab.Height + 4;
  10934. if Lab.Height + 40 > GetSystemMetrics( SM_CYSCREEN ) then break;
  10935. end;
  10936. Buttons := NewList;
  10937. W := 0;
  10938. if Answers = '' then
  10939. begin
  10940. Btn := NewButton( Dialog, ' OK ' ).PlaceUnder;
  10941. W := Btn.Width;
  10942. Buttons.Add( Btn );
  10943. end
  10944. else
  10945. while Answers <> '' do
  10946. begin
  10947. Btn := NewButton( Dialog, ' ' + Parse( Answers, '/' ) + ' ' );
  10948. Buttons.Add( Btn );
  10949. if W = 0 then
  10950. Btn.PlaceUnder
  10951. else
  10952. Btn.PlaceRight;
  10953. Btn.AutoSize( TRUE );
  10954. if W > 0 then
  10955. begin
  10956. //Inc( W, 6 );
  10957. Btn.Left := Btn.Left + 6;
  10958. end;
  10959. W := Btn.BoundsRect.Right + 12;
  10960. end;
  10961. if Dialog.ClientWidth < W then
  10962. Dialog.ClientWidth := W;
  10963. W := (Dialog.ClientWidth - W) div 2;
  10964. for I := 0 to Buttons.Count-1 do
  10965. begin
  10966. Btn := Buttons.Items[ I ];
  10967. Btn.Tag := I + 1;
  10968. {$IFDEF F_P105ORBELOW}
  10969. M := MakeMethod( Dialog, @OKClick );
  10970. Btn.OnClick := POnEvent( @ M )^;
  10971. M := MakeMethod( Dialog, @KeyClick );
  10972. Btn.OnKeyDown := POnKey( @ M )^;
  10973. {$ELSE}
  10974. Btn.OnClick := TOnEvent( MakeMethod( Dialog, @OKClick ) );
  10975. Btn.OnKeyDown := TOnKey( MakeMethod( Dialog, @KeyClick ) );
  10976. {$ENDIF}
  10977. Btn.Left := Btn.Left + W;
  10978. if I = 0 then
  10979. begin
  10980. Btn.ResizeParentBottom;
  10981. Dialog.ActiveControl := Btn;
  10982. end;
  10983. end;
  10984. Dialog.CenterOnParent.Tabulate.CanResize := FALSE;
  10985. Buttons.Free;
  10986. if Assigned( CallBack ) then
  10987. CallBack( Dialog );
  10988. Dialog.CreateWindow; // virtual!!!
  10989. if (Applet <> nil) and Applet.IsApplet then
  10990. begin
  10991. Dialog.ShowModal;
  10992. Result := Dialog.ModalResult;
  10993. Dialog.Free;
  10994. end
  10995. else
  10996. begin
  10997. DlgWnd := Dialog.Handle;
  10998. while IsWindow( DlgWnd ) and (Dialog.ModalResult = 0) do
  10999. Dialog.ProcessMessage;
  11000. Result := Dialog.ModalResult;
  11001. Dialog.Free;
  11002. CreatingWindow := nil;
  11003. Applet := AppCtl;
  11004. end;
  11005. AppletTerminated := AppTermFlag;
  11006. end;
  11007. //[END ShowQuestionEx]
  11008. //[function ShowQuestion]
  11009. function ShowQuestion( const S: String; Answers: String ): Integer;
  11010. begin
  11011. Result := ShowQuestionEx( S, Answers, nil );
  11012. end;
  11013. //[END ShowQuestion]
  11014. //[procedure ShowMsgModal]
  11015. procedure ShowMsgModal( const S: String );
  11016. begin
  11017. ShowQuestion( S, '' );
  11018. end;
  11019. //[ENDe ShowMsgModal]
  11020. //[procedure SpeakerBeep]
  11021. procedure SpeakerBeep( Freq: Word; Duration: DWORD );
  11022. begin
  11023. if WinVer >= wvNT then
  11024. Windows.Beep( Freq, Duration )
  11025. else
  11026. begin
  11027. if Freq < 18 then Exit;
  11028. Freq := 1193181 div Freq;
  11029. if Freq = 0 then Exit;
  11030. asm
  11031. mov al,0b6H
  11032. out 43H,al
  11033. mov ax,Freq
  11034. //xchg al, ah
  11035. out 42h,al
  11036. xchg al, ah
  11037. out 42h,al
  11038. in al,61H
  11039. or al,03H
  11040. out 61H,al
  11041. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF} ;
  11042. Sleep(Duration);
  11043. asm
  11044. in al,61H
  11045. and al,0fcH
  11046. out 61H,al
  11047. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF} ;
  11048. end;
  11049. end;
  11050. //[ENDe SpeakerBeep]
  11051. {++}(*
  11052. //[API FormatMessage]
  11053. function FormatMessage; external kernel32 name 'FormatMessageA';
  11054. *){--}
  11055. //[FUNCTION SysErrorMessage]
  11056. function SysErrorMessage(ErrorCode: Integer): string;
  11057. var
  11058. Len: Integer;
  11059. Buffer: array[0..255] of Char;
  11060. begin
  11061. Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
  11062. FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, Buffer,
  11063. SizeOf(Buffer), nil);
  11064. while (Len > 0) and (Buffer[Len - 1] in [#0..#32 {, '.'}]) do Dec(Len);
  11065. SetString(Result, Buffer, Len);
  11066. end;
  11067. //[END SysErrorMessage]
  11068. //[function MakeMethod]
  11069. function MakeMethod( Data, Code: Pointer ): TMethod;
  11070. begin
  11071. Result.Data := Data;
  11072. Result.Code := Code;
  11073. end;
  11074. //[END MakeMethod]
  11075. //[function GetShiftState]
  11076. function GetShiftState: DWORD;
  11077. begin
  11078. Result := 0;
  11079. if GetKeyState( VK_SHIFT ) < 0 then
  11080. Result := Result or MK_SHIFT;
  11081. if GetKeyState( VK_CONTROL ) < 0 then
  11082. Result := Result or MK_CONTROL;
  11083. //if LONGBOOL(Msg.lParam and $20000000) then
  11084. if GetKeyState( VK_MENU ) < 0 then
  11085. Result := Result or MK_ALT;
  11086. end;
  11087. //[END GetShiftState]
  11088. //[FUNCTION MakeRect]
  11089. {$IFDEF ASM_VERSION}
  11090. function MakeRect( Left, Top, Right, Bottom: Integer ): TRect; stdcall;
  11091. asm
  11092. PUSH ESI
  11093. PUSH EDI
  11094. MOV EDI, @Result
  11095. LEA ESI, [Left]
  11096. MOVSD
  11097. MOVSD
  11098. MOVSD
  11099. MOVSD
  11100. POP EDI
  11101. POP ESI
  11102. end;
  11103. {$ELSE ASM_VERSION} //Pascal
  11104. function MakeRect( Left, Top, Right, Bottom: Integer ): TRect; stdcall;
  11105. begin
  11106. Result.Left := Left;
  11107. Result.Top := Top;
  11108. Result.Right:= Right;
  11109. Result.Bottom := Bottom;
  11110. end;
  11111. {$ENDIF ASM_VERSION}
  11112. //[END MakeRect]
  11113. //[FUNCTION RectsEqual]
  11114. {$IFDEF ASM_VERSION}
  11115. function RectsEqual( const R1, R2: TRect ): Boolean;
  11116. asm
  11117. //LEA EAX, [R1]
  11118. //LEA EDX, [R2]
  11119. MOV ECX, size_TRect
  11120. CALL CompareMem
  11121. end;
  11122. {$ELSE ASM_VERSION} //Pascal
  11123. function RectsEqual( const R1, R2: TRect ): Boolean;
  11124. begin
  11125. Result := CompareMem( @R1, @R2, Sizeof( TRect ) );
  11126. end;
  11127. {$ENDIF ASM_VERSION}
  11128. //[END RectsEqual]
  11129. //[function RectsIntersected]
  11130. function RectsIntersected( const R1, R2: TRect ): Boolean;
  11131. begin
  11132. Result := ((R1.Left <= R2.Left) and (R1.Right > R2.Left ) or
  11133. (R1.Left <= R2.Right) and (R1.Right >= R2.Right) or
  11134. (R1.Left >= R2.Left) and (R1.Right <= R2.Right))
  11135. and
  11136. ((R1.Top <= R2.Top) and (R1.Bottom > R2.Top) or
  11137. (R1.Top <= R2.Bottom) and (R1.Bottom >= R2.Bottom) or
  11138. (R1.Top >= R2.Top) and (R1.Bottom <= R2.Bottom)) ;
  11139. end;
  11140. //[END RectsIntersected]
  11141. //[FUNCTION PointInRect]
  11142. {$IFDEF ASM_VERSION}
  11143. function PointInRect( const P: TPoint; const R: TRect ): Boolean;
  11144. asm
  11145. PUSH ESI
  11146. MOV ECX, EAX
  11147. MOV ESI, EDX
  11148. LODSD
  11149. CMP EAX, [ECX]
  11150. JG @@fail
  11151. LODSD
  11152. CMP EAX, [ECX+4]
  11153. JG @@fail
  11154. LODSD
  11155. CMP [ECX], EAX
  11156. JG @@fail
  11157. LODSD
  11158. CMP [ECX+4], EAX
  11159. @@fail: SETLE AL
  11160. POP ESI
  11161. end;
  11162. {$ELSE ASM_VERSION} //Pascal
  11163. function PointInRect( const P: TPoint; const R: TRect ): Boolean;
  11164. begin
  11165. Result := (P.x >= R.Left) and (P.x < R.Right)
  11166. and (P.y >= R.Top) and (P.y < R.Bottom);
  11167. end;
  11168. {$ENDIF ASM_VERSION}
  11169. //[END PointInRect]
  11170. //[FUNCTION MakePoint]
  11171. {$IFDEF ASM_VERSION}
  11172. function MakePoint( X, Y: Integer ): TPoint;
  11173. asm
  11174. MOV ECX, @Result
  11175. MOV [ECX].TPoint.x, EAX
  11176. MOV [ECX].TPoint.y, EDX
  11177. end;
  11178. {$ELSE ASM_VERSION} //Pascal
  11179. function MakePoint( X, Y: Integer ): TPoint;
  11180. begin
  11181. Result.x := X;
  11182. Result.y := Y;
  11183. end;
  11184. {$ENDIF ASM_VERSION}
  11185. //[END MakePoint]
  11186. //[FUNCTION MakeFlags]
  11187. {$IFDEF ASM_VERSION}
  11188. function MakeFlags( FlgSet: PDWORD; FlgArray: array of Integer): Integer;
  11189. asm
  11190. PUSH EBX
  11191. PUSH ESI
  11192. MOV EBX, [EAX]
  11193. MOV ESI, EDX
  11194. XOR EDX, EDX
  11195. INC ECX
  11196. JZ @@exit
  11197. @@loo:
  11198. LODSD
  11199. TEST EAX, EAX
  11200. JGE @@ge
  11201. NOT EAX
  11202. TEST BL, 1
  11203. JZ @@or
  11204. DEC EBX
  11205. @@ge:
  11206. TEST BL, 1
  11207. JZ @@nx
  11208. @@or:
  11209. OR EDX, EAX
  11210. @@nx:
  11211. SHR EBX, 1
  11212. LOOP @@loo
  11213. @@exit:
  11214. XCHG EAX, EDX
  11215. POP ESI
  11216. POP EBX
  11217. end;
  11218. {$ELSE ASM_VERSION} //Pascal
  11219. function MakeFlags( FlgSet: PDWORD; FlgArray: array of Integer): Integer;
  11220. var I : Integer;
  11221. Mask : DWORD;
  11222. begin
  11223. Result := 0;
  11224. Mask := FlgSet^;
  11225. for I := 0 to High( FlgArray ) do
  11226. begin
  11227. if (FlgArray[ I ] < 0) and not LongBool( Mask and 1 ) then
  11228. Result := Result or not FlgArray[ I ]
  11229. else
  11230. if (FlgArray[ I ] >= 0) and LongBool( Mask and 1 ) then
  11231. Result := Result or FlgArray[ I ];
  11232. Mask := Mask shr 1;
  11233. end;
  11234. end;
  11235. {$ENDIF ASM_VERSION}
  11236. //[END MakeFlags]
  11237. //[procedure HelpFastIncNum2Els]
  11238. procedure HelpFastIncNum2Els( DataArray: Pointer; Value, Count: Integer );
  11239. asm
  11240. PUSH ESI
  11241. PUSH EDI
  11242. {$IFDEF F_P}
  11243. MOV ESI, [DataArray]
  11244. MOV EDX, [Value]
  11245. MOV ECX, [Count]
  11246. {$ELSE DELPHI}
  11247. MOV ESI, EAX
  11248. {$ENDIF F_P/DELPHI}
  11249. MOV EDI, ESI
  11250. CLD
  11251. @@1:
  11252. LODSD
  11253. ADD EAX, EDX
  11254. STOSD
  11255. LOOP @@1
  11256. POP EDI
  11257. POP ESI
  11258. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  11259. //[ENDe HelpFastIncNum2Els]
  11260. //[procedure Swap]
  11261. procedure Swap( var X, Y: Integer );
  11262. {$IFDEF F_P}
  11263. var Tmp: Integer;
  11264. begin
  11265. Tmp := X;
  11266. X := Y;
  11267. Y := Tmp;
  11268. end;
  11269. {$ELSE DELPHI}
  11270. asm
  11271. MOV ECX, [EDX]
  11272. XCHG ECX, [EAX]
  11273. MOV [EDX], ECX
  11274. end;
  11275. //[ENDe Swap]
  11276. {$ENDIF F_P/DELPHI}
  11277. //[function Min]
  11278. function Min( X, Y: Integer ): Integer;
  11279. asm
  11280. {$IFDEF F_P}
  11281. MOV EAX, [X]
  11282. MOV EDX, [Y]
  11283. {$ENDIF F_P}
  11284. {$IFDEF USE_CMOV}
  11285. CMP EAX, EDX
  11286. CMOVG EAX, EDX
  11287. {$ELSE}
  11288. CMP EAX, EDX
  11289. JLE @@exit
  11290. MOV EAX, EDX
  11291. @@exit:
  11292. {$ENDIF}
  11293. end {$IFDEF F_P} [ 'EAX', 'EDX' ] {$ENDIF};
  11294. //[END Min]
  11295. //[function Max]
  11296. function Max( X, Y: Integer ): Integer;
  11297. asm
  11298. {$IFDEF F_P}
  11299. MOV EAX, [X]
  11300. MOV EDX, [Y]
  11301. {$ENDIF F_P}
  11302. {$IFDEF USE_CMOV}
  11303. CMP EAX, EDX
  11304. CMOVL EAX, EDX
  11305. {$ELSE}
  11306. CMP EAX, EDX
  11307. JGE @@exit
  11308. MOV EAX, EDX
  11309. @@exit:
  11310. {$ENDIF}
  11311. end {$IFDEF F_P} [ 'EAX', 'EDX' ] {$ENDIF};
  11312. //[END Max]
  11313. {$IFDEF REDEFINE_ABS}
  11314. //[function Abs]
  11315. function Abs( X: Integer ): Integer;
  11316. asm
  11317. {$IFDEF F_P}
  11318. MOV EAX, [X]
  11319. {$ENDIF F_P}
  11320. TEST EAX, EAX
  11321. JGE @@1
  11322. NEG EAX
  11323. @@1:
  11324. end {$IFDEF F_P} [ 'EAX' ] {$ENDIF};
  11325. //[END Abs]
  11326. {$ENDIF}
  11327. //[function Sgn]
  11328. function Sgn( X: Integer ): Integer;
  11329. asm
  11330. CMP EAX, 0
  11331. {$IFDEF USE_CMOV}
  11332. MOV EDX, -1
  11333. CMOVL EAX, EDX
  11334. MOV EDX, 1
  11335. CMOVG EAX, EDX
  11336. {$ELSE}
  11337. JZ @@exit
  11338. MOV EAX, 1
  11339. JG @@exit
  11340. MOV EAX, -1
  11341. @@exit:
  11342. {$ENDIF}
  11343. end;
  11344. //[END Sgn]
  11345. //[function iSqrt]
  11346. function iSQRT( X: Integer ): Integer;
  11347. var I, N: Integer;
  11348. begin
  11349. Result := 0;
  11350. while Result < X do
  11351. begin
  11352. I := 1;
  11353. while I > 0 do
  11354. begin
  11355. N := (Result + I) * (Result + I);
  11356. if N > X then
  11357. begin
  11358. I := I shr 1;
  11359. break;
  11360. end
  11361. else
  11362. if N = X then
  11363. begin
  11364. Result := Result + I;
  11365. Exit;
  11366. end;
  11367. I := I shl 1;
  11368. end;
  11369. if I <= 0 then Exit;
  11370. Result := Result + I;
  11371. end;
  11372. end;
  11373. //[END iSqrt]
  11374. {$IFDEF ASM_VERSION}
  11375. //[PROCEDURE StartDC]
  11376. procedure StartDC;
  11377. asm
  11378. { <- EBX : PBitmap
  11379. -> EAX = dc
  11380. [ESP+8] = var dc
  11381. [ESP+4] = var SaveBmp
  11382. }
  11383. PUSH 0
  11384. CALL CreateCompatibleDC
  11385. POP EDX
  11386. PUSH EAX
  11387. PUSH EDX
  11388. MOV EAX, EBX
  11389. CALL [EBX].TBitmap.fDetachCanvas
  11390. MOV EAX, EBX
  11391. CALL TBitmap.GetHandle
  11392. PUSH EAX
  11393. PUSH dword ptr [ESP+8]
  11394. CALL SelectObject
  11395. POP EDX
  11396. PUSH EAX
  11397. PUSH EDX
  11398. MOV EAX, [ESP+8]
  11399. end;
  11400. //[END StartDC]
  11401. //[procedure FinishDC]
  11402. procedure FinishDC;
  11403. asm
  11404. POP ECX
  11405. POP EAX
  11406. POP EDX
  11407. PUSH ECX
  11408. PUSH EDX
  11409. PUSH EAX
  11410. PUSH EDX
  11411. CALL SelectObject
  11412. CALL DeleteDC
  11413. end;
  11414. //[ENDe FinishDC]
  11415. {$ELSE ASM_VERSION}
  11416. {$ENDIF ASM_VERSION}
  11417. //[procedure FastIncNum2Elements]
  11418. procedure FastIncNum2Elements( List: TList; FromIdx, Count, Value: Integer );
  11419. begin
  11420. HelpFastIncNum2Els( @List.fItems[ FromIdx ], Value, Count );
  11421. end;
  11422. //[function EnumDynHandlers FORWARD DECLARATION]
  11423. function EnumDynHandlers( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  11424. forward;
  11425. //[procedure DummyObjProc]
  11426. procedure DummyObjProc( Sender: PObj );
  11427. begin
  11428. end;
  11429. //[procedure DummyObjProcParam]
  11430. procedure DummyObjProcParam( Sender: PObj; Param: Pointer );
  11431. begin
  11432. end;
  11433. //[procedure DummyPaintProc]
  11434. procedure DummyPaintProc( Sender: PControl; DC: HDC );
  11435. begin
  11436. end;
  11437. //[procedure Free_And_Nil]
  11438. procedure Free_And_Nil( var Obj );
  11439. var Obj1: PObj;
  11440. begin
  11441. Obj1 := PObj( Obj );
  11442. Pointer( Obj ) := nil;
  11443. Obj1.Free;
  11444. end;
  11445. //[ENDe Free_And_Nil]
  11446. {$IFDEF USE_NAMES}
  11447. function FindObj( const Name: String ): PObj;
  11448. var i: Integer;
  11449. Obj: PObj;
  11450. begin
  11451. if NamedObjectsList = nil then
  11452. NamedObjectsList := NewList;
  11453. for i := 0 to NamedObjectsList.Count-1 do
  11454. begin
  11455. Obj := NamedObjectsList.Items[ i ];
  11456. if Name = Obj.FName then
  11457. begin
  11458. Result := Obj; Exit;
  11459. end;
  11460. end;
  11461. Result := nil;
  11462. end;
  11463. {$ENDIF}
  11464. {-}
  11465. { _TObj }
  11466. //[procedure _TObj.Init]
  11467. procedure _TObj.Init;
  11468. begin
  11469. {$IFDEF _D2orD3}
  11470. FillChar( Pointer( Integer(@Self) + 4 )^, Sizeof( Self ) - 4, 0 );
  11471. {$ENDIF}
  11472. end;
  11473. //[function _TObj.VmtAddr]
  11474. function _TObj.VmtAddr: Pointer;
  11475. asm
  11476. MOV EAX, [EAX]
  11477. end;
  11478. { TObj }
  11479. class function TObj.AncestorOfObject(Obj: Pointer): Boolean;
  11480. asm
  11481. MOV ECX, [EAX]
  11482. MOV EAX, EDX
  11483. JMP @@loop1
  11484. @@loop:
  11485. MOV EAX,[EAX]
  11486. @@loop1:
  11487. TEST EAX,EAX
  11488. JE @@exit
  11489. CMP EAX,ECX
  11490. JNE @@loop
  11491. @@success:
  11492. MOV AL,1
  11493. @@exit:
  11494. end;
  11495. {+}
  11496. {$IFDEF ASM_VERSION}
  11497. constructor TObj.Create;
  11498. asm
  11499. //CALL System.@ObjSetup - Generated always by compiler
  11500. //JZ @@exit
  11501. PUSH EAX
  11502. MOV EDX, [EAX]
  11503. CALL dword ptr [EDX]
  11504. POP EAX
  11505. @@exit:
  11506. end;
  11507. {$ELSE ASM_VERSION} //Pascal
  11508. constructor TObj.Create;
  11509. begin
  11510. Init;
  11511. {++}(* inherited; *){--}
  11512. end;
  11513. {$ENDIF ASM_VERSION}
  11514. {$IFDEF ASM_VERSION}
  11515. //[procedure TObj.DoDestroy]
  11516. procedure TObj.DoDestroy;
  11517. asm
  11518. MOV EDX, [EAX].fRefCount
  11519. SAR EDX, 1
  11520. JZ @@1
  11521. JC @@exit
  11522. DEC [EAX].fRefCount
  11523. STC
  11524. @@1: JC @@exit
  11525. MOV EDX, [EAX]
  11526. CALL dword ptr [EDX + 4]
  11527. @@exit:
  11528. end;
  11529. {$ELSE ASM_VERSION} //Pascal
  11530. procedure TObj.DoDestroy;
  11531. begin
  11532. if fRefCount <> 0 then
  11533. begin
  11534. if not LongBool( fRefCount and 1) then
  11535. Dec( fRefCount );
  11536. end
  11537. else
  11538. Destroy;
  11539. end;
  11540. {$ENDIF ASM_VERSION}
  11541. {$IFDEF ASM_VERSION}
  11542. //[procedure TObj.RefDec]
  11543. procedure TObj.RefDec;
  11544. asm
  11545. SUB [EAX].fRefCount, 2
  11546. JGE @@exit
  11547. TEST [EAX].fRefCount, 1
  11548. JZ @@exit
  11549. MOV EDX, [EAX]
  11550. PUSH dword ptr [EDX+4]
  11551. @@exit:
  11552. end;
  11553. {$ELSE ASM_VERSION} //Pascal
  11554. procedure TObj.RefDec;
  11555. begin
  11556. Dec( fRefCount, 2 );
  11557. if (fRefCount < 0) and LongBool(fRefCount and 1) then
  11558. Destroy;
  11559. end;
  11560. {$ENDIF ASM_VERSION}
  11561. //[procedure TObj.RefInc]
  11562. procedure TObj.RefInc;
  11563. begin
  11564. Inc( fRefCount, 2 );
  11565. end;
  11566. {-}
  11567. //[function TObj.VmtAddr]
  11568. function TObj.VmtAddr: Pointer;
  11569. asm
  11570. MOV EAX, [EAX - 4]
  11571. end;
  11572. //[function TObj.InstanceSize]
  11573. function TObj.InstanceSize: Integer;
  11574. asm
  11575. MOV EAX, [EAX]
  11576. MOV EAX,[EAX-4]
  11577. end;
  11578. {+}
  11579. //[procedure TObj.Free]
  11580. {$IFDEF F_P}
  11581. procedure TObj.Free;
  11582. begin
  11583. if Self <> nil then
  11584. DoDestroy;
  11585. end;
  11586. {$ELSE DELPHI}
  11587. procedure TObj.Free;
  11588. asm
  11589. TEST EAX,EAX
  11590. JNE DoDestroy
  11591. end;
  11592. {$ENDIF F_P/DELPHI}
  11593. {$IFDEF ASM_VERSION}
  11594. destructor TObj.Destroy;
  11595. asm
  11596. PUSH EAX
  11597. CALL Final
  11598. POP EAX
  11599. {$IFDEF USE_NAMES}
  11600. PUSH EAX
  11601. XOR EDX, EDX
  11602. CALL SetName
  11603. POP EAX
  11604. {$ENDIF}
  11605. XOR EDX, EDX
  11606. CALL System.@FreeMem
  11607. //CALL System.@Dispose
  11608. end;
  11609. {$ELSE ASM_VERSION} //Pascal
  11610. destructor TObj.Destroy;
  11611. begin
  11612. Final;
  11613. {$IFDEF USE_NAMES}
  11614. Name := '';
  11615. {$ENDIF}
  11616. {$IFDEF DEBUG_ENDSESSION}
  11617. if EndSession_Initiated then
  11618. LogFileOutput( GetStartDir + 'es_debug.txt',
  11619. 'FINALLED: ' + Int2Hex( DWORD( @ Self )
  11620. {$IFDEF USE_NAMES}
  11621. + ' (name:' + FName + ')'
  11622. {$ENDIF}
  11623. , 8 ) );
  11624. {$ENDIF}
  11625. {-}
  11626. Dispose( @Self );
  11627. {+} {++}(*
  11628. inherited; *){--}
  11629. end;
  11630. {$ENDIF ASM_VERSION}
  11631. {++}(*
  11632. //[procedure TObj.Init]
  11633. procedure TObj.Init;
  11634. begin
  11635. end;
  11636. *){--}
  11637. {$IFDEF ASM_VERSION}
  11638. //[procedure TObj.Final]
  11639. procedure TObj.Final;
  11640. asm //cmd //opd
  11641. XOR ECX, ECX
  11642. XCHG ECX, [EAX].fOnDestroy.TMethod.Code
  11643. JECXZ @@doAutoFree
  11644. PUSH EAX
  11645. XCHG EDX, EAX
  11646. MOV EAX, [EDX].fOnDestroy.TMethod.Data
  11647. CALL ECX
  11648. POP EAX
  11649. @@doAutoFree:
  11650. XOR ECX, ECX
  11651. XCHG ECX, [EAX].fAutoFree
  11652. JECXZ @@exit
  11653. PUSH ESI
  11654. PUSH ECX
  11655. MOV ESI, [ECX].TList.fItems
  11656. MOV ECX, [ECX].TList.fCount
  11657. @@freeloop:
  11658. LODSD
  11659. XCHG EDX, EAX
  11660. LODSD
  11661. PUSH ECX
  11662. CALL EDX
  11663. POP ECX
  11664. DEC ECX
  11665. LOOP @@freeloop
  11666. POP EAX
  11667. CALL TObj.Free
  11668. POP ESI
  11669. @@exit:
  11670. end;
  11671. {$ELSE ASM_VERSION} //Pascal
  11672. procedure TObj.Final;
  11673. var I: Integer;
  11674. ProcMethod: TMethod;
  11675. Proc: TObjectMethod Absolute ProcMethod;
  11676. begin
  11677. if Assigned( fOnDestroy ) then
  11678. begin
  11679. fOnDestroy( @Self );
  11680. fOnDestroy := nil;
  11681. end;
  11682. if fAutoFree <> nil then
  11683. begin
  11684. for I := 0 to fAutoFree.fCount div 2 - 1 do
  11685. begin
  11686. ProcMethod.Code := fAutoFree.fItems[ I * 2 ];
  11687. ProcMethod.Data := fAutoFree.fItems[ I * 2 + 1 ];
  11688. {-}
  11689. Proc;
  11690. {+}{++}(*
  11691. asm
  11692. MOV EAX, [ProcMethod.Data]
  11693. {$IFDEF F_P}
  11694. PUSH EAX
  11695. {$ENDIF F_P}
  11696. MOV ECX, [ProcMethod.Code]
  11697. CALL ECX
  11698. end {$IFDEF F_P}[ 'EAX', 'EDX', 'ECX' ]{$ENDIF};
  11699. *){--}
  11700. end;
  11701. fAutoFree.Free;
  11702. fAutoFree := nil;
  11703. end;
  11704. end;
  11705. {$ENDIF ASM_VERSION}
  11706. {$IFDEF ASM_VERSION}
  11707. //[procedure TObj.Add2AutoFree]
  11708. procedure TObj.Add2AutoFree(Obj: PObj);
  11709. asm //cmd //opd
  11710. PUSH EBX
  11711. PUSH EDX
  11712. XCHG EBX, EAX
  11713. MOV EAX, [EBX].fAutoFree
  11714. TEST EAX, EAX
  11715. JNZ @@1
  11716. CALL NewList
  11717. MOV [EBX].fAutoFree, EAX
  11718. @@1: MOV EBX, EAX
  11719. XOR EDX, EDX
  11720. POP ECX
  11721. CALL TList.Insert
  11722. XCHG EAX, EBX
  11723. XOR EDX, EDX
  11724. MOV ECX, offset TObj.Free
  11725. //XOR ECX, ECX
  11726. CALL TList.Insert
  11727. POP EBX
  11728. end;
  11729. {$ELSE ASM_VERSION} //Pascal
  11730. procedure TObj.Add2AutoFree(Obj: PObj);
  11731. begin
  11732. if fAutoFree = nil then
  11733. fAutoFree := NewList;
  11734. fAutoFree.Insert( 0, Obj );
  11735. fAutoFree.Insert( 0, Pointer( @TObj.Free ) );
  11736. end;
  11737. {$ENDIF ASM_VERSION}
  11738. {$IFDEF ASM_VERSION}
  11739. //[procedure TObj.Add2AutoFreeEx]
  11740. procedure TObj.Add2AutoFreeEx( Proc: TObjectMethod );
  11741. asm //cmd //opd
  11742. PUSH EBX
  11743. XCHG EAX, EBX
  11744. MOV EAX, [EBX].fAutoFree
  11745. TEST EAX, EAX
  11746. JNZ @@1
  11747. CALL NewList
  11748. MOV [EBX].fAutoFree, EAX
  11749. @@1: XOR EDX, EDX
  11750. MOV ECX, [EBP+12] // Data
  11751. MOV EBX, EAX
  11752. CALL TList.Insert
  11753. XCHG EAX, EBX
  11754. XOR EDX, EDX
  11755. MOV ECX, [EBP+8] // Code
  11756. CALL TList.Insert
  11757. POP EBX
  11758. end;
  11759. {$ELSE ASM_VERSION} //Pascal
  11760. procedure TObj.Add2AutoFreeEx( Proc: TObjectMethod );
  11761. {$IFDEF F_P}
  11762. var Ptr1, Ptr2: Pointer;
  11763. {$ENDIF F_P}
  11764. begin
  11765. if fAutoFree = nil then
  11766. fAutoFree := NewList;
  11767. {$IFDEF F_P}
  11768. asm
  11769. MOV EAX, [Proc]
  11770. MOV [Ptr1], EAX
  11771. MOV EAX, [Proc+4]
  11772. MOV [Ptr2], EAX
  11773. end [ 'EAX' ];
  11774. fAutoFree.Insert( 0, Ptr2 );
  11775. fAutoFree.Insert( 0, Ptr1 );
  11776. {$ELSE DELPHI}
  11777. fAutoFree.Insert( 0, Pointer( TMethod( Proc ).Data ) );
  11778. fAutoFree.Insert( 0, Pointer( TMethod( Proc ).Code ) );
  11779. {$ENDIF}
  11780. end;
  11781. {$ENDIF ASM_VERSION}
  11782. {$IFDEF USE_NAMES}
  11783. procedure TObj.SetName(const NewName: String);
  11784. begin
  11785. if FName <> '' then
  11786. begin
  11787. NamedObjectsList.Remove( @ Self );
  11788. FName := '';
  11789. end;
  11790. if FindObj( NewName ) <> nil then Exit; // prevent duplications!
  11791. FName := NewName;
  11792. if FName <> '' then
  11793. NamedObjectsList.Add( @ Self );
  11794. end;
  11795. {$ENDIF}
  11796. { TList }
  11797. {$IFDEF USE_CONSTRUCTORS}
  11798. //[function NewList]
  11799. function NewList: PList;
  11800. begin
  11801. New( Result, Create );
  11802. //Result.fAddBy := 4;
  11803. end;
  11804. //[END NewList]
  11805. //[procedure TList.Init]
  11806. procedure TList.Init;
  11807. begin
  11808. inherited;
  11809. fAddBy := 4;
  11810. end;
  11811. {$ELSE not_USE_CONSTRUCTORS}
  11812. //[function NewList]
  11813. function NewList: PList;
  11814. begin
  11815. {-}
  11816. New( Result, Create );
  11817. {+} {++}(* Result := PList.Create; *){--}
  11818. //Result.fAddBy := 4;
  11819. end;
  11820. //[END NewList]
  11821. {$ENDIF USE_CONSTRUCTORS}
  11822. {$IFDEF _D4orHigher}
  11823. function NewListInit( const AItems: array of Pointer ): PList;
  11824. var i: Integer;
  11825. begin
  11826. Result := NewList;
  11827. Result.Capacity := Length( AItems );
  11828. for i := 0 to High( AItems ) do
  11829. Result.Add( AItems[ i ] );
  11830. end;
  11831. {$ENDIF}
  11832. {$IFDEF ASM_VERSION}
  11833. destructor TList.Destroy;
  11834. asm
  11835. PUSH EAX
  11836. CALL TList.Clear
  11837. POP EAX
  11838. CALL TObj.Destroy
  11839. end;
  11840. {$ELSE ASM_VERSION} //Pascal
  11841. destructor TList.Destroy;
  11842. begin
  11843. Clear;
  11844. inherited;
  11845. end;
  11846. {$ENDIF ASM_VERSION}
  11847. {$IFDEF ASM_VERSION}
  11848. //[procedure TList.Release]
  11849. procedure TList.Release;
  11850. asm
  11851. TEST EAX, EAX
  11852. JZ @@e
  11853. MOV ECX, [EAX].fCount
  11854. JECXZ @@e
  11855. MOV EDX, [EAX].fItems
  11856. PUSH EAX
  11857. @@1:
  11858. MOV EAX, [EDX+ECX*4-4]
  11859. TEST EAX, EAX
  11860. JZ @@2
  11861. PUSH EDX
  11862. PUSH ECX
  11863. CALL System.@FreeMem
  11864. POP ECX
  11865. POP EDX
  11866. @@2: LOOP @@1
  11867. POP EAX
  11868. @@e: CALL TObj.Free
  11869. end;
  11870. {$ELSE ASM_VERSION} //Pascal
  11871. procedure TList.Release;
  11872. var I: Integer;
  11873. begin
  11874. if @ Self = nil then Exit;
  11875. for I := 0 to fCount - 1 do
  11876. if fItems[ I ] <> nil then
  11877. FreeMem( fItems[ I ] );
  11878. Free;
  11879. end;
  11880. {$ENDIF ASM_VERSION}
  11881. //[procedure TList.ReleaseObjects]
  11882. procedure TList.ReleaseObjects;
  11883. var I: Integer;
  11884. begin
  11885. if @ Self = nil then Exit;
  11886. for I := fCount-1 downto 0 do
  11887. PObj( fItems[ I ] ).Free;
  11888. Free;
  11889. end;
  11890. {$IFDEF ASM_VERSION}
  11891. //[procedure TList.SetCapacity]
  11892. procedure TList.SetCapacity( Value: Integer );
  11893. asm
  11894. CMP EDX, [EAX].fCount
  11895. {$IFDEF USE_CMOV}
  11896. CMOVL EDX, [EAX].fCount
  11897. {$ELSE}
  11898. JGE @@1
  11899. MOV EDX, [EAX].fCount
  11900. @@1: {$ENDIF}
  11901. CMP EDX, [EAX].fCapacity
  11902. JE @@exit
  11903. MOV [EAX].fCapacity, EDX
  11904. SAL EDX, 2
  11905. LEA EAX, [EAX].fItems
  11906. CALL System.@ReallocMem
  11907. @@exit:
  11908. end;
  11909. {$ELSE ASM_VERSION} //Pascal
  11910. //var NewItems: PPointerList;
  11911. procedure TList.SetCapacity( Value: Integer );
  11912. begin
  11913. if Value < Count then
  11914. Value := Count;
  11915. if Value = fCapacity then Exit;
  11916. ReallocMem( fItems, Value * Sizeof( Pointer ) );
  11917. fCapacity := Value;
  11918. end;
  11919. {$ENDIF ASM_VERSION}
  11920. {$IFDEF ASM_VERSION}
  11921. //[procedure TList.Clear]
  11922. procedure TList.Clear;
  11923. asm
  11924. PUSH [EAX].fItems
  11925. XOR EDX, EDX
  11926. MOV [EAX].fItems, EDX
  11927. MOV [EAX].fCount, EDX
  11928. MOV [EAX].fCapacity, EDX
  11929. POP EAX
  11930. CALL System.@FreeMem
  11931. end;
  11932. {$ELSE ASM_VERSION} //Pascal
  11933. procedure TList.Clear;
  11934. begin
  11935. if fItems <> nil then
  11936. FreeMem( fItems );
  11937. fItems := nil;
  11938. fCount := 0;
  11939. fCapacity := 0;
  11940. end;
  11941. {$ENDIF ASM_VERSION}
  11942. //[procedure TList.SetAddBy]
  11943. procedure TList.SetAddBy(Value: Integer);
  11944. begin
  11945. if Value < 1 then Value := 1;
  11946. fAddBy := Value;
  11947. end;
  11948. {$IFDEF ASM_VERSION}
  11949. //[procedure TList.Add]
  11950. procedure TList.Add( Value: Pointer );
  11951. asm
  11952. PUSH EDX
  11953. LEA ECX, [EAX].fCount
  11954. MOV EDX, [ECX]
  11955. INC dword ptr [ECX]
  11956. PUSH EDX
  11957. CMP EDX, [EAX].fCapacity
  11958. PUSH EAX
  11959. JL @@ok
  11960. MOV ECX, [EAX].fAddBy
  11961. TEST ECX, ECX
  11962. JNZ @@add
  11963. MOV ECX, EDX
  11964. SHR ECX, 2
  11965. INC ECX
  11966. @@add:
  11967. ADD EDX, ECX
  11968. CALL TList.SetCapacity
  11969. @@ok:
  11970. POP ECX // ECX = Self
  11971. POP EAX // EAX = fCount -> Result (for TList.Insert)
  11972. POP EDX // EDX = Value
  11973. MOV ECX, [ECX].fItems
  11974. MOV [ECX + EAX*4], EDX
  11975. end;
  11976. {$ELSE ASM_VERSION} //Pascal
  11977. procedure TList.Add( Value: Pointer );
  11978. begin
  11979. //if fAddBy <= 0 then fAddBy := 4;
  11980. if fCapacity <= Count then
  11981. begin
  11982. if fAddBy <= 0 then
  11983. Capacity := Count + Min( 1000, Count div 4 + 1 )
  11984. else
  11985. Capacity := Count + fAddBy;
  11986. end;
  11987. fItems[ fCount ] := Value;
  11988. Inc( fCount );
  11989. end;
  11990. {$ENDIF ASM_VERSION}
  11991. {$IFDEF _D4orHigher}
  11992. procedure TList.AddItems(const AItems: array of Pointer);
  11993. var i: Integer;
  11994. begin
  11995. Capacity := Count + Length( AItems );
  11996. for i := 0 to High( AItems ) do
  11997. Add( AItems[ i ] );
  11998. end;
  11999. {$ENDIF}
  12000. //[procedure TList.Delete]
  12001. procedure TList.Delete( Idx: Integer );
  12002. begin
  12003. {Assert( (Idx >= 0) and (Idx < fCount), 'TList.Delete: index out of bounds' );
  12004. Move( fItems[ Idx + 1 ], fItems[ Idx ], Sizeof( Pointer ) * (Count - Idx - 1) );
  12005. Dec( fCount );}
  12006. DeleteRange( Idx, 1 );
  12007. end;
  12008. {$IFDEF ASM_VERSION}
  12009. //[procedure TList.DeleteRange]
  12010. procedure TList.DeleteRange(Idx, Len: Integer);
  12011. asm //cmd //opd
  12012. TEST ECX, ECX
  12013. JLE @@exit
  12014. CMP EDX, [EAX].fCount
  12015. JGE @@exit
  12016. PUSH EBX
  12017. XCHG EBX, EAX
  12018. LEA EAX, [EDX+ECX]
  12019. CMP EAX, [EBX].fCount
  12020. JBE @@1
  12021. MOV ECX, [EBX].fCount
  12022. SUB ECX, EDX
  12023. @@1:
  12024. MOV EAX, [EBX].fItems
  12025. PUSH [EBX].fCount
  12026. SUB [EBX].fCount, ECX
  12027. MOV EBX, EDX
  12028. LEA EDX, [EAX+EDX*4]
  12029. LEA EAX, [EDX+ECX*4]
  12030. ADD EBX, ECX
  12031. POP ECX
  12032. SUB ECX, EBX
  12033. SHL ECX, 2
  12034. CALL System.Move
  12035. POP EBX
  12036. @@exit:
  12037. end;
  12038. {$ELSE ASM_VERSION} //Pascal
  12039. procedure TList.DeleteRange(Idx, Len: Integer);
  12040. begin
  12041. if Len <= 0 then Exit;
  12042. if Idx >= Count then Exit;
  12043. Assert( (Idx >= 0), 'TList.DeleteRange: index out of bounds' );
  12044. if DWORD( Idx + Len ) > DWORD( Count ) then
  12045. Len := Count - Idx;
  12046. Move( fItems[ Idx + Len ], fItems[ Idx ], Sizeof( Pointer ) * (Count - Idx - Len) );
  12047. Dec( fCount, Len );
  12048. end;
  12049. {$ENDIF ASM_VERSION}
  12050. //[procedure TList.Remove]
  12051. procedure TList.Remove(Value: Pointer);
  12052. var I: Integer;
  12053. begin
  12054. I := IndexOf( Value );
  12055. if I >= 0 then
  12056. Delete( I );
  12057. end;
  12058. //[procedure TList.Put]
  12059. procedure TList.Put( Idx: Integer; Value: Pointer );
  12060. begin
  12061. if Idx < 0 then Exit;
  12062. if Idx >= Count then Exit;
  12063. //Assert( (Idx >= 0) and (Idx < fCount), 'TList.Put: index out of bounds' );
  12064. fItems[ Idx ] := Value;
  12065. end;
  12066. //[function TList.Get]
  12067. function TList.Get( Idx: Integer ): Pointer;
  12068. begin
  12069. Result := nil;
  12070. if Idx < 0 then Exit;
  12071. if Idx >= fCount then Exit;
  12072. //Assert( (Idx >= 0) and (Idx < fCount), 'TList.Get: index out of bounds' );
  12073. Result := fItems[ Idx ];
  12074. end;
  12075. {$IFDEF ASM_VERSION}
  12076. //[function TList.IndexOf]
  12077. function TList.IndexOf( Value: Pointer ): Integer;
  12078. asm
  12079. PUSH EDI
  12080. MOV EDI, [EAX].fItems
  12081. MOV ECX, [EAX].fCount
  12082. PUSH EDI
  12083. DEC EAX // make "NZ" - EAX always <> 1
  12084. MOV EAX, EDX
  12085. REPNZ SCASD
  12086. POP EDX
  12087. {$IFDEF USE_CMOV}
  12088. CMOVNZ EDI, EDX
  12089. {$ELSE}
  12090. JZ @@succ
  12091. MOV EDI, EDX
  12092. @@succ: {$ENDIF}
  12093. MOV EAX, EDI
  12094. STC
  12095. SBB EAX, EDX
  12096. SAR EAX, 2
  12097. POP EDI
  12098. end;
  12099. {$ELSE ASM_VERSION} //Pascal
  12100. function TList.IndexOf( Value: Pointer ): Integer;
  12101. var I: Integer;
  12102. begin
  12103. Result := -1;
  12104. for I := 0 to Count - 1 do
  12105. begin
  12106. if fItems[ I ] = Value then
  12107. begin
  12108. Result := I;
  12109. break;
  12110. end;
  12111. end;
  12112. end;
  12113. {$ENDIF ASM_VERSION}
  12114. {$IFDEF ASM_VERSION}
  12115. //[procedure TList.Insert]
  12116. procedure TList.Insert(Idx: Integer; Value: Pointer);
  12117. asm
  12118. PUSH ECX
  12119. PUSH EAX
  12120. PUSH [EAX].fCount
  12121. PUSH EDX
  12122. CALL TList.Add // don't matter what to add
  12123. POP EDX // EDX = Idx, Eax = Count-1
  12124. POP EAX
  12125. SUB EAX, EDX
  12126. SAL EAX, 2
  12127. MOV ECX, EAX // ECX = (Count - Idx - 1) * 4
  12128. POP EAX
  12129. MOV EAX, [EAX].fItems
  12130. LEA EAX, [EAX + EDX*4]
  12131. JL @@1
  12132. PUSH EAX
  12133. LEA EDX, [EAX + 4]
  12134. CALL System.Move
  12135. POP EAX // EAX = @fItems[ Idx ]
  12136. @@1:
  12137. POP ECX // ECX = Value
  12138. MOV [EAX], ECX
  12139. end;
  12140. {$ELSE ASM_VERSION} //Pascal
  12141. procedure TList.Insert(Idx: Integer; Value: Pointer);
  12142. begin
  12143. Assert( (Idx >= 0) and (Idx <= Count), 'List index out of bounds' );
  12144. Add( nil );
  12145. if fCount > Idx then
  12146. Move( FItems[ Idx ], FItems[ Idx + 1 ], (fCount - Idx - 1) * Sizeof( Pointer ) );
  12147. FItems[ Idx ] := Value;
  12148. end;
  12149. {$ENDIF ASM_VERSION}
  12150. {$IFDEF ASM_VERSION}
  12151. //[procedure TList.MoveItem]
  12152. procedure TList.MoveItem(OldIdx, NewIdx: Integer);
  12153. asm
  12154. CMP EDX, ECX
  12155. JE @@exit
  12156. CMP ECX, [EAX].fCount
  12157. JGE @@exit
  12158. PUSH EDI
  12159. MOV EDI, [EAX].fItems
  12160. PUSH dword ptr [EDI + EDX*4]
  12161. PUSH ECX
  12162. PUSH EAX
  12163. CALL TList.Delete
  12164. POP EAX
  12165. POP EDX
  12166. POP ECX
  12167. POP EDI
  12168. CALL TList.Insert
  12169. @@exit:
  12170. end;
  12171. {$ELSE ASM_VERSION} //Pascal
  12172. procedure TList.MoveItem(OldIdx, NewIdx: Integer);
  12173. var Item: Pointer;
  12174. //I: Integer;
  12175. begin
  12176. if OldIdx = NewIdx then Exit;
  12177. if NewIdx >= Count then Exit;
  12178. Item := Items[ OldIdx ];
  12179. Delete( OldIdx );
  12180. Insert( NewIdx, Item );
  12181. end;
  12182. {$ENDIF ASM_VERSION}
  12183. {$IFDEF ASM_VERSION}
  12184. //[function TList.Last]
  12185. function TList.Last: Pointer;
  12186. asm //cmd //opd
  12187. MOV ECX, [EAX].fCount
  12188. JECXZ @@0
  12189. MOV EAX, [EAX].fItems
  12190. DEC ECX
  12191. MOV ECX, [EAX + ECX*4]
  12192. @@0: XCHG EAX, ECX
  12193. end;
  12194. {$ELSE ASM_VERSION} //Pascal
  12195. function TList.Last: Pointer;
  12196. begin
  12197. if Count = 0 then
  12198. Result := nil
  12199. else
  12200. Result := Items[ Count-1 ];
  12201. end;
  12202. {$ENDIF ASM_VERSION}
  12203. {$IFDEF ASM_VERSION}
  12204. //[procedure TList.Swap]
  12205. procedure TList.Swap(Idx1, Idx2: Integer);
  12206. asm
  12207. MOV EAX, [EAX].fItems
  12208. PUSH dword ptr [EAX + EDX*4]
  12209. PUSH ECX
  12210. MOV ECX, [EAX + ECX*4]
  12211. MOV [EAX + EDX*4], ECX
  12212. POP ECX
  12213. POP EDX
  12214. MOV [EAX + ECX*4], EDX
  12215. end;
  12216. {$ELSE ASM_VERSION} //Pascal
  12217. procedure TList.Swap(Idx1, Idx2: Integer);
  12218. var Tmp: Pointer;
  12219. begin
  12220. Tmp := FItems[ Idx1 ];
  12221. FItems[ Idx1 ] := FItems[ Idx2 ];
  12222. FItems[ Idx2 ] := Tmp;
  12223. end;
  12224. {$ENDIF ASM_VERSION}
  12225. //[procedure TList.SetCount]
  12226. procedure TList.SetCount(const Value: Integer);
  12227. begin
  12228. if Value >= Count then exit;
  12229. fCount := Value;
  12230. end;
  12231. //[procedure TList.Assign]
  12232. procedure TList.Assign(SrcList: PList);
  12233. begin
  12234. Clear;
  12235. if SrcList.fCount > 0 then
  12236. begin
  12237. Capacity := SrcList.fCount;
  12238. fCount := SrcList.fCount;
  12239. Move( SrcList.FItems[ 0 ], FItems[ 0 ], Sizeof( Pointer ) * fCount );
  12240. end;
  12241. end;
  12242. { -- Window procedure -- }
  12243. {$IFDEF ASM_VERSION} //!!//!!
  12244. //[FUNCTION CallCtlWndProc]
  12245. function CallCtlWndProc( Ctl: PControl; var Msg: TMsg ): Integer;
  12246. begin
  12247. Result := Ctl.WndProc( Msg );
  12248. end;
  12249. //[END CallCtlWndProc]
  12250. //[function WndFunc]
  12251. function WndFunc( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  12252. : Integer; stdcall;
  12253. const size_TMsg = sizeof( TMsg );
  12254. asm
  12255. ADD ESP, -size_TMsg
  12256. MOV EDX, ESP
  12257. PUSH ESI
  12258. PUSH EDI
  12259. MOV EDI, EDX
  12260. LEA ESI, [W]
  12261. MOVSD
  12262. MOVSD
  12263. MOVSD
  12264. MOVSD
  12265. MOV EDI, EDX
  12266. MOV EAX, [EDI]
  12267. TEST EAX, EAX
  12268. JZ @@self_is_nil
  12269. MOV ECX, [CreatingWindow]
  12270. JECXZ @@get_self_prop
  12271. MOV [ECX].TControl.fHandle, EAX
  12272. //set_self_prop:
  12273. PUSH ECX
  12274. PUSH ECX
  12275. PUSH Offset[ID_SELF]
  12276. PUSH EAX
  12277. CALL SetProp
  12278. XOR EAX, EAX
  12279. MOV [CreatingWindow], EAX
  12280. POP EAX // EAX = self_
  12281. JMP @@self_got
  12282. @@get_self_prop:
  12283. PUSH Offset[ID_SELF]
  12284. PUSH EAX
  12285. CALL GetProp
  12286. TEST EAX, EAX
  12287. JNZ @@self_got
  12288. @@self_is_nil:
  12289. OR EAX, [ Applet ]
  12290. JNZ @@self_got
  12291. //try_defwndproc:
  12292. POP EDI
  12293. POP ESI
  12294. MOV ESP, EBP
  12295. POP EBP
  12296. JMP DefWindowProc
  12297. //@@id_self:
  12298. // DB 'SELF_',0
  12299. @@self_got:
  12300. MOV EDX, EDI
  12301. //CALL TControl.WndProc
  12302. CALL CallCtlWndProc
  12303. POP EDI
  12304. POP ESI
  12305. MOV ESP, EBP
  12306. end;
  12307. {$ELSE ASM_VERSION} //Pascal
  12308. function WndFunc( W: HWnd; Msg: Cardinal; wParam, lParam: Integer )
  12309. : Integer; stdcall;
  12310. var M: TMsg;
  12311. self_: PControl;
  12312. begin
  12313. M.hwnd := W;
  12314. M.message := Msg;
  12315. M.wParam := wParam;
  12316. M.lParam := lParam;
  12317. {$IFDEF DEBUG_ENDSESSION}
  12318. if EndSession_Initiated then
  12319. begin
  12320. LogFileOutput( GetStartDir + 'es_debug.txt',
  12321. 'HWND:' + Int2Str( W ) + ' MSG:$' + Int2Hex( Msg, 4 ) +
  12322. ' WParam: ' + Int2Str( wParam ) + '($' + Int2Hex( wParam, 8 ) + ')' +
  12323. ' LParam: ' + Int2Str( lParam ) + '($' + Int2Hex( lParam, 8 ) + ')' );
  12324. end;
  12325. {$ENDIF}
  12326. self_ := nil;
  12327. if W <> 0 then
  12328. begin
  12329. if CreatingWindow <> nil then
  12330. begin
  12331. {$IFDEF DEBUG_CREATEWINDOW}
  12332. LogFileOutput( GetStartDir + 'Session.log',
  12333. 'WndFunc: Creating window = ' + Int2Hex( Integer( CreatingWindow ), 4 ) +
  12334. ' hwnd=' + Int2Str( M.hwnd ) +
  12335. ' message=' + Int2Hex( M.message, 4 ) +
  12336. ' wParam=' + Int2Str( M.wParam ) + '=$' + Int2Hex( M.wParam, 4 ) +
  12337. ' lParam=' + Int2Str( M.lParam ) + '=$' + Int2Hex( M.lParam, 4 )
  12338. );
  12339. {$ENDIF DEBUG_CREATEWINDOW}
  12340. self_ := CreatingWindow;
  12341. CreatingWindow.fHandle := W;
  12342. SetProp( W, ID_SELF, THandle( CreatingWindow ) );
  12343. CreatingWindow := nil;
  12344. end
  12345. else
  12346. self_ := Pointer( GetProp( W, ID_SELF ) );
  12347. end;
  12348. if self_ <> nil then
  12349. Result := self_.WndProc( M )
  12350. else
  12351. if Assigned( Applet ) then
  12352. Result := Applet.WndProc( M )
  12353. else
  12354. Result := DefWindowProc( W, Msg, wParam, lParam );
  12355. {$IFDEF DEBUG_ENDSESSION}
  12356. if EndSession_Initiated then
  12357. begin
  12358. LogFileOutput( GetStartDir + 'es_debug.txt',
  12359. 'HWND:' + Int2Str( W ) + ' MSG:$' + Int2Hex( Msg, 4 ) +
  12360. ' Result: ' + Int2Str( Result ) + '($' + Int2Hex( Result, 8 ) + ')' );
  12361. end;
  12362. {$ENDIF}
  12363. end;
  12364. //[END WndFunc]
  12365. {$ENDIF ASM_VERSION}
  12366. var
  12367. IdleHandlers: PList;
  12368. ProcessIdle: procedure ( Sender: PObj ) = DummyObjProc;
  12369. //[procedure ProcessIdleProc]
  12370. procedure ProcessIdleProc( Sender: PObj );
  12371. var
  12372. i: integer;
  12373. m: TMethod;
  12374. begin
  12375. if AppletTerminated then exit; // YS +
  12376. i := 0;
  12377. with IdleHandlers{-}^{+} do
  12378. while i < Count do begin
  12379. m.Code:=Items[i];
  12380. Inc(i);
  12381. m.Data:=Items[i];
  12382. Inc(i);
  12383. TOnEvent(m)(Sender);
  12384. end;
  12385. end;
  12386. //[function FindIdleHandler]
  12387. function FindIdleHandler( const OnIdle: TOnEvent ): integer;
  12388. var
  12389. i: integer;
  12390. begin
  12391. i := 0;
  12392. if not AppletTerminated then //+ {Maxim Pushkar}
  12393. with TMethod(OnIdle), IdleHandlers{-}^{+} do
  12394. while i < Count do begin
  12395. if (Items[i] = Code) and (Items[i + 1] = Data) then
  12396. begin
  12397. Result := i;
  12398. exit;
  12399. end;
  12400. Inc(i, 2);
  12401. end;
  12402. Result := -1;
  12403. end;
  12404. //[END FindIdleHandler]
  12405. //[procedure RegisterIdleHandler]
  12406. procedure RegisterIdleHandler( const OnIdle: TOnEvent );
  12407. begin
  12408. if IdleHandlers = nil then begin
  12409. IdleHandlers := NewList;
  12410. if Applet <> nil then
  12411. Applet.Add2AutoFree(IdleHandlers);
  12412. end;
  12413. with TMethod(OnIdle) do
  12414. begin
  12415. IdleHandlers.Add(Code);
  12416. IdleHandlers.Add(Data);
  12417. end;
  12418. ProcessIdle := @ProcessIdleProc;
  12419. end;
  12420. //[procedure UnRegisterIdleHandler]
  12421. procedure UnRegisterIdleHandler( const OnIdle: TOnEvent );
  12422. var
  12423. i: integer;
  12424. begin
  12425. i := FindIdleHandler(OnIdle);
  12426. if i <> -1 then
  12427. with IdleHandlers{-}^{+} do
  12428. begin
  12429. Delete(i);
  12430. Delete(i);
  12431. end;
  12432. end;
  12433. //[procedure TerminateExecution]
  12434. procedure TerminateExecution( var AppletWnd: PControl );
  12435. var App: PControl;
  12436. Appalreadyterminated: Boolean;
  12437. begin
  12438. Appalreadyterminated := AppletTerminated;
  12439. AppletTerminated := TRUE;
  12440. AppletRunning := FALSE;
  12441. App := Applet;
  12442. Applet := nil;
  12443. if (App <> nil) {and (App.RefCount >= 0)} then
  12444. begin
  12445. App.RefInc;
  12446. if not Appalreadyterminated then
  12447. begin
  12448. App.ProcessMessages;
  12449. App.Perform( WM_CLOSE, 0, 0 );
  12450. end;
  12451. AppletWnd := nil;
  12452. App.Free;
  12453. App.RefDec;
  12454. end;
  12455. end;
  12456. //[PROCEDURE CallTControlCreateWindow]
  12457. {$IFDEF ASM_VERSION}
  12458. procedure CallTControlCreateWindow( Ctl: PControl );
  12459. begin
  12460. Ctl.CreateWindow;
  12461. end;
  12462. //[END CallTControlCreateWindow]
  12463. //[PROCEDURE Run]
  12464. procedure Run( var AppletWnd: PControl );
  12465. asm
  12466. PUSH EBX
  12467. XCHG EBX, EAX
  12468. INC [AppletRunning]
  12469. MOV EAX, [EBX]
  12470. MOV [Applet], EAX
  12471. CALL CallTControlCreateWindow
  12472. JMP @@2
  12473. @@1:
  12474. CALL WaitMessage
  12475. MOV EAX, [EBX]
  12476. CALL TControl.ProcessMessages
  12477. {$IFNDEF NOT_USE_OnIdle}
  12478. MOV EAX, [EBX]
  12479. CALL [ProcessIdle]
  12480. {$ENDIF}
  12481. @@2:
  12482. CMP [AppletTerminated],0
  12483. JZ @@1
  12484. XCHG EAX, EBX
  12485. POP EBX
  12486. TEST EAX, EAX
  12487. JNZ TerminateExecution
  12488. end;
  12489. {$ELSE ASM_VERSION} //Pascal
  12490. procedure Run( var AppletWnd: PControl );
  12491. begin
  12492. AppletRunning := True;
  12493. Applet := AppletWnd;
  12494. AppletWnd.CreateWindow; //virtual!!!
  12495. while not AppletTerminated do
  12496. begin
  12497. WaitMessage;
  12498. AppletWnd.ProcessMessages;
  12499. {$IFNDEF NOT_USE_OnIdle}
  12500. ProcessIdle( AppletWnd );
  12501. {$ENDIF}
  12502. end;
  12503. if AppletWnd <> nil then
  12504. TerminateExecution( AppletWnd );
  12505. end;
  12506. //[END Run]
  12507. {$ENDIF ASM_VERSION}
  12508. //[procedure AppletMinimize]
  12509. procedure AppletMinimize;
  12510. begin
  12511. if Applet = nil then Exit;
  12512. Applet.Perform( WM_SYSCOMMAND, SC_MINIMIZE, 0 );
  12513. end;
  12514. //[procedure AppletHide]
  12515. procedure AppletHide;
  12516. begin
  12517. if Applet = nil then Exit;
  12518. AppletMinimize;
  12519. Applet.Hide;
  12520. end;
  12521. //[procedure AppletRestore]
  12522. procedure AppletRestore;
  12523. begin
  12524. if Applet = nil then Exit;
  12525. Applet.Show;
  12526. Applet.Perform( WM_SYSCOMMAND, SC_RESTORE, 0 );
  12527. end;
  12528. //[function ScreenWidth]
  12529. function ScreenWidth: Integer;
  12530. begin
  12531. Result := GetSystemMetrics( SM_CXSCREEN );
  12532. end;
  12533. //[END ScreenWidth]
  12534. //[function ScreenHeight]
  12535. function ScreenHeight: Integer;
  12536. begin
  12537. Result := GetSystemMetrics( SM_CYSCREEN );
  12538. end;
  12539. //[END ScreenHeight]
  12540. {$IFDEF USE_CONSTRUCTORS}
  12541. {$DEFINE WNDPROCAPP_USED}
  12542. {$DEFINE WNDPROCAPP_ASM_USED}
  12543. {$ENDIF USE_CONSTRUCTORS}
  12544. {$IFNDEF ASM_VERSION}
  12545. {$DEFINE WNDPROCAPP_USED}
  12546. {$ENDIF ASM_VERSION}
  12547. {$DEFINE WNDPROCAPP_USED}
  12548. {$IFNDEF WNDPROCAPP_USED}
  12549. //[WndProcXXX FORWARD DECLARATIONS]
  12550. {$IFNDEF ASM_VERSION}
  12551. function WndProcApp( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12552. {$ENDIF}
  12553. {$ENDIF}
  12554. function WndProcForm( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12555. //function WndProcCtrl( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12556. function WndProcPaint( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12557. function WndProcGradient( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12558. function WndProcGradientEx( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12559. function WndProcLabelEffect( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12560. //function WndProcParentResize(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12561. //function WndProcResize(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12562. function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12563. function WndProcCommonNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean; forward;
  12564. var fGlobalProcKeybd: function( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean =
  12565. WndProcDummy;
  12566. //[END OF WndProcXXX FORWARD DECLARATIONS]
  12567. { -- Graphics support -- }
  12568. //[function _NewGraphicTool]
  12569. function _NewGraphicTool: PGraphicTool;
  12570. begin
  12571. {-}
  12572. New( Result, Create );
  12573. {+}
  12574. {++}(*Result := PGraphicTool.Create;*){--}
  12575. end;
  12576. //[END _NewGraphicTool]
  12577. //[FUNCTION SimpleGetCtlBrushHandle]
  12578. {$IFDEF ASM_VERSION}
  12579. function SimpleGetCtlBrushHandle( Sender: PControl ): HBrush;
  12580. asm // //
  12581. @@1: MOV ECX, [EAX].TControl.fParent
  12582. JECXZ @@2
  12583. MOV EDX, [EAX].TControl.fColor
  12584. CMP EDX, [ECX].TControl.fColor
  12585. XCHG EAX, ECX
  12586. JE @@1
  12587. XCHG EAX, ECX
  12588. @@2: PUSH EBX
  12589. XCHG EBX, EAX
  12590. MOV ECX, [EBX].TControl.fTmpBrush
  12591. JECXZ @@3
  12592. MOV EAX, [EBX].TControl.fColor
  12593. CALL Color2RGB
  12594. CMP EAX, [EBX].TControl.fTmpBrushColorRGB
  12595. JE @@3
  12596. XOR EAX, EAX
  12597. XCHG [EBX].TControl.fTmpBrush, EAX
  12598. PUSH EAX
  12599. CALL DeleteObject
  12600. @@3: MOV EAX, [EBX].TControl.fTmpBrush
  12601. TEST EAX, EAX
  12602. JNE @@4
  12603. MOV EAX, [EBX].TControl.fColor
  12604. CALL Color2RGB
  12605. MOV [EBX].TControl.fTmpBrushColorRGB, EAX
  12606. PUSH EAX
  12607. CALL CreateSolidBrush
  12608. MOV [EBX].TControl.fTmpBrush, EAX
  12609. @@4: POP EBX
  12610. end;
  12611. {$ELSE ASM_VERSION PAS_VERSION}
  12612. function SimpleGetCtlBrushHandle( Sender: PControl ): HBrush;
  12613. begin
  12614. if (Sender.fParent <> nil) and (Sender.fColor = Sender.fParent.fColor) then
  12615. Result := SimpleGetCtlBrushHandle( Sender.fParent )
  12616. else
  12617. begin
  12618. if (Sender.fTmpBrush <> 0) and
  12619. (Color2RGB( Sender.fColor ) <> Sender.fTmpBrushColorRGB) then
  12620. begin
  12621. DeleteObject( Sender.fTmpBrush );
  12622. Sender.fTmpBrush := 0;
  12623. end;
  12624. if Sender.fTmpBrush = 0 then
  12625. begin
  12626. Sender.fTmpBrushColorRGB := Color2RGB( Sender.fColor );
  12627. Sender.fTmpBrush := CreateSolidBrush( Sender.fTmpBrushColorRGB );
  12628. end;
  12629. Result := Sender.fTmpBrush;
  12630. end;
  12631. end;
  12632. {$ENDIF ASM_VERSION}
  12633. //[END SimpleGetCtlBrushHandle]
  12634. //[function NormalGetCtlBrushHandle]
  12635. function NormalGetCtlBrushHandle( Sender: PControl ): HBrush;
  12636. begin
  12637. if (Sender.fParent <> nil) then
  12638. Sender.Brush.fParentGDITool := Sender.fParent.Brush;
  12639. {if (Sender.Brush.fHandle <> 0) and
  12640. (Color2RGB( Sender.fBrush.fData.Color ) <> Sender.fBrush.fColorRGB) then
  12641. DeleteObject( Sender.Brush.ReleaseHandle );}
  12642. Result := Sender.Brush.Handle;
  12643. end;
  12644. //[END NormalGetCtlBrushHandle]
  12645. {++}(*
  12646. //[API CreateFontIndirect]
  12647. function CreateFontIndirect(const p1: TLogFont): HFONT; stdcall;
  12648. external gdi32 name 'CreateFontIndirectA';
  12649. *){--}
  12650. //[MakeXXXHandle FORWARD DECLARATIONS]
  12651. function MakeFontHandle( Self_: PGraphicTool ): THandle; forward;
  12652. function MakeBrushHandle( Self_: PGraphicTool ): THandle; forward;
  12653. function MakePenHandle( Self_: PGraphicTool ): THandle; forward;
  12654. function MakeGeometricPenHandle( Self_: PGraphicTool ): THandle; forward;
  12655. //[END OF MakeXXXHandle FORWARD DECLARATIONS]
  12656. //[FUNCTION NewBrush]
  12657. {$IFDEF ASM_VERSION}
  12658. function NewBrush: PGraphicTool;
  12659. asm
  12660. MOV [Global_GetCtlBrushHandle], offset NormalGetCtlBrushHandle
  12661. CALL _NewGraphicTool
  12662. MOV [EAX].TGraphicTool.fNewProc, offset[NewBrush]
  12663. MOV [EAX].TGraphicTool.fType, gttBrush
  12664. MOV [EAX].TGraphicTool.fMakeHandleProc, offset[MakeBrushHandle]
  12665. MOV [EAX].TGraphicTool.fData.Color, clBtnFace
  12666. end;
  12667. {$ELSE ASM_VERSION} //Pascal
  12668. function NewBrush: PGraphicTool;
  12669. begin
  12670. Global_GetCtlBrushHandle := NormalGetCtlBrushHandle;
  12671. Result := _NewGraphicTool;
  12672. with Result {-}^{+} do
  12673. begin
  12674. fNewProc := @ NewBrush;
  12675. fType := gttBrush;
  12676. fMakeHandleProc := @ MakeBrushHandle;
  12677. Result.fData.Color := clBtnFace;
  12678. //Result.fData.Brush.Style := bsSolid;
  12679. end;
  12680. end;
  12681. {$ENDIF ASM_VERSION}
  12682. //[END NewBrush]
  12683. const size_FontData = sizeof( Integer {fFontHeight} ) + sizeof( Integer {fFontWidth} ) +
  12684. sizeof( TFontPitch ) + sizeof( TFontStyle ) +
  12685. sizeof( Integer {fFontOrientation} ) +
  12686. sizeof( Integer {fFontWeight} ) + sizeof( TFontCharset ) +
  12687. sizeof( TFontQuality );
  12688. //[FUNCTION NewFont]
  12689. {$IFDEF ASM_VERSION}
  12690. function NewFont: PGraphicTool;
  12691. const FontDtSz = sizeof( TGDIFont );
  12692. asm
  12693. CALL _NewGraphicTool
  12694. MOV [EAX].TGraphicTool.fNewProc, offset[NewFont]
  12695. MOV [EAX].TGraphicTool.fType, gttFont
  12696. MOV [EAX].TGraphicTool.fMakeHandleProc, offset[MakeFontHandle]
  12697. MOV EDX, [DefFontColor]
  12698. MOV [EAX].TGraphicTool.fData.Color, EDX
  12699. PUSH EAX
  12700. LEA EDX, [EAX].TGraphicTool.fData.Font
  12701. MOV EAX, offset[ DefFont ]
  12702. XOR ECX, ECX
  12703. MOV CL, FontDtSz
  12704. CALL System.Move
  12705. POP EAX
  12706. end;
  12707. {$ELSE ASM_VERSION} //Pascal
  12708. function NewFont: PGraphicTool;
  12709. begin
  12710. Result := _NewGraphicTool;
  12711. with Result {-}^{+} do
  12712. begin
  12713. fNewProc := @ NewFont;
  12714. fType := gttFont;
  12715. fMakeHandleProc := @ MakeFontHandle;
  12716. fData.Color := DefFontColor;
  12717. Move( DefFont, fData.Font, Sizeof( TGDIFont ) );
  12718. end;
  12719. end;
  12720. {$ENDIF ASM_VERSION}
  12721. //[END NewFont]
  12722. //[FUNCTION NewPen]
  12723. {$IFDEF ASM_VERSION}
  12724. function NewPen: PGraphicTool;
  12725. asm
  12726. CALL _NewGraphicTool
  12727. MOV [EAX].TGraphicTool.fNewProc, offset[NewPen]
  12728. MOV [EAX].TGraphicTool.fType, gttPen
  12729. MOV [EAX].TGraphicTool.fMakeHandleProc, offset[MakePenHandle]
  12730. MOV [EAX].TGraphicTool.fData.Pen.Mode, pmCopy
  12731. end;
  12732. {$ELSE ASM_VERSION} //Pascal
  12733. function NewPen: PGraphicTool;
  12734. begin
  12735. Result := _NewGraphicTool;
  12736. with Result{-}^{+} do
  12737. begin
  12738. fNewProc := @ NewPen;
  12739. fType := gttPen;
  12740. fMakeHandleProc := @ MakePenHandle;
  12741. fData.Pen.Mode := pmCopy;
  12742. end;
  12743. end;
  12744. {$ENDIF ASM_VERSION}
  12745. //[END NewPen]
  12746. //+
  12747. //[function Color2RGB]
  12748. function Color2RGB( Color: TColor ): TColor;
  12749. begin
  12750. if Color < 0 then
  12751. Result := GetSysColor(Color and $FF) else
  12752. Result := Color;
  12753. end;
  12754. //[END Color2RGB]
  12755. //[function ColorsMix]
  12756. function ColorsMix( Color1, Color2: TColor ): TColor;
  12757. {$IFDEF F_P}
  12758. begin
  12759. Result := ((Color2RGB( Color1 ) and $FEFEFE) shr 1) +
  12760. ((Color2RGB( Color2 ) and $FEFEFE) shr 1);
  12761. end;
  12762. {$ELSE DELPHI}
  12763. asm
  12764. PUSH EDX
  12765. CALL Color2Rgb
  12766. XCHG EAX, [ESP]
  12767. CALL Color2Rgb
  12768. POP EDX
  12769. AND EAX, 0FEFEFEh
  12770. AND EDX, 0FEFEFEh
  12771. SHR EAX, 1
  12772. SHR EDX, 1
  12773. ADD EAX, EDX
  12774. end;
  12775. {$ENDIF F_P/DELPHI}
  12776. //[END ColorsMix]
  12777. //[FUNCTION Color2RGBQuad]
  12778. {$IFDEF ASM_VERSION}
  12779. function Color2RGBQuad( Color: TColor ): TRGBQuad;
  12780. asm
  12781. CALL Color2RGB
  12782. // code by bart:
  12783. xchg ah,al // xxRRGGBB
  12784. ror eax,16 // BBGGxxRR
  12785. xchg ah,al // BBGGRRxx
  12786. shr eax,8 // 00BBGGRR
  12787. end;
  12788. {$ELSE ASM_VERSION} //Pascal
  12789. function Color2RGBQuad( Color: TColor ): TRGBQuad;
  12790. var C: Integer;
  12791. begin
  12792. C := Color2RGB( Color );
  12793. C := ((C shr 16) and $FF)
  12794. or ((C shl 16) and $FF0000)
  12795. or (C and $FF00);
  12796. Result := TRGBQuad( C );
  12797. end;
  12798. {$ENDIF ASM_VERSION}
  12799. //[END Color2RGBQuad]
  12800. //[FUNCTION Color2Color16]
  12801. {$IFDEF ASM_VERSION}
  12802. function Color2Color16( Color: TColor ): WORD;
  12803. asm
  12804. MOV EDX, EAX
  12805. SHR EDX, 19
  12806. AND EDX, $1F
  12807. MOV ECX, EAX
  12808. SHR ECX, 5
  12809. AND ECX, $7E0;
  12810. MOV AH, AL
  12811. AND EAX, $F800
  12812. OR EAX, EDX
  12813. OR EAX, ECX
  12814. end;
  12815. {$ELSE ASM_VERSION}
  12816. function Color2Color16( Color: TColor ): WORD;
  12817. begin
  12818. Color := Color2RGB( Color );
  12819. Result := (Color shr 19) and $1F or
  12820. (Color shr 5) and $7E0 or
  12821. (Color shl 8) and $F800;
  12822. end;
  12823. {$ENDIF ASM_VERSION}
  12824. //[END Color2Color16]
  12825. { TGraphicTool }
  12826. {$IFDEF ASM_VERSION}
  12827. //[function TGraphicTool.Assign]
  12828. function TGraphicTool.Assign(Value: PGraphicTool): PGraphicTool;
  12829. const SzfData = sizeof( fData );
  12830. asm // //
  12831. TEST EDX, EDX
  12832. JNZ @@1
  12833. TEST EAX, EAX
  12834. JZ @@0
  12835. CALL TObj.DoDestroy
  12836. XOR EAX, EAX
  12837. @@0: RET
  12838. @@1: PUSH EDI
  12839. MOV EDI, EDX
  12840. TEST EAX, EAX
  12841. JNZ @@2
  12842. XCHG EAX, EDX
  12843. CALL dword ptr[EAX].TGraphicTool.fNewProc
  12844. @@2: CMP EAX, EDI
  12845. JE @@exit
  12846. PUSH EBX
  12847. XCHG EBX, EAX
  12848. MOV ECX, [EBX].TGraphicTool.fHandle
  12849. JECXZ @@3
  12850. CMP ECX, [EDI].TGraphicTool.fHandle
  12851. JE @@exit1
  12852. @@3:
  12853. MOV EAX, EBX
  12854. CALL TGraphicTool.Changed
  12855. LEA EDX, [EBX].TGraphicTool.fData
  12856. LEA EAX, [EDI].TGraphicTool.fData
  12857. MOV ECX, SzfData
  12858. CALL System.Move
  12859. MOV EAX, EBX
  12860. CALL TGraphicTool.Changed
  12861. @@exit1:
  12862. XCHG EAX, EBX
  12863. POP EBX
  12864. @@exit: POP EDI
  12865. end;
  12866. {$ELSE ASM_VERSION}
  12867. function TGraphicTool.Assign(Value: PGraphicTool): PGraphicTool;
  12868. var _Self: PGraphicTool;
  12869. begin
  12870. Result := nil;
  12871. if Value = nil then
  12872. begin
  12873. if @Self <> nil then
  12874. DoDestroy;
  12875. Exit;
  12876. end;
  12877. _Self := @Self;
  12878. if _Self = nil then
  12879. _Self := Value.fNewProc();
  12880. Result := _Self;
  12881. if _Self = Value then Exit; // to avoid infinite loop when assigning to itself
  12882. if _Self.fHandle <> 0 then
  12883. if Value.fHandle = _Self.fHandle then Exit;
  12884. _Self.Changed; // to destroy handle if allocated and release it from the canvas (if any uses it)
  12885. Assert( Value.fType = _Self.fType, 'Attempt to assign to different GDI tool type' );
  12886. Move( Value.fData, _Self.fData, Sizeof( fData ) );
  12887. _Self.Changed; // to inform owner control, that its tool (font, brush) changed
  12888. end;
  12889. {$ENDIF ASM_VERSION}
  12890. //[procedure TGraphicTool.AssignHandle]
  12891. procedure TGraphicTool.AssignHandle(NewHandle: Integer);
  12892. begin
  12893. //------------ by Yury Sidorov --------
  12894. //Changed;
  12895. //-------------------------------------//
  12896. if fHandle <> 0 then //
  12897. DeleteObject( fHandle ); //
  12898. //-------------------------------------//
  12899. fHandle := NewHandle;
  12900. GetObject( fHandle, Sizeof( TGDIFont ), @ fData.Font );
  12901. Changed;
  12902. end;
  12903. {$IFDEF ASM_VERSION}
  12904. //[procedure TGraphicTool.Changed]
  12905. procedure TGraphicTool.Changed;
  12906. asm
  12907. XOR ECX, ECX
  12908. XCHG ECX, [EAX].fHandle
  12909. JECXZ @@exit
  12910. PUSH EAX
  12911. PUSH ECX
  12912. CALL @@CallOnChange
  12913. CALL DeleteObject
  12914. POP EAX
  12915. @@exit:
  12916. @@CallOnChange:
  12917. MOV ECX, [EAX].fOnChange.TMethod.Code
  12918. JECXZ @@no_onChange
  12919. PUSH EAX
  12920. XCHG EDX, EAX
  12921. MOV EAX, [EDX].fOnChange.TMethod.Data
  12922. CALL ECX
  12923. POP EAX
  12924. @@no_onChange:
  12925. end;
  12926. {$ELSE ASM_VERSION} //Pascal
  12927. procedure TGraphicTool.Changed;
  12928. var H: THandle;
  12929. begin
  12930. if fHandle <> 0 then
  12931. begin
  12932. H := fHandle;
  12933. fHandle := 0;
  12934. ////////////////////////////////
  12935. if Assigned( fOnChange ) then
  12936. fOnChange( @Self );
  12937. ////////////////////////////////
  12938. DeleteObject( H );
  12939. {$IFDEF DEBUG_GDIOBJECTS}
  12940. case fType of
  12941. gttBrush: Dec( BrushCount );
  12942. gttFont: Dec( FontCount );
  12943. gttPen: Dec( PenCount );
  12944. end;
  12945. {$ENDIF}
  12946. end;
  12947. //////////////////////////////////
  12948. if Assigned( fOnChange ) then
  12949. fOnChange( @Self );
  12950. //////////////////////////////////
  12951. end;
  12952. {$ENDIF ASM_VERSION}
  12953. {$IFDEF ASM_VERSION}
  12954. //[destructor TGraphicTool.Destroy]
  12955. destructor TGraphicTool.Destroy;
  12956. asm
  12957. PUSH EAX
  12958. CMP [EAX].fType, gttFont
  12959. JE @@0
  12960. MOV ECX, [EAX].fData.Brush.Bitmap
  12961. JECXZ @@0
  12962. PUSH ECX
  12963. CALL DeleteObject
  12964. POP EAX
  12965. PUSH EAX
  12966. @@0:
  12967. MOV ECX, [EAX].fHandle
  12968. JECXZ @@1
  12969. PUSH ECX
  12970. CALL DeleteObject
  12971. @@1:
  12972. POP EAX
  12973. CALL TObj.Destroy
  12974. end;
  12975. {$ELSE ASM_VERSION} //Pascal
  12976. destructor TGraphicTool.Destroy;
  12977. begin
  12978. case fType of
  12979. gttBrush: if fData.Brush.Bitmap <> 0 then
  12980. DeleteObject( fData.Brush.Bitmap );
  12981. gttPen: if fData.Pen.BrushBitmap <> 0 then
  12982. DeleteObject( fData.Pen.BrushBitmap )
  12983. end;
  12984. if fHandle <> 0 then
  12985. begin
  12986. DeleteObject( fHandle );
  12987. {$IFDEF DEBUG_GDIOBJECTS}
  12988. case fType of
  12989. gttPen: Dec( PenCount );
  12990. gttBrush: Dec( BrushCount );
  12991. gttFont: Dec( FontCount );
  12992. end;
  12993. {$ENDIF}
  12994. //fHandle := 0; Why to do this? It is now destroying!
  12995. end;
  12996. inherited;
  12997. end;
  12998. {$ENDIF ASM_VERSION}
  12999. //[function TGraphicTool.HandleAllocated]
  13000. function TGraphicTool.HandleAllocated: Boolean;
  13001. begin
  13002. Result := fHandle <> 0;
  13003. end;
  13004. {$IFDEF ASM_VERSION}
  13005. //[function TGraphicTool.ReleaseHandle]
  13006. function TGraphicTool.ReleaseHandle: Integer;
  13007. asm // //
  13008. PUSH EAX
  13009. CALL Changed
  13010. POP EDX
  13011. XOR EAX, EAX
  13012. XCHG [EDX].fHandle, EAX
  13013. end;
  13014. {$ELSE ASM_VERSION PAS_VERSION}
  13015. function TGraphicTool.ReleaseHandle: Integer;
  13016. begin
  13017. Changed;
  13018. Result := fHandle;
  13019. fHandle := 0;
  13020. end;
  13021. {$ENDIF ASM_VERSION}
  13022. {$IFDEF ASM_VERSION}
  13023. //[procedure TGraphicTool.SetInt]
  13024. procedure TGraphicTool.SetInt( const Index: Integer; Value: Integer );
  13025. asm
  13026. LEA EDX, [EDX+EAX].fData
  13027. CMP [EDX], ECX
  13028. JE @@exit
  13029. MOV [EDX], ECX
  13030. CALL Changed
  13031. @@exit:
  13032. end;
  13033. {$ELSE ASM_VERSION} //Pascal
  13034. procedure TGraphicTool.SetInt( const Index: Integer; Value: Integer );
  13035. var Where: PInteger;
  13036. begin
  13037. Where := Pointer( Integer( @ fData ) + Index );
  13038. if Where^ = Value then Exit;
  13039. Where^ := Value;
  13040. Changed;
  13041. end;
  13042. {$ENDIF ASM_VERSION}
  13043. {$IFDEF F_P}
  13044. //[function TGraphicTool.GetInt]
  13045. function TGraphicTool.GetInt(const Index: Integer): Integer;
  13046. var Where: PInteger;
  13047. begin
  13048. Where := Pointer( Integer( @ fData ) + Index );
  13049. Result := Where^;
  13050. end;
  13051. {$ENDIF}
  13052. //[procedure TGraphicTool.SetColor]
  13053. procedure TGraphicTool.SetColor( Value: TColor );
  13054. begin
  13055. SetInt( go_Color, Value );
  13056. fColorRGB := Color2RGB( Value );
  13057. end;
  13058. {$IFDEF ASM_VERSION}
  13059. //[function TGraphicTool.IsFontTrueType]
  13060. function TGraphicTool.IsFontTrueType: Boolean;
  13061. asm
  13062. CALL GetHandle
  13063. TEST EAX, EAX
  13064. JZ @@exit
  13065. PUSH EBX
  13066. PUSH EAX // fHandle
  13067. PUSH 0
  13068. CALL GetDC
  13069. PUSH EAX // DC
  13070. MOV EBX, EAX
  13071. CALL SelectObject
  13072. PUSH EAX
  13073. XOR ECX, ECX
  13074. PUSH ECX
  13075. PUSH ECX
  13076. PUSH ECX
  13077. PUSH ECX
  13078. PUSH EBX
  13079. CALL GetFontData
  13080. XCHG EAX, [ESP]
  13081. PUSH EAX
  13082. PUSH EBX
  13083. CALL SelectObject
  13084. PUSH EBX
  13085. PUSH 0
  13086. CALL ReleaseDC
  13087. POP EAX
  13088. INC EAX
  13089. SETNZ AL
  13090. POP EBX
  13091. @@exit:
  13092. end;
  13093. {$ELSE ASM_VERSION} //Pascal
  13094. function TGraphicTool.IsFontTrueType: Boolean;
  13095. var OldFont: HFont;
  13096. DC: HDC;
  13097. begin
  13098. Result := False;
  13099. if GetHandle = 0 then Exit;
  13100. DC := GetDC( 0 );
  13101. OldFont := SelectObject( DC, fHandle );
  13102. if GetFontData( DC, 0, 0, nil, 0 ) <> GDI_ERROR then
  13103. Result := True;
  13104. SelectObject( DC, OldFont );
  13105. ReleaseDC( 0, DC );
  13106. end;
  13107. {$ENDIF ASM_VERSION}
  13108. //[procedure TGraphicTool.SetBrushBitmap]
  13109. procedure TGraphicTool.SetBrushBitmap(const Value: HBitmap);
  13110. begin
  13111. if fData.Brush.Bitmap = Value then Exit;
  13112. if fData.Brush.Bitmap <> 0 then
  13113. begin
  13114. ///////////
  13115. Changed; // !!!
  13116. ///////////
  13117. DeleteObject( fData.Brush.Bitmap );
  13118. end;
  13119. fData.Brush.Bitmap := Value;
  13120. Changed;
  13121. end;
  13122. //[procedure TGraphicTool.SetBrushStyle]
  13123. procedure TGraphicTool.SetBrushStyle(const Value: TBrushStyle);
  13124. begin
  13125. if fData.Brush.Style = Value then Exit;
  13126. fData.Brush.Style := Value;
  13127. Changed;
  13128. end;
  13129. //[procedure TGraphicTool.SetFontCharset]
  13130. procedure TGraphicTool.SetFontCharset(const Value: TFontCharset);
  13131. begin
  13132. if fData.Font.Charset = Value then Exit;
  13133. fData.Font.Charset := Value;
  13134. Changed;
  13135. end;
  13136. //[procedure TGraphicTool.SetFontQuality]
  13137. procedure TGraphicTool.SetFontQuality(const Value: TFontQuality);
  13138. begin
  13139. if fData.Font.Quality = Value then Exit;
  13140. fData.Font.Quality := Value;
  13141. Changed;
  13142. end;
  13143. //[function TGraphicTool.GetFontName]
  13144. function TGraphicTool.GetFontName: String;
  13145. begin
  13146. Result := fData.Font.Name;
  13147. end;
  13148. //[procedure TGraphicTool.SetFontName]
  13149. procedure TGraphicTool.SetFontName(const Value: String);
  13150. begin
  13151. if fData.Font.Name = Value then Exit;
  13152. FillChar( fData.Font.Name[ 0 ], LF_FACESIZE, 0 );
  13153. StrLCopy( fData.Font.Name, PChar( Value ), LF_FACESIZE );
  13154. Changed;
  13155. end;
  13156. {$IFDEF ASM_VERSION}
  13157. //[procedure TextAreaEx]
  13158. procedure TextAreaEx( Sender: PCanvas; var Sz : TSize; var Pt : TPoint );
  13159. asm
  13160. PUSH EBX
  13161. PUSH ESI
  13162. PUSH EDI
  13163. PUSH EBP
  13164. MOV EBP, ESP
  13165. PUSH EDX // [EBP-4] = @Sz
  13166. PUSH ECX // [EBP-8] = @Pt
  13167. MOV EBX, EAX
  13168. CALL TCanvas.GetFont
  13169. MOV ESI, [EAX].TGraphicTool.fData.Font.Orientation
  13170. CALL TGraphicTool.IsFontTrueType
  13171. TEST AL, AL
  13172. JZ @@exit
  13173. MOV EDI, [EBP-8]
  13174. XOR EAX, EAX
  13175. STOSD
  13176. STOSD
  13177. TEST ESI, ESI
  13178. JZ @@exit
  13179. PUSH EAX // Pts[1].x
  13180. PUSH EAX // Pts[1].y
  13181. PUSH ESI
  13182. FILD dword ptr [ESP]
  13183. POP EDX
  13184. FILD word ptr [@@1800]
  13185. FDIV
  13186. //FWAIT
  13187. FLDPI
  13188. FMUL
  13189. //FWAIT
  13190. FLD ST(0)
  13191. FSINCOS
  13192. FWAIT
  13193. MOV ESI, [EBP-4]
  13194. LODSD // Sz.cx
  13195. PUSH EAX
  13196. FILD dword ptr [ESP]
  13197. FMUL
  13198. FISTP dword ptr [ESP] // Pts[2].x
  13199. FWAIT
  13200. NEG EAX
  13201. PUSH EAX
  13202. FILD dword ptr [ESP]
  13203. FMUL
  13204. FISTP dword ptr [ESP] // Pts[2].y
  13205. FWAIT
  13206. FLDPI
  13207. FLD1
  13208. FLD1
  13209. FADD
  13210. FDIV
  13211. FADD
  13212. FSINCOS
  13213. FWAIT
  13214. LODSD
  13215. NEG EAX
  13216. PUSH EAX
  13217. FILD dword ptr [ESP]
  13218. FMUL
  13219. FISTP dword ptr [ESP] // Pts[4].x
  13220. FWAIT
  13221. NEG EAX
  13222. PUSH EAX
  13223. FILD dword ptr [ESP]
  13224. FMUL
  13225. FISTP dword ptr [ESP] // Pts[4].y
  13226. FWAIT
  13227. POP ECX
  13228. POP EDX
  13229. PUSH EDX
  13230. PUSH ECX
  13231. ADD EDX, [ESP+12]
  13232. ADD ECX, [ESP+8]
  13233. PUSH EDX
  13234. PUSH ECX
  13235. MOV ESI, ESP
  13236. XOR EDX, EDX // MinX
  13237. XOR EDI, EDI // MinY
  13238. XOR ECX, ECX
  13239. MOV CL, 3
  13240. @@loo1: LODSD
  13241. CMP EAX, EDI
  13242. JGE @@1
  13243. XCHG EDI, EAX
  13244. @@1: LODSD
  13245. CMP EAX, EDX
  13246. JGE @@2
  13247. XCHG EDX, EAX
  13248. @@2: LOOP @@loo1
  13249. MOV ESI, [EBP-4]
  13250. MOV [ESI], ECX
  13251. MOV [ESI+4], ECX
  13252. MOV CL, 4
  13253. @@loo2:
  13254. POP EBX
  13255. SUB EBX, EDI
  13256. CMP EBX, [ESI+4]
  13257. JLE @@3
  13258. MOV [ESI+4], EBX
  13259. @@3:
  13260. POP EAX
  13261. SUB EAX, EDX
  13262. CMP EAX, [ESI]
  13263. JLE @@4
  13264. MOV [ESI], EAX
  13265. @@4:
  13266. LOOP @@loo2
  13267. MOV EDI, [EBP-8]
  13268. STOSD
  13269. XCHG EAX, EBX
  13270. STOSD
  13271. JMP @@exit
  13272. @@1800: DW 1800
  13273. @@exit:
  13274. MOV ESP, EBP
  13275. POP EBP
  13276. POP EDI
  13277. POP ESI
  13278. POP EBX
  13279. end;
  13280. {$ELSE ASM_VERSION} //Pascal
  13281. procedure TextAreaEx( Sender: PCanvas; var Sz : TSize; var Pt : TPoint );
  13282. var Orient : Integer;
  13283. Pts : array[ 1..4 ] of TPoint;
  13284. MinX, MinY, I : Integer;
  13285. A : Double;
  13286. begin
  13287. if not Sender.Font.IsFontTrueType then Exit;
  13288. Orient := Sender.Font.FontOrientation;
  13289. Pt.x := 0; Pt.y := 0;
  13290. if Orient = 0 then
  13291. Exit;
  13292. A := Orient / 1800.0 * PI;
  13293. Pts[ 1 ] := Pt;
  13294. Pts[ 2 ].x := Round( Sz.cx * cos( A ) );
  13295. Pts[ 2 ].y := - Round( Sz.cx * sin( A ) );
  13296. Pts[ 4 ].x := - Round( Sz.cy * cos( A + PI / 2 ) );
  13297. Pts[ 4 ].y := Round( Sz.cy * sin( A + PI / 2 ) );
  13298. Pts[ 3 ].x := Pts[ 2 ].x + Pts[ 4 ].x;
  13299. Pts[ 3 ].y := Pts[ 2 ].y + Pts[ 4 ].y;
  13300. MinX := 0; MinY := 0;
  13301. for I := 2 to 4 do
  13302. begin
  13303. if Pts[ I ].x < MinX then
  13304. MinX := Pts[ I ].x;
  13305. if Pts[ I ].y < MinY then
  13306. MinY := Pts[ I ].y;
  13307. end;
  13308. Sz.cx := 0;
  13309. Sz.cy := 0;
  13310. for I := 1 to 4 do
  13311. begin
  13312. Pts[ I ].x := Pts[ I ].x - MinX;
  13313. Pts[ I ].y := Pts[ I ].y - MinY;
  13314. if Pts[ I ].x > Sz.cx then
  13315. Sz.cx := Pts[ I ].x;
  13316. if Pts[ I ].y > Sz.cy then
  13317. Sz.cy := Pts[ I ].y;
  13318. end;
  13319. Pt := Pts[ 1 ];
  13320. end;
  13321. {$ENDIF ASM_VERSION}
  13322. {$IFDEF ASM_VERSION}
  13323. //[procedure TGraphicTool.SetFontOrientation]
  13324. procedure TGraphicTool.SetFontOrientation(Value: Integer);
  13325. asm
  13326. PUSH EAX
  13327. @@1: MOV EAX, EDX
  13328. MOV ECX, 3600
  13329. CDQ
  13330. IDIV ECX // EDX = Value mod 3600
  13331. POP EAX
  13332. MOV byte ptr [GlobalGraphics_UseFontOrient], 1
  13333. MOV [GlobalCanvas_OnTextArea], offset[TextAreaEx]
  13334. MOV [EAX].fData.Font.Escapement, EDX
  13335. MOV ECX, EDX
  13336. MOV DX, go_FontOrientation
  13337. CALL SetInt
  13338. end;
  13339. {$ELSE ASM_VERSION} //Pascal
  13340. procedure TGraphicTool.SetFontOrientation(Value: Integer);
  13341. begin
  13342. GlobalGraphics_UseFontOrient := True;
  13343. GlobalCanvas_OnTextArea := TextAreaEx;
  13344. Value := Value mod 3600; // -3599..+3599
  13345. SetInt( go_FontOrientation, Value );
  13346. SetInt( go_FontEscapement, Value );
  13347. end;
  13348. {$ENDIF ASM_VERSION}
  13349. //[procedure TGraphicTool.SetFontPitch]
  13350. procedure TGraphicTool.SetFontPitch(const Value: TFontPitch);
  13351. begin
  13352. if fData.Font.Pitch = Value then Exit;
  13353. fData.Font.Pitch := Value;
  13354. Changed;
  13355. end;
  13356. {$IFDEF ASM_VERSION}
  13357. //[function TGraphicTool.GetFontStyle]
  13358. function TGraphicTool.GetFontStyle: TFontStyle;
  13359. asm
  13360. MOV EDX, dword ptr [EAX].fData.Font.Italic
  13361. AND EDX, $010101
  13362. MOV EAX, [EAX].fData.Font.Weight
  13363. CMP EAX, 700
  13364. SETGE AL //AL:1 = fsBold
  13365. ADD EDX, EDX
  13366. OR EAX, EDX //AL:2 = fsItalic
  13367. SHR EDX, 7
  13368. OR EAX, EDX //AL:3 = fsUnderline
  13369. SHR EDX, 7
  13370. OR EAX, EDX //AL:4 = fsStrikeOut
  13371. end;
  13372. {$ELSE ASM_VERSION} //Pascal
  13373. function TGraphicTool.GetFontStyle: TFontStyle;
  13374. type PFontStyle = ^TFontStyle;
  13375. begin
  13376. Result := [ ];
  13377. if fData.Font.Weight >= 700 then Result := [ fsBold ];
  13378. if fData.Font.Italic then Result := Result + [ fsItalic ];
  13379. if fData.Font.Underline then Result := Result + [ fsUnderline ];
  13380. if fData.Font.StrikeOut then Result := Result + [ fsStrikeOut ];
  13381. end;
  13382. {$ENDIF ASM_VERSION}
  13383. {$IFDEF ASM_VERSION}
  13384. //[procedure TGraphicTool.SetFontStyle]
  13385. procedure TGraphicTool.SetFontStyle(const Value: TFontStyle);
  13386. asm
  13387. PUSH EDI
  13388. MOV EDI, EAX
  13389. PUSH EDX
  13390. CALL GetFontStyle
  13391. POP EDX
  13392. CMP AL, DL
  13393. JE @@exit
  13394. PUSH EDI
  13395. LEA EDI, [EDI].fData.Font.Weight
  13396. MOV ECX, [EDI]
  13397. SHR EDX, 1
  13398. JNC @@1
  13399. CMP ECX, 700
  13400. JGE @@2
  13401. MOV ECX, 700
  13402. JMP @@2
  13403. @@1: CMP ECX, 700
  13404. JL @@2
  13405. XOR ECX, ECX
  13406. @@2: XCHG EAX, ECX
  13407. STOSD // change Weight
  13408. SHR EDX, 1
  13409. SETC AL
  13410. STOSB // change Italic
  13411. SHR EDX, 1
  13412. SETC AL
  13413. STOSB // change Underline
  13414. SHR EDX, 1
  13415. SETC AL
  13416. STOSB // change StrikeOut
  13417. POP EAX
  13418. CALL Changed
  13419. @@exit: POP EDI
  13420. end;
  13421. {$ELSE ASM_VERSION} //Pascal
  13422. procedure TGraphicTool.SetFontStyle(const Value: TFontStyle);
  13423. begin
  13424. if FontStyle = Value then Exit;
  13425. if fsBold in Value then
  13426. begin
  13427. if fData.Font.Weight < 700 then
  13428. fData.Font.Weight := 700;
  13429. end
  13430. else
  13431. begin
  13432. if fData.Font.Weight >= 700 then
  13433. fData.Font.Weight := 0;
  13434. end;
  13435. fData.Font.Italic := fsItalic in Value;
  13436. fData.Font.Underline := fsUnderline in Value;
  13437. fData.Font.StrikeOut := fsStrikeOut in Value;
  13438. Changed;
  13439. end;
  13440. {$ENDIF ASM_VERSION}
  13441. //[procedure TGraphicTool.SetPenMode]
  13442. procedure TGraphicTool.SetPenMode(const Value: TPenMode);
  13443. begin
  13444. if fData.Pen.Mode = Value then Exit;
  13445. fData.Pen.Mode := Value;
  13446. Changed;
  13447. end;
  13448. //[procedure TGraphicTool.SetPenStyle]
  13449. procedure TGraphicTool.SetPenStyle(const Value: TPenStyle);
  13450. begin
  13451. if fData.Pen.Style = Value then Exit;
  13452. fData.Pen.Style := Value;
  13453. Changed;
  13454. end;
  13455. {$IFDEF ASM_VERSION}
  13456. //[function TGraphicTool.GetHandle]
  13457. function TGraphicTool.GetHandle: THandle;
  13458. const DataSz = sizeof( TGDIToolData );
  13459. asm
  13460. PUSH EBX
  13461. @@start:
  13462. XCHG EBX, EAX
  13463. MOV ECX, [EBX].fHandle
  13464. JECXZ @@1
  13465. MOV EAX, [EBX].fData.Color
  13466. CALL Color2RGB
  13467. CMP EAX, [EBX].fColorRGB
  13468. JE @@1
  13469. MOV EAX, EBX
  13470. CALL ReleaseHandle
  13471. PUSH EAX
  13472. CALL DeleteObject
  13473. @@1: MOV ECX, [EBX].fHandle
  13474. INC ECX
  13475. LOOP @@exit
  13476. MOV ECX, [EBX].fParentGDITool
  13477. JECXZ @@2
  13478. LEA EDX, [ECX].fData
  13479. LEA EAX, [EBX].fData
  13480. MOV ECX, DataSz
  13481. CALL CompareMem
  13482. TEST AL, AL
  13483. MOV EAX, [EBX].fParentGDITool
  13484. JNZ @@start
  13485. @@2: MOV ECX, [EBX].fHandle
  13486. INC ECX
  13487. LOOP @@exit
  13488. MOV EAX, [EBX].fData.Color
  13489. CALL Color2RGB
  13490. MOV [EBX].fColorRGB, EAX
  13491. XCHG EAX, EBX
  13492. CALL dword ptr [EAX].fMakeHandleProc
  13493. XCHG ECX, EAX
  13494. @@exit: XCHG EAX, ECX
  13495. POP EBX
  13496. end;
  13497. {$ELSE ASM_VERSION} //Pascal
  13498. function TGraphicTool.GetHandle: THandle;
  13499. begin
  13500. Result := fHandle;
  13501. if Result <> 0 then
  13502. begin
  13503. if Color2RGB( fData.Color ) <> fColorRGB then
  13504. begin
  13505. DeleteObject( ReleaseHandle );
  13506. Result := 0;
  13507. end;
  13508. end;
  13509. if Result = 0 then
  13510. begin
  13511. if Assigned( fParentGDITool ) then
  13512. begin
  13513. if CompareMem( @ fData, @ fParentGDITool.fData, Sizeof( fData ) ) then
  13514. begin
  13515. Result := fParentGDITool.Handle;
  13516. Exit;
  13517. end;
  13518. end;
  13519. if fHandle = 0 then
  13520. begin
  13521. fColorRGB := Color2RGB( fData.Color );
  13522. fMakeHandleProc( @Self );
  13523. end;
  13524. Result := fHandle;
  13525. end;
  13526. end;
  13527. {$ENDIF ASM_VERSION}
  13528. //[FUNCTION MakeBrushHandle]
  13529. {$IFDEF ASM_VERSION}
  13530. function MakeBrushHandle( Self_: PGraphicTool ): THandle;
  13531. asm
  13532. PUSH EBX
  13533. XCHG EBX, EAX
  13534. MOV EAX, [EBX].TGraphicTool.fHandle
  13535. TEST EAX, EAX
  13536. JNZ @@exit
  13537. MOV EAX, [EBX].TGraphicTool.fData.Color
  13538. CALL Color2RGB // EAX = ColorRef
  13539. XOR EDX, EDX
  13540. MOV ECX, [EBX].TGraphicTool.fData.Brush.Bitmap
  13541. PUSH ECX
  13542. JECXZ @@1
  13543. MOV DL, BS_PATTERN
  13544. JMP @@2
  13545. @@1:
  13546. MOV CL, [EBX].TGraphicTool.fData.Brush.Style
  13547. MOV DL, CL
  13548. SUB CL, 2
  13549. JL @@2
  13550. XCHG ECX, [ESP]
  13551. @@2: PUSH EAX
  13552. PUSH EDX
  13553. PUSH ESP
  13554. CALL CreateBrushIndirect
  13555. MOV [EBX].TGraphicTool.fHandle, EAX
  13556. ADD ESP, 12
  13557. @@exit:
  13558. POP EBX
  13559. end;
  13560. {$ELSE ASM_VERSION} //Pascal
  13561. function MakeBrushHandle( Self_: PGraphicTool ): THandle;
  13562. var
  13563. LogBrush: TLogBrush;
  13564. begin
  13565. if Self_.fHandle = 0 then
  13566. begin
  13567. LogBrush.lbColor := Color2RGB( Self_.fData.Color );
  13568. if Self_.fData.Brush.Bitmap <> 0 then
  13569. begin
  13570. LogBrush.lbStyle := BS_PATTERN;
  13571. LogBrush.lbHatch := Self_.fData.Brush.Bitmap;
  13572. end
  13573. else
  13574. begin
  13575. LogBrush.lbHatch := 0;
  13576. case Self_.fData.Brush.Style of
  13577. bsSolid: LogBrush.lbStyle := BS_SOLID;
  13578. bsClear: LogBrush.lbStyle := BS_NULL;
  13579. else
  13580. LogBrush.lbStyle := BS_HATCHED;
  13581. LogBrush.lbHatch := Ord( Self_.fData.Brush.Style ) - Ord( bsHorizontal );
  13582. LogBrush.lbColor := Color2RGB( Self_.fData.Brush.LineColor );
  13583. end;
  13584. end;
  13585. Self_.fHandle := CreateBrushIndirect(LogBrush);
  13586. {$IFDEF DEBUG_GDIOBJECTS}
  13587. if Self_.fHandle <> 0 then
  13588. Inc( BrushCount )
  13589. else
  13590. ShowMessage( 'Could not create brush, error ' + Int2Str( GetLastError ) +
  13591. ': ' + SysErrorMessage( GetLastError ) );
  13592. {$ENDIF}
  13593. end;
  13594. //GlobalGraphics_OnObjectCreated( @Self );
  13595. Result := Self_.fHandle;
  13596. end;
  13597. {$ENDIF ASM_VERSION}
  13598. //[END MakeBrushHandle]
  13599. //[FUNCTION MakeFontHandle]
  13600. {$IFDEF ASM_VERSION}
  13601. function MakeFontHandle( Self_: PGraphicTool ): THandle;
  13602. asm
  13603. XCHG EDX, EAX
  13604. MOV EAX, [EDX].TGraphicTool.fHandle
  13605. TEST EAX, EAX
  13606. JNZ @@exit
  13607. PUSH EDX
  13608. LEA ECX, [EDX].TGraphicTool.fData.Font
  13609. PUSH ECX
  13610. CALL CreateFontIndirect
  13611. POP EDX
  13612. MOV [EDX].TGraphicTool.fHandle, EAX
  13613. @@exit:
  13614. end;
  13615. {$ELSE ASM_VERSION} //Pascal
  13616. function MakeFontHandle( Self_: PGraphicTool ): THandle;
  13617. //var LogFont: TLogFont;
  13618. begin
  13619. with Self_{-}^{+} do
  13620. begin
  13621. if fHandle = 0 then
  13622. begin
  13623. fHandle := CreateFontIndirect( PLogFont( @ fData.Font )^ );
  13624. {$IFDEF DEBUG_GDIOBJECTS}
  13625. Inc( FontCount );
  13626. {$ENDIF}
  13627. end;
  13628. Result := fHandle;
  13629. end;
  13630. end;
  13631. {$ENDIF ASM_VERSION}
  13632. //[END MakeFontHandle]
  13633. //[FUNCTION MakePenHandle]
  13634. {$IFDEF ASM_VERSION}
  13635. function MakePenHandle( Self_: PGraphicTool ): THandle;
  13636. asm
  13637. PUSH EBX
  13638. MOV EBX, EAX
  13639. MOV EAX, [EBX].TGraphicTool.fHandle
  13640. TEST EAX, EAX
  13641. JNZ @@exit
  13642. MOV EAX, [EBX].TGraphicTool.fData.Color
  13643. CALL Color2RGB
  13644. PUSH EAX
  13645. PUSH EAX
  13646. PUSH [EBX].TGraphicTool.fData.Pen.Width
  13647. MOVZX EAX, [EBX].TGraphicTool.fData.Pen.Style
  13648. PUSH EAX
  13649. PUSH ESP
  13650. CALL CreatePenIndirect
  13651. MOV [EBX].TGraphicTool.fHandle, EAX
  13652. ADD ESP, 16
  13653. @@exit:
  13654. POP EBX
  13655. end;
  13656. {$ELSE ASM_VERSION} //Pascal
  13657. function MakePenHandle( Self_: PGraphicTool ): THandle;
  13658. var
  13659. LogPen: TLogPen;
  13660. begin
  13661. with Self_{-}^{+} do
  13662. begin
  13663. //GlobalGraphics_OnObjectCreating( @Self );
  13664. if fHandle = 0 then
  13665. with LogPen do
  13666. begin
  13667. lopnStyle := Byte( fData.Pen.Style );
  13668. lopnWidth.X := fData.Pen.Width;
  13669. lopnColor := Color2RGB( fData.Color );
  13670. fHandle := CreatePenIndirect( LogPen );
  13671. {$IFDEF DEBUG_GDIOBJECTS}
  13672. Inc( PenCount );
  13673. {$ENDIF}
  13674. end;
  13675. //GlobalGraphics_OnObjectCreated( @Self );
  13676. Result := fHandle;
  13677. end;
  13678. end;
  13679. {$ENDIF ASM_VERSION}
  13680. //[END MakePenHandle]
  13681. //+
  13682. //[procedure TGraphicTool.SetGeometricPen]
  13683. procedure TGraphicTool.SetGeometricPen(const Value: Boolean);
  13684. begin
  13685. if fData.Pen.Geometric = Value then Exit;
  13686. fData.Pen.Geometric := Value;
  13687. fMakeHandleProc := MakeGeometricPenHandle;
  13688. Changed;
  13689. end;
  13690. //[procedure TGraphicTool.SetPenEndCap]
  13691. procedure TGraphicTool.SetPenEndCap(const Value: TPenEndCap);
  13692. begin
  13693. if fData.Pen.EndCap = Value then Exit;
  13694. fData.Pen.EndCap := Value;
  13695. Changed;
  13696. end;
  13697. //[procedure TGraphicTool.SetPenJoin]
  13698. procedure TGraphicTool.SetPenJoin(const Value: TPenJoin);
  13699. begin
  13700. if fData.Pen.Join = Value then Exit;
  13701. fData.Pen.Join := Value;
  13702. Changed;
  13703. end;
  13704. //[FUNCTION MakeGeometricPenHandle]
  13705. {$IFDEF ASM_VERSION}
  13706. function MakeGeometricPenHandle( Self_: PGraphicTool ): THandle;
  13707. asm
  13708. MOV ECX, [EAX].TGraphicTool.fHandle
  13709. INC ECX
  13710. LOOP @@exit
  13711. PUSH EBX
  13712. XCHG EBX, EAX
  13713. MOV EAX, [EBX].TGraphicTool.fData.Color
  13714. CALL Color2RGB // EAX = Color2RGB( fColor )
  13715. CDQ // EDX = lbHatch (0)
  13716. MOV ECX, [EBX].TGraphicTool.fData.Pen.BrushBitmap
  13717. JECXZ @@no_brush_bitmap
  13718. XCHG EDX, ECX // lbHatch = fPenBrushBitmap
  13719. MOV CL, BS_PATTERN // = 3
  13720. JMP @@create_pen
  13721. @@no_brush_bitmap:
  13722. MOVZX ECX, [EBX].TGraphicTool.fData.Pen.BrushStyle
  13723. CMP CL, 1
  13724. JLE @@create_pen
  13725. MOV EDX, ECX
  13726. MOV CL, 2
  13727. SUB EDX, ECX
  13728. @@create_pen:
  13729. PUSH EDX
  13730. PUSH EAX
  13731. PUSH ECX
  13732. MOV ECX, ESP
  13733. CDQ
  13734. PUSH EDX
  13735. PUSH EDX
  13736. PUSH ECX
  13737. PUSH [EBX].TGraphicTool.fData.Pen.Width
  13738. MOVZX ECX, [EBX].TGraphicTool.fData.Pen.Join
  13739. SHL ECX, 12
  13740. MOVZX EDX, [EBX].TGraphicTool.fData.Pen.EndCap
  13741. SHL EDX, 8
  13742. OR EDX, ECX
  13743. OR DL, byte ptr [EBX].TGraphicTool.fData.Pen.Style
  13744. OR EDX, PS_GEOMETRIC
  13745. PUSH EDX
  13746. CALL ExtCreatePen
  13747. POP ECX
  13748. POP ECX
  13749. POP ECX
  13750. MOV [EBX].TGraphicTool.fHandle, EAX
  13751. POP EBX
  13752. RET
  13753. @@exit:
  13754. XCHG EAX, ECX
  13755. end;
  13756. {$ELSE ASM_VERSION} //Pascal
  13757. function MakeGeometricPenHandle( Self_: PGraphicTool ): THandle;
  13758. const
  13759. PenStyles: array[ TPenStyle ] of Word =
  13760. (PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL,
  13761. PS_INSIDEFRAME);
  13762. PenEndCapStyles: array[ TPenEndCap ] of Word =
  13763. (PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT);
  13764. PenJoinStyles: array[ TPenJoin ] of Word =
  13765. (PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER );
  13766. var
  13767. LogBrush: TLogBrush;
  13768. begin
  13769. if Self_.fHandle = 0 then
  13770. with Self_{-}^{+}, LogBrush do
  13771. begin
  13772. lbColor := Color2RGB( fData.Color );
  13773. lbHatch := 0;
  13774. if fData.Pen.BrushBitmap <> 0 then
  13775. begin
  13776. lbStyle := BS_PATTERN;
  13777. lbHatch := fData.Pen.BrushBitmap;
  13778. end
  13779. else
  13780. case fData.Pen.BrushStyle of
  13781. bsSolid: lbStyle := BS_SOLID;
  13782. bsClear: lbStyle := BS_NULL;
  13783. else begin
  13784. lbStyle := BS_HATCHED;
  13785. case fData.Pen.BrushStyle of
  13786. bsHorizontal: lbHatch := HS_HORIZONTAL;
  13787. bsVertical: lbHatch := HS_VERTICAL;
  13788. bsFDiagonal: lbHatch := HS_FDIAGONAL;
  13789. bsBDiagonal: lbHatch := HS_BDIAGONAL;
  13790. bsCross: lbHatch := HS_CROSS;
  13791. bsDiagCross: lbHatch := HS_DIAGCROSS;
  13792. end;
  13793. end;
  13794. end;
  13795. end;
  13796. Self_.fHandle := ExtCreatePen( PS_GEOMETRIC or Byte( Self_.fData.Pen.Style ) or
  13797. PenEndCapStyles[ Self_.fData.Pen.EndCap ] or
  13798. PenJoinStyles[ Self_.fData.Pen.Join ],
  13799. Self_.fData.Pen.Width, LogBrush, 0, nil );
  13800. {Assert( Self_.fHandle <> 0, 'Error ' + Int2Str( GetLastError ) +
  13801. ': ' + SysErrorMessage( GetLastError ) );}
  13802. {$IFDEF DEBUG_GDIOBJECTS}
  13803. Inc( PenCount );
  13804. {$ENDIF}
  13805. Result := Self_.fHandle;
  13806. end;
  13807. {$ENDIF ASM_VERSION}
  13808. //[END MakeGeometricPenHandle]
  13809. //[procedure TGraphicTool.SetFontWeight]
  13810. procedure TGraphicTool.SetFontWeight(const Value: Integer);
  13811. begin
  13812. if fData.Font.Weight = Value then Exit;
  13813. fData.Font.Weight := Value;
  13814. Changed;
  13815. end;
  13816. //[procedure TGraphicTool.SetLogFontStruct]
  13817. procedure TGraphicTool.SetLogFontStruct(const Value: TLogFont);
  13818. begin
  13819. if CompareMem(@fData.Font, @Value, SizeOf(TLogFont)) then Exit;
  13820. Move(Value, fData.Font, SizeOF(TLogFont));
  13821. Changed;
  13822. end;
  13823. //[function TGraphicTool.GetLogFontStruct]
  13824. function TGraphicTool.GetLogFontStruct: TLogFont;
  13825. begin
  13826. Move(fData.Font, Result, SizeOf(TLogFont));
  13827. end;
  13828. { TCanvas }
  13829. type
  13830. TStock = Packed Record
  13831. StockPen: HPEN;
  13832. StockBrush: HBRUSH;
  13833. StockFont: HFONT;
  13834. end;
  13835. var
  13836. Stock: TStock;
  13837. //[destructor TCanvas.Destroy]
  13838. destructor TCanvas.Destroy;
  13839. begin
  13840. Handle := 0;
  13841. fPen.Free;
  13842. fBrush.Free;
  13843. fFont.Free;
  13844. //if Assigned( GlobalCanvas_OnDestroyCanvas ) then
  13845. // GlobalCanvas_OnDestroyCanvas( Self );
  13846. inherited;
  13847. end;
  13848. {$IFDEF ASM_VERSION}
  13849. //[function TCanvas.Assign]
  13850. function TCanvas.Assign(SrcCanvas: PCanvas): Boolean;
  13851. asm
  13852. PUSH EBX
  13853. PUSH ESI
  13854. XCHG EBX, EAX
  13855. MOV ESI, EDX
  13856. MOV EAX, [EBX].fFont
  13857. MOV EDX, [ESI].fFont
  13858. CALL TGraphicTool.Assign
  13859. MOV [EBX].fFont, EAX
  13860. MOV EAX, [EBX].fBrush
  13861. MOV EDX, [ESI].fBrush
  13862. CALL TGraphicTool.Assign
  13863. MOV [EBX].fBrush, EAX
  13864. MOV EAX, [EBX].fPen
  13865. MOV EDX, [ESI].fPen
  13866. CALL TGraphicTool.Assign
  13867. MOV [EBX].fPen, EAX
  13868. CALL AssignChangeEvents
  13869. MOV ECX, [EBX].fFont
  13870. OR ECX, [EBX].fBrush
  13871. OR ECX, [EBX].fPen
  13872. SETNZ AL
  13873. MOV EDX, [ESI].fPenPos.x
  13874. MOV ECX, [ESI].fPenPos.y
  13875. CMP EDX, [EBX].fPenPos.x
  13876. JNE @@chg_penpos
  13877. CMP ECX, [EBX].fPenPos.y
  13878. JE @@1
  13879. @@chg_penpos:
  13880. MOV AL, 1
  13881. MOV [EBX].fPenPos.x, EDX
  13882. MOV [EBX].fPenPos.y, ECX
  13883. @@1:
  13884. MOV EDX, [ESI].fCopyMode
  13885. CMP EDX, [EBX].fCopyMode
  13886. JE @@2
  13887. MOV [EBX].fCopyMode, EDX
  13888. MOV AL, 1
  13889. @@2:
  13890. POP ESI
  13891. POP EBX
  13892. end;
  13893. {$ELSE ASM_VERSION} //Pascal
  13894. function TCanvas.Assign(SrcCanvas: PCanvas): Boolean;
  13895. begin
  13896. fFont := fFont.Assign( SrcCanvas.fFont );
  13897. fBrush := fBrush.Assign( SrcCanvas.fBrush );
  13898. fPen := fPen.Assign( SrcCanvas.fPen );
  13899. AssignChangeEvents;
  13900. Result := (fFont <> nil) or (fBrush <> nil) or (fPen <> nil);
  13901. if (SrcCanvas.PenPos.x <> PenPos.x) or (SrcCanvas.PenPos.y <> PenPos.y) then
  13902. begin
  13903. Result := True;
  13904. PenPos := SrcCanvas.PenPos;
  13905. end;
  13906. if SrcCanvas.ModeCopy <> ModeCopy then
  13907. begin
  13908. Result := True;
  13909. ModeCopy := SrcCanvas.ModeCopy;
  13910. end;
  13911. end;
  13912. {$ENDIF ASM_VERSION}
  13913. {$IFDEF ASM_VERSION}
  13914. //[procedure TCanvas.CreateBrush]
  13915. procedure TCanvas.CreateBrush;
  13916. asm
  13917. PUSH EBX
  13918. MOV EBX, EAX
  13919. MOV ECX, [EAX].fBrush
  13920. JECXZ @@chk_owner
  13921. MOV EAX, ECX
  13922. CALL TGraphicTool.GetHandle
  13923. PUSH EAX
  13924. MOV EAX, EBX
  13925. CALL AssignChangeEvents
  13926. MOV EAX, EBX
  13927. CALL TCanvas.GetHandle
  13928. PUSH EAX
  13929. CALL SelectObject
  13930. MOV EDX, [EBX].TCanvas.fBrush
  13931. CMP [EDX].TGraphicTool.fData.Brush.Style, bsSolid
  13932. MOV EAX, [EDX].TGraphicTool.fData.Color
  13933. @@0:
  13934. MOV EBX, [EBX].TCanvas.fHandle
  13935. MOV ECX, offset[Color2RGB]
  13936. JNZ @@1
  13937. PUSH OPAQUE
  13938. PUSH EBX
  13939. CALL ECX //Color2RGB
  13940. PUSH EAX
  13941. PUSH EBX
  13942. JMP @@2
  13943. @@1:
  13944. PUSH TRANSPARENT
  13945. PUSH EBX
  13946. CALL ECX //Color2RGB
  13947. NOT EAX
  13948. PUSH EAX
  13949. PUSH EBX
  13950. @@2:
  13951. CALL SetBkColor
  13952. CALL SetBkMode
  13953. @@exit:
  13954. POP EBX
  13955. RET
  13956. @@chk_owner:
  13957. MOV ECX, [EBX].fOwnerControl
  13958. JECXZ @@exit
  13959. MOV EAX, [ECX].TControl.fColor
  13960. XOR ECX, ECX
  13961. JMP @@0
  13962. end;
  13963. {$ELSE ASM_VERSION} //Pascal
  13964. procedure TCanvas.CreateBrush;
  13965. begin
  13966. //UnrealizeObject( Brush.Handle );
  13967. // if GdiObject parameter of UnrealizeObject is brush handle,
  13968. // this call does nothing (from Win32.hlp)
  13969. if assigned( fBrush ) then
  13970. begin
  13971. SelectObject( GetHandle, fBrush.Handle );
  13972. //fBrush.fOnChange := ObjectChanged;
  13973. AssignChangeEvents;
  13974. if fBrush.fData.Brush.Style = bsSolid then
  13975. begin
  13976. SetBkColor( fHandle, Color2RGB( fBrush.fData.Color ) );
  13977. SetBkMode( fHandle, OPAQUE );
  13978. end
  13979. else
  13980. begin
  13981. { Win95 doesn't draw brush hatches if bkcolor = brush color }
  13982. { Since bkmode is transparent, nothing should use bkcolor anyway }
  13983. SetBkColor( fHandle, not Color2RGB( fBrush.fData.Color ) );
  13984. SetBkMode( fHandle, TRANSPARENT );
  13985. end;
  13986. end
  13987. else
  13988. if Assigned( fOwnerControl ) then
  13989. begin
  13990. SetBkColor( GetHandle, Color2RGB( PControl( fOwnerControl ).fColor ) );
  13991. SetBkMode( fHandle, OPAQUE );
  13992. end;
  13993. end;
  13994. {$ENDIF ASM_VERSION}
  13995. {$IFDEF ASM_VERSION}
  13996. //[procedure TCanvas.CreateFont]
  13997. procedure TCanvas.CreateFont;
  13998. asm
  13999. PUSH EBX
  14000. MOV EBX, EAX
  14001. MOV ECX, [EAX].TCanvas.fFont
  14002. JECXZ @@chk_owner
  14003. MOV EAX, [ECX].TGraphicTool.fData.Color
  14004. PUSH ECX
  14005. CALL Color2RGB
  14006. XCHG EAX, [ESP]
  14007. CALL TGraphicTool.GetHandle
  14008. PUSH EAX
  14009. MOV EAX, EBX
  14010. CALL AssignChangeEvents;
  14011. MOV EAX, EBX
  14012. CALL TCanvas.GetHandle
  14013. PUSH EAX
  14014. MOV EBX, EAX
  14015. CALL SelectObject
  14016. @@set_txcolor:
  14017. PUSH EBX
  14018. CALL SetTextColor
  14019. @@exit:
  14020. POP EBX
  14021. RET
  14022. @@chk_owner:
  14023. MOV ECX, [EBX].fOwnerControl
  14024. JECXZ @@exit
  14025. MOV EBX, [EBX].fHandle
  14026. MOV EAX, [ECX].TControl.fTextColor
  14027. CALL Color2RGB
  14028. PUSH EAX
  14029. JMP @@set_txcolor
  14030. end;
  14031. {$ELSE ASM_VERSION} //Pascal
  14032. procedure TCanvas.CreateFont;
  14033. begin
  14034. if assigned( fFont ) then
  14035. begin
  14036. SelectObject( GetHandle, fFont.Handle );
  14037. SetTextColor( fHandle, Color2RGB( fFont.fData.Color ) );
  14038. //fFont.fOnChange := ObjectChanged;
  14039. AssignChangeEvents;
  14040. end
  14041. else
  14042. if Assigned( fOwnerControl ) then
  14043. begin
  14044. SetTextColor( fHandle, Color2RGB( PControl( fOwnerControl ).fTextColor ) );
  14045. end;
  14046. end;
  14047. {$ENDIF ASM_VERSION}
  14048. {$IFDEF ASM_VERSION}
  14049. //[procedure TCanvas.CreatePen]
  14050. procedure TCanvas.CreatePen;
  14051. asm
  14052. MOV ECX, [EAX].TCanvas.fPen
  14053. JECXZ @@exit
  14054. PUSH EBX
  14055. MOV EBX, EAX
  14056. MOV DL, [ECX].TGraphicTool.fData.Pen.Mode
  14057. MOVZX EDX, DL
  14058. INC EDX
  14059. PUSH EDX
  14060. MOV EAX, ECX
  14061. CALL TGraphicTool.GetHandle
  14062. PUSH EAX
  14063. MOV EAX, EBX
  14064. CALL AssignChangeEvents
  14065. MOV EAX, EBX
  14066. CALL TCanvas.GetHandle
  14067. PUSH EAX
  14068. MOV EBX, EAX
  14069. CALL SelectObject
  14070. PUSH EBX
  14071. CALL SetROP2
  14072. POP EBX
  14073. @@exit:
  14074. end;
  14075. {$ELSE ASM_VERSION} //Pascal
  14076. procedure TCanvas.CreatePen;
  14077. begin
  14078. if assigned( fPen ) then
  14079. begin
  14080. SelectObject( GetHandle, fPen.Handle );
  14081. SetROP2( fHandle, Ord( fPen.fData.Pen.Mode ) + 1 );
  14082. //fPen.fOnChange := ObjectChanged;
  14083. AssignChangeEvents;
  14084. end;
  14085. end;
  14086. {$ENDIF ASM_VERSION}
  14087. //[function TCanvas.GetPixels]
  14088. function TCanvas.GetPixels(X, Y: Integer): TColor;
  14089. begin
  14090. RequiredState( HandleValid );
  14091. Result := Windows.GetPixel(FHandle, X, Y);
  14092. end;
  14093. //[procedure TCanvas.SetPixels]
  14094. procedure TCanvas.SetPixels(X, Y: Integer; const Value: TColor);
  14095. begin
  14096. Changing;
  14097. RequiredState( HandleValid );
  14098. Windows.SetPixel(FHandle, X, Y, Color2RGB( Value ));
  14099. end;
  14100. {$IFDEF ASM_VERSION}
  14101. //[procedure TCanvas.DeselectHandles]
  14102. procedure TCanvas.DeselectHandles;
  14103. asm
  14104. PUSH EBX
  14105. PUSH ESI
  14106. PUSH EDI
  14107. LEA EBX, [EAX].TCanvas.fState
  14108. //CALL TCanvas.GetHandle
  14109. MOV EAX, [EAX].TCanvas.fHandle
  14110. TEST EAX, EAX
  14111. JZ @@exit
  14112. MOVZX EDX, byte ptr[EBX]
  14113. AND DL, PenValid or BrushValid or FontValid
  14114. JZ @@exit
  14115. PUSH EAX
  14116. LEA EDI, [Stock]
  14117. MOV ECX, [EDI]
  14118. INC ECX
  14119. LOOP @@1
  14120. MOV ESI, offset[ GetStockObject ]
  14121. PUSH BLACK_PEN
  14122. CALL ESI
  14123. STOSD
  14124. PUSH HOLLOW_BRUSH
  14125. CALL ESI
  14126. STOSD
  14127. PUSH SYSTEM_FONT
  14128. CALL ESI
  14129. STOSD
  14130. @@1:
  14131. LEA ESI, [Stock]
  14132. POP EDX
  14133. LODSD
  14134. PUSH EAX
  14135. PUSH EDX
  14136. LODSD
  14137. PUSH EAX
  14138. PUSH EDX
  14139. LODSD
  14140. PUSH EAX
  14141. PUSH EDX
  14142. MOV ESI, offset[ SelectObject ]
  14143. CALL ESI
  14144. CALL ESI
  14145. CALL ESI
  14146. AND byte ptr [EBX], not( PenValid or BrushValid or FontValid )
  14147. @@exit:
  14148. POP EDI
  14149. POP ESI
  14150. POP EBX
  14151. end;
  14152. {$ELSE ASM_VERSION} //Pascal
  14153. procedure TCanvas.DeselectHandles;
  14154. begin
  14155. //if (GetHandle <> 0) and
  14156. if (fHandle <> 0) and
  14157. LongBool(fState and (PenValid or BrushValid or FontValid)) then
  14158. with Stock do
  14159. begin
  14160. if StockPen = 0 then
  14161. begin
  14162. StockPen := GetStockObject(BLACK_PEN);
  14163. StockBrush := GetStockObject(HOLLOW_BRUSH);
  14164. StockFont := GetStockObject(SYSTEM_FONT);
  14165. end;
  14166. SelectObject( fHandle, StockPen );
  14167. SelectObject( fHandle, StockBrush );
  14168. SelectObject( fHandle, StockFont );
  14169. fState := fState and not( PenValid or BrushValid or FontValid );
  14170. end;
  14171. end;
  14172. {$ENDIF ASM_VERSION}
  14173. {$IFDEF ASM_VERSION}
  14174. //[function TCanvas.RequiredState]
  14175. function TCanvas.RequiredState(ReqState: DWORD): Integer; stdcall;
  14176. asm
  14177. PUSH EBX
  14178. PUSH ESI
  14179. MOV EBX, ReqState
  14180. MOV ESI, [EBP+8] //Self
  14181. MOV EAX, ESI
  14182. TEST BL, ChangingCanvas
  14183. JZ @@1
  14184. CALL Changing
  14185. @@1: AND BL, 0Fh
  14186. TEST BL, HandleValid
  14187. JZ @@2
  14188. CALL TCanvas.GetHandle
  14189. TEST EAX, EAX
  14190. JZ @@ret_0
  14191. @@2:
  14192. MOV AL, [ESI].TCanvas.fState
  14193. NOT EAX
  14194. AND BL, AL
  14195. JZ @@ret_handle
  14196. TEST BL, FontValid
  14197. JZ @@3
  14198. MOV EAX, ESI
  14199. CALL CreateFont
  14200. @@3: TEST BL, PenValid
  14201. JZ @@5
  14202. MOV EAX, ESI
  14203. CALL CreatePen
  14204. MOV ECX, [ESI].TCanvas.fPen
  14205. JCXZ @@5
  14206. MOV AL, [ECX].TGraphicTool.fData.Pen.Style
  14207. DEC AL
  14208. {$IFDEF PARANOIA}
  14209. DB $2C, 3
  14210. {$ELSE}
  14211. SUB AL, 3
  14212. {$ENDIF}
  14213. JB @@6
  14214. @@5: TEST BL, BrushValid
  14215. JZ @@7
  14216. @@6: MOV EAX, ESI
  14217. CALL CreateBrush
  14218. @@7: OR [ESI].TCanvas.fState, BL
  14219. @@ret_handle:
  14220. MOV EAX, [ESI].TCanvas.fHandle
  14221. @@ret_0:
  14222. POP ESI
  14223. POP EBX
  14224. end;
  14225. {$ELSE ASM_VERSION} //Pascal
  14226. function TCanvas.RequiredState(ReqState: DWORD): Integer; stdcall;
  14227. var
  14228. NeededState: Byte;
  14229. begin
  14230. if Boolean(ReqState and ChangingCanvas) then
  14231. Changing;
  14232. ReqState := ReqState and 15;
  14233. NeededState := Byte( ReqState ) and not fState;
  14234. Result := 0;
  14235. if Boolean(ReqState and HandleValid) then
  14236. begin
  14237. if GetHandle = 0 then Exit;
  14238. // Important!
  14239. end;
  14240. if NeededState <> 0 then
  14241. begin
  14242. if Boolean( NeededState and FontValid ) then
  14243. CreateFont;
  14244. if Boolean( NeededState and PenValid ) then
  14245. begin
  14246. CreatePen;
  14247. if assigned( fPen ) then
  14248. if fPen.fData.Pen.Style in [psDash, psDot, psDashDot, psDashDotDot] then
  14249. NeededState := NeededState or BrushValid;
  14250. end;
  14251. if Boolean( NeededState and BrushValid ) then
  14252. CreateBrush;
  14253. fState := fState or NeededState;
  14254. end;
  14255. Result := fHandle;
  14256. end;
  14257. {$ENDIF ASM_VERSION}
  14258. {$IFDEF ASM_VERSION}
  14259. //[procedure TCanvas.SetHandle]
  14260. procedure TCanvas.SetHandle(Value: HDC);
  14261. asm
  14262. PUSH EBX
  14263. MOV EBX, EAX
  14264. MOV ECX, [EBX].fHandle
  14265. CMP ECX, EDX
  14266. JZ @@exit
  14267. JECXZ @@chk_val
  14268. PUSH EDX
  14269. PUSH ECX
  14270. CALL DeselectHandles
  14271. POP EDX
  14272. MOV ECX, [EBX].fOwnerControl
  14273. JECXZ @@chk_Release
  14274. CMP [ECX].TControl.fPaintDC, EDX
  14275. JE @@clr_Handle
  14276. @@chk_Release:
  14277. PUSH EDX
  14278. CMP [EBX].fOnGetHandle.TMethod.Code, offset[TControl.DC2Canvas]
  14279. JNE @@deldc
  14280. PUSH [ECX].TControl.fHandle
  14281. CALL ReleaseDC
  14282. JMP @@clr_Handle
  14283. @@deldc:
  14284. CALL DeleteDC
  14285. @@clr_Handle:
  14286. XOR ECX, ECX
  14287. MOV [EBX].TCanvas.fHandle, ECX
  14288. MOV [EBX].TCanvas.fIsPaintDC, CL
  14289. AND [EBX].TCanvas.fState, not HandleValid
  14290. POP EDX
  14291. @@chk_val:
  14292. TEST EDX, EDX
  14293. JZ @@exit
  14294. OR [EBX].TCanvas.fState, HandleValid
  14295. MOV [EBX].TCanvas.fHandle, EDX
  14296. LEA EDX, [EBX].TCanvas.fPenPos
  14297. MOV EAX, EBX
  14298. CALL SetPenPos
  14299. @@exit: POP EBX
  14300. end;
  14301. {$ELSE ASM_VERSION} //Pascal
  14302. procedure TCanvas.SetHandle(Value: HDC);
  14303. {$IFDEF F_P}
  14304. var Ptr1: Pointer;
  14305. {$ENDIF F_P}
  14306. begin
  14307. if fHandle = Value then Exit;
  14308. if fHandle <> 0 then
  14309. begin
  14310. DeselectHandles;
  14311. {if not fIsPaintDC and
  14312. not( assigned(fOwnerControl) and
  14313. PControl(fOwnerControl).fDoubleBuffered )
  14314. then}
  14315. if not( assigned(fOwnerControl) and
  14316. (PControl(fOwnerControl).fPaintDC = fHandle) ) then
  14317. begin
  14318. {$IFDEF F_P}
  14319. Ptr1 := Self;
  14320. asm
  14321. MOV EAX, [Ptr1]
  14322. MOV EAX, [EAX].TCanvas.fOnGetHandle
  14323. MOV [Ptr1], EAX
  14324. end [ 'EAX' ];
  14325. if Ptr1 = @ TControl.DC2Canvas then
  14326. {$ELSE DELPHI}
  14327. //////////////////// SLAG
  14328. if TMethod(fOnGetHandle).Code =
  14329. @TControl.Dc2Canvas then
  14330. {$ENDIF F_P/DELPHI}
  14331. ReleaseDC(PControl(fOwnerControl).Handle, fHandle )
  14332. else
  14333. DeleteDC( fHandle );
  14334. ////////////////////
  14335. end;
  14336. fHandle := 0;
  14337. fIsPaintDC := False;
  14338. fState := fState and not HandleValid;
  14339. end;
  14340. if Value <> 0 then
  14341. begin
  14342. fState := fState or HandleValid;
  14343. fHandle := Value;
  14344. SetPenPos( fPenPos );
  14345. end;
  14346. end;
  14347. {$ENDIF ASM_VERSION}
  14348. {$IFDEF ASM_VERSION}
  14349. //[procedure TCanvas.SetPenPos]
  14350. procedure TCanvas.SetPenPos(const Value: TPoint);
  14351. asm
  14352. MOV ECX, [EDX].TPoint.y
  14353. MOV EDX, [EDX].TPoint.x
  14354. MOV [EAX].fPenPos.x, EDX
  14355. MOV [EAX].fPenPos.y, ECX
  14356. CALL MoveTo
  14357. end;
  14358. {$ELSE ASM_VERSION} //Pascal
  14359. procedure TCanvas.SetPenPos(const Value: TPoint);
  14360. begin
  14361. fPenPos := Value;
  14362. MoveTo( Value.x, Value.y );
  14363. end;
  14364. {$ENDIF ASM_VERSION}
  14365. {$IFDEF ASM_VERSION}
  14366. //[procedure TCanvas.Changing]
  14367. procedure TCanvas.Changing;
  14368. asm
  14369. PUSHAD
  14370. MOV ECX, [EAX].fOnChange.TMethod.Code
  14371. JECXZ @@exit
  14372. XCHG EDX, EAX
  14373. MOV EAX, [EDX].fOnChange.TMethod.Data
  14374. CALL ECX
  14375. @@exit:
  14376. POPAD
  14377. end;
  14378. {$ELSE ASM_VERSION} //Pascal
  14379. procedure TCanvas.Changing;
  14380. begin
  14381. if Assigned( fOnChange ) then
  14382. fOnChange( @Self );
  14383. end;
  14384. {$ENDIF ASM_VERSION}
  14385. {$IFDEF ASM_VERSION}
  14386. //[procedure TCanvas.Arc]
  14387. procedure TCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  14388. asm
  14389. PUSH ESI
  14390. PUSH HandleValid or PenValid or ChangingCanvas
  14391. PUSH dword ptr [EBP+8]
  14392. CALL RequiredState
  14393. MOV EDX, EAX
  14394. LEA ESI, [Y4]
  14395. STD
  14396. XOR ECX, ECX
  14397. MOV CL, 8
  14398. @@1:
  14399. LODSD
  14400. PUSH EAX
  14401. LOOP @@1
  14402. CLD
  14403. PUSH EDX //Canvas.fHandle
  14404. CALL Windows.Arc
  14405. POP ESI
  14406. end;
  14407. {$ELSE ASM_VERSION} //Pascal
  14408. procedure TCanvas.Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  14409. begin
  14410. RequiredState( HandleValid or PenValid or ChangingCanvas );
  14411. Windows.Arc(FHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4);
  14412. end;
  14413. {$ENDIF ASM_VERSION}
  14414. {$IFDEF ASM_VERSION}
  14415. //[procedure TCanvas.Chord]
  14416. procedure TCanvas.Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  14417. asm
  14418. PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
  14419. PUSH dword ptr [EBP + 8]
  14420. CALL RequiredState
  14421. MOV EDX, EAX
  14422. PUSH ESI
  14423. LEA ESI, [Y4]
  14424. STD
  14425. XOR ECX, ECX
  14426. MOV CL, 8
  14427. @@1:
  14428. LODSD
  14429. PUSH EAX
  14430. LOOP @@1
  14431. CLD
  14432. PUSH EDX //Canvas.fHandle
  14433. CALL Windows.Chord
  14434. POP ESI
  14435. end;
  14436. {$ELSE ASM_VERSION} //Pascal
  14437. procedure TCanvas.Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  14438. begin
  14439. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  14440. Windows.Chord(FHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4);
  14441. end;
  14442. {$ENDIF ASM_VERSION}
  14443. {$IFDEF ASM_VERSION}
  14444. //[procedure TCanvas.CopyRect]
  14445. procedure TCanvas.CopyRect(const DstRect: TRect; SrcCanvas: PCanvas;
  14446. const SrcRect: TRect);
  14447. asm
  14448. PUSH ESI
  14449. PUSH EDI
  14450. PUSH [EAX].fCopyMode
  14451. PUSH EDX
  14452. PUSH HandleValid or BrushValid
  14453. PUSH ECX
  14454. PUSH HandleValid or FontValid or BrushValid or ChangingCanvas
  14455. PUSH EAX
  14456. MOV ESI, offset[ RequiredState ]
  14457. CALL ESI
  14458. MOV EDI, EAX // EDI = @Self.fHandle
  14459. CALL ESI
  14460. MOV EDX, EAX // EDX = SrcCanvas.fHandle
  14461. POP ECX // ECX = @DstRect
  14462. MOV ESI, [SrcRect]
  14463. MOV EAX, [ESI].TRect.Bottom
  14464. SUB EAX, [ESI].TRect.Top
  14465. PUSH EAX
  14466. MOV EAX, [ESI].TRect.Right
  14467. SUB EAX, [ESI].TRect.Left
  14468. PUSH EAX
  14469. PUSH [ESI].TRect.Top
  14470. LODSD
  14471. PUSH EAX
  14472. PUSH EDX
  14473. MOV EAX, [ECX].TRect.Bottom
  14474. MOV EDX, [ECX].TRect.Top
  14475. SUB EAX, EDX
  14476. PUSH EAX
  14477. MOV EAX, [ECX].TRect.Right
  14478. MOV ESI, [ECX].TRect.Left
  14479. SUB EAX, ESI
  14480. PUSH EAX
  14481. PUSH EDX
  14482. PUSH ESI
  14483. PUSH EDI
  14484. CALL StretchBlt
  14485. POP EDI
  14486. POP ESI
  14487. end;
  14488. {$ELSE ASM_VERSION} //Pascal
  14489. procedure TCanvas.CopyRect(const DstRect: TRect; SrcCanvas: PCanvas;
  14490. const SrcRect: TRect);
  14491. begin
  14492. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  14493. SrcCanvas.RequiredState( HandleValid or BrushValid );
  14494. StretchBlt( fHandle, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,
  14495. DstRect.Bottom - DstRect.Top, SrcCanvas.Handle, SrcRect.Left, SrcRect.Top,
  14496. SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, ModeCopy);
  14497. end;
  14498. {$ENDIF ASM_VERSION}
  14499. {$IFDEF ASM_VERSION}
  14500. //[procedure TCanvas.DrawFocusRect]
  14501. procedure TCanvas.DrawFocusRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  14502. asm
  14503. PUSH EDX
  14504. PUSH HandleValid or BrushValid or FontValid or ChangingCanvas
  14505. PUSH EAX
  14506. CALL RequiredState
  14507. PUSH EAX
  14508. CALL Windows.DrawFocusRect
  14509. end;
  14510. {$ELSE ASM_VERSION} //Pascal
  14511. procedure TCanvas.DrawFocusRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  14512. begin
  14513. RequiredState( HandleValid or BrushValid or FontValid or ChangingCanvas );
  14514. Windows.DrawFocusRect(FHandle, Rect);
  14515. end;
  14516. {$ENDIF ASM_VERSION}
  14517. {$IFDEF ASM_VERSION}
  14518. //[procedure TCanvas.Ellipse]
  14519. procedure TCanvas.Ellipse(X1, Y1, X2, Y2: Integer);
  14520. asm
  14521. PUSH [Y2]
  14522. PUSH [X2]
  14523. PUSH ECX
  14524. PUSH EDX
  14525. PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
  14526. PUSH EAX
  14527. CALL RequiredState
  14528. PUSH EAX
  14529. CALL Windows.Ellipse
  14530. end;
  14531. {$ELSE ASM_VERSION} //Pascal
  14532. procedure TCanvas.Ellipse(X1, Y1, X2, Y2: Integer);
  14533. begin
  14534. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  14535. Windows.Ellipse(FHandle, X1, Y1, X2, Y2);
  14536. end;
  14537. {$ENDIF ASM_VERSION}
  14538. {$IFDEF ASM_VERSION}
  14539. //[procedure TCanvas.FillRect]
  14540. procedure TCanvas.FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  14541. asm
  14542. PUSH EBX
  14543. XCHG EBX, EAX
  14544. PUSH EDX
  14545. PUSH HandleValid or BrushValid or ChangingCanvas
  14546. PUSH EBX
  14547. CALL RequiredState
  14548. MOV ECX, [EBX].fBrush
  14549. JECXZ @@chk_ctl
  14550. @@fill_with_Brush:
  14551. XCHG EAX, ECX
  14552. CALL TGraphicTool.GetHandle
  14553. POP EDX
  14554. PUSH EAX
  14555. JMP @@fin
  14556. @@chk_ctl:
  14557. MOV ECX, [EBX].fOwnerControl
  14558. JECXZ @@dflt_fill
  14559. XCHG EAX, ECX
  14560. MOV ECX, [EAX].TControl.fBrush
  14561. INC ECX
  14562. LOOP @@fill_with_Brush
  14563. MOV EAX, [EAX].TControl.fColor
  14564. CALL Color2RGB
  14565. PUSH EAX
  14566. CALL CreateSolidBrush
  14567. POP EDX
  14568. PUSH EAX
  14569. PUSH EAX
  14570. PUSH EDX
  14571. PUSH [EBX].fHandle
  14572. CALL Windows.FillRect
  14573. CALL DeleteObject
  14574. POP EBX
  14575. RET
  14576. @@dflt_fill:
  14577. POP EDX
  14578. PUSH COLOR_WINDOW + 1
  14579. @@fin:
  14580. PUSH EDX
  14581. PUSH [EBX].fHandle
  14582. CALL Windows.FillRect
  14583. POP EBX
  14584. end;
  14585. {$ELSE ASM_VERSION} //Pascal
  14586. procedure TCanvas.FillRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  14587. var Br: HBrush;
  14588. begin
  14589. RequiredState( HandleValid or BrushValid or ChangingCanvas );
  14590. if assigned( fBrush ) then
  14591. begin
  14592. Windows.FillRect(fHandle, Rect, fBrush.Handle);
  14593. end
  14594. else
  14595. if assigned( fOwnerControl ) then
  14596. begin
  14597. if assigned( PControl( fOwnerControl ).fBrush ) then
  14598. Windows.FillRect( fHandle, Rect, PControl( fOwnerControl ).fBrush.Handle )
  14599. else
  14600. begin
  14601. Br := CreateSolidBrush( Color2RGB(PControl(fOwnerControl).fColor) );
  14602. Windows.FillRect(fHandle, Rect, Br );
  14603. DeleteObject( Br );
  14604. end;
  14605. end
  14606. else
  14607. begin
  14608. Windows.FillRect(fHandle, Rect, HBrush(COLOR_WINDOW + 1) );
  14609. end;
  14610. end;
  14611. {$ENDIF ASM_VERSION}
  14612. {$IFDEF ASM_VERSION}
  14613. //[procedure TCanvas.FillRgn]
  14614. procedure TCanvas.FillRgn(const Rgn: HRgn);
  14615. asm
  14616. PUSH EBX
  14617. XCHG EBX, EAX
  14618. PUSH EDX
  14619. PUSH HandleValid or BrushValid or ChangingCanvas
  14620. PUSH EBX
  14621. CALL RequiredState
  14622. MOV ECX, [EBX].TCanvas.fBrush
  14623. JECXZ @@1
  14624. //PUSH [ECX].TGraphicTool.fData.Color
  14625. //JMP @@cr_br
  14626. @@fill_rgn_using_Brush:
  14627. XCHG EAX, ECX
  14628. CALL TGraphicTool.GetHandle
  14629. POP EDX
  14630. PUSH EAX
  14631. PUSH EDX
  14632. PUSH [EBX].fHandle
  14633. CALL Windows.FillRgn
  14634. JMP @@fin
  14635. @@1: MOV ECX, [EBX].TCanvas.fOwnerControl
  14636. MOV EAX, -1 // clWhite
  14637. JECXZ @@2
  14638. XCHG EAX, ECX
  14639. MOV ECX, [EAX].TControl.fBrush
  14640. INC ECX
  14641. LOOP @@fill_rgn_using_Brush
  14642. MOV EAX, [EAX].TControl.fColor
  14643. @@2:
  14644. CALL Color2RGB
  14645. PUSH EAX
  14646. CALL CreateSolidBrush // EAX = Br
  14647. POP EDX // Rgn
  14648. PUSH EAX //-------------------//
  14649. PUSH EAX // Br
  14650. PUSH EDX // Rgn
  14651. PUSH [EBX].FHandle // fHandle
  14652. CALL Windows.FillRgn
  14653. CALL DeleteObject
  14654. @@fin:
  14655. POP EBX
  14656. end;
  14657. {$ELSE ASM_VERSION} //Pascal
  14658. procedure TCanvas.FillRgn(const Rgn: HRgn);
  14659. var Br : HBrush;
  14660. begin
  14661. RequiredState( HandleValid or BrushValid or ChangingCanvas );
  14662. if assigned( fBrush ) then
  14663. Windows.FillRgn(FHandle, Rgn, fBrush.Handle )
  14664. else
  14665. if assigned( fOwnerControl ) then
  14666. begin
  14667. if Assigned( PControl( fOwnerControl ).fBrush ) then
  14668. Windows.FillRgn( FHandle, Rgn, PControl( fOwnerControl ).fBrush.Handle )
  14669. else
  14670. begin
  14671. Br := CreateSolidBrush( Color2RGB(PControl(fOwnerControl).fColor) );
  14672. Windows.FillRgn( fHandle, Rgn, Br );
  14673. DeleteObject( Br );
  14674. end;
  14675. end
  14676. else
  14677. begin
  14678. Br := CreateSolidBrush( DWORD(clWindow) );
  14679. Windows.FillRgn( fHandle, Rgn, Br );
  14680. DeleteObject( Br );
  14681. end;
  14682. end;
  14683. {$ENDIF ASM_VERSION}
  14684. {$IFDEF ASM_VERSION}
  14685. //[procedure TCanvas.FloodFill]
  14686. procedure TCanvas.FloodFill(X, Y: Integer; Color: TColor;
  14687. FillStyle: TFillStyle);
  14688. asm
  14689. PUSH EBX
  14690. MOV EBX, EAX
  14691. MOVZX EAX, [FillStyle]
  14692. TEST EAX, EAX
  14693. MOV EAX, FLOODFILLSURFACE // = 1
  14694. JZ @@1
  14695. //MOV EAX, FLOODFILLBORDER // = 0
  14696. DEC EAX
  14697. @@1:
  14698. PUSH EAX
  14699. PUSH [Color]
  14700. PUSH ECX
  14701. PUSH EDX
  14702. PUSH HandleValid or BrushValid or ChangingCanvas
  14703. PUSH EBX
  14704. CALL RequiredState
  14705. PUSH EAX
  14706. CALL Windows.ExtFloodFill
  14707. POP EBX
  14708. end;
  14709. {$ELSE ASM_VERSION} //Pascal
  14710. procedure TCanvas.FloodFill(X, Y: Integer; Color: TColor;
  14711. FillStyle: TFillStyle);
  14712. const
  14713. FillStyles: array[TFillStyle] of Word =
  14714. (FLOODFILLSURFACE, FLOODFILLBORDER);
  14715. begin
  14716. RequiredState( HandleValid or BrushValid or ChangingCanvas );
  14717. Windows.ExtFloodFill(FHandle, X, Y, Color, FillStyles[FillStyle]);
  14718. end;
  14719. {$ENDIF ASM_VERSION}
  14720. {$IFDEF ASM_VERSION}
  14721. //[procedure TCanvas.FrameRect]
  14722. procedure TCanvas.FrameRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  14723. asm
  14724. PUSH EBX
  14725. XCHG EBX, EAX
  14726. PUSH EDX
  14727. MOV ECX, [EBX].TCanvas.fBrush
  14728. JECXZ @@1
  14729. PUSH [ECX].TGraphicTool.fData.Color
  14730. JMP @@cr_br
  14731. @@1: MOV ECX, [EBX].TCanvas.fOwnerControl
  14732. JECXZ @@2
  14733. PUSH [ECX].TControl.fColor
  14734. JMP @@cr_br
  14735. @@2: PUSH clWhite
  14736. @@cr_br:POP EAX // @Rect
  14737. CALL Color2RGB
  14738. PUSH EAX
  14739. CALL CreateSolidBrush
  14740. POP EDX
  14741. PUSH EAX
  14742. PUSH EAX
  14743. PUSH EDX
  14744. PUSH HandleValid or ChangingCanvas
  14745. PUSH EBX
  14746. ///MOV EBX, EDX
  14747. CALL RequiredState
  14748. PUSH EAX
  14749. CALL Windows.FrameRect
  14750. ///PUSH EBX
  14751. CALL DeleteObject
  14752. POP EBX
  14753. end;
  14754. {$ELSE ASM_VERSION} //Pascal
  14755. procedure TCanvas.FrameRect({$IFNDEF FPC}const{$ENDIF} Rect: TRect);
  14756. var SolidBr : HBrush;
  14757. begin
  14758. RequiredState( HandleValid or ChangingCanvas );
  14759. if assigned( fBrush ) then
  14760. SolidBr := CreateSolidBrush( Color2RGB( fBrush.fData.Color ) )
  14761. else
  14762. if assigned( fOwnerControl ) then
  14763. SolidBr := CreateSolidBrush( PControl(fOwnerControl).fColor )
  14764. else
  14765. SolidBr := CreateSolidBrush( clWhite );
  14766. Windows.FrameRect(FHandle, Rect, SolidBr);
  14767. DeleteObject( SolidBr );
  14768. end;
  14769. {$ENDIF ASM_VERSION}
  14770. {$IFDEF ASM_VERSION}
  14771. //[procedure TCanvas.LineTo]
  14772. procedure TCanvas.LineTo(X, Y: Integer);
  14773. asm
  14774. PUSH ECX
  14775. PUSH EDX
  14776. PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
  14777. PUSH EAX
  14778. CALL RequiredState
  14779. PUSH EAX //Canvas.fHandle
  14780. CALL Windows.LineTo
  14781. end;
  14782. {$ELSE ASM_VERSION} //Pascal
  14783. procedure TCanvas.LineTo(X, Y: Integer);
  14784. begin
  14785. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  14786. Windows.LineTo( fHandle, X, Y );
  14787. end;
  14788. {$ENDIF ASM_VERSION}
  14789. {$IFDEF ASM_VERSION}
  14790. //[procedure TCanvas.MoveTo]
  14791. procedure TCanvas.MoveTo(X, Y: Integer);
  14792. asm
  14793. PUSH 0
  14794. PUSH ECX
  14795. PUSH EDX
  14796. PUSH HandleValid
  14797. PUSH EAX
  14798. CALL RequiredState
  14799. PUSH EAX //Canvas.fHandle
  14800. CALL Windows.MoveToEx
  14801. end;
  14802. {$ELSE ASM_VERSION} //Pascal
  14803. procedure TCanvas.MoveTo(X, Y: Integer);
  14804. begin
  14805. RequiredState( HandleValid );
  14806. Windows.MoveToEx( fHandle, X, Y, nil );
  14807. end;
  14808. {$ENDIF ASM_VERSION}
  14809. //[procedure TCanvas.ObjectChanged]
  14810. procedure TCanvas.ObjectChanged(Sender: PGraphicTool);
  14811. begin
  14812. DeselectHandles;
  14813. //if Assigned( GlobalCanvas_OnObjectChanged ) then
  14814. // GlobalCanvas_OnObjectChanged( Sender );
  14815. end;
  14816. {$IFDEF ASM_VERSION}
  14817. //[procedure TCanvas.Pie]
  14818. procedure TCanvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  14819. asm
  14820. PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
  14821. PUSH dword ptr [EBP + 8]
  14822. CALL RequiredState
  14823. MOV EDX, EAX
  14824. PUSH ESI
  14825. LEA ESI, [Y4]
  14826. STD
  14827. XOR ECX, ECX
  14828. MOV CL, 8
  14829. @@1:
  14830. LODSD
  14831. PUSH EAX
  14832. LOOP @@1
  14833. CLD
  14834. PUSH EDX //Canvas.fHandle
  14835. CALL Windows.Pie
  14836. POP ESI
  14837. end;
  14838. {$ELSE ASM_VERSION} //Pascal
  14839. procedure TCanvas.Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); stdcall;
  14840. begin
  14841. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  14842. Windows.Pie( fHandle, X1, Y1, X2, Y2, X3, Y3, X4, Y4);
  14843. end;
  14844. {$ENDIF ASM_VERSION}
  14845. {++}(*
  14846. {$IFDEF F_P}
  14847. //[Windows API FUNCTIONS ADDITIONAL DECLARATIONS FOR Free Pascal]
  14848. function Windows_Polygon; external gdi32 name 'Polygon';
  14849. function Windows_Polyline; external gdi32 name 'Polyline';
  14850. function FillRect; external user32 name 'FillRect';
  14851. function OffsetRect; external user32 name 'OffsetRect';
  14852. function CreateAcceleratorTable; external user32 name 'CreateAcceleratorTableA';
  14853. function TrackPopupMenu; external user32 name 'TrackPopupMenu';
  14854. function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL;
  14855. const NewState: TTokenPrivileges; BufferLength: DWORD;
  14856. var PreviousState: TTokenPrivileges; var ReturnLength: DWORD): BOOL; external advapi32 name 'AdjustTokenPrivileges';
  14857. function InflateRect; external user32 name 'InflateRect';
  14858. {$IFDEF F_P105ORBELOW}
  14859. function InvalidateRect; external user32 name 'InvalidateRect';
  14860. function ValidateRect; external user32 name 'ValidateRect';
  14861. {$ENDIF F_P105ORBELOW}
  14862. //[END OF Windows API FUNCTIONS ADDITIONAL DECLARATIONS FOR Free Pascal]
  14863. {$ENDIF}
  14864. *){--}
  14865. {$IFDEF ASM_VERSION}
  14866. //[procedure TCanvas.Polygon]
  14867. procedure TCanvas.Polygon(const Points: array of TPoint);
  14868. asm
  14869. INC ECX
  14870. PUSH ECX
  14871. PUSH EDX
  14872. PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
  14873. PUSH EAX
  14874. CALL RequiredState
  14875. PUSH EAX
  14876. CALL Windows.Polygon
  14877. end;
  14878. {$ELSE ASM_VERSION} //Pascal
  14879. procedure TCanvas.Polygon(const Points: array of TPoint);
  14880. type
  14881. PPoints = ^TPoints;
  14882. TPoints = array[0..0] of TPoint;
  14883. begin
  14884. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  14885. {$IFDEF F_P} Windows_Polygon
  14886. {$ELSE DELPHI} Windows.Polygon
  14887. {$ENDIF}( fHandle, PPoints(@Points)^, High(Points) + 1);
  14888. end;
  14889. {$ENDIF ASM_VERSION}
  14890. {$IFDEF ASM_VERSION}
  14891. //[procedure TCanvas.Polyline]
  14892. procedure TCanvas.Polyline(const Points: array of TPoint);
  14893. asm
  14894. INC ECX
  14895. PUSH ECX
  14896. PUSH EDX
  14897. PUSH HandleValid or PenValid or BrushValid or ChangingCanvas
  14898. PUSH EAX
  14899. CALL RequiredState
  14900. PUSH EAX
  14901. CALL Windows.Polyline
  14902. end;
  14903. {$ELSE ASM_VERSION} //Pascal
  14904. procedure TCanvas.Polyline(const Points: array of TPoint);
  14905. type
  14906. PPoints = ^TPoints;
  14907. TPoints = array[0..0] of TPoint;
  14908. begin
  14909. RequiredState( HandleValid or PenValid or BrushValid or ChangingCanvas );
  14910. {$IFDEF F_P}Windows_Polyline
  14911. {$ELSE DELPHI}Windows.Polyline
  14912. {$ENDIF}( fHandle, PPoints(@Points)^, High(Points) + 1);
  14913. end;
  14914. {$ENDIF ASM_VERSION}
  14915. {$IFDEF ASM_VERSION}
  14916. //[procedure TCanvas.Rectangle]
  14917. procedure TCanvas.Rectangle(X1, Y1, X2, Y2: Integer);
  14918. asm
  14919. PUSH [Y2]
  14920. PUSH [X2]
  14921. PUSH ECX
  14922. PUSH EDX
  14923. PUSH HandleValid or BrushValid or PenValid or ChangingCanvas
  14924. PUSH EAX
  14925. CALL RequiredState
  14926. PUSH EAX
  14927. CALL Windows.Rectangle
  14928. end;
  14929. {$ELSE ASM_VERSION} //Pascal
  14930. procedure TCanvas.Rectangle(X1, Y1, X2, Y2: Integer);
  14931. begin
  14932. RequiredState( HandleValid or BrushValid or PenValid or ChangingCanvas );
  14933. Windows.Rectangle( fHandle, X1, Y1, X2, Y2);
  14934. end;
  14935. {$ENDIF ASM_VERSION}
  14936. {$IFDEF ASM_VERSION}
  14937. //[procedure TCanvas.RoundRect]
  14938. procedure TCanvas.RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
  14939. asm
  14940. PUSH [Y3]
  14941. PUSH [X3]
  14942. PUSH [Y2]
  14943. PUSH [X2]
  14944. PUSH ECX
  14945. PUSH EDX
  14946. PUSH HandleValid or BrushValid or PenValid or ChangingCanvas
  14947. PUSH EAX
  14948. CALL RequiredState
  14949. PUSH EAX
  14950. CALL Windows.RoundRect
  14951. end;
  14952. {$ELSE ASM_VERSION} //Pascal
  14953. procedure TCanvas.RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
  14954. begin
  14955. RequiredState( HandleValid or BrushValid or PenValid or ChangingCanvas );
  14956. Windows.RoundRect( fHandle, X1, Y1, X2, Y2, X3, Y3);
  14957. end;
  14958. {$ENDIF ASM_VERSION}
  14959. {$IFDEF ASM_VERSION}
  14960. //[procedure TCanvas.TextArea]
  14961. procedure TCanvas.TextArea(const Text: String; var Sz: TSize;
  14962. var P0: TPoint);
  14963. asm
  14964. PUSH EBX
  14965. MOV EBX, EAX
  14966. PUSH ECX
  14967. CALL TextExtent
  14968. POP EDX
  14969. MOV ECX, [P0]
  14970. XOR EAX, EAX
  14971. MOV [ECX].TPoint.x, EAX
  14972. MOV [ECX].TPoint.y, EAX
  14973. CMP [GlobalCanvas_OnTextArea], EAX
  14974. JZ @@exit
  14975. MOV EAX, EBX
  14976. CALL [GlobalCanvas_OnTextArea]
  14977. @@exit:
  14978. POP EBX
  14979. end;
  14980. {$ELSE ASM_VERSION} //Pascal
  14981. procedure TCanvas.TextArea(const Text: String; var Sz: TSize;
  14982. var P0: TPoint);
  14983. begin
  14984. Sz := TextExtent( Text );
  14985. P0.x := 0; P0.y := 0;
  14986. if Assigned( GlobalCanvas_OnTextArea ) then
  14987. GlobalCanvas_OnTextArea( @Self, Sz, P0 );
  14988. end;
  14989. {$ENDIF ASM_VERSION}
  14990. {$IFDEF ASM_VERSION}
  14991. //[function TCanvas.TextExtent]
  14992. function TCanvas.TextExtent(const Text: string): TSize;
  14993. asm
  14994. PUSH EBX
  14995. PUSH ESI
  14996. MOV EBX, EAX
  14997. PUSH ECX // prepare @Result
  14998. MOV EAX, EDX
  14999. CALL System.@LStrLen
  15000. PUSH EAX // prepare Length(Text)
  15001. CALL EDX2PChar
  15002. PUSH EDX // prepare PChar(Text)
  15003. PUSH HandleValid or FontValid
  15004. PUSH EBX
  15005. CALL RequiredState
  15006. XCHG ESI, EAX
  15007. TEST ESI, ESI // ESI = fHandle before
  15008. JNZ @@1
  15009. PUSH ESI
  15010. CALL CreateCompatibleDC
  15011. MOV EDX, EBX
  15012. XCHG EAX, EDX // EAX := @Self; EDX := DC
  15013. CALL SetHandle
  15014. @@1:
  15015. //********************************************************** // Added By M.Gerasimov
  15016. //*
  15017. CMP [EBX].TCanvas.fIsPaintDC, 1
  15018. JZ @@2
  15019. XOR ESI,ESI
  15020. @@2:
  15021. //*
  15022. //********************************************************** // Added By M.Gerasimov
  15023. PUSH HandleValid or FontValid
  15024. PUSH EBX
  15025. CALL RequiredState
  15026. PUSH EAX // prepare DC
  15027. CALL Windows.GetTextExtentPoint32
  15028. TEST ESI, ESI
  15029. JNZ @@exit
  15030. XOR EDX, EDX
  15031. XCHG EAX, EBX
  15032. CALL SetHandle
  15033. @@exit:
  15034. POP ESI
  15035. POP EBX
  15036. end;
  15037. {$ELSE ASM_VERSION} //Pascal
  15038. function TCanvas.TextExtent(const Text: string): TSize;
  15039. var DC : HDC;
  15040. ClearHandle : Boolean;
  15041. begin
  15042. //Result.cX := 0;
  15043. //Result.cY := 0;
  15044. ClearHandle := False;
  15045. RequiredState( HandleValid or FontValid );
  15046. DC := fHandle;
  15047. if DC = 0 then
  15048. begin
  15049. DC := CreateCompatibleDC( 0 );
  15050. ClearHandle := True;
  15051. SetHandle( DC );
  15052. end;
  15053. //********************************************************** // Added By Gerasimov
  15054. //*
  15055. If Not fIsPaintDC then ClearHandle := True;
  15056. //*
  15057. //********************************************************** // Added By Gerasimov
  15058. RequiredState( HandleValid or FontValid );
  15059. Windows.GetTextExtentPoint32( fHandle, PChar(Text), Length(Text), Result);
  15060. if ClearHandle then
  15061. SetHandle( 0 );
  15062. { DC must be freed here automatically (never leaks):
  15063. if Canvas created on base of existing DC, no memDC created,
  15064. if Canvas has fHandle:HDC = 0, it is not fIsPaintDC always. }
  15065. end;
  15066. {$ENDIF ASM_VERSION}
  15067. //[function TCanvas.TextHeight]
  15068. function TCanvas.TextHeight(const Text: string): Integer;
  15069. begin
  15070. Result := TextExtent(Text).cY;
  15071. end;
  15072. {$IFDEF ASM_VERSION}
  15073. //[procedure TCanvas.TextOut]
  15074. procedure TCanvas.TextOut(X, Y: Integer; const Text: String); stdcall;
  15075. asm
  15076. PUSH EBX
  15077. MOV EBX, [EBP+8]
  15078. MOV EAX, [Text]
  15079. PUSH EAX
  15080. CALL System.@LStrLen
  15081. XCHG EAX, [ESP] // prepare Length(Text)
  15082. //CALL System.@LStrToPChar // string does not need to be null-terminated !
  15083. PUSH EAX // prepare PChar(Text)
  15084. PUSH [Y] // prepare Y
  15085. PUSH [X] // prepare X
  15086. PUSH HandleValid or FontValid or BrushValid or ChangingCanvas
  15087. PUSH EBX
  15088. CALL RequiredState
  15089. PUSH EAX // prepare fHandle
  15090. CALL Windows.TextOut
  15091. { -- by suggetion of Alexey (Lecha2002)
  15092. MOV EAX, EBX
  15093. MOV EDX, [Text]
  15094. CALL TextWidth
  15095. MOV EDX, [X]
  15096. ADD EDX, EAX
  15097. MOV ECX, [Y]
  15098. MOV EAX, EBX
  15099. CALL MoveTo
  15100. }
  15101. POP EBX
  15102. end;
  15103. {$ELSE ASM_VERSION} //Pascal
  15104. procedure TCanvas.TextOut(X, Y: Integer; const Text: String); stdcall;
  15105. begin
  15106. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15107. Windows.TextOut(FHandle, X, Y, PChar(Text), Length(Text));
  15108. //MoveTo(X + TextWidth(Text), Y); -- by suggestion of Alexey (Lecha2002)
  15109. end;
  15110. {$ENDIF ASM_VERSION}
  15111. {$IFDEF ASM_VERSION}
  15112. //[procedure TCanvas.TextRect]
  15113. procedure TCanvas.TextRect(const Rect: TRect; X, Y: Integer; const Text: string);
  15114. asm
  15115. PUSH EBX
  15116. XCHG EBX, EAX
  15117. PUSH 0 // prepare 0
  15118. PUSH EDX
  15119. PUSH ECX
  15120. MOV EAX, [Text]
  15121. //CALL System.@LStrToPChar
  15122. PUSH EAX
  15123. //MOV EAX, [Text]
  15124. CALL System.@LStrLen
  15125. POP ECX // ECX = @Text[1]
  15126. POP EDX // EDX = X
  15127. XCHG EAX, [ESP] // prepare Length(Text), EAX = @Rect
  15128. PUSH ECX // prepare PChar(Text)
  15129. PUSH EAX // prepare @Rect
  15130. XOR EAX, EAX
  15131. MOV AL, ETO_CLIPPED // = 4
  15132. MOV ECX, [EBX].fBrush
  15133. JECXZ @@opaque
  15134. CMP [ECX].TGraphicTool.fData.Brush.Style, bsClear
  15135. JZ @@txtout
  15136. @@opaque:
  15137. DB $0C, ETO_OPAQUE //OR AL, ETO_OPAQUE
  15138. @@txtout:
  15139. PUSH EAX // prepare Options
  15140. PUSH [Y] // prepare Y
  15141. PUSH EDX // prepare X
  15142. PUSH HandleValid or FontValid or BrushValid or ChangingCanvas
  15143. PUSH EBX
  15144. CALL RequiredState // EAX = fHandle
  15145. PUSH EAX // prepare fHandle
  15146. CALL Windows.ExtTextOut
  15147. POP EBX
  15148. end;
  15149. {$ELSE ASM_VERSION} //Pascal
  15150. procedure TCanvas.TextRect(const Rect: TRect; X, Y: Integer; const Text: string);
  15151. var
  15152. Options: Integer;
  15153. begin
  15154. //Changing;
  15155. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15156. Options := ETO_CLIPPED;
  15157. if assigned( fBrush ) and (fBrush.fData.Brush.Style <> bsClear)
  15158. or not assigned( fBrush ) then Inc(Options, ETO_OPAQUE);
  15159. Windows.ExtTextOut( fHandle, X, Y, Options,
  15160. @Rect, PChar(Text),
  15161. Length(Text), nil);
  15162. end;
  15163. {$ENDIF ASM_VERSION}
  15164. //[procedure TCanvas.ExtTextOut]
  15165. procedure TCanvas.ExtTextOut( X, Y: Integer; Options: DWORD; const Rect: TRect; const Text: String;
  15166. const Spacing: array of Integer );
  15167. begin
  15168. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15169. Windows.ExtTextOut(FHandle, X, Y, Options, @Rect, PChar(Text), Length(Text), @Spacing[ 0 ]);
  15170. end;
  15171. //[procedure TCanvas.DrawText]
  15172. procedure TCanvas.DrawText(Text:String; var Rect:TRect; Flags:DWord);
  15173. begin
  15174. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15175. Windows.DrawText(Handle,PChar(Text),Length(Text),Rect,Flags);
  15176. end;
  15177. //[function TCanvas.ClipRect]
  15178. function TCanvas.ClipRect: TRect;
  15179. begin
  15180. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15181. GetClipBox(Handle, Result);
  15182. end;
  15183. //[function TCanvas.TextWidth]
  15184. function TCanvas.TextWidth(const Text: string): Integer;
  15185. begin
  15186. Result := TextExtent(Text).cX;
  15187. end;
  15188. {$IFDEF ASM_VERSION}
  15189. //[function TCanvas.GetBrush]
  15190. function TCanvas.GetBrush: PGraphicTool;
  15191. asm
  15192. MOV ECX, [EAX].fBrush
  15193. INC ECX
  15194. LOOP @@exit
  15195. PUSH EAX
  15196. CALL NewBrush
  15197. POP EDX
  15198. PUSH EAX
  15199. MOV [EDX].fBrush, EAX
  15200. MOV [EAX].TGraphicTool.fOnChange.TMethod.Code, Offset[TCanvas.ObjectChanged]
  15201. MOV [EAX].TGraphicTool.fOnChange.TMethod.Data, EDX
  15202. MOV ECX, [EDX].fOwnerControl
  15203. JECXZ @@1
  15204. PUSH [ECX].TControl.fBrush
  15205. MOV ECX, [ECX].TControl.fColor
  15206. MOV [EAX].TGraphicTool.fData.Color, ECX
  15207. POP EDX
  15208. TEST EDX, EDX
  15209. JZ @@1
  15210. CALL TGraphicTool.Assign
  15211. @@1: POP ECX
  15212. @@exit: XCHG EAX, ECX
  15213. end;
  15214. {$ELSE ASM_VERSION} //Pascal
  15215. function TCanvas.GetBrush: PGraphicTool;
  15216. begin
  15217. if not assigned( fBrush ) then
  15218. begin
  15219. fBrush := NewBrush;
  15220. if assigned( fOwnerControl ) then
  15221. begin
  15222. fBrush.fData.Color := PControl(fOwnerControl).fColor;
  15223. if assigned( PControl(fOwnerControl).fBrush ) then
  15224. {fBrush := }fBrush.Assign( PControl(fOwnerControl).fBrush );
  15225. // both statements above needed
  15226. end;
  15227. //fBrush.OnChange := ObjectChanged;
  15228. AssignChangeEvents;
  15229. end;
  15230. Result := fBrush;
  15231. end;
  15232. {$ENDIF ASM_VERSION}
  15233. {$IFDEF ASM_VERSION}
  15234. //[function TCanvas.GetFont]
  15235. function TCanvas.GetFont: PGraphicTool;
  15236. asm
  15237. MOV ECX, [EAX].TCanvas.fFont
  15238. INC ECX
  15239. LOOP @@exit
  15240. PUSH EAX
  15241. CALL NewFont
  15242. POP EDX
  15243. PUSH EAX
  15244. MOV [EDX].TCanvas.fFont, EAX
  15245. MOV [EAX].TGraphicTool.fOnChange.TMethod.Code, Offset[TCanvas.ObjectChanged]
  15246. MOV [EAX].TGraphicTool.fOnChange.TMethod.Data, EDX
  15247. MOV ECX, [EDX].fOwnerControl
  15248. JECXZ @@1
  15249. PUSH [ECX].TControl.fFont
  15250. MOV ECX, [ECX].TControl.fTextColor
  15251. MOV [EAX].TGraphicTool.fData.Color, ECX
  15252. POP EDX
  15253. TEST EDX, EDX
  15254. JZ @@1
  15255. CALL TGraphicTool.Assign
  15256. @@1: POP ECX
  15257. @@exit: MOV EAX, ECX
  15258. end;
  15259. {$ELSE ASM_VERSION} //Pascal
  15260. function TCanvas.GetFont: PGraphicTool;
  15261. begin
  15262. if not assigned( fFont ) then
  15263. begin
  15264. fFont := NewFont;
  15265. if assigned( fOwnerControl ) then
  15266. begin
  15267. fFont.Color := PControl(fOwnerControl).fTextColor;
  15268. if assigned( PControl(fOwnerControl).fFont ) then
  15269. {fFont := }fFont.Assign( PControl(fOwnerControl).fFont );
  15270. end;
  15271. //fFont.OnChange := ObjectChanged;
  15272. AssignChangeEvents;
  15273. end;
  15274. Result := fFont;
  15275. end;
  15276. {$ENDIF ASM_VERSION}
  15277. {$IFDEF ASM_VERSION}
  15278. //[function TCanvas.GetPen]
  15279. function TCanvas.GetPen: PGraphicTool;
  15280. asm
  15281. MOV ECX, [EAX].TCanvas.fPen
  15282. INC ECX
  15283. LOOP @@exit
  15284. PUSH EAX
  15285. CALL NewPen
  15286. POP EDX
  15287. MOV [EDX].fPen, EAX
  15288. PUSH EAX
  15289. MOV EAX, EDX
  15290. CALL AssignChangeEvents
  15291. POP ECX
  15292. @@exit: MOV EAX, ECX
  15293. end;
  15294. {$ELSE ASM_VERSION} //Pascal
  15295. function TCanvas.GetPen: PGraphicTool;
  15296. begin
  15297. if not assigned( fPen ) then
  15298. begin
  15299. fPen := NewPen;
  15300. AssignChangeEvents;
  15301. end;
  15302. Result := fPen;
  15303. end;
  15304. {$ENDIF ASM_VERSION}
  15305. {$IFDEF ASM_VERSION}
  15306. //[function TCanvas.GetHandle]
  15307. function TCanvas.GetHandle: HDC;
  15308. asm
  15309. CMP word ptr[EAX].fOnGetHandle.TMethod.Code+2, 0
  15310. MOV EDX, EAX
  15311. MOV EAX, [EDX].fHandle
  15312. JZ @@exit
  15313. MOV EAX, [EDX].fOnGetHandle.TMethod.Data
  15314. PUSH EDX
  15315. CALL [EDX].fOnGetHandle.TMethod.Code
  15316. XCHG EAX, [ESP]
  15317. POP EDX
  15318. PUSH EDX
  15319. CALL SetHandle
  15320. POP EAX
  15321. @@exit:
  15322. end;
  15323. {$ELSE ASM_VERSION} //Pascal
  15324. function TCanvas.GetHandle: HDC;
  15325. begin
  15326. if assigned( fOnGetHandle ) then
  15327. begin
  15328. Result := fOnGetHandle( @Self );
  15329. //fHandle := Result;
  15330. SetHandle( Result );
  15331. end
  15332. else
  15333. Result := fHandle;
  15334. end;
  15335. {$ENDIF ASM_VERSION}
  15336. {$IFDEF ASM_VERSION}
  15337. //[procedure TCanvas.AssignChangeEvents]
  15338. procedure TCanvas.AssignChangeEvents;
  15339. asm
  15340. PUSH ESI
  15341. LEA ESI, [EAX].fBrush
  15342. MOV CL, 3
  15343. MOV EDX, EAX
  15344. @@1: LODSD
  15345. TEST EAX, EAX
  15346. JZ @@nxt
  15347. MOV [EAX].TGraphicTool.fOnChange.TMethod.Data, EDX
  15348. MOV [EAX].TGraphicTool.fOnChange.TMethod.Code, offset[ ObjectChanged ]
  15349. @@nxt: DEC CL
  15350. JNZ @@1
  15351. POP ESI
  15352. end;
  15353. {$ELSE ASM_VERSION} //Pascal
  15354. procedure TCanvas.AssignChangeEvents;
  15355. begin
  15356. if assigned( fFont ) then
  15357. fFont.fOnChange := ObjectChanged;
  15358. if assigned( fBrush ) then
  15359. fBrush.fOnChange := ObjectChanged;
  15360. if assigned( fPen ) then
  15361. fPen.fOnChange := ObjectChanged;
  15362. end;
  15363. {$ENDIF ASM_VERSION}
  15364. {$IFNDEF _FPC}
  15365. {$IFNDEF _D2}
  15366. //[procedure TCanvas.WDrawText]
  15367. procedure TCanvas.WDrawText(WText: WideString; var Rect: TRect;
  15368. Flags: DWord);
  15369. begin
  15370. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15371. Windows.DrawTextW(Handle,PWideChar(WText),Length(WText),Rect,Flags);
  15372. end;
  15373. //[procedure TCanvas.WExtTextOut]
  15374. procedure TCanvas.WExtTextOut(X, Y: Integer; Options: DWORD;
  15375. const Rect: TRect; const WText: WideString;
  15376. const Spacing: array of Integer);
  15377. begin
  15378. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15379. Windows.ExtTextOutW(FHandle, X, Y, Options, @Rect, PWideChar(WText), Length(WText), @Spacing[ 0 ]);
  15380. end;
  15381. //[procedure TCanvas.WTextOut]
  15382. procedure TCanvas.WTextOut(X, Y: Integer; const WText: WideString);
  15383. begin
  15384. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15385. Windows.TextOutW(FHandle, X, Y, PWideChar(WText), Length(WText));
  15386. MoveTo(X + WTextWidth(WText), Y);
  15387. end;
  15388. //[procedure TCanvas.WTextRect]
  15389. procedure TCanvas.WTextRect(const Rect: TRect; X, Y: Integer;
  15390. const WText: WideString);
  15391. var
  15392. Options: Integer;
  15393. begin
  15394. //Changing;
  15395. RequiredState( HandleValid or FontValid or BrushValid or ChangingCanvas );
  15396. Options := ETO_CLIPPED;
  15397. if assigned( fBrush ) and (fBrush.fData.Brush.Style <> bsClear)
  15398. or not assigned( fBrush ) then Inc(Options, ETO_OPAQUE);
  15399. Windows.ExtTextOutW( fHandle, X, Y, Options,
  15400. @Rect, PWideChar(WText),
  15401. Length(WText), nil);
  15402. end;
  15403. //[function TCanvas.WTextExtent]
  15404. function TCanvas.WTextExtent(const WText: WideString): TSize;
  15405. var DC : HDC;
  15406. ClearHandle : Boolean;
  15407. begin
  15408. ClearHandle := False;
  15409. RequiredState( HandleValid or FontValid );
  15410. DC := fHandle;
  15411. if DC = 0 then
  15412. begin
  15413. DC := CreateCompatibleDC( 0 );
  15414. ClearHandle := True;
  15415. SetHandle( DC );
  15416. end;
  15417. RequiredState( HandleValid or FontValid );
  15418. Windows.GetTextExtentPoint32W( fHandle, PWideChar(WText), Length(WText), Result);
  15419. if ClearHandle then
  15420. SetHandle( 0 );
  15421. end;
  15422. //[function TCanvas.WTextHeight]
  15423. function TCanvas.WTextHeight(const WText: WideString): Integer;
  15424. begin
  15425. Result := WTextExtent( WText ).cy;
  15426. end;
  15427. //[function TCanvas.WTextWidth]
  15428. function TCanvas.WTextWidth(const WText: WideString): Integer;
  15429. begin
  15430. Result := WTextExtent( WText ).cx;
  15431. end;
  15432. {$ENDIF _D2}
  15433. {$ENDIF _FPC}
  15434. {-}
  15435. //[function MakeInt64]
  15436. function MakeInt64( Lo, Hi: DWORD ): I64;
  15437. begin
  15438. Result.Lo := Lo;
  15439. Result.Hi := Hi;
  15440. end;
  15441. //[function Int2Int64]
  15442. function Int2Int64( X: Integer ): I64;
  15443. asm
  15444. MOV [EDX], EAX
  15445. MOV ECX, EDX
  15446. CDQ
  15447. MOV [ECX+4], EDX
  15448. end;
  15449. //[procedure IncInt64]
  15450. procedure IncInt64( var I64: I64; Delta: Integer );
  15451. asm
  15452. ADD [EAX], EDX
  15453. ADC dword ptr [EAX+4], 0
  15454. end;
  15455. //[procedure DecInt64]
  15456. procedure DecInt64( var I64: I64; Delta: Integer );
  15457. asm
  15458. SUB [EAX], EDX
  15459. SBB dword ptr [EDX], 0
  15460. end;
  15461. //[function Add64]
  15462. function Add64( const X, Y: I64 ): I64;
  15463. asm
  15464. PUSH ESI
  15465. XCHG ESI, EAX
  15466. LODSD
  15467. ADD EAX, [EDX]
  15468. MOV [ECX], EAX
  15469. LODSD
  15470. ADC EAX, [EDX+4]
  15471. MOV [ECX+4], EAX
  15472. POP ESI
  15473. end;
  15474. //[function Sub64]
  15475. function Sub64( const X, Y: I64 ): I64;
  15476. asm
  15477. PUSH ESI
  15478. XCHG ESI, EAX
  15479. LODSD
  15480. SUB EAX, [EDX]
  15481. MOV [ECX], EAX
  15482. LODSD
  15483. SBB EAX, [EDX+4]
  15484. MOV [ECX+4], EAX
  15485. POP ESI
  15486. end;
  15487. //[function Neg64]
  15488. function Neg64( const X: I64 ): I64;
  15489. asm
  15490. MOV ECX, [EAX]
  15491. NEG ECX
  15492. MOV [EDX], ECX
  15493. MOV ECX, 0
  15494. SBB ECX, [EAX+4]
  15495. MOV [EDX+4], ECX
  15496. end;
  15497. //[function Mul64EDX]
  15498. function Mul64EDX( const X: I64; M: Integer ): I64;
  15499. asm
  15500. PUSH ESI
  15501. PUSH EDI
  15502. XCHG ESI, EAX
  15503. MOV EDI, ECX
  15504. MOV ECX, EDX
  15505. LODSD
  15506. MUL ECX
  15507. STOSD
  15508. XCHG EDX, ECX
  15509. LODSD
  15510. MUL EDX
  15511. ADD EAX, ECX
  15512. STOSD
  15513. POP EDI
  15514. POP ESI
  15515. end;
  15516. //[FUNCTION Mul64i]
  15517. {$IFDEF ASM_VERSION}
  15518. function Mul64i( const X: I64; Mul: Integer ): I64;
  15519. asm //cmd //opd
  15520. TEST EDX, EDX
  15521. PUSHFD
  15522. JGE @@1
  15523. NEG EDX
  15524. @@1: PUSH ECX
  15525. CALL Mul64EDX
  15526. POP EAX
  15527. POPFD
  15528. JGE @@2
  15529. MOV EDX, EAX
  15530. CALL Neg64
  15531. @@2:
  15532. end;
  15533. {$ELSE ASM_VERSION} //Pascal
  15534. function Mul64i( const X: I64; Mul: Integer ): I64;
  15535. var Minus: Boolean;
  15536. begin
  15537. Minus := FALSE;
  15538. if Mul < 0 then
  15539. begin
  15540. Minus := TRUE;
  15541. Mul := -Mul;
  15542. end;
  15543. Result := Mul64EDX( X, Mul );
  15544. if Minus then
  15545. Result := Neg64( Result );
  15546. end;
  15547. {$ENDIF ASM_VERSION}
  15548. //[END Mul64i]
  15549. //[function Div64EDX]
  15550. function Div64EDX( const X: I64; D: Integer ): I64;
  15551. asm
  15552. PUSH ESI
  15553. PUSH EDI
  15554. XCHG ESI, EAX
  15555. MOV EDI, ECX
  15556. MOV ECX, EDX
  15557. MOV EAX, [ESI+4]
  15558. CDQ
  15559. DIV ECX
  15560. MOV [EDI+4], EAX
  15561. LODSD
  15562. DIV ECX
  15563. STOSD
  15564. POP EDI
  15565. POP ESI
  15566. end;
  15567. //[FUNCTION Div64i]
  15568. {$IFDEF ASM_VERSION}
  15569. function Div64i( const X: I64; D: Integer ): I64;
  15570. asm //cmd //opd
  15571. PUSH EBX
  15572. XOR EBX, EBX
  15573. PUSH ESI
  15574. XCHG ESI, EAX
  15575. LODSD
  15576. MOV [ECX], EAX
  15577. LODSD
  15578. MOV [ECX+4], EAX
  15579. MOV ESI, ECX
  15580. PUSH EDX
  15581. XCHG EAX, ECX
  15582. CALL Sgn64
  15583. TEST EAX, EAX
  15584. JGE @@1
  15585. INC EBX
  15586. MOV EAX, ESI
  15587. MOV EDX, ESI
  15588. CALL Neg64
  15589. @@1: POP EDX
  15590. TEST EDX, EDX
  15591. JGE @@2
  15592. XOR EBX, 1
  15593. NEG EDX
  15594. @@2: MOV EAX, ESI
  15595. MOV ECX, ESI
  15596. CALL Div64EDX
  15597. DEC EBX
  15598. JNZ @@3
  15599. MOV EDX, ESI
  15600. XCHG EAX, ESI
  15601. CALL Neg64
  15602. @@3: POP ESI
  15603. POP EBX
  15604. end;
  15605. {$ELSE ASM_VERSION} //Pascal
  15606. function Div64i( const X: I64; D: Integer ): I64;
  15607. var Minus: Boolean;
  15608. begin
  15609. Minus := FALSE;
  15610. if D < 0 then
  15611. begin
  15612. D := -D;
  15613. Minus := TRUE;
  15614. end;
  15615. Result := X;
  15616. if Sgn64( Result ) < 0 then
  15617. begin
  15618. Result := Neg64( Result );
  15619. Minus := not Minus;
  15620. end;
  15621. Result := Div64EDX( Result, D );
  15622. if Minus then
  15623. Result := Neg64( Result );
  15624. end;
  15625. {$ENDIF ASM_VERSION}
  15626. //[END Div64i]
  15627. //[function Mod64i]
  15628. function Mod64i( const X: I64; D: Integer ): Integer;
  15629. begin
  15630. Result := Sub64( X, Mul64i( Div64i( X, D ), D ) ).Lo;
  15631. end;
  15632. //[function Sgn64]
  15633. function Sgn64( const X: I64 ): Integer;
  15634. asm
  15635. XOR EDX, EDX
  15636. CMP [EAX+4], EDX
  15637. XCHG EAX, EDX
  15638. JG @@ret_1
  15639. JL @@ret_neg
  15640. CMP [EDX], EAX
  15641. JZ @@exit
  15642. @@ret_1:
  15643. INC EAX
  15644. RET
  15645. @@ret_neg:
  15646. DEC EAX
  15647. @@exit:
  15648. end;
  15649. //[function Cmp64]
  15650. function Cmp64( const X, Y: I64 ): Integer;
  15651. begin
  15652. Result := Sgn64( Sub64( X, Y ) );
  15653. end;
  15654. //[function Int64_2Str]
  15655. function Int64_2Str( X: I64 ): String;
  15656. var M: Boolean;
  15657. Y: Integer;
  15658. Buf: array[ 0..31 ] of Char;
  15659. I: Integer;
  15660. begin
  15661. M := FALSE;
  15662. case Sgn64( X ) of
  15663. -1: begin M := TRUE; X := Neg64( X ); end;
  15664. 0: begin Result := '0'; Exit; end;
  15665. end;
  15666. I := 31;
  15667. Buf[ 31 ] := #0;
  15668. while Sgn64( X ) > 0 do
  15669. begin
  15670. Dec( I );
  15671. Y := Mod64i( X, 10 );
  15672. Buf[ I ] := Char( Y + Integer( '0' ) );
  15673. X := Div64i( X, 10 );
  15674. end;
  15675. if M then
  15676. begin
  15677. Dec( I );
  15678. Buf[ I ] := '-';
  15679. end;
  15680. Result := PChar( @Buf[ I ] );
  15681. end;
  15682. //[function Str2Int64]
  15683. function Str2Int64( const S: String ): I64;
  15684. var I: Integer;
  15685. M: Boolean;
  15686. begin
  15687. Result.Lo := 0;
  15688. Result.Hi := 0;
  15689. I := 1;
  15690. if S = '' then Exit;
  15691. M := FALSE;
  15692. if S[ 1 ] = '-' then
  15693. begin
  15694. M := TRUE;
  15695. Inc( I );
  15696. end
  15697. else
  15698. if S[ 1 ] = '+' then
  15699. Inc( I );
  15700. while I <= Length( S ) do
  15701. begin
  15702. if not( S[ I ] in [ '0'..'9' ] ) then
  15703. break;
  15704. Result := Mul64i( Result, 10 );
  15705. IncInt64( Result, Integer( S[ I ] ) - Integer( '0' ) );
  15706. Inc( I );
  15707. end;
  15708. if M then
  15709. Result := Neg64( Result );
  15710. end;
  15711. //[function Int64_2Double]
  15712. function Int64_2Double( const X: I64 ): Double;
  15713. asm
  15714. FILD qword ptr [EAX]
  15715. FSTP @Result
  15716. end;
  15717. //[function Double2Int64]
  15718. function Double2Int64( D: Double ): I64;
  15719. asm
  15720. FLD D
  15721. FISTP qword ptr [EAX]
  15722. end;
  15723. {+}
  15724. function IsNan(const AValue: Double): Boolean;
  15725. {$IFDEF _D2orD3}
  15726. type PI64 = ^I64;
  15727. {$ENDIF}
  15728. begin
  15729. {-}
  15730. Result := (PI64(@AValue).Hi and $7FF00000 = $7FF00000) and
  15731. ((PI64(@AValue).Hi and $000FFFFF <> 0) or (PI64(@AValue).Lo <> 0));
  15732. {+}{++}(*Result := AValue = NAN;*){--}
  15733. end;
  15734. //[function IntPower]
  15735. function IntPower(Base: Extended; Exponent: Integer): Extended;
  15736. {$IFDEF F_P}
  15737. begin
  15738. if Exponent = 0 then
  15739. begin
  15740. Result := 1.0;
  15741. Exit;
  15742. end;
  15743. if Exponent < 0 then
  15744. begin
  15745. Exponent := -Exponent;
  15746. Base := 1.0 / Base;
  15747. end;
  15748. Result := Base;
  15749. REPEAT
  15750. Result := Result * Base;
  15751. Dec( Exponent );
  15752. UNTIL Exponent <= 0;
  15753. end;
  15754. {$ELSE DELPHI}
  15755. // This version of code by Galkov:
  15756. // Changes in comparison to Delphi standard:
  15757. // no Overflow exception if Exponent is very big negative value
  15758. // (just 0 in result in such case).
  15759. asm
  15760. fld1 { Result := 1 }
  15761. test eax,eax // check Exponent for 0, return 0 ** 0 = 1
  15762. jz @@3 // (though Mathematics says that this is not so...)
  15763. fld Base
  15764. jg @@2
  15765. fdivr ST,ST(1) { Base := 1 / Base }
  15766. neg eax
  15767. jmp @@2
  15768. @@1: fmul ST,ST { X := Base * Base }
  15769. @@2: shr eax,1
  15770. jnc @@1
  15771. fmul ST(1),ST { Result := Result * X }
  15772. jnz @@1
  15773. fstp st { pop X from FPU stack }
  15774. @@3: fwait
  15775. end;
  15776. (* version of code by Borland:
  15777. asm
  15778. mov ecx, eax
  15779. cdq
  15780. fld1 { Result := 1 }
  15781. xor eax, edx
  15782. sub eax, edx { eax := Abs(Exponent) }
  15783. jz @@3
  15784. fld Base
  15785. jmp @@2
  15786. @@1: fmul ST, ST { X := Base * Base }
  15787. @@2: shr eax,1
  15788. jnc @@1
  15789. fmul ST(1),ST { Result := Result * X }
  15790. jnz @@1
  15791. fstp st { pop X from FPU stack }
  15792. cmp ecx, 0
  15793. jge @@3
  15794. fld1
  15795. fdivrp { Result := 1 / Result }
  15796. @@3:
  15797. fwait
  15798. end;*)
  15799. {$ENDIF F_P/DELPHI}
  15800. //[function Str2Double]
  15801. function Str2Double( const S: String ): Double;
  15802. var I: Integer;
  15803. M, Pt: Boolean;
  15804. D: Double;
  15805. Ex: Integer;
  15806. begin
  15807. Result := 0.0;
  15808. if S = '' then Exit;
  15809. M := FALSE;
  15810. I := 1;
  15811. if S[ 1 ] = '-' then
  15812. begin
  15813. M := TRUE;
  15814. Inc( I );
  15815. end;
  15816. Pt := FALSE;
  15817. D := 1.0;
  15818. while I <= Length( S ) do
  15819. begin
  15820. case S[ I ] of
  15821. '.': if not Pt then Pt := TRUE else break;
  15822. '0'..'9': if not Pt then
  15823. Result := Result * 10.0 + Integer( S[ I ] ) - Integer( '0' )
  15824. else
  15825. begin
  15826. D := D * 0.1;
  15827. Result := Result + (Integer( S[ I ] ) - Integer( '0' )) * D;
  15828. end;
  15829. 'e', 'E': begin
  15830. Ex := Str2Int( CopyEnd( S, I + 1 ) );
  15831. Result := Result * IntPower( 10.0, Ex );
  15832. break;
  15833. end;
  15834. end;
  15835. Inc( I );
  15836. end;
  15837. if M then
  15838. Result := -Result;
  15839. end;
  15840. //[function TruncD]
  15841. function TruncD( D: Double ): Double;
  15842. {-}
  15843. asm
  15844. FLD D
  15845. PUSH ECX
  15846. FNSTCW [ESP]
  15847. POP ECX
  15848. PUSH ECX
  15849. OR byte ptr [ESP+1], $0C
  15850. FLDCW [ESP]
  15851. PUSH ECX
  15852. FRNDINT
  15853. FSTP @Result
  15854. FLDCW [ESP]
  15855. POP ECX
  15856. POP ECX
  15857. end;
  15858. {+}{++}(*
  15859. begin
  15860. Result := Trunc( D );
  15861. end;
  15862. *){--}
  15863. // Precision 15
  15864. //[function Extended2Str]
  15865. function Extended2Str( E: Extended ): String;
  15866. function UnpackFromBuf( const Buf: array of Byte; N: Integer ): String;
  15867. var I, J, K, L: Integer;
  15868. begin
  15869. SetLength( Result, 16 );
  15870. J := 1;
  15871. for I := 7 downto 0 do
  15872. begin
  15873. K := Buf[ I ] shr 4;
  15874. Result[ J ] := Char( Ord('0') + K );
  15875. Inc( J );
  15876. K := Buf[ I ] and $F;
  15877. Result[ J ] := Char( Ord('0') + K );
  15878. Inc( J );
  15879. end;
  15880. Assert( Result[ 1 ] = '0', 'error!' );
  15881. Delete( Result, 1, 1 );
  15882. if N <= 0 then
  15883. begin
  15884. while N < 0 do
  15885. begin
  15886. Result := '0' + Result;
  15887. Inc( N );
  15888. end;
  15889. Result := '0.' + Result;
  15890. end
  15891. else
  15892. if N < Length( Result ) then
  15893. begin
  15894. Result := Copy( Result, 1, N ) + '.' + CopyEnd( Result, N + 1 );
  15895. end
  15896. else
  15897. begin
  15898. while N > Length( Result ) do
  15899. begin
  15900. Result := Result + '0';
  15901. end;
  15902. Exit;
  15903. end;
  15904. L := Length( Result );
  15905. while L > 1 do
  15906. begin
  15907. if not (Result[ L ] in ['0','.']) then break;
  15908. Dec( L );
  15909. if Result[ L + 1 ] = '.' then break;
  15910. end;
  15911. if L < Length( Result ) then Delete( Result, L + 1, MaxInt );
  15912. end;
  15913. var
  15914. S: Boolean;
  15915. var F: Extended;
  15916. N: Integer;
  15917. Buf1: array[ 0..9 ] of Byte;
  15918. I10: Integer;
  15919. begin
  15920. Result := '0';
  15921. if E = 0 then Exit;
  15922. S := E < 0;
  15923. if S then E := -E;
  15924. N := 15;
  15925. F := 5E12;
  15926. I10 := 10;
  15927. while E < F do
  15928. begin
  15929. Dec( N );
  15930. E := E * I10;
  15931. end;
  15932. if N = 15 then
  15933. while E >= 1E13 do
  15934. begin
  15935. Inc( N );
  15936. E := E / I10;
  15937. end;
  15938. while TRUE do
  15939. begin
  15940. asm
  15941. FLD [E]
  15942. FBSTP [Buf1]
  15943. end;
  15944. if Buf1[ 7 ] <> 0 then break;
  15945. E := E * I10;
  15946. Dec( N );
  15947. end;
  15948. Result := UnpackFromBuf( Buf1, N );
  15949. if S then Result := '-' + Result;
  15950. end;
  15951. //[function Double2Str]
  15952. function Double2Str( D: Double ): String;
  15953. begin
  15954. Result := Extended2Str( D );
  15955. end;
  15956. //[function Double2StrEx]
  15957. function Double2StrEx( D: Double ): String;
  15958. var E, E1, E2: Double;
  15959. S: String;
  15960. begin
  15961. Result := Double2Str( D );
  15962. E := Str2Double( Result );
  15963. E1 := E - D;
  15964. if E1 < 0.0 then E1 := -E1;
  15965. if E1 < 1e-307 then Exit;
  15966. while TRUE do
  15967. begin
  15968. E := D - (E - D) * 0.3;
  15969. S := Double2Str( E );
  15970. if S = Result then break;
  15971. E := Str2Double( S );
  15972. E2 := E - D;
  15973. if E2 < 0.0 then E2 := -E2;
  15974. if E2 > E1 * 0.75 then break;
  15975. Result := S;
  15976. if E2 < E1 * 0.1 then break;
  15977. end;
  15978. end;
  15979. //[function GetBits]
  15980. function GetBits( N: DWORD; first, last: Byte ): DWord;
  15981. {$IFDEF F_P}
  15982. begin
  15983. Result := 0;
  15984. if last > 31 then last := 31;
  15985. if first > last then Exit;
  15986. Result := (N and not ($FFFFFFFF shl last)) shr first;
  15987. end;
  15988. {$ELSE DELPHI}
  15989. asm
  15990. XCHG EAX, EDX // (1) EDX=N, AL=first
  15991. {$IFDEF PARANOIA}
  15992. DB $3C, 31
  15993. {$ELSE}
  15994. CMP AL, 31 // first(AL) > 31 ?
  15995. {$ENDIF}
  15996. JBE @@1 // (2) åñëè äà, òî Result := 0;
  15997. @@0:
  15998. XOR EAX, EAX // (2)
  15999. RET // (1)
  16000. @@1:
  16001. XCHG EAX, ECX // (1) AL = last CL = first
  16002. SHR EDX, CL // (2) EDX = N shr first
  16003. SUB AL, CL // (2) AL = last - first
  16004. JL @@0 // (2) åñëè last < first òî Result := 0;
  16005. {$IFDEF PARANOIA}
  16006. DB $3C, 32
  16007. {$ELSE}
  16008. CMP AL, 32 // (2) last - first >= 32 ?
  16009. {$ENDIF}
  16010. XCHG ECX, EAX // (1) CL = last - first
  16011. XCHG EAX, EDX // (1) EAX = N shr first
  16012. JAE @@exit // (2) åñëè last - first > 31, òî Result := EAX;
  16013. SBB EDX, EDX // (2) EDX = -1
  16014. DEC EDX // (1) EDX = 1111...10 = -2
  16015. SHL EDX, CL // (2) EDX = 111...100..0 (ãäå n(0)=last-first+1)
  16016. NOT EDX // (2) EDX = ìàñêà 000..0111...1 (ãäå n(1)=last-first+1)
  16017. AND EAX, EDX // (2)
  16018. @@exit:
  16019. // EAX = ðåçóëüòàò, (1 áàéò íà êîìàíäó RET)
  16020. end;
  16021. {$ENDIF F_P/DELPHI}
  16022. //[function GetBitsL]
  16023. function GetBitsL( N: DWORD; from, len: Byte ): DWord;
  16024. {$IFDEF F_P}
  16025. begin
  16026. Result := GetBits( N, from, from + len - 1 );
  16027. end;
  16028. {$ELSE DELPHI}
  16029. asm
  16030. ADD CL, DL
  16031. DEC CL
  16032. JMP GetBits
  16033. end;
  16034. {$ENDIF F_P/DELPHI}
  16035. //[FUNCTION Int2Hex]
  16036. {$IFDEF ASM_VERSION}
  16037. function Int2Hex( Value : DWord; Digits : Integer ) : String;
  16038. asm
  16039. // EAX = Value
  16040. // EDX = Digits (actually DL needed)
  16041. // ECX = @Result
  16042. PUSH 0
  16043. ADD ESP, -0Ch
  16044. PUSH EBX
  16045. PUSH ECX
  16046. LEA EBX, [ESP+8+0Fh] // EBX := @Buf[ 15 ]
  16047. AND EDX, $F
  16048. @@loop: DEC EBX
  16049. DEC EDX
  16050. PUSH EAX
  16051. {$IFDEF PARANOIA}
  16052. DB $24, $0F
  16053. {$ELSE}
  16054. AND AL, 0Fh
  16055. {$ENDIF}
  16056. {$IFDEF PARANOIA}
  16057. DB $3C, 9
  16058. {$ELSE}
  16059. CMP AL, 9
  16060. {$ENDIF}
  16061. JA @@10
  16062. {$IFDEF PARANOIA}
  16063. DB $04, 30h-41h+0Ah
  16064. {$ELSE}
  16065. ADD AL,30h-41h+0Ah
  16066. {$ENDIF}
  16067. @@10:
  16068. {$IFDEF PARANOIA}
  16069. DB $04, 41h-0Ah
  16070. {$ELSE}
  16071. ADD AL,41h-0Ah
  16072. {$ENDIF}
  16073. MOV byte ptr [EBX], AL
  16074. POP EAX
  16075. SHR EAX, 4
  16076. JNZ @@loop
  16077. TEST EDX, EDX
  16078. JG @@loop
  16079. POP EAX // EAX = @Result
  16080. MOV EDX, EBX // EDX = @resulting string
  16081. CALL System.@LStrFromPChar
  16082. POP EBX
  16083. ADD ESP, 10h
  16084. {== by KSer - to test it only.
  16085. function Int2Hex( Value : DWord; Digits : Integer ) : shortString;
  16086. asm
  16087. MOV [ECX], DL
  16088. XADD EDX, ECX
  16089. @@loop1:
  16090. PUSH EAX
  16091. db $24, $0F // and al,$0F
  16092. AAM
  16093. //AAD
  16094. DB $D5, $11
  16095. db $04, $30 // add al,$30
  16096. MOV [EDX], AL
  16097. POP EAX
  16098. SHR EAX, 4
  16099. DEC EDX
  16100. LOOP @@loop1
  16101. }
  16102. end;
  16103. {$ELSE ASM_VERSION} //Pascal (mixed)
  16104. function Int2Hex( Value : DWord; Digits : Integer ) : String;
  16105. var Buf: array[ 0..8 ] of Char;
  16106. Dest : PChar;
  16107. function HexDigit( B : Byte ) : Char;
  16108. {$IFDEF F_P}
  16109. const
  16110. HexDigitChr: array[ 0..15 ] of Char = ( '0','1','2','3','4','5','6','7',
  16111. '8','9','A','B','C','D','E','F' );
  16112. begin
  16113. Result := HexDigitChr[ B and $F ];
  16114. end;
  16115. {$ELSE DELPHI}
  16116. asm
  16117. {$IFDEF PARANOIA}
  16118. DB $3C,9
  16119. {$ELSE}
  16120. CMP AL,9
  16121. {$ENDIF}
  16122. JA @@1
  16123. {$IFDEF PARANOIA}
  16124. DB $04, $30-$41+$0A
  16125. {$ELSE}
  16126. ADD AL,30h-41h+0Ah
  16127. {$ENDIF}
  16128. @@1:
  16129. {$IFDEF PARANOIA}
  16130. DB $04, $41-$0A
  16131. {$ELSE}
  16132. ADD AL,41h-0Ah
  16133. {$ENDIF}
  16134. end;
  16135. {$ENDIF F_P/DELPHI}
  16136. begin
  16137. Dest := @Buf[ 8 ];
  16138. Dest^ := #0;
  16139. repeat
  16140. Dec( Dest );
  16141. Dest^ := '0';
  16142. if Value <> 0 then
  16143. begin
  16144. Dest^ := HexDigit( Value and $F );
  16145. Value := Value shr 4;
  16146. end;
  16147. Dec( Digits );
  16148. until (Value = 0) and (Digits <= 0);
  16149. Result := Dest;
  16150. end;
  16151. {$ENDIF ASM_VERSION}
  16152. //[END Int2Hex]
  16153. //[FUNCTION Hex2Int]
  16154. {$IFDEF ASM_VERSION}
  16155. function Hex2Int( const Value : String) : Integer;
  16156. asm
  16157. CALL EAX2PChar
  16158. PUSH ESI
  16159. XCHG ESI, EAX
  16160. XOR EDX, EDX
  16161. TEST ESI, ESI
  16162. JE @@exit
  16163. LODSB
  16164. {$IFDEF PARANOIA}
  16165. DB $3C, '$'
  16166. {$ELSE}
  16167. CMP AL, '$'
  16168. {$ENDIF}
  16169. JNE @@1
  16170. @@0: LODSB
  16171. @@1: TEST AL, AL
  16172. JE @@exit
  16173. {$IFDEF PARANOIA}
  16174. DB $2C, '0'
  16175. {$ELSE}
  16176. SUB AL, '0'
  16177. {$ENDIF}
  16178. {$IFDEF PARANOIA}
  16179. DB $3C, 9
  16180. {$ELSE}
  16181. CMP AL, '9' - '0'
  16182. {$ENDIF}
  16183. JBE @@3
  16184. {$IFDEF PARANOIA}
  16185. DB $2C, $11
  16186. {$ELSE}
  16187. SUB AL, 'A' - '0'
  16188. {$ENDIF}
  16189. {$IFDEF PARANOIA}
  16190. DB $3C, 5
  16191. {$ELSE}
  16192. CMP AL, 'F' - 'A'
  16193. {$ENDIF}
  16194. JBE @@2
  16195. {$IFDEF PARANOIA}
  16196. DB $2C, 32
  16197. {$ELSE}
  16198. SUB AL, 32
  16199. {$ENDIF}
  16200. {$IFDEF PARANOIA}
  16201. DB $3C, 5
  16202. {$ELSE}
  16203. CMP AL, 'F' - 'A'
  16204. {$ENDIF}
  16205. JA @@exit
  16206. @@2:
  16207. {$IFDEF PARANOIA}
  16208. DB $04, 0Ah
  16209. {$ELSE}
  16210. ADD AL, 0Ah
  16211. {$ENDIF}
  16212. @@3:
  16213. SHL EDX, 4
  16214. ADD DL, AL
  16215. JMP @@0
  16216. @@exit: XCHG EAX, EDX
  16217. POP ESI
  16218. end;
  16219. {$ELSE ASM_VERSION} //Pascal
  16220. function Hex2Int( const Value : String) : Integer;
  16221. var I : Integer;
  16222. begin
  16223. Result := 0;
  16224. I := 1;
  16225. if Value = '' then Exit;
  16226. if Value[ 1 ] = '$' then Inc( I );
  16227. while I <= Length( Value ) do
  16228. begin
  16229. if Value[ I ] in [ '0'..'9' ] then
  16230. Result := (Result shl 4) or (Ord(Value[I]) - Ord('0'))
  16231. else
  16232. if Value[ I ] in [ 'A'..'F' ] then
  16233. Result := (Result shl 4) or (Ord(Value[I]) - Ord('A') + 10)
  16234. else
  16235. if Value[ I ] in [ 'a'..'f' ] then
  16236. Result := (Result shl 4) or (Ord(Value[I]) - Ord('a') + 10)
  16237. else
  16238. break;
  16239. Inc( I );
  16240. end;
  16241. end;
  16242. {$ENDIF ASM_VERSION}
  16243. //[END Hex2Int]
  16244. //[FUNCTION Octal2Int]
  16245. function Octal2Int( const Value: String ) : Integer;
  16246. var I: Integer;
  16247. begin
  16248. Result := 0;
  16249. for I := 1 to Length( Value ) do
  16250. begin
  16251. if Value[ I ] in [ '0'..'7' ] then
  16252. Result := Result * 8 + Ord( Value[ I ] ) - Ord( '0' )
  16253. else break;
  16254. end;
  16255. end;
  16256. //[END Octal2Int]
  16257. //[FUNCTION Binary2Int]
  16258. function Binary2Int( const Value: String ) : Integer;
  16259. var I: Integer;
  16260. begin
  16261. Result := 0;
  16262. for I := 1 to Length( Value ) do
  16263. begin
  16264. if Value[ I ] in [ '0'..'1' ] then
  16265. Result := Result * 2 + Ord( Value[ I ] ) - Ord( '0' )
  16266. else break;
  16267. end;
  16268. end;
  16269. //[END Binary2Int]
  16270. //[FUNCTION cHex2Int]
  16271. {$IFDEF ASM_VERSION}
  16272. function cHex2Int( const Value : String) : Integer;
  16273. asm
  16274. TEST EAX, EAX
  16275. JZ @@exit
  16276. CMP word ptr [EAX], '0x'
  16277. JZ @@skip_2_chars
  16278. CMP word ptr [EAX], '0X'
  16279. JNZ @@2Hex2Int
  16280. @@skip_2_chars:
  16281. INC EAX
  16282. INC EAX
  16283. @@2Hex2Int:
  16284. JMP Hex2Int
  16285. @@exit:
  16286. end;
  16287. {$ELSE ASM_VERSION}
  16288. function cHex2Int( const Value : String) : Integer;
  16289. begin
  16290. if StrEq( Copy( Value, 1, 2 ), '0x' ) then
  16291. Result := Hex2Int( CopyEnd( Value, 3 ) )
  16292. else Result := Hex2Int( Value );
  16293. end;
  16294. {$ENDIF ASM_VERSION}
  16295. //[END cHex2Int]
  16296. //[FUNCTION Int2Str]
  16297. {$IFDEF ASM_VERSION}
  16298. function Int2Str( Value : Integer ) : String;
  16299. asm
  16300. XOR ECX, ECX
  16301. PUSH ECX
  16302. ADD ESP, -0Ch
  16303. PUSH EBX
  16304. LEA EBX, [ESP + 15 + 4]
  16305. PUSH EDX
  16306. CMP EAX, ECX
  16307. PUSHFD
  16308. JGE @@1
  16309. NEG EAX
  16310. @@1:
  16311. MOV CL, 10
  16312. @@2:
  16313. DEC EBX
  16314. XOR EDX, EDX
  16315. DIV ECX
  16316. ADD DL, 30h
  16317. MOV [EBX], DL
  16318. TEST EAX, EAX
  16319. JNZ @@2
  16320. POPFD
  16321. JGE @@3
  16322. DEC EBX
  16323. MOV byte ptr [EBX], '-'
  16324. @@3:
  16325. POP EAX
  16326. MOV EDX, EBX
  16327. CALL System.@LStrFromPChar
  16328. POP EBX
  16329. ADD ESP, 10h
  16330. end;
  16331. {$ELSE ASM_VERSION} //Pascal
  16332. function Int2Str( Value : Integer ) : String;
  16333. var Buf : array[ 0..15 ] of Char;
  16334. Dst : PChar;
  16335. Minus : Boolean;
  16336. D: DWORD;
  16337. begin
  16338. Dst := @Buf[ 15 ];
  16339. Dst^ := #0;
  16340. Minus := False;
  16341. if Value < 0 then
  16342. begin
  16343. Value := -Value;
  16344. Minus := True;
  16345. end;
  16346. D := Value;
  16347. repeat
  16348. Dec( Dst );
  16349. Dst^ := Char( (D mod 10) + Byte( '0' ) );
  16350. D := D div 10;
  16351. until D = 0;
  16352. if Minus then
  16353. begin
  16354. Dec( Dst );
  16355. Dst^ := '-';
  16356. end;
  16357. Result := Dst;
  16358. end;
  16359. {$ENDIF ASM_VERSION}
  16360. //[END Int2Str]
  16361. //[function UInt2Str]
  16362. function UInt2Str( Value: DWORD ): String;
  16363. var Buf : array[ 0..15 ] of Char;
  16364. Dst : PChar;
  16365. D: DWORD;
  16366. begin
  16367. Dst := @Buf[ 15 ];
  16368. Dst^ := #0;
  16369. D := Value;
  16370. repeat
  16371. Dec( Dst );
  16372. Dst^ := Char( (D mod 10) + Byte( '0' ) );
  16373. D := D div 10;
  16374. until D = 0;
  16375. Result := Dst;
  16376. end;
  16377. //[function Int2StrEx]
  16378. function Int2StrEx( Value, MinWidth: Integer ): String;
  16379. begin
  16380. Result := Int2Str( Value );
  16381. while Length( Result ) < MinWidth do
  16382. Result := ' ' + Result;
  16383. end;
  16384. //[function Int2Rome]
  16385. function Int2Rome( Value: Integer ): String;
  16386. const RomeDigs: String = 'IVXLCDMT';
  16387. function RomeNum( N, FromIdx: Integer ): String;
  16388. begin
  16389. CASE N OF
  16390. 1, 2, 3: Result := StrRepeat( RomeDigs[ FromIdx ], N );
  16391. 4: Result := RomeDigs[ FromIdx ] + RomeDigs[ FromIdx + 1 ];
  16392. 5, 6, 7, 8: Result := RomeDigs[ FromIdx + 1 ] + StrRepeat( RomeDigs[ FromIdx ],
  16393. N - 5 );
  16394. 9: Result := RomeDigs[ FromIdx ] + RomeDigs[ FromIdx + 2 ]
  16395. else Result := '';
  16396. END;
  16397. end;
  16398. var I, J: Integer;
  16399. begin
  16400. Result := '';
  16401. if Value < 1 then Exit;
  16402. if Value > 8999 then Exit;
  16403. // maximum possible is TMMMCMXCIX, i.e. 8999
  16404. J := 1;
  16405. for I := 1 to 3 do
  16406. begin
  16407. Result := RomeNum( Value mod 10, J ) + Result;
  16408. Value := Value div 10;
  16409. if Value = 0 then Exit;
  16410. Inc( J, 2 );
  16411. end;
  16412. end;
  16413. //[FUNCTION Int2Ths]
  16414. {$IFDEF ASM_VERSION}
  16415. function Int2Ths( I : Integer ) : String;
  16416. asm
  16417. PUSH EBP
  16418. MOV EBP, ESP
  16419. PUSH EAX
  16420. PUSH EDX
  16421. CALL Int2Str
  16422. POP EDX
  16423. POP EAX
  16424. TEST EAX, EAX
  16425. JGE @@0
  16426. NEG EAX
  16427. @@0:
  16428. CMP EAX, 1000
  16429. JL @@Exit
  16430. PUSH EDX
  16431. MOV EAX, [EDX]
  16432. PUSH EAX
  16433. CALL System.@LStrLen // EAX = Length(Result)
  16434. POP EDX
  16435. PUSH EDX // EDX = @Result[ 1 ]
  16436. XOR ECX, ECX
  16437. @@1:
  16438. ROL ECX, 8
  16439. DEC EAX
  16440. MOV CL, [EDX+EAX]
  16441. JZ @@fin
  16442. CMP ECX, 300000h
  16443. JL @@1
  16444. PUSH ECX
  16445. XOR ECX, ECX
  16446. MOV CL, [ThsSeparator]
  16447. JMP @@1
  16448. @@fin: //CMP CX, ',-'
  16449. CMP CL, '-'
  16450. JNE @@fin1
  16451. CMP CH, [ThsSeparator]
  16452. JNE @@fin1
  16453. MOV CH, 0 // this corrects -,ddd,...
  16454. @@fin1: CMP ECX, 01000000h
  16455. JGE @@fin2
  16456. INC EAX
  16457. ROL ECX, 8
  16458. JMP @@fin1
  16459. @@fin2: PUSH ECX
  16460. LEA EDX, [ESP+EAX]
  16461. MOV EAX, [EBP-4]
  16462. CALL System.@LStrFromPChar
  16463. @@Exit:
  16464. MOV ESP, EBP
  16465. POP EBP
  16466. end;
  16467. {$ELSE ASM_VERSION} //Pascal
  16468. function Int2Ths( I : Integer ) : String;
  16469. var S : String;
  16470. begin
  16471. S := Int2Str( I );
  16472. Result := '';
  16473. while S <> '' do
  16474. begin
  16475. if Result <> '' then
  16476. Result := ThsSeparator + Result;
  16477. Result := CopyTail( S, 3 ) + Result;
  16478. S := Copy( S, 1, Length( S ) - 3 );
  16479. end;
  16480. if Copy( Result, 1, 2 ) = '-' + ThsSeparator then
  16481. Result := '-' + CopyEnd( Result, 3 );
  16482. end;
  16483. {$ENDIF ASM_VERSION}
  16484. //[END Int2Ths]
  16485. //[FUNCTION Int2Digs]
  16486. {$IFDEF ASM_VERSION}
  16487. function Int2Digs( Value, Digits : Integer ) : String;
  16488. asm
  16489. PUSH EBP
  16490. MOV EBP, ESP
  16491. PUSH EDX // [EBP-4] = Digits
  16492. PUSH ECX
  16493. MOV EDX, ECX
  16494. CALL Int2Str
  16495. POP ECX
  16496. PUSH ECX // [EBP-8] = @Result
  16497. MOV EAX, [ECX]
  16498. PUSH EAX
  16499. CALL System.@LStrLen
  16500. POP EDX // EDX = @Result[1]
  16501. MOV ECX, EAX // ECX = Length( Result )
  16502. ADD EAX, EAX
  16503. SUB ESP, EAX
  16504. MOV EAX, ESP
  16505. PUSHAD
  16506. CALL StrCopy
  16507. POPAD
  16508. MOV EDX, EAX
  16509. ADD ESP, -100
  16510. CMP byte ptr [EDX], '-'
  16511. PUSHFD
  16512. JNE @@1
  16513. INC EDX
  16514. @@1:
  16515. MOV EAX, [EBP-4] // EAX = Digits
  16516. CMP ECX, EAX
  16517. JGE @@2
  16518. DEC EDX
  16519. MOV byte ptr [EDX], '0'
  16520. INC ECX
  16521. JMP @@1
  16522. @@2:
  16523. POPFD
  16524. JNE @@3
  16525. DEC EDX
  16526. MOV byte ptr [EDX], '-'
  16527. @@3:
  16528. MOV EAX, [EBP-8]
  16529. CALL System.@LStrFromPChar
  16530. MOV ESP, EBP
  16531. POP EBP
  16532. end;
  16533. {$ELSE ASM_VERSION} //Pascal
  16534. function Int2Digs( Value, Digits : Integer ) : String;
  16535. var M : String;
  16536. begin
  16537. Result := Int2Str( Value );
  16538. M := '';
  16539. if Value < 0 then
  16540. begin
  16541. M := '-';
  16542. Result := CopyEnd( Result, 2 );
  16543. end;
  16544. if Digits >= 0 then
  16545. while Length( M + Result ) < Digits do
  16546. Result := '0' + Result
  16547. else
  16548. while Length( Result ) < -Digits do
  16549. Result := '0' + Result;
  16550. Result := M + Result;
  16551. end;
  16552. {$ENDIF ASM_VERSION}
  16553. //[END Int2Digs]
  16554. //[FUNCTION Num2Bytes]
  16555. {$IFDEF ASM_VERSION}
  16556. function Num2Bytes( Value : Double ) : String;
  16557. asm
  16558. PUSH EBX
  16559. PUSH ESI
  16560. PUSH EDI
  16561. MOV EBX, ESP
  16562. MOV ESI, EAX
  16563. MOV ECX, 4
  16564. MOV EDX, 'TGMk'
  16565. @@1:
  16566. FLD [Value]
  16567. @@10:
  16568. FICOM dword ptr [@@1024]
  16569. FSTSW AX
  16570. SAHF
  16571. JB @@2
  16572. FIDIV dword ptr [@@1024]
  16573. FST [Value]
  16574. WAIT
  16575. TEST DL, 20h
  16576. JE @@ror
  16577. AND DL, not 20h
  16578. JMP @@nxt
  16579. @@1024: DD 1024
  16580. @@100: DD 100
  16581. @@ror:
  16582. ROR EDX, 8
  16583. @@nxt:
  16584. LOOP @@10
  16585. @@2:
  16586. TEST DL, 20h
  16587. JZ @@3
  16588. MOV DL, 0
  16589. @@3: MOV DH, 0
  16590. PUSH DX
  16591. MOV EDI, ESP
  16592. FLD ST(0)
  16593. CALL System.@TRUNC
  16594. {$IFDEF _D2orD3}
  16595. PUSH 0
  16596. {$ELSE}
  16597. PUSH EDX
  16598. {$ENDIF}
  16599. PUSH EAX
  16600. FILD qword ptr [ESP]
  16601. POP EDX
  16602. POP EDX
  16603. MOV EDX, ESI
  16604. CALL Int2Str
  16605. FSUBP ST(1), ST
  16606. FIMUL dword ptr [@@100]
  16607. CALL System.@TRUNC
  16608. TEST EAX, EAX
  16609. JZ @@4
  16610. XOR ECX, ECX
  16611. MOV CL, 0Ah
  16612. CDQ
  16613. IDIV ECX
  16614. TEST EDX, EDX
  16615. JZ @@5
  16616. MOV AH, DL
  16617. SHL EAX, 16
  16618. ADD EAX, '00. '
  16619. PUSH EAX
  16620. MOV EDI, ESP
  16621. INC EDI
  16622. JMP @@4
  16623. @@5: SHL EAX, 8
  16624. ADD AX, '0.'
  16625. PUSH AX
  16626. MOV EDI, ESP
  16627. @@4:
  16628. MOV EAX, [ESI]
  16629. CALL System.@LStrLen
  16630. ADD ESP, -100
  16631. SUB EDI, EAX
  16632. PUSH ESI
  16633. PUSH EDI
  16634. MOV ESI, [ESI]
  16635. MOV ECX, EAX
  16636. REP MOVSB
  16637. POP EDX
  16638. POP EAX
  16639. CALL System.@LStrFromPChar
  16640. MOV ESP, EBX
  16641. POP EDI
  16642. POP ESI
  16643. POP EBX
  16644. end;
  16645. {$ELSE ASM_VERSION} //Pascal
  16646. function Num2Bytes( Value : Double ) : String;
  16647. const Suffix = 'KMGT';
  16648. var V, I : Integer;
  16649. begin
  16650. Result := '';
  16651. I := 0;
  16652. while (Value >= 1024) and (I < 4) do
  16653. begin
  16654. Inc( I );
  16655. Value := Value / 1024.0;
  16656. end;
  16657. Result := Int2Str( Trunc( Value ) );
  16658. V := Trunc( (Value - Trunc( Value )) * 100 );
  16659. if V <> 0 then
  16660. begin
  16661. if (V mod 10) = 0 then
  16662. V := V div 10;
  16663. Result := Result + ',' + Int2Str( V );
  16664. end;
  16665. if I > 0 then
  16666. Result := Result + Suffix[ I ];
  16667. end;
  16668. {$ENDIF ASM_VERSION}
  16669. //[END Num2Bytes]
  16670. //[FUNCTION S2Int]
  16671. {$IFDEF ASM_VERSION}
  16672. function S2Int( S: PChar ): Integer;
  16673. asm
  16674. XCHG EDX, EAX
  16675. XOR EAX, EAX
  16676. TEST EDX, EDX
  16677. JZ @@exit
  16678. XOR ECX, ECX
  16679. MOV CL, [EDX]
  16680. INC EDX
  16681. CMP CL, '-'
  16682. PUSHFD
  16683. JE @@0
  16684. @@1: CMP CL, '+'
  16685. JNE @@2
  16686. @@0: MOV CL, [EDX]
  16687. INC EDX
  16688. @@2: SUB CL, '0'
  16689. CMP CL, '9'-'0'
  16690. JA @@fin
  16691. LEA EAX, [EAX+EAX*4] //
  16692. LEA EAX, [ECX+EAX*2] //
  16693. JMP @@0
  16694. @@fin: POPFD
  16695. JNE @@exit
  16696. NEG EAX
  16697. @@exit:
  16698. end;
  16699. {$ELSE ASM_VERSION} //Pascal
  16700. function S2Int( S: PChar ): Integer;
  16701. var M : Integer;
  16702. begin
  16703. Result := 0;
  16704. if S = '' then Exit;
  16705. M := 1;
  16706. if S^ = '-' then
  16707. begin
  16708. M := -1;
  16709. Inc( S );
  16710. end
  16711. else
  16712. if S^ = '+' then
  16713. Inc( S );
  16714. while S^ in [ '0'..'9' ] do
  16715. begin
  16716. Result := Result * 10 + Integer( S^ ) - Integer( '0' );
  16717. Inc( S );
  16718. end;
  16719. if M < 0 then
  16720. Result := -Result;
  16721. end;
  16722. {$ENDIF ASM_VERSION}
  16723. //[END S2Int]
  16724. //[FUNCTION Str2Int]
  16725. {$IFDEF ASM_VERSION}
  16726. function Str2Int(const Value : String) : Integer;
  16727. asm
  16728. CALL EAX2PChar
  16729. CALL S2Int
  16730. end;
  16731. {$ELSE ASM_VERSION} //Pascal
  16732. function Str2Int(const Value : String) : Integer;
  16733. begin
  16734. Result := S2Int( PChar( Value ) );
  16735. end;
  16736. {$ENDIF ASM_VERSION}
  16737. //[END Str2Int]
  16738. //[function StrCopy]
  16739. function StrCopy( Dest, Source: PChar ): PChar; assembler;
  16740. asm
  16741. {$IFDEF F_P}
  16742. MOV EAX, [Dest]
  16743. MOV EDX, [Source]
  16744. {$ENDIF F_P}
  16745. PUSH EDI
  16746. PUSH ESI
  16747. MOV ESI,EAX
  16748. MOV EDI,EDX
  16749. OR ECX, -1
  16750. XOR AL,AL
  16751. REPNE SCASB
  16752. NOT ECX
  16753. MOV EDI,ESI
  16754. MOV ESI,EDX
  16755. MOV EDX,ECX
  16756. MOV EAX,EDI
  16757. SHR ECX,2
  16758. REP MOVSD
  16759. MOV ECX,EDX
  16760. AND ECX,3
  16761. REP MOVSB
  16762. POP ESI
  16763. POP EDI
  16764. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  16765. function StrCat( Dest, Source: PChar ): PChar;
  16766. begin
  16767. StrCopy( StrScan( Dest, #0 ), Source );
  16768. Result := Dest;
  16769. end;
  16770. //[function StrScan]
  16771. function StrScan(Str: PChar; Chr: Char): PChar; assembler;
  16772. asm
  16773. {$IFDEF F_P}
  16774. MOV EAX, [Str]
  16775. MOVZX EDX, [Chr]
  16776. {$ENDIF}
  16777. PUSH EDI
  16778. PUSH EAX
  16779. MOV EDI,Str
  16780. OR ECX, -1
  16781. XOR AL,AL
  16782. REPNE SCASB
  16783. NOT ECX
  16784. POP EDI
  16785. XCHG EAX, EDX
  16786. REPNE SCASB
  16787. XCHG EAX, EDI
  16788. POP EDI
  16789. JE @@1
  16790. XOR EAX, EAX
  16791. RET
  16792. @@1: DEC EAX
  16793. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  16794. //[function StrRScan]
  16795. function StrRScan(const Str: PChar; Chr: Char): PChar; assembler;
  16796. asm
  16797. {$IFDEF F_P}
  16798. MOV EAX, [Str]
  16799. MOVZX EDX, [Chr]
  16800. {$ENDIF F_P}
  16801. PUSH EDI
  16802. MOV EDI,Str
  16803. MOV ECX,0FFFFFFFFH
  16804. XOR AL,AL
  16805. REPNE SCASB
  16806. NOT ECX
  16807. STD
  16808. DEC EDI
  16809. MOV AL,Chr
  16810. REPNE SCASB
  16811. MOV EAX,0
  16812. JNE @@1
  16813. MOV EAX,EDI
  16814. INC EAX
  16815. @@1: CLD
  16816. POP EDI
  16817. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  16818. //[function StrScanLen]
  16819. function StrScanLen(Str: PChar; Chr: Char; Len: Integer): PChar; assembler;
  16820. asm
  16821. {$IFDEF F_P}
  16822. MOV EAX, [Str]
  16823. MOVZX EDX, [Chr]
  16824. MOV ECX, [Len]
  16825. {$ENDIF F_P}
  16826. PUSH EDI
  16827. XCHG EDI, EAX
  16828. XCHG EAX, EDX
  16829. REPNE SCASB
  16830. XCHG EAX, EDI
  16831. POP EDI
  16832. { -> EAX => to next character after found or to the end of Str,
  16833. ZF = 0 if character found. }
  16834. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  16835. //[FUNCTION TrimLeft]
  16836. {$IFDEF ASM_VERSION}
  16837. function TrimLeft(const S: string): string;
  16838. asm
  16839. XCHG EAX, EDX
  16840. CALL EDX2PChar
  16841. DEC EDX
  16842. @@1: INC EDX
  16843. MOVZX ECX, byte ptr [EDX]
  16844. JECXZ @@fin
  16845. CMP CL, ' '
  16846. JBE @@1
  16847. @@fin:
  16848. CALL System.@LStrFromPChar
  16849. end;
  16850. {$ELSE ASM_VERSION} //Pascal
  16851. function TrimLeft(const S: string): string;
  16852. var
  16853. I, L: Integer;
  16854. begin
  16855. L := Length(S);
  16856. I := 1;
  16857. while (I <= L) and (S[I] <= ' ') do Inc(I);
  16858. Result := Copy(S, I, Maxint);
  16859. end;
  16860. {$ENDIF ASM_VERSION}
  16861. //[END TrimLeft]
  16862. //[FUNCTION TrimRight]
  16863. {$IFDEF ASM_VERSION}
  16864. function TrimRight(const S: string): string;
  16865. asm
  16866. PUSH EDX
  16867. PUSH EAX
  16868. PUSH EAX
  16869. CALL System.@LStrLen
  16870. XCHG EAX, [ESP]
  16871. //CALL System.@LStrToPChar
  16872. CALL EAX2PChar
  16873. POP ECX
  16874. INC ECX
  16875. @@1: DEC ECX
  16876. MOV DL, [EAX+ECX]
  16877. JL @@fin
  16878. CMP DL, ' '
  16879. JBE @@1
  16880. @@fin:
  16881. INC ECX
  16882. POP EAX
  16883. XOR EDX, EDX
  16884. INC EDX
  16885. CALL System.@LStrCopy
  16886. end;
  16887. {$ELSE ASM_VERSION} //Pascal
  16888. function TrimRight(const S: string): string;
  16889. var
  16890. I: Integer;
  16891. begin
  16892. I := Length(S);
  16893. while (I > 0) and (S[I] <= ' ') do Dec(I);
  16894. Result := Copy(S, 1, I);
  16895. end;
  16896. {$ENDIF ASM_VERSION}
  16897. //[END TrimRight]
  16898. //[FUNCTION Trim]
  16899. {$IFDEF ASM_VERSION}
  16900. function Trim( const S : string): string;
  16901. asm
  16902. PUSH EDX
  16903. CALL TrimRight
  16904. POP EDX
  16905. MOV EAX, [EDX]
  16906. CALL TrimLeft
  16907. end;
  16908. {$ELSE ASM_VERSION} //Pascal
  16909. function Trim( const S : string): string;
  16910. begin
  16911. Result := TrimLeft( TrimRight( S ) );
  16912. end;
  16913. {$ENDIF ASM_VERSION}
  16914. //[END Trim]
  16915. //[function RemoveSpaces]
  16916. function RemoveSpaces( const S: String ): String;
  16917. var I: Integer;
  16918. begin
  16919. Result := S;
  16920. for I := Length( S ) downto 1 do
  16921. if S[ I ] <= ' ' then Delete( Result, I, 1 );
  16922. end;
  16923. //[procedure Str2LowerCase]
  16924. procedure Str2LowerCase( S: PChar );
  16925. asm
  16926. {$IFDEF F_P}
  16927. MOV EAX, [S]
  16928. {$ENDIF}
  16929. XOR ECX, ECX
  16930. @@1:
  16931. MOV CL, byte ptr [EAX]
  16932. JECXZ @@exit
  16933. SUB CL, 'A'
  16934. CMP CL, 'Z'-'A'
  16935. JA @@2
  16936. ADD byte ptr [EAX], 32
  16937. @@2: INC EAX
  16938. JMP @@1
  16939. @@exit:
  16940. end {$IFDEF F_P} [ 'EAX', 'ECX' ] {$ENDIF};
  16941. //[FUNCTION LowerCase]
  16942. {$IFDEF ASM_VERSION}
  16943. function LowerCase(const S: string): string;
  16944. asm
  16945. PUSH ESI
  16946. XCHG EAX, EDX
  16947. PUSH EAX
  16948. CALL System.@LStrAsg
  16949. POP EAX
  16950. CALL UniqueString
  16951. PUSH EAX
  16952. CALL System.@LStrLen
  16953. POP ESI
  16954. XCHG ECX, EAX
  16955. JECXZ @@exit
  16956. @@go:
  16957. LODSB
  16958. {$IFDEF PARANOIA}
  16959. DB $2C, 'A'
  16960. {$ELSE}
  16961. SUB AL, 'A'
  16962. {$ENDIF}
  16963. {$IFDEF PARANOIA}
  16964. DB $3C, 26
  16965. {$ELSE}
  16966. CMP AL, 'Z'-'A'+1
  16967. {$ENDIF}
  16968. JNB @@1
  16969. ADD byte ptr [ESI - 1], 20h
  16970. @@1:
  16971. LOOP @@go
  16972. @@exit:
  16973. POP ESI
  16974. end;
  16975. {$ELSE ASM_VERSION} //Pascal
  16976. function LowerCase(const S: string): string;
  16977. var I : Integer;
  16978. begin
  16979. Result := S;
  16980. for I := 1 to Length( S ) do
  16981. if Result[ I ] in [ 'A'..'Z' ] then
  16982. Inc( Result[ I ], 32 );
  16983. end;
  16984. {$ENDIF ASM_VERSION}
  16985. //[END LowerCase]
  16986. //[FUNCTION UpperCase]
  16987. {$IFDEF ASM_VERSION}
  16988. function UpperCase(const S: string): string;
  16989. asm
  16990. PUSH ESI
  16991. XCHG EAX, EDX
  16992. PUSH EAX
  16993. CALL System.@LStrAsg
  16994. POP EAX
  16995. CALL UniqueString
  16996. PUSH EAX
  16997. CALL System.@LStrLen
  16998. POP ESI
  16999. XCHG ECX, EAX
  17000. JECXZ @@exit
  17001. @@go:
  17002. LODSB
  17003. {$IFDEF PARANOIA}
  17004. DB $2C, 'a'
  17005. {$ELSE}
  17006. SUB AL, 'a'
  17007. {$ENDIF}
  17008. {$IFDEF PARANOIA}
  17009. DB $3C, $1A
  17010. {$ELSE}
  17011. CMP AL, 'z'-'a'+1
  17012. {$ENDIF}
  17013. JNB @@1
  17014. SUB byte ptr [ESI - 1], 20h
  17015. @@1:
  17016. LOOP @@go
  17017. @@exit:
  17018. POP ESI
  17019. end;
  17020. {$ELSE ASM_VERSION} //Pascal
  17021. function UpperCase(const S: string): string;
  17022. var I : Integer;
  17023. begin
  17024. Result := S;
  17025. for I := 1 to Length( S ) do
  17026. if Result[ I ] in [ 'a'..'z' ] then
  17027. Dec( Result[ I ], 32 );
  17028. end;
  17029. {$ENDIF ASM_VERSION}
  17030. //[END UpperCase]
  17031. {$IFDEF F_P}
  17032. //[function DummyStrFun]
  17033. function DummyStrFun( const S: String ): String;
  17034. begin
  17035. Result := S;
  17036. end;
  17037. {$ENDIF F_P}
  17038. //[FUNCTION CopyEnd]
  17039. {$IFDEF ASM_VERSION}
  17040. function CopyEnd( const S : String; Idx : Integer ) : String;
  17041. asm
  17042. PUSH ECX
  17043. PUSH EAX
  17044. PUSH EDX
  17045. CALL System.@LStrLen
  17046. POP EDX
  17047. TEST EDX, EDX
  17048. JG @@1
  17049. XOR EDX, EDX
  17050. INC EDX
  17051. @@1:
  17052. SUB EAX, EDX
  17053. MOV ECX, EAX
  17054. POP EAX
  17055. JGE @@ret_end
  17056. POP EAX
  17057. JL System.@LStrClr
  17058. @@ret_end:
  17059. INC ECX
  17060. CALL System.@LStrCopy
  17061. end;
  17062. {$ELSE ASM_VERSION} //Pascal
  17063. function CopyEnd( const S : String; Idx : Integer ) : String;
  17064. begin
  17065. Result := Copy( S, Idx, MaxInt );
  17066. end;
  17067. {$ENDIF ASM_VERSION}
  17068. //[END CopyEnd]
  17069. //[FUNCTION CopyTail]
  17070. {$IFDEF ASM_VERSION}
  17071. function CopyTail( const S : String; Len : Integer ) : String;
  17072. asm
  17073. PUSH ECX
  17074. PUSH EAX
  17075. PUSH EDX
  17076. CALL System.@LStrLen
  17077. POP ECX
  17078. CMP ECX, EAX
  17079. {$IFDEF USE_CMOV}
  17080. CMOVG ECX, EAX
  17081. {$ELSE}
  17082. JLE @@1
  17083. MOV ECX, EAX
  17084. @@1: {$ENDIF}
  17085. MOV EDX, EAX
  17086. SUB EDX, ECX
  17087. INC EDX
  17088. POP EAX
  17089. CALL System.@LStrCopy
  17090. end;
  17091. {$ELSE ASM_VERSION} //Pascal
  17092. function CopyTail( const S : String; Len : Integer ) : String;
  17093. var L : Integer;
  17094. begin
  17095. L := Length( S );
  17096. if L < Len then
  17097. Len := L;
  17098. Result := '';
  17099. if Len = 0 then Exit;
  17100. Result := Copy( S, L - Len + 1, Len );
  17101. end;
  17102. {$ENDIF ASM_VERSION}
  17103. //[END CopyTail]
  17104. //[PROCEDURE DeleteTail]
  17105. {$IFDEF ASM_VERSION}
  17106. procedure DeleteTail( var S : String; Len : Integer );
  17107. asm
  17108. PUSH EAX
  17109. PUSH EDX
  17110. MOV EAX, [EAX]
  17111. CALL System.@LStrLen
  17112. POP ECX
  17113. CMP ECX, EAX
  17114. {$IFDEF USE_CMOV}
  17115. CMOVG ECX, EAX
  17116. {$ELSE}
  17117. JLE @@1
  17118. MOV ECX, EAX
  17119. @@1: {$ENDIF}
  17120. MOV EDX, EAX
  17121. SUB EDX, ECX
  17122. INC EDX
  17123. POP EAX
  17124. CALL System.@LStrDelete
  17125. end;
  17126. {$ELSE ASM_VERSION} //Pascal
  17127. procedure DeleteTail( var S : String; Len : Integer );
  17128. var L : Integer;
  17129. begin
  17130. L := Length( S );
  17131. if Len > L then
  17132. Len := L;
  17133. Delete( S, L - Len + 1, Len );
  17134. end;
  17135. {$ENDIF ASM_VERSION}
  17136. //[END DeleteTail]
  17137. //[FUNCTION IndexOfChar]
  17138. {$IFDEF ASM_VERSION}
  17139. function IndexOfChar( const S : String; Chr : Char ) : Integer;
  17140. asm
  17141. //PUSH EDX
  17142. //CALL System.@LStrToPChar
  17143. //POP EDX
  17144. CALL EAX2PChar
  17145. PUSH EAX
  17146. CALL StrScan
  17147. POP EDX
  17148. TEST EAX, EAX
  17149. JE @@exit__1
  17150. SUB EAX, EDX
  17151. INC EAX
  17152. RET
  17153. @@exit__1:
  17154. DEC EAX
  17155. end;
  17156. {$ELSE ASM_VERSION} //Pascal
  17157. function IndexOfChar( const S : String; Chr : Char ) : Integer;
  17158. var P, F : PChar;
  17159. begin
  17160. P := PChar( S );
  17161. F := StrScan( P, Chr );
  17162. Result := -1;
  17163. if F = nil then Exit;
  17164. Result := Integer( F ) - Integer( P ) + 1;
  17165. end;
  17166. {$ENDIF ASM_VERSION}
  17167. //[END IndexOfChar]
  17168. //[FUNCTION IndexOfCharsMin]
  17169. {$IFDEF ASM_VERSION}
  17170. function IndexOfCharsMin( const S, Chars : String ) : Integer;
  17171. asm
  17172. PUSH ESI
  17173. PUSH EAX
  17174. CALL EDX2PChar
  17175. MOV ESI, EDX
  17176. XOR ECX, ECX
  17177. DEC ECX
  17178. @@1: LODSB
  17179. TEST AL, AL
  17180. JZ @@exit
  17181. XCHG EDX, EAX
  17182. POP EAX
  17183. PUSH EAX
  17184. PUSH ECX
  17185. CALL IndexOfChar
  17186. POP ECX
  17187. TEST EAX, EAX
  17188. JLE @@1
  17189. TEST ECX, ECX
  17190. JLE @@2
  17191. CMP EAX, ECX
  17192. JGE @@1
  17193. @@2: //XCHG ECX, EAX
  17194. //JMP @@1
  17195. @@exit: XCHG EAX, ECX
  17196. JL @@1
  17197. POP ECX
  17198. POP ESI
  17199. end;
  17200. {$ELSE ASM_VERSION} //Pascal
  17201. function IndexOfCharsMin( const S, Chars : String ) : Integer;
  17202. var I, J : Integer;
  17203. begin
  17204. Result := -1;
  17205. for I := 1 to Length( Chars ) do
  17206. begin
  17207. J := IndexOfChar( S, Chars[ I ] );
  17208. if J > 0 then
  17209. begin
  17210. if (Result < 0) or (J < Result) then
  17211. Result := J;
  17212. end;
  17213. end;
  17214. end;
  17215. {$ENDIF ASM_VERSION}
  17216. //[END IndexOfCharsMin]
  17217. {$IFNDEF _FPC}
  17218. {$IFNDEF _D2}
  17219. //[function IndexOfWideCharsMin]
  17220. function IndexOfWideCharsMin( const S, Chars : WideString ) : Integer;
  17221. var I, J : Integer;
  17222. begin
  17223. Result := -1;
  17224. for I := 1 to Length( Chars ) do
  17225. begin
  17226. J := pos( Chars[ I ], S );
  17227. if J > 0 then
  17228. begin
  17229. if (Result < 0) or (J < Result) then
  17230. Result := J;
  17231. end;
  17232. end;
  17233. end;
  17234. {$ENDIF _D2}
  17235. {$ENDIF _FPC}
  17236. //[FUNCTION IndexOfStr]
  17237. {$IFDEF ASM_VERSION}
  17238. function IndexOfStr( const S, Sub : String ) : Integer;
  17239. asm
  17240. PUSH EBX
  17241. PUSH ESI
  17242. PUSH EDI
  17243. PUSH EAX
  17244. MOV EAX, EDX
  17245. PUSH EDX
  17246. CALL System.@LStrLen
  17247. MOV EDI, EAX
  17248. POP EAX
  17249. //CALL System.@LStrToPChar
  17250. CALL EAX2PChar
  17251. MOV BL, [EAX]
  17252. XCHG EAX, [ESP]
  17253. //CALL System.@LStrToPChar
  17254. CALL EAX2PChar
  17255. MOV ESI, EAX
  17256. DEC EAX
  17257. @@1: INC EAX
  17258. MOV DL, BL
  17259. CALL StrScan
  17260. TEST EAX, EAX
  17261. JE @@exit__1
  17262. POP EDX
  17263. PUSH EDX
  17264. MOV ECX, EDI
  17265. PUSH EAX
  17266. CALL StrLComp
  17267. POP EAX
  17268. JNE @@1
  17269. SUB EAX, ESI
  17270. INC EAX
  17271. JMP @@exit
  17272. @@exit__1:
  17273. DEC EAX
  17274. @@exit:
  17275. POP EDX
  17276. POP EDI
  17277. POP ESI
  17278. POP EBX
  17279. end;
  17280. {$ELSE ASM_VERSION} //Pascal
  17281. function IndexOfStr( const S, Sub : String ) : Integer;
  17282. var I : Integer;
  17283. begin
  17284. Result := Length( S );
  17285. if Sub = '' then Exit;
  17286. Result := 0;
  17287. if S = '' then Exit;
  17288. if Length( Sub ) > Length( S ) then Exit;
  17289. Result := 1;
  17290. while Result + Length( Sub ) - 1 <= Length( S ) do
  17291. begin
  17292. I := IndexOfChar( CopyEnd( S, Result ), Sub[ 1 ] );
  17293. if I <= 0 then break;
  17294. Result := Result + I - 1;
  17295. if Result <= 0 then Exit;
  17296. if Copy( S, Result, Length( Sub ) ) = Sub then Exit;
  17297. Inc( Result );
  17298. end;
  17299. Result := -1;
  17300. end;
  17301. {$ENDIF ASM_VERSION}
  17302. //[END IndexOfStr]
  17303. //[FUNCTION Parse]
  17304. {$IFDEF ASM_VERSION} //???
  17305. function Parse( var S : String; const Separators : String ) : String;
  17306. asm
  17307. PUSH EBX
  17308. PUSH EDI
  17309. MOV EBX, EAX
  17310. PUSH ECX
  17311. MOV EAX, [EBX]
  17312. CALL IndexOfCharsMin
  17313. INC EAX
  17314. JNE @@1
  17315. MOV EAX, [EBX]
  17316. CALL System.@LStrLen
  17317. INC EAX
  17318. INC EAX
  17319. @@1:
  17320. DEC EAX
  17321. MOV EDI, EAX
  17322. MOV ECX, EAX
  17323. DEC ECX
  17324. XOR EDX, EDX
  17325. INC EDX
  17326. MOV EAX, [EBX]
  17327. CALL System.@LStrCopy
  17328. MOV EAX, [EBX]
  17329. MOV EDX, EDI
  17330. INC EDX
  17331. MOV ECX, EBX
  17332. CALL CopyEnd
  17333. POP EDI
  17334. POP EBX
  17335. end;
  17336. {$ELSE ASM_VERSION} //Pascal
  17337. function Parse( var S : String; const Separators : String ) : String;
  17338. var Pos : Integer;
  17339. begin
  17340. Pos := IndexOfCharsMin( S, Separators );
  17341. if Pos <= 0 then
  17342. Pos := Length( S ) + 1;
  17343. Result := S;
  17344. S := Copy( Result, Pos + 1, MaxInt );
  17345. Result := Copy( Result, 1, Pos - 1 );
  17346. end;
  17347. {$ENDIF ASM_VERSION}
  17348. //[END Parse]
  17349. {$IFNDEF _FPC}
  17350. {$IFNDEF _D2}
  17351. //[function WParse]
  17352. function WParse( var S : WideString; const Separators : WideString ) : WideString;
  17353. var Pos : Integer;
  17354. begin
  17355. Pos := IndexOfWideCharsMin( S, Separators );
  17356. if Pos <= 0 then
  17357. Pos := Length( S ) + 1;
  17358. Result := S;
  17359. S := Copy( Result, Pos + 1, MaxInt );
  17360. Result := Copy( Result, 1, Pos - 1 );
  17361. end;
  17362. {$ENDIF _D2}
  17363. {$ENDIF _FPC}
  17364. //[function ParsePascalString]
  17365. function ParsePascalString( var S : String; const Separators : String ) : String;
  17366. var Pos, Idx : Integer;
  17367. Hex, Spc : boolean;
  17368. procedure SkipSpaces;
  17369. begin
  17370. if not Spc then
  17371. while (Length( S ) >= Pos) and (S[ Pos ] = ' ') do
  17372. Inc( Pos );
  17373. end;
  17374. var Buf : String;
  17375. Ou, Val : Integer;
  17376. begin
  17377. Pos := 1;
  17378. Spc := IndexOfChar( Separators, ' ' ) >= 0;
  17379. SkipSpaces;
  17380. if Length( S ) < Pos then
  17381. begin
  17382. Result := S;
  17383. S := '';
  17384. exit;
  17385. end;
  17386. Buf := PChar( S );
  17387. Ou := 1;
  17388. if S[ Pos ] in [ '''', '#' ] then
  17389. begin
  17390. // skip here string constant expression
  17391. while Pos <= Length( S ) do
  17392. begin
  17393. if S[ Pos ] = '''' then
  17394. begin
  17395. Inc( Pos );
  17396. while Pos <= Length( S ) do
  17397. begin
  17398. if S[ Pos ] = '''' then
  17399. if (Pos = Length( S )) or (S[ Pos+1 ] <> '''') then
  17400. begin
  17401. Inc( Pos );
  17402. break;
  17403. end
  17404. else Inc( Pos );
  17405. Buf[ Ou ] := S[ Pos ];
  17406. Inc( Ou );
  17407. Inc( Pos );
  17408. end;
  17409. //if Pos < Length( S ) then Inc( Pos );
  17410. end
  17411. else
  17412. if S[ Pos ] = '#' then
  17413. begin
  17414. Inc( Pos ); Hex := False; Val := 0;
  17415. if (Pos < Length( S )) and (S[ Pos ] = '$') then
  17416. begin
  17417. Inc( Pos ); Hex := True;
  17418. end;
  17419. Dec( Pos );
  17420. while Pos < Length( S ) do
  17421. begin
  17422. Inc( Pos );
  17423. if (S[ Pos ] in [ '0'..'9' ]) or
  17424. Hex and (S[ Pos ] in [ 'a'..'f', 'A'..'F' ]) then
  17425. begin
  17426. if Hex then
  17427. Val := Val * 16
  17428. else
  17429. Val := Val * 10;
  17430. if S[ Pos ] <= '9' then
  17431. Val := Val + Integer( S[ Pos ] ) - Integer( '0' )
  17432. else
  17433. if S[ Pos ] <= 'F' then
  17434. Val := Val + 10 + Integer( S[ Pos ] ) - Integer( 'A' )
  17435. else
  17436. Val := Val + 10 + Integer( S[ Pos ] ) - Integer( 'a' );
  17437. continue;
  17438. end;
  17439. Inc( Pos ); break;
  17440. end;
  17441. Buf[ Ou ] := Char( Val );
  17442. Inc( Ou );
  17443. end
  17444. else break;
  17445. SkipSpaces;
  17446. if S[ Pos ] <> '+' then break;
  17447. SkipSpaces;
  17448. end;
  17449. end;
  17450. Idx := IndexOfCharsMin( CopyEnd( S, Pos ), Separators );
  17451. if Idx <= 0 then
  17452. begin
  17453. Result := Copy( Buf, 1, Ou - 1 ) + CopyEnd( S, Pos );
  17454. S := '';
  17455. end
  17456. else
  17457. begin
  17458. Result := Copy( Buf, 1, Ou - 1 ) + Copy( S, Pos, Idx - 1 );
  17459. S := CopyEnd( S, Pos + Idx );
  17460. end;
  17461. end;
  17462. //[function String2PascalStrExpr]
  17463. function String2PascalStrExpr( const S : String ) : String;
  17464. var I, Strt : Integer;
  17465. function String2DoubleQuotas( const S : String ) : String;
  17466. var I, J : Integer;
  17467. begin
  17468. if IndexOfChar( S, '''' ) <= 0 then
  17469. Result := S
  17470. else
  17471. begin
  17472. J := 0;
  17473. for I := 1 to Length( S ) do
  17474. if S[ I ] = '''' then Inc( J );
  17475. SetLength( Result, Length( S ) + J );
  17476. J := 1;
  17477. for I := 1 to Length( S ) do
  17478. begin
  17479. Result[ J ] := S[ I ];
  17480. Inc( J );
  17481. if S[ I ] = '''' then
  17482. begin
  17483. Result[ J ] := '''';
  17484. Inc( J );
  17485. end;
  17486. end;
  17487. end;
  17488. end;
  17489. begin
  17490. Result := '';
  17491. if S = '' then
  17492. begin
  17493. Result := '''''';
  17494. exit;
  17495. end;
  17496. Strt := 1;
  17497. for I := 1 to Length( S ) + 1 do
  17498. begin
  17499. if (I > Length( S )) or (S[ I ] < ' ') then
  17500. begin
  17501. if (I > Strt) and (I > 1) then
  17502. begin
  17503. if Result <> '' then
  17504. Result := Result + '+';
  17505. Result := Result + '''' + String2DoubleQuotas( Copy( S, Strt, I - Strt ) ) + '''';
  17506. end;
  17507. if I > Length( S ) then break;
  17508. if Result <> '' then
  17509. Result := Result + '+'
  17510. else
  17511. Result := Result + '''''+';
  17512. Result := Result + '#' + Int2Str( Integer( S[ I ] ) );
  17513. Strt := I + 1;
  17514. end;
  17515. end;
  17516. end;
  17517. //[function CompareMem]
  17518. function CompareMem(P1, P2: Pointer; Length: Integer): Boolean; assembler;
  17519. asm
  17520. {$IFDEF F_P}
  17521. MOV EAX, [P1]
  17522. MOV EDX, [P2]
  17523. MOV ECX, [Length]
  17524. {$ENDIF}
  17525. PUSH ESI
  17526. PUSH EDI
  17527. MOV ESI,P1
  17528. MOV EDI,P2
  17529. MOV EDX,ECX
  17530. XOR EAX,EAX
  17531. AND EDX,3
  17532. SHR ECX,1
  17533. SHR ECX,1
  17534. REPE CMPSD
  17535. JNE @@2
  17536. MOV ECX,EDX
  17537. REPE CMPSB
  17538. JNE @@2
  17539. @@1: INC EAX
  17540. @@2: POP EDI
  17541. POP ESI
  17542. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  17543. //[FUNCTION AllocMem]
  17544. {$IFDEF ASM_VERSION}
  17545. function AllocMem( Size : Integer ) : Pointer;
  17546. asm //cmd //opd
  17547. TEST EAX, EAX
  17548. JZ @@exit
  17549. PUSH EAX
  17550. CALL System.@GetMem
  17551. POP EDX
  17552. PUSH EAX
  17553. MOV CL, 0
  17554. CALL System.@FillChar
  17555. POP EAX
  17556. @@exit:
  17557. end;
  17558. {$ELSE ASM_VERSION} //Pascal
  17559. function AllocMem( Size : Integer ) : Pointer;
  17560. begin
  17561. Result := nil;
  17562. if Size > 0 then
  17563. begin
  17564. GetMem( Result, Size );
  17565. FillChar( Result^, Size, 0 );
  17566. end;
  17567. end;
  17568. {$ENDIF ASM_VERSION}
  17569. //[END AllocMem]
  17570. //[procedure DisposeMem]
  17571. procedure DisposeMem( var Addr : Pointer );
  17572. begin
  17573. if Addr <> nil then
  17574. FreeMem( Addr );
  17575. Addr := nil;
  17576. end;
  17577. //[function AnsiUpperCase]
  17578. function AnsiUpperCase(const S: string): string;
  17579. var
  17580. Len: Integer;
  17581. begin
  17582. Len := Length(S);
  17583. SetString(Result, PChar(S), Len);
  17584. if Len > 0 then CharUpperBuff(Pointer(Result), Len);
  17585. end;
  17586. //[function AnsiLowerCase]
  17587. function AnsiLowerCase(const S: string): string;
  17588. var
  17589. Len: Integer;
  17590. begin
  17591. Len := Length(S);
  17592. SetString(Result, PChar(S), Len);
  17593. if Len > 0 then CharLowerBuff(Pointer(Result), Len);
  17594. end;
  17595. {$IFNDEF _D2}
  17596. {$IFNDEF _FPC}
  17597. //[function WAnsiUpperCase]
  17598. function WAnsiUpperCase(const S: WideString): WideString;
  17599. var Len: Integer;
  17600. begin
  17601. Len := Length(S);
  17602. Result := S;
  17603. if Len > 0 then CharUpperBuffW(Pointer(Result), Len);
  17604. end;
  17605. //[function WAnsiLowerCase]
  17606. function WAnsiLowerCase(const S: WideString): WideString;
  17607. var Len: Integer;
  17608. begin
  17609. Len := Length(S);
  17610. Result := S;
  17611. if Len > 0 then CharLowerBuffW(Pointer(Result), Len);
  17612. end;
  17613. {$ENDIF _FPC}
  17614. {$ENDIF _D2}
  17615. //[function AnsiCompareStr]
  17616. function AnsiCompareStr(const S1, S2: string): Integer;
  17617. begin
  17618. Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), -1,
  17619. PChar(S2), -1 ) - 2;
  17620. end;
  17621. //[function _AnsiCompareStr]
  17622. function _AnsiCompareStr(S1, S2: PChar): Integer;
  17623. begin
  17624. Result := CompareString( LOCALE_USER_DEFAULT, 0, S1, -1,
  17625. S2, -1) - 2;
  17626. end;
  17627. //[function AnsiCompareStrNoCase]
  17628. function AnsiCompareStrNoCase(const S1, S2: string): Integer;
  17629. begin
  17630. Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, PChar(S1), -1,
  17631. PChar(S2), -1 ) - 2;
  17632. end;
  17633. //[function _AnsiCompareStrNoCase]
  17634. function _AnsiCompareStrNoCase(S1, S2: PChar): Integer;
  17635. begin
  17636. Result := CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1, -1,
  17637. S2, -1) - 2;
  17638. end;
  17639. //[function AnsiCompareText]
  17640. function AnsiCompareText( const S1, S2: String ): Integer;
  17641. begin
  17642. Result := AnsiCompareStrNoCase( S1, S2 );
  17643. end;
  17644. //[function StrLCopy]
  17645. function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
  17646. asm
  17647. {$IFDEF F_P}
  17648. MOV EAX, [Dest]
  17649. MOV EDX, [Source]
  17650. MOV ECX, [MaxLen]
  17651. {$ENDIF F_P}
  17652. PUSH EDI
  17653. PUSH ESI
  17654. PUSH EBX
  17655. MOV ESI,EAX
  17656. MOV EDI,EDX
  17657. MOV EBX,ECX
  17658. XOR AL,AL
  17659. TEST ECX,ECX
  17660. JZ @@1
  17661. REPNE SCASB
  17662. JNE @@1
  17663. INC ECX
  17664. @@1: SUB EBX,ECX
  17665. MOV EDI,ESI
  17666. MOV ESI,EDX
  17667. MOV EDX,EDI
  17668. MOV ECX,EBX
  17669. SHR ECX,2
  17670. REP MOVSD
  17671. MOV ECX,EBX
  17672. AND ECX,3
  17673. REP MOVSB
  17674. STOSB
  17675. MOV EAX,EDX
  17676. POP EBX
  17677. POP ESI
  17678. POP EDI
  17679. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  17680. //[FUNCTION StrPCopy]
  17681. {$IFDEF ASM_VERSION}
  17682. function StrPCopy(Dest: PChar; const Source: string): PChar;
  17683. asm
  17684. PUSH EAX
  17685. MOV EAX, EDX
  17686. CALL System.@LStrLen
  17687. MOV ECX, EAX
  17688. POP EAX
  17689. CALL EDX2PChar
  17690. CALL StrLCopy
  17691. end;
  17692. {$ELSE ASM_VERSION} //Pascal
  17693. function StrPCopy(Dest: PChar; const Source: string): PChar;
  17694. begin
  17695. Result := StrLCopy(Dest, PChar(Source), Length(Source));
  17696. end;
  17697. {$ENDIF ASM_VERSION}
  17698. //[END StrPCopy]
  17699. //[FUNCTION StrEq]
  17700. {$IFDEF ASM_VERSION}
  17701. function StrEq( const S1, S2 : String ) : Boolean;
  17702. asm
  17703. TEST EDX, EDX
  17704. JNZ @@1
  17705. @@0: CMP EAX, EDX
  17706. JMP @@exit
  17707. @@1: TEST EAX, EAX
  17708. JZ @@0
  17709. MOV ECX, [EAX-4]
  17710. CMP ECX, [EDX-4]
  17711. JNE @@exit
  17712. PUSH EAX
  17713. PUSH EDX
  17714. PUSH 0
  17715. MOV EDX, ESP
  17716. CALL LowerCase
  17717. PUSH 0
  17718. MOV EAX, [ESP + 8]
  17719. MOV EDX, ESP
  17720. CALL LowerCase
  17721. POP EAX
  17722. POP EDX
  17723. PUSH EDX
  17724. PUSH EAX
  17725. CALL System.@LStrCmp
  17726. MOV EAX, ESP
  17727. PUSHFD
  17728. XOR EDX, EDX
  17729. MOV DL, 2
  17730. CALL System.@LStrArrayClr
  17731. POPFD
  17732. POP EDX
  17733. POP EDX
  17734. POP EDX
  17735. POP EDX
  17736. @@exit:
  17737. SETZ AL
  17738. end;
  17739. {$ELSE ASM_VERSION} //Pascal
  17740. function StrEq( const S1, S2 : String ) : Boolean;
  17741. begin
  17742. Result := (Length( S1 ) = Length( S2 )) and
  17743. (LowerCase( S1 ) = LowerCase( S2 ));
  17744. end;
  17745. {$ENDIF ASM_VERSION}
  17746. //[END StrEq]
  17747. //[FUNCTION AnsiEq]
  17748. {$IFDEF ASM_VERSION}
  17749. function AnsiEq( const S1, S2 : String ) : Boolean;
  17750. asm
  17751. CALL AnsiCompareStrNoCase
  17752. TEST EAX, EAX
  17753. SETZ AL
  17754. end;
  17755. {$ELSE ASM_VERSION} //Pascal
  17756. function AnsiEq( const S1, S2 : String ) : Boolean;
  17757. begin
  17758. Result := AnsiCompareStrNoCase( S1, S2 ) = 0;
  17759. end;
  17760. {$ENDIF ASM_VERSION}
  17761. //[END AnsiEq]
  17762. {$IFNDEF _D2}
  17763. {$IFNDEF _FPC}
  17764. //[function WAnsiEq]
  17765. function WAnsiEq( const S1, S2 : WideString ) : Boolean;
  17766. begin
  17767. Result := WAnsiLowerCase( S1 )=WAnsiLowerCase( S2 );
  17768. end;
  17769. {$ENDIF _FPC}
  17770. {$ENDIF _D2}
  17771. //[FUNCTION StrIn]
  17772. {$IFDEF ASM_VERSION}
  17773. function StrIn(const S: String; const A: array of String): Boolean;
  17774. asm
  17775. @@1:
  17776. TEST ECX, ECX
  17777. JL @@ret_0
  17778. PUSH EDX
  17779. MOV EDX, [EDX+ECX*4]
  17780. DEC ECX
  17781. PUSH ECX
  17782. PUSH EAX
  17783. CALL StrEq
  17784. DEC AL
  17785. POP EAX
  17786. POP ECX
  17787. POP EDX
  17788. JNZ @@1
  17789. MOV AL, 1
  17790. RET
  17791. @@ret_0:XOR EAX, EAX
  17792. end;
  17793. {$ELSE ASM_VERSION} //Pascal
  17794. function StrIn(const S: String; const A: array of String): Boolean;
  17795. var I : Integer;
  17796. begin
  17797. for I := Low( A ) to High( A ) do
  17798. if StrEq( S, A[ I ] ) then
  17799. begin
  17800. Result := True;
  17801. Exit;
  17802. end;
  17803. Result := False;
  17804. end;
  17805. {$ENDIF ASM_VERSION}
  17806. //[END StrIn]
  17807. {$IFNDEF _D2}
  17808. {$IFNDEF _FPC}
  17809. //[function WStrIn]
  17810. function WStrIn( const S : WideString; const A : array of WideString ) : Boolean;
  17811. var I : Integer;
  17812. begin
  17813. for I := Low( A ) to High( A ) do
  17814. if WAnsiEq( S, A[ I ] ) then
  17815. begin
  17816. Result := True;
  17817. Exit;
  17818. end;
  17819. Result := False;
  17820. end;
  17821. {$ENDIF _FPC}
  17822. {$ENDIF _D2}
  17823. //[function StrIs]
  17824. function StrIs( const S : String; const A : array of String; var Idx: Integer ) : Boolean;
  17825. var I : Integer;
  17826. begin
  17827. Idx := -1;
  17828. for I := Low( A ) to High( A ) do
  17829. if StrEq( S, A[ I ] ) then
  17830. begin
  17831. Idx := I;
  17832. Result := True;
  17833. Exit;
  17834. end;
  17835. Result := False;
  17836. end;
  17837. //[function IntIn]
  17838. function IntIn( Value: Integer; const List: array of Integer ): Boolean;
  17839. var I: Integer;
  17840. begin
  17841. Result := FALSE;
  17842. for I := 0 to High( List ) do
  17843. begin
  17844. if Value = List[ I ] then
  17845. begin
  17846. Result := TRUE;
  17847. break;
  17848. end;
  17849. end;
  17850. end;
  17851. //[FUNCTION _StrSatisfy]
  17852. {$IFDEF ASM_VERSION}
  17853. function _StrSatisfy( S, Mask : PChar ) : Boolean;
  17854. asm
  17855. TEST EAX, EAX
  17856. JZ @@exit
  17857. XCHG ECX, EAX
  17858. // EDX <- Mask
  17859. // ECX <- S
  17860. XOR EAX, EAX
  17861. MOV AL, '*'
  17862. @@rest_satisfy:
  17863. PUSH ECX
  17864. PUSH EDX
  17865. @@nx_char:
  17866. MOV AH, [EDX]
  17867. OR AH, [ECX]
  17868. JZ @@fin //@@ret_true
  17869. MOV AH, 0
  17870. CMP word ptr [EDX], AX //'*'
  17871. JE @@fin //@@ret_true
  17872. CMP byte ptr [ECX], AH
  17873. JNE @@10
  17874. DEC EDX
  17875. @@1:
  17876. INC EDX
  17877. CMP byte ptr [EDX], AL //'*'
  17878. JE @@1
  17879. //CMP byte ptr [EDX], '?'
  17880. //JE @@1
  17881. CMP byte ptr [EDX], AH
  17882. SETZ AL
  17883. JMP @@fin
  17884. @@10: CMP byte ptr [EDX], AH
  17885. JE @@ret_false
  17886. CMP byte ptr [EDX], '?'
  17887. JNE @@11
  17888. @@go_nx_char:
  17889. INC ECX
  17890. INC EDX
  17891. JMP @@nx_char
  17892. @@11:
  17893. CMP byte ptr [EDX], AL //'*'
  17894. JNE @@20
  17895. INC EDX
  17896. @@12: CMP byte ptr [ECX], AH
  17897. JE @@ret_false
  17898. CALL @@rest_satisfy
  17899. TEST AL, AL
  17900. JNE @@fin
  17901. MOV AL, '*'
  17902. INC ECX
  17903. JMP @@12
  17904. @@20: MOV AH, [EDX]
  17905. XOR AH, [ECX]
  17906. JE @@go_nx_char
  17907. @@ret_false:
  17908. XOR EAX, EAX
  17909. @@fin:
  17910. POP EDX
  17911. POP ECX
  17912. @@exit:
  17913. end;
  17914. {$ELSE ASM_VERSION} //Pascal
  17915. function _StrSatisfy( S, Mask : PChar ) : Boolean;
  17916. label next_char;
  17917. begin
  17918. next_char:
  17919. Result := True;
  17920. if (S^ = #0) and (Mask^ = #0) then exit;
  17921. if (Mask^ = '*') and (Mask[1] = #0) then exit;
  17922. if S^ = #0 then
  17923. begin
  17924. while Mask^ = '*' do
  17925. Inc( Mask );
  17926. Result := Mask^ = #0;
  17927. exit;
  17928. end;
  17929. Result := False;
  17930. if Mask^ = #0 then exit;
  17931. if Mask^ = '?' then
  17932. begin
  17933. Inc( S ); Inc( Mask ); goto next_char;
  17934. end;
  17935. if Mask^ = '*' then
  17936. begin
  17937. Inc( Mask );
  17938. while S^ <> #0 do
  17939. begin
  17940. Result := _StrSatisfy( S, Mask );
  17941. if Result then exit;
  17942. Inc( S );
  17943. end;
  17944. exit; // (Result = False)
  17945. end;
  17946. Result := S^ = Mask^;
  17947. Inc( S ); Inc( Mask );
  17948. if Result then goto next_char;
  17949. end;
  17950. {$ENDIF ASM_VERSION}
  17951. //[END _StrSatisfy]
  17952. //[FUNCTION StrSatisfy]
  17953. {$IFDEF ASM_VERSION}
  17954. function StrSatisfy( const S, Mask: String ): Boolean;
  17955. asm
  17956. PUSH ESI
  17957. XCHG ESI, EAX
  17958. PUSH 0
  17959. XCHG EAX, EDX
  17960. CALL EAX2PChar
  17961. MOV EDX, ESP
  17962. CMP byte ptr [EAX], 0
  17963. JZ @@0
  17964. CALL AnsiLowerCase
  17965. @@0:
  17966. XCHG EAX, ESI
  17967. PUSH 0
  17968. CALL EAX2PChar
  17969. MOV EDX, ESP
  17970. CMP byte ptr [EAX], 0
  17971. JZ @@1
  17972. CALL AnsiLowerCase
  17973. @@1:
  17974. POP EAX
  17975. POP EDX
  17976. PUSH EDX
  17977. PUSH EAX
  17978. CALL _StrSatisfy
  17979. XCHG ESI, EAX
  17980. CALL RemoveStr
  17981. CALL RemoveStr
  17982. XCHG EAX, ESI
  17983. POP ESI
  17984. end;
  17985. {$ELSE ASM_VERSION} //Pascal
  17986. function StrSatisfy( const S, Mask: String ): Boolean;
  17987. begin
  17988. Result := _StrSatisfy( PChar( AnsiLowerCase( S ) ),
  17989. PChar( AnsiLowerCase( Mask ) ) );
  17990. end;
  17991. {$ENDIF ASM_VERSION}
  17992. //[END StrSatisfy]
  17993. //[FUNCTION _2StrSatisfy]
  17994. {$IFDEF ASM_VERSION}
  17995. function _2StrSatisfy( S, Mask: PChar ): Boolean;
  17996. asm // //
  17997. PUSH EBX
  17998. XCHG EBX, EAX
  17999. PUSH 0
  18000. MOV EAX, ESP
  18001. CALL System.@LStrFromPChar
  18002. PUSH 0
  18003. MOV EAX, ESP
  18004. MOV EDX, EBX
  18005. CALL System.@LStrFromPChar
  18006. POP EAX
  18007. POP EDX
  18008. PUSH EDX
  18009. PUSH EAX
  18010. CALL StrSatisfy
  18011. XCHG EBX, EAX
  18012. CALL RemoveStr
  18013. CALL RemoveStr
  18014. XCHG EAX, EBX
  18015. POP EBX
  18016. end;
  18017. {$ELSE ASM_VERSION} // Pascal
  18018. function _2StrSatisfy( S, Mask: PChar ): Boolean;
  18019. begin
  18020. Result := StrSatisfy( S, Mask );
  18021. end;
  18022. {$ENDIF ASM_VERSION}
  18023. //[END _2StrSatisfy]
  18024. //[function StrReplace]
  18025. function StrReplace( var S: String; const From, ReplTo: String ): Boolean;
  18026. var I: Integer;
  18027. begin
  18028. I := pos( From, S );
  18029. if I > 0 then
  18030. begin
  18031. S := Copy( S, 1, I - 1 ) + ReplTo + CopyEnd( S, I + Length( From ) );
  18032. Result := TRUE;
  18033. end
  18034. else Result := FALSE;
  18035. end;
  18036. {-}
  18037. {$IFDEF _FPC}
  18038. //[procedure SetLengthW]
  18039. procedure SetLengthW( var W: WideString; NewLength: Integer );
  18040. begin
  18041. while Length( W ) < NewLength do
  18042. W := W + ' ' + W;
  18043. if Length( W ) > NewLength then
  18044. Delete( W, NewLength + 1, Length( W ) - NewLength );
  18045. end;
  18046. //[function CopyW]
  18047. function CopyW( const W: WideString; From, Count: Integer ): WideString;
  18048. begin
  18049. Result := '';
  18050. if Count <= 0 then Exit;
  18051. SetLengthW( Result, Count );
  18052. Move( W[ From ], Result[ 1 ], Count * Sizeof( WideChar ) );
  18053. end;
  18054. //[function posW]
  18055. function posW( const S1, S2: String ): Integer;
  18056. var I, L1: Integer;
  18057. begin
  18058. L1 := Length( S1 );
  18059. for I := 1 to Length( S2 )-L1+1 do
  18060. begin
  18061. if Copy( S2, I, L1 ) = S1 then
  18062. begin
  18063. Result := I;
  18064. Exit;
  18065. end;
  18066. end;
  18067. Result := 0;
  18068. end;
  18069. {$ENDIF _FPC}
  18070. {$IFNDEF _FPC}
  18071. {$IFNDEF _D2}
  18072. //[function WStrReplace]
  18073. function WStrReplace( var S: WideString; const From, ReplTo: WideString ): Boolean;
  18074. var I: Integer;
  18075. begin
  18076. I := pos( From, S );
  18077. if I > 0 then
  18078. begin
  18079. S := Copy( S, 1, I - 1 ) + ReplTo + Copy( S, I + Length( From ), MaxInt );
  18080. Result := TRUE;
  18081. end
  18082. else Result := FALSE;
  18083. end;
  18084. //[function WStrRepeat]
  18085. function WStrRepeat( const S: WideString; Count: Integer ): WideString;
  18086. var I, L: Integer;
  18087. begin
  18088. L := Length( S );
  18089. SetLength( Result, L * Count );
  18090. for I := 0 to Count-1 do
  18091. Move( S[ 1 ], Result[ 1 + I * L ], L * Sizeof( WideChar ) );
  18092. end;
  18093. {$ENDIF _D2}
  18094. {$ENDIF _FPC}
  18095. {+}
  18096. //[function StrRepeat]
  18097. function StrRepeat( const S: String; Count: Integer ): String;
  18098. var I, L: Integer;
  18099. begin
  18100. L := Length( S );
  18101. SetLength( Result, L * Count );
  18102. for I := 0 to Count-1 do
  18103. Move( S[ 1 ], Result[ 1 + I * L ], L );
  18104. end;
  18105. //[PROCEDURE NormalizeUnixText]
  18106. {$IFDEF ASM_VERSION}
  18107. procedure NormalizeUnixText( var S: String );
  18108. asm //cmd //opd
  18109. CMP dword ptr [EAX], 0
  18110. JZ @@exit
  18111. PUSH EBX
  18112. PUSH EDI
  18113. MOV EBX, EAX
  18114. CALL UniqueString
  18115. MOV EDI, [EBX]
  18116. @@1: MOV EAX, EDI
  18117. CALL System.@LStrLen
  18118. XCHG ECX, EAX
  18119. MOV AX, $0D0A
  18120. CMP byte ptr [EDI], AL
  18121. JNE @@loo
  18122. MOV byte ptr [EDI], AH
  18123. @@loo:
  18124. TEST ECX, ECX
  18125. JZ @@fin
  18126. @@loo1:
  18127. REPNZ SCASB
  18128. JNZ @@fin
  18129. CMP byte ptr [EDI-2], AH
  18130. JE @@loo
  18131. MOV byte ptr [EDI-1], AH
  18132. JNE @@loo1
  18133. @@fin: POP EDI
  18134. POP EBX
  18135. @@exit:
  18136. end;
  18137. {$ELSE ASM_VERSION} //Pascal
  18138. procedure NormalizeUnixText( var S: String );
  18139. var I: Integer;
  18140. begin
  18141. if S <> '' then
  18142. begin
  18143. if S[ 1 ] = #10 then
  18144. S[ 1 ] := #13;
  18145. for I := 2 to Length(S) do
  18146. if (S[I]=#10) and (S[I-1]<>#13) then
  18147. S[I] := #13;
  18148. end;
  18149. end;
  18150. {$ENDIF ASM_VERSION}
  18151. //[END NormalizeUnixText]
  18152. //[function StrComp]
  18153. function StrComp(const Str1, Str2: PChar): Integer; assembler;
  18154. asm
  18155. {$IFDEF F_P}
  18156. MOV EAX, [Str1]
  18157. MOV EDX, [Str2]
  18158. {$ENDIF F_P}
  18159. PUSH EDI
  18160. PUSH ESI
  18161. MOV EDI,EDX
  18162. XCHG ESI,EAX
  18163. OR ECX, -1
  18164. XOR EAX,EAX
  18165. REPNE SCASB
  18166. NOT ECX
  18167. MOV EDI,EDX
  18168. XOR EDX,EDX
  18169. REPE CMPSB
  18170. MOV AL,[ESI-1]
  18171. MOV DL,[EDI-1]
  18172. SUB EAX,EDX
  18173. POP ESI
  18174. POP EDI
  18175. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18176. function StrComp_NoCase(const Str1, Str2: PChar): Integer;
  18177. asm
  18178. {$IFDEF F_P}
  18179. MOV EAX, [Str1]
  18180. MOV EDX, [Str2]
  18181. {$ENDIF F_P}
  18182. PUSH EDI
  18183. PUSH ESI
  18184. MOV EDI,EDX
  18185. XCHG ESI,EAX
  18186. OR ECX, -1
  18187. XOR EAX,EAX
  18188. REPNE SCASB
  18189. NOT ECX
  18190. MOV EDI,EDX
  18191. @@0:
  18192. XOR EDX,EDX
  18193. REPE CMPSB
  18194. MOV AL,[ESI-1]
  18195. MOV AH, AL
  18196. SUB AH, 'a'
  18197. CMP AH, 25
  18198. JA @@1
  18199. SUB AL, $20
  18200. @@1:
  18201. MOV DL,[EDI-1]
  18202. MOV AH, DL
  18203. SUB AH, 'a'
  18204. CMP AH, 25
  18205. JA @@2
  18206. SUB DL, $20
  18207. @@2:
  18208. MOV AH, 0
  18209. SUB EAX,EDX
  18210. JNZ @@exit
  18211. CMP DL, 0
  18212. JNZ @@0
  18213. @@exit:
  18214. POP ESI
  18215. POP EDI
  18216. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18217. //[function StrLComp_NoCase]
  18218. function StrLComp_NoCase(const Str1, Str2: PChar; MaxLen: Cardinal): Integer;
  18219. asm
  18220. {$IFDEF F_P}
  18221. MOV EAX, [Str1]
  18222. MOV EDX, [Str2]
  18223. MOV ECX, [MaxLen]
  18224. {$ENDIF F_P}
  18225. PUSH EDI
  18226. PUSH ESI
  18227. PUSH EBX
  18228. MOV EDI,EDX
  18229. MOV ESI,EAX
  18230. MOV EBX,ECX
  18231. XOR EAX,EAX
  18232. OR ECX,ECX
  18233. JE @@exit
  18234. REPNE SCASB
  18235. SUB EBX,ECX
  18236. MOV ECX,EBX
  18237. MOV EDI,EDX
  18238. @@0:
  18239. XOR EDX,EDX
  18240. REPE CMPSB
  18241. MOV AL,[ESI-1]
  18242. MOV AH, AL
  18243. SUB AH, 'a'
  18244. CMP AH, 25
  18245. JA @@1
  18246. SUB AL, $20
  18247. @@1:
  18248. MOV DL,[EDI-1]
  18249. MOV AH, DL
  18250. SUB AH, 'a'
  18251. CMP AH, 25
  18252. JA @@2
  18253. SUB DL, $20
  18254. @@2:
  18255. MOV AH, 0
  18256. SUB EAX,EDX
  18257. JECXZ @@exit
  18258. JZ @@0
  18259. @@exit:
  18260. POP EBX
  18261. POP ESI
  18262. POP EDI
  18263. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18264. //[function StrLComp]
  18265. function StrLComp(const Str1, Str2: PChar; MaxLen: Cardinal): Integer; assembler;
  18266. asm
  18267. {$IFDEF F_P}
  18268. MOV EAX, [Str1]
  18269. MOV EDX, [Str2]
  18270. MOV ECX, [MaxLen]
  18271. {$ENDIF F_P}
  18272. PUSH EDI
  18273. PUSH ESI
  18274. PUSH EBX
  18275. MOV EDI,EDX
  18276. MOV ESI,EAX
  18277. MOV EBX,ECX
  18278. XOR EAX,EAX
  18279. OR ECX,ECX
  18280. JE @@1
  18281. REPNE SCASB
  18282. SUB EBX,ECX
  18283. MOV ECX,EBX
  18284. MOV EDI,EDX
  18285. XOR EDX,EDX
  18286. REPE CMPSB
  18287. MOV AL,[ESI-1]
  18288. MOV DL,[EDI-1]
  18289. SUB EAX,EDX
  18290. @@1: POP EBX
  18291. POP ESI
  18292. POP EDI
  18293. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18294. //[function StrLen]
  18295. function StrLen(const Str: PChar): Cardinal; assembler;
  18296. asm
  18297. {$IFDEF F_P}
  18298. MOV EAX, [Str]
  18299. {$ENDIF F_P}
  18300. XCHG EAX, EDI
  18301. XCHG EDX, EAX
  18302. OR ECX, -1
  18303. XOR EAX, EAX
  18304. CMP EAX, EDI
  18305. JE @@exit0
  18306. REPNE SCASB
  18307. DEC EAX
  18308. DEC EAX
  18309. SUB EAX,ECX
  18310. @@exit0:
  18311. MOV EDI,EDX
  18312. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18313. //[FUNCTION __DelimiterLast]
  18314. {$IFDEF ASM_VERSION}
  18315. function __DelimiterLast( Str: PChar; Delimiters: PChar ): PChar;
  18316. asm
  18317. PUSH ESI
  18318. CALL EAX2PChar
  18319. MOV ESI, EDX
  18320. MOV EDX, EAX
  18321. @@tolast:
  18322. CMP byte ptr [EAX], 0
  18323. JZ @@next1
  18324. INC EAX
  18325. JMP @@tolast
  18326. @@next1:
  18327. PUSH EAX
  18328. @@next:
  18329. LODSB
  18330. TEST AL, AL
  18331. JZ @@exit
  18332. PUSH EDX
  18333. XCHG EDX, EAX
  18334. CALL StrRScan
  18335. POP EDX
  18336. TEST EAX, EAX
  18337. JZ @@next
  18338. POP ECX
  18339. CMP byte ptr [ECX], 0
  18340. JZ @@next1
  18341. CMP EAX, ECX
  18342. JG @@next1
  18343. PUSH ECX
  18344. JLE @@next
  18345. @@exit: POP EAX
  18346. POP ESI
  18347. end;
  18348. {$ELSE ASM_VERSION} //Pascal
  18349. function __DelimiterLast( Str: PChar; Delimiters: PChar ): PChar;
  18350. var
  18351. P, F : PChar;
  18352. begin
  18353. P := Str;
  18354. Result := P + StrLen( Str );
  18355. while Delimiters^ <> #0 do
  18356. begin
  18357. F := StrRScan( P, Delimiters^ );
  18358. if F <> nil then
  18359. if (Result^ = #0) or (Integer(F) > Integer(Result)) then
  18360. Result := F;
  18361. Inc( Delimiters );
  18362. end;
  18363. end;
  18364. {$ENDIF ASM_VERSION}
  18365. //[END __DelimiterLast]
  18366. //[function SkipSpaces]
  18367. function SkipSpaces( P: PChar ): PChar;
  18368. begin
  18369. while True do
  18370. begin
  18371. while (P[0] <> #0) and (P[0] <= ' ') do Inc(P);
  18372. if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break;
  18373. end;
  18374. Result := P;
  18375. end;
  18376. //[function SkipParam]
  18377. function SkipParam(P: PChar): PChar;
  18378. begin
  18379. P := SkipSpaces( P );
  18380. while P[0] > ' ' do
  18381. if P[0] = '"' then
  18382. begin
  18383. Inc(P);
  18384. while (P[0] <> #0) and (P[0] <> '"') do
  18385. Inc(P);
  18386. if P[0] <> #0 then Inc(P);
  18387. end
  18388. else
  18389. Inc(P);
  18390. Result := P;
  18391. end;
  18392. //[FUNCTION ParamStr]
  18393. function ParamStr( Idx: Integer ): String;
  18394. var
  18395. P, P1: PChar;
  18396. Buffer: array[ 0..260 ] of Char;
  18397. begin
  18398. if Idx = 0 then
  18399. SetString( Result, Buffer, GetModuleFileName( 0, Buffer, Sizeof( Buffer ) ) )
  18400. else
  18401. begin
  18402. P := GetCommandLine;
  18403. repeat
  18404. P := SkipSpaces( P );
  18405. P1 := P;
  18406. P := SkipParam(P);
  18407. if Idx = 0 then Break;
  18408. Dec(Idx);
  18409. until (Idx < 0) or (P = P1);
  18410. Result := Copy( P1, 1, P - P1 );
  18411. if Length( Result ) >= 2 then
  18412. if (Result[ 1 ] = '"') and (Result[ Length( Result ) ] = '"') then
  18413. Result := Copy( Result, 2, Length( Result ) - 2 );
  18414. end;
  18415. end;
  18416. //[END ParamStr]
  18417. //[FUNCTION ParamCount]
  18418. function ParamCount: Integer;
  18419. var
  18420. S: string;
  18421. begin
  18422. Result := 0;
  18423. while True do
  18424. begin
  18425. S := ParamStr(Result + 1);
  18426. if S = '' then Break;
  18427. Inc(Result);
  18428. end;
  18429. end;
  18430. //[END ParamCount]
  18431. //[FUNCTION DelimiterLast]
  18432. {$IFDEF ASM_VERSION}
  18433. function DelimiterLast( const Str, Delimiters: String ): Integer;
  18434. asm
  18435. CALL EAX2PChar
  18436. CALL EDX2PChar
  18437. PUSH EAX
  18438. CALL __DelimiterLast
  18439. POP EDX
  18440. SUB EAX, EDX
  18441. INC EAX
  18442. end;
  18443. {$ELSE ASM_VERSION} //Pascal
  18444. function DelimiterLast( const Str, Delimiters: String ): Integer;
  18445. var PStr: PChar;
  18446. begin
  18447. PStr := PChar( Str );
  18448. Result := Integer( __DelimiterLast( PStr, PChar( Delimiters ) ) )
  18449. - Integer( PStr )
  18450. + 1; // {Viman}
  18451. end;
  18452. {$ENDIF ASM_VERSION}
  18453. //[END DelimiterLast]
  18454. // Thanks to Marco Bobba - Marisa Bo for this code
  18455. //[function StrIsStartingFrom]
  18456. function StrIsStartingFrom( Str, Pattern: PChar ): Boolean;
  18457. asm
  18458. {$IFDEF F_P}
  18459. MOV EAX, [Str]
  18460. MOV EDX, [Pattern]
  18461. {$ENDIF F_P}
  18462. XOR ECX, ECX
  18463. @@1:
  18464. MOV CL, [EDX] // pattern[ i ]
  18465. INC EDX
  18466. MOV CH, [EAX] // str[ i ]
  18467. INC EAX
  18468. JECXZ @@2 // str = pattern; CL = #0, CH = #0
  18469. CMP CL, CH
  18470. JE @@1
  18471. @@2:
  18472. TEST CL, CL
  18473. SETZ AL
  18474. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18475. function StrIsStartingFromNoCase( Str, Pattern: PChar ): Boolean;
  18476. asm
  18477. {$IFDEF F_P}
  18478. MOV EAX, [Str]
  18479. MOV EDX, [Pattern]
  18480. {$ENDIF F_P}
  18481. XOR ECX, ECX
  18482. @@1:
  18483. MOV CL, [EDX] // pattern[ i ]
  18484. INC EDX
  18485. MOV CH, [EAX] // str[ i ]
  18486. INC EAX
  18487. JECXZ @@2 // str = pattern; CL = #0, CH = #0
  18488. CMP CL, 'a'
  18489. JB @@cl_ok
  18490. CMP CL, 'z'
  18491. JA @@cl_ok
  18492. SUB CL, 32
  18493. @@cl_ok:
  18494. CMP CH, 'a'
  18495. JB @@ch_ok
  18496. CMP CH, 'z'
  18497. JA @@ch_ok
  18498. SUB CH, 32
  18499. @@ch_ok:
  18500. CMP CL, CH
  18501. JE @@1
  18502. @@2:
  18503. TEST CL, CL
  18504. SETZ AL
  18505. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18506. {$IFNDEF _FPC}
  18507. //[FUNCTION Format]
  18508. {$IFDEF ASM_VERSION}
  18509. function Format( const fmt: string; params: array of const ): String;
  18510. asm
  18511. PUSH ESI
  18512. PUSH EDI
  18513. PUSH EBX
  18514. MOV EBX, ESP
  18515. ADD ESP, -2048
  18516. MOV ESI, ESP
  18517. INC ECX
  18518. JZ @@2
  18519. @@1:
  18520. MOV EDI, [EDX + ECX*8 - 8]
  18521. PUSH EDI
  18522. LOOP @@1
  18523. @@2:
  18524. PUSH ESP
  18525. PUSH EAX
  18526. PUSH ESI
  18527. CALL wvsprintf
  18528. MOV EDX, ESI
  18529. MOV EAX, @Result
  18530. CALL System.@LStrFromPChar
  18531. MOV ESP, EBX
  18532. POP EBX
  18533. POP EDI
  18534. POP ESI
  18535. end;
  18536. {$ELSE ASM_VERSION} //Pascal
  18537. function Format( const fmt: string; params: array of const ): String;
  18538. var Buffer: array[ 0..2047 ] of Char;
  18539. ElsArray, El: PDWORD;
  18540. I : Integer;
  18541. P : PDWORD;
  18542. begin
  18543. ElsArray := nil;
  18544. if High( params ) >= 0 then
  18545. GetMem( ElsArray, (High( params ) + 1) * sizeof( Pointer ) );
  18546. El := ElsArray;
  18547. for I := 0 to High( params ) do
  18548. begin
  18549. P := @params[ I ];
  18550. P := Pointer( P^ );
  18551. El^ := DWORD( P );
  18552. Inc( El );
  18553. end;
  18554. wvsprintf( @Buffer[0], PChar( fmt ), PChar( ElsArray ) );
  18555. Result := Buffer;
  18556. if ElsArray <> nil then
  18557. FreeMem( ElsArray );
  18558. end;
  18559. {$ENDIF ASM_VERSION}
  18560. //[END Format]
  18561. //[function LStrFromPWCharLen]
  18562. function LStrFromPWCharLen(Source: PWideChar; Length: Integer): String;
  18563. var
  18564. DestLen: Integer;
  18565. Buffer: array[0..2047] of Char;
  18566. begin
  18567. if Length <= 0 then
  18568. begin
  18569. //_LStrClr(Result);
  18570. Result := '';
  18571. Exit;
  18572. end;
  18573. if Length < SizeOf(Buffer) div 2 then
  18574. begin
  18575. DestLen := WideCharToMultiByte(0, 0, Source, Length,
  18576. Buffer, SizeOf(Buffer), nil, nil);
  18577. if DestLen > 0 then
  18578. begin
  18579. Result := Buffer;
  18580. //System.LStrFromPCharLen(Result, Buffer, DestLen);
  18581. Exit;
  18582. end;
  18583. end;
  18584. DestLen := WideCharToMultiByte(0, 0, Source, Length, nil, 0, nil, nil);
  18585. // _LStrFromPCharLen(Dest, nil, DestLen);
  18586. SetLength( Result, DestLen );
  18587. WideCharToMultiByte(0, 0, Source, Length, Pointer(Result), DestLen, nil, nil);
  18588. end;
  18589. //[function LStrFromPWChar]
  18590. function LStrFromPWChar(Source: PWideChar): String;
  18591. {* from Delphi5 - because D2 does not contain it. }
  18592. asm
  18593. PUSH EDX
  18594. XOR EDX,EDX
  18595. TEST EAX,EAX
  18596. JE @@5
  18597. PUSH EAX
  18598. @@0: CMP DX,[EAX+0]
  18599. JE @@4
  18600. CMP DX,[EAX+2]
  18601. JE @@3
  18602. CMP DX,[EAX+4]
  18603. JE @@2
  18604. CMP DX,[EAX+6]
  18605. JE @@1
  18606. ADD EAX,8
  18607. JMP @@0
  18608. @@1: ADD EAX,2
  18609. @@2: ADD EAX,2
  18610. @@3: ADD EAX,2
  18611. @@4: XCHG EDX,EAX
  18612. POP EAX
  18613. SUB EDX,EAX
  18614. SHR EDX,1
  18615. @@5: POP ECX
  18616. JMP LStrFromPWCharLen
  18617. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  18618. {$ENDIF _FPC}
  18619. /////////////////////////////////////////////////////////////////////////
  18620. //
  18621. //
  18622. // F I L E S
  18623. //
  18624. //
  18625. /////////////////////////////////////////////////////////////////////////
  18626. //[FILES]
  18627. {
  18628. This part of the unit modified by Tim Slusher and Vladimir Kladov.
  18629. }
  18630. {* Set of utility methods to work with files
  18631. and reqistry.
  18632. When programming KOL, which is Windows API-oriented, You should
  18633. avoid alien (for Windows) embedded Pascal files handling, and
  18634. use API-calls which implemented very well. This set of functions
  18635. is intended to make this easier.
  18636. Also TDirList object implementation present here and some registry
  18637. access functions, which allow to make code more elegant.
  18638. }
  18639. {$UNDEF ASM_LOCAL}
  18640. {$IFDEF ASM_VERSION}
  18641. {$DEFINE ASM_LOCAL}
  18642. {$ENDIF ASM_VERSION}
  18643. //[FUNCTION FileCreate]
  18644. {$IFDEF ASM_VERSION}
  18645. function FileCreate( const FileName: string; OpenFlags: DWord): THandle;
  18646. asm
  18647. XOR ECX, ECX
  18648. PUSH ECX
  18649. MOV ECX, EDX
  18650. SHR ECX, 16
  18651. AND CX, $1FFF
  18652. JNZ @@1
  18653. MOV CL, FILE_ATTRIBUTE_NORMAL
  18654. @@1: PUSH ECX
  18655. MOV CL, DH
  18656. PUSH ECX // CreationMode
  18657. PUSH 0
  18658. MOV CL, DL
  18659. PUSH ECX // ShareMode
  18660. MOV DX, 0
  18661. PUSH EDX // AccessMode
  18662. //CALL System.@LStrToPChar // FileName must not be ''
  18663. PUSH EAX
  18664. CALL CreateFile
  18665. end;
  18666. {$ELSE ASM_VERSION} //Pascal
  18667. function FileCreate(const FileName: string; OpenFlags: DWord): THandle;
  18668. var Attr: DWORD;
  18669. begin
  18670. Attr := (OpenFlags shr 16) and $1FFF;
  18671. if Attr = 0 then Attr := FILE_ATTRIBUTE_NORMAL;
  18672. Result := CreateFile( PChar(FileName), OpenFlags and $F0000000,
  18673. OpenFlags and $F, nil, (OpenFlags shr 8) and $F,
  18674. Attr, 0 );
  18675. end;
  18676. {$ENDIF ASM_VERSION}
  18677. //[END FileCreate]
  18678. //[FUNCTION FileClose]
  18679. {$IFDEF ASM_VERSION}
  18680. function FileClose( Handle: THandle): Boolean;
  18681. asm
  18682. PUSH EAX
  18683. CALL CloseHandle
  18684. TEST EAX, EAX
  18685. SETNZ AL
  18686. end;
  18687. {$ELSE ASM_VERSION} //Pascal
  18688. function FileClose(Handle: THandle): boolean;
  18689. begin
  18690. Result := CloseHandle(Handle);
  18691. end;
  18692. {$ENDIF ASM_VERSION}
  18693. //[END FileClose]
  18694. //[FUNCTION FileExists]
  18695. {$IFDEF ASM_VERSION}
  18696. function FileExists( const FileName : String ) : Boolean;
  18697. const size_TWin32FindData = sizeof( TWin32FindData );
  18698. asm
  18699. CALL EAX2PChar
  18700. PUSH EAX
  18701. CALL GetFileAttributes
  18702. INC EAX
  18703. JZ @@exit
  18704. DEC EAX
  18705. {$IFDEF PARANOIA}
  18706. DB $24, FILE_ATTRIBUTE_DIRECTORY
  18707. {$ELSE}
  18708. AND AL, FILE_ATTRIBUTE_DIRECTORY
  18709. {$ENDIF}
  18710. SETZ AL
  18711. @@exit:
  18712. end;
  18713. {$ELSE ASM_VERSION} //Pascal
  18714. function FileExists( const FileName : String ) : Boolean;
  18715. var
  18716. Code: Integer;
  18717. begin
  18718. Code := GetFileAttributes(PChar(FileName));
  18719. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0);
  18720. end;
  18721. {$ENDIF ASM_VERSION}
  18722. //[END FileExists]
  18723. //[FUNCTION FileSeek]
  18724. {$IFDEF ASM_VERSION}
  18725. function FileSeek( Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  18726. asm
  18727. MOVZX ECX, CL
  18728. PUSH ECX
  18729. PUSH 0
  18730. PUSH EDX
  18731. PUSH EAX
  18732. CALL SetFilePointer
  18733. end;
  18734. {$ELSE ASM_VERSION} //Pascal
  18735. function FileSeek(Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  18736. begin
  18737. Result := SetFilePointer(Handle, MoveTo, nil, Ord( MoveMethod ) );
  18738. end;
  18739. {$ENDIF ASM_VERSION}
  18740. //[END FileSeek]
  18741. //[FUNCTION FileRead]
  18742. {$IFDEF ASM_VERSION}
  18743. function FileRead( Handle: THandle; var Buffer; Count: DWord): DWord;
  18744. asm
  18745. PUSH EBP
  18746. PUSH 0
  18747. MOV EBP, ESP
  18748. PUSH 0
  18749. PUSH EBP
  18750. PUSH ECX
  18751. PUSH EDX
  18752. PUSH EAX
  18753. CALL ReadFile
  18754. TEST EAX, EAX
  18755. POP EAX
  18756. JNZ @@exit
  18757. XOR EAX, EAX
  18758. @@exit:
  18759. POP EBP
  18760. end;
  18761. {$ELSE ASM_VERSION} //Pascal
  18762. function FileRead(Handle: THandle; var Buffer; Count: DWord): DWord;
  18763. begin
  18764. if not ReadFile(Handle, Buffer, Count, Result, nil) then
  18765. Result := 0;
  18766. end;
  18767. {$ENDIF ASM_VERSION}
  18768. //[END FileRead]
  18769. //[FUNCTION File2Str]
  18770. {$IFDEF ASM_VERSION}
  18771. function File2Str( Handle: THandle): String;
  18772. asm
  18773. PUSH EDX
  18774. TEST EAX, EAX
  18775. JZ @@exit // return ''
  18776. PUSH EBX
  18777. MOV EBX, EAX // EBX = Handle
  18778. XOR EDX, EDX
  18779. XOR ECX, ECX
  18780. INC ECX
  18781. CALL FileSeek
  18782. PUSH EAX // Pos
  18783. PUSH 0
  18784. PUSH EBX
  18785. CALL GetFileSize
  18786. POP EDX
  18787. SUB EAX, EDX // EAX = Size - Pos
  18788. JZ @@exitEBX
  18789. PUSH EAX
  18790. CALL System.@GetMem
  18791. XCHG EAX, EBX
  18792. MOV EDX, EBX
  18793. POP ECX
  18794. PUSH ECX
  18795. CALL FileRead
  18796. POP ECX
  18797. MOV EDX, EBX
  18798. POP EBX
  18799. POP EAX
  18800. PUSH EDX
  18801. {$IFDEF _D2}
  18802. CALL _LStrFromPCharLen
  18803. {$ELSE}
  18804. CALL System.@LStrFromPCharLen
  18805. {$ENDIF}
  18806. JMP @@freebuf
  18807. @@exitEBX:
  18808. POP EBX
  18809. @@exit:
  18810. XCHG EDX, EAX
  18811. POP EAX // @Result
  18812. PUSH EDX
  18813. CALL System.@LStrFromPChar
  18814. @@freebuf:
  18815. POP EAX
  18816. TEST EAX, EAX
  18817. JZ @@fin
  18818. CALL System.@FreeMem
  18819. @@fin:
  18820. end;
  18821. {$ELSE ASM_VERSION} //Pascal
  18822. function File2Str(Handle: THandle): String;
  18823. var Pos, Size: DWORD;
  18824. begin
  18825. Result := '';
  18826. if Handle = 0 then Exit;
  18827. Pos := FileSeek( Handle, 0, spCurrent );
  18828. Size := GetFileSize( Handle, nil );
  18829. SetString( Result, nil, Size - Pos + 1 );
  18830. FileRead( Handle, Result[ 1 ], Size - Pos );
  18831. Result[ Size - Pos + 1 ] := #0;
  18832. end;
  18833. {$ENDIF ASM_VERSION}
  18834. //[END File2Str]
  18835. //[FUNCTION FileWrite]
  18836. {$IFDEF ASM_VERSION}
  18837. function FileWrite( Handle: THandle; const Buffer; Count: DWord): DWord;
  18838. asm
  18839. PUSH EBP
  18840. PUSH EBP
  18841. MOV EBP, ESP
  18842. PUSH 0
  18843. PUSH EBP
  18844. PUSH ECX
  18845. PUSH EDX
  18846. PUSH EAX
  18847. CALL WriteFile
  18848. TEST EAX, EAX
  18849. POP EAX
  18850. JNZ @@exit
  18851. XOR EAX, EAX
  18852. @@exit:
  18853. POP EBP
  18854. end;
  18855. {$ELSE ASM_VERSION} //Pascal
  18856. function FileWrite(Handle: THandle; const Buffer; Count: DWord): DWord;
  18857. begin
  18858. if not WriteFile(Handle, Buffer, Count, Result, nil) then
  18859. Result := 0;
  18860. end;
  18861. {$ENDIF ASM_VERSION}
  18862. //[END FileWrite]
  18863. //[FUNCTION FileEOF]
  18864. {$IFDEF ASM_VERSION}
  18865. function FileEOF( Handle: THandle ) : Boolean;
  18866. asm
  18867. PUSH EAX
  18868. PUSH 0
  18869. PUSH EAX
  18870. CALL GetFileSize
  18871. XCHG EAX, [ESP]
  18872. MOV CL, spCurrent
  18873. XOR EDX, EDX
  18874. CALL FileSeek
  18875. POP EDX
  18876. CMP EAX, EDX
  18877. SETGE AL
  18878. end;
  18879. {$ELSE ASM_VERSION} //Pascal
  18880. function FileEOF( Handle: THandle ) : Boolean;
  18881. var Siz, Pos : DWord;
  18882. begin
  18883. Siz := GetFileSize( Handle, nil );
  18884. Pos := FileSeek( Handle, 0, spCurrent );
  18885. Result := Pos >= Siz;
  18886. end;
  18887. {$ENDIF ASM_VERSION}
  18888. //[END FileEOF]
  18889. //[FUNCTION FileFullPath]
  18890. {$IFDEF ASM_noVERSION}
  18891. function FileFullPath( const FileName: String ) : String;
  18892. const
  18893. BkSlash: String = '\';
  18894. szTShFileInfo = sizeof( TShFileInfo );
  18895. asm
  18896. PUSH EBX
  18897. PUSH ESI
  18898. MOV EBX, EDX
  18899. PUSH EAX
  18900. XCHG EAX, EDX
  18901. CALL System.@LStrClr
  18902. POP EDX
  18903. PUSH 0
  18904. MOV EAX, ESP
  18905. CALL System.@LStrAsg
  18906. MOV ESI, ESP
  18907. @@loo: CMP dword ptr [ESI], 0
  18908. JZ @@fin
  18909. MOV EAX, ESI
  18910. MOV EDX, [BkSlash]
  18911. PUSH 0
  18912. MOV ECX, ESP
  18913. CALL Parse
  18914. CMP dword ptr [EBX], 0
  18915. JE @@1
  18916. MOV EAX, EBX
  18917. MOV EDX, [BkSlash]
  18918. CALL System.@LStrCat
  18919. JMP @@2
  18920. @@1:
  18921. POP EAX
  18922. PUSH EAX
  18923. CALL System.@LStrLen
  18924. CMP EAX, 2
  18925. JNE @@2
  18926. POP EAX
  18927. PUSH EAX
  18928. CMP byte ptr [EAX+1], ':'
  18929. JNE @@2
  18930. MOV EAX, EBX
  18931. POP EDX
  18932. PUSH EDX
  18933. CALL System.@LStrAsg
  18934. JMP @@3
  18935. @@2:
  18936. PUSH 0
  18937. MOV EAX, ESP
  18938. MOV EDX, [EBX]
  18939. CALL System.@LStrAsg
  18940. MOV EAX, ESP
  18941. MOV EDX, [ESP+4]
  18942. CALL System.@LStrCat
  18943. POP EAX
  18944. PUSH EAX
  18945. SUB ESP, szTShFileInfo
  18946. MOV EDX, ESP
  18947. PUSH SHGFI_DISPLAYNAME
  18948. PUSH szTShFileInfo
  18949. PUSH EDX
  18950. PUSH 0
  18951. PUSH EAX
  18952. CALL ShGetFileInfo
  18953. LEA EDX, [ESP].TShFileInfo.szDisplayName
  18954. CMP byte ptr [EDX], 0
  18955. JE @@clr_stk
  18956. LEA EAX, [ESP+szTShFileInfo+4]
  18957. CALL System.@LStrFromPChar
  18958. @@clr_stk:
  18959. ADD ESP, szTShFileInfo
  18960. CALL RemoveStr
  18961. POP EDX
  18962. PUSH EDX
  18963. MOV EAX, EBX
  18964. CALL System.@LStrCat
  18965. @@3: CALL RemoveStr
  18966. JMP @@loo
  18967. @@fin: CALL RemoveStr
  18968. POP ESI
  18969. POP EBX
  18970. end;
  18971. {$ELSE ASM_VERSION} //Pascal
  18972. function FileFullPath( const FileName: String ) : String;
  18973. var SFI: TShFileInfo;
  18974. Src, S: String;
  18975. begin
  18976. Result := '';
  18977. Src := FileName;
  18978. while Src <> '' do
  18979. begin
  18980. S := Parse( Src, '\' );
  18981. if Result <> '' then
  18982. Result := Result + '\';
  18983. if (Result = '') and (Length( S ) = 2) and (S[ 2 ] = ':') then
  18984. Result := S
  18985. else
  18986. begin
  18987. ShGetFileInfo( PChar( Result + S ), 0, SFI, Sizeof( SFI ),
  18988. SHGFI_DISPLAYNAME );
  18989. if SFI.szDisplayName[ 0 ] <> #0 then
  18990. S := SFI.szDisplayName;
  18991. Result := Result + S;
  18992. end;
  18993. end;
  18994. if ExtractFileExt( Result ) = '' then
  18995. // case when flag 'Hide extensions for registered file types' is set on
  18996. // in the Explorer:
  18997. Result := Result + ExtractFileExt( FileName );
  18998. end;
  18999. {$ENDIF ASM_VERSION}
  19000. //[END FileFullPath]
  19001. //[function FileShortPath]
  19002. function FileShortPath( const FileName: String ): String;
  19003. var Buf: array[ 0..MAX_PATH ] of Char;
  19004. begin
  19005. GetShortPathName( PChar( FileName ), Buf, Sizeof( Buf ) );
  19006. Result := Buf;
  19007. end;
  19008. //[function FileIconSystemIdx]
  19009. function FileIconSystemIdx( const Path: String ): Integer;
  19010. var SFI: TShFileInfo;
  19011. begin
  19012. SFI.iIcon := 0; // Bartov
  19013. ShGetFileInfo( PChar( Path ), 0, SFI, sizeof( SFI ),
  19014. //-- Babenko Alexey: -----------------//
  19015. // SHGFI_ICON or //
  19016. //----------------------------------//
  19017. SHGFI_SMALLICON or SHGFI_SYSICONINDEX );
  19018. Result := SFI.iIcon;
  19019. end;
  19020. //[function FileIconSysIdxOffline]
  19021. function FileIconSysIdxOffline( const Path: String ): Integer;
  19022. var SFI: TShFileInfo;
  19023. begin
  19024. SFI.iIcon := 0; // Bartov
  19025. ShGetFileInfo( PChar( Path ), FILE_ATTRIBUTE_NORMAL, SFI, sizeof( SFI ),
  19026. //-- Babenko Alexey: -----------------//
  19027. //SHGFI_ATTRIBUTES or SHGFI_ICON or //
  19028. //----------------------------------//
  19029. SHGFI_SMALLICON or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES );
  19030. Result := SFI.iIcon;
  19031. end;
  19032. //[procedure LogFileOutput]
  19033. procedure LogFileOutput( const filepath, str: String );
  19034. var F: HFile;
  19035. begin
  19036. F := FileCreate( filepath, ofOpenWrite or ofOpenAlways );
  19037. if F = INVALID_HANDLE_VALUE then Exit;
  19038. FileSeek( F, 0, spEnd );
  19039. FileWrite( F, {$IFNDEF _D2} String {$ENDIF}
  19040. ( str + #13#10 )[ 1 ], Length( str ) + 2 );
  19041. FileClose( F );
  19042. end;
  19043. //[function StrSaveToFile]
  19044. function StrSaveToFile( const Filename, Str: String ): Boolean;
  19045. begin
  19046. Result := Mem2File( PChar( Filename ), PChar( Str ), Length( Str ) )
  19047. = Length( Str );
  19048. end;
  19049. //[function StrLoadFromFile]
  19050. function StrLoadFromFile( const Filename: String ): String;
  19051. var F: HFile;
  19052. begin
  19053. if StrEq( Filename, 'CON' ) then
  19054. Result := File2Str(GetStdHandle(STD_INPUT_HANDLE))
  19055. else
  19056. begin
  19057. Result := '';
  19058. F := FileCreate( Filename, ofOpenRead or ofOpenExisting or ofShareDenyWrite );
  19059. if F = INVALID_HANDLE_VALUE then Exit;
  19060. Result := File2Str( F );
  19061. FileClose( F ); {Dark Knight}
  19062. end;
  19063. end;
  19064. //[function Mem2File]
  19065. function Mem2File( Filename: PChar; Mem: Pointer; Len: Integer ): Integer;
  19066. var F: HFile;
  19067. begin
  19068. Result := 0;
  19069. F := FileCreate( Filename, ofOpenWrite or ofCreateAlways );
  19070. if F = INVALID_HANDLE_VALUE then Exit;
  19071. Result := FileWrite( F, Mem^, Len );
  19072. FileClose( F );
  19073. end;
  19074. //[function File2Mem]
  19075. function File2Mem( Filename: PChar; Mem: Pointer; MaxLen: Integer ): Integer;
  19076. var F: HFile;
  19077. begin
  19078. Result := 0;
  19079. F := FileCreate( Filename, ofOpenRead or ofOpenExisting or ofShareDenyWrite );
  19080. if F = INVALID_HANDLE_VALUE then Exit;
  19081. Result := FileRead( F, Mem^, MaxLen );
  19082. FileClose( F );
  19083. end;
  19084. //[FUNCTION DirectoryExists]
  19085. {$IFDEF ASM_VERSION}
  19086. function DirectoryExists( const Name: string): Boolean;
  19087. asm
  19088. //CALL System.@LStrToPChar // Name must not be ''
  19089. PUSH EAX
  19090. CALL GetFileAttributes
  19091. INC EAX
  19092. JZ @@exit
  19093. DEC EAX
  19094. {$IFDEF PARANOIA}
  19095. DB $24, FILE_ATTRIBUTE_DIRECTORY
  19096. {$ELSE}
  19097. AND AL, FILE_ATTRIBUTE_DIRECTORY
  19098. {$ENDIF}
  19099. SETNZ AL
  19100. @@exit:
  19101. end;
  19102. {$ELSE ASM_VERSION} //Pascal
  19103. function DirectoryExists(const Name: string): Boolean;
  19104. var
  19105. Code: Integer;
  19106. begin
  19107. Code := GetFileAttributes(PChar(Name));
  19108. Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
  19109. end;
  19110. {$ENDIF ASM_VERSION}
  19111. //[END DirectoryExists]
  19112. //[function CheckDirectoryContent]
  19113. function CheckDirectoryContent( const Name: String; SubDirsOnly: Boolean; const Mask: String ): Boolean;
  19114. var FD: TWin32FindData;
  19115. FH: THandle;
  19116. begin
  19117. if not DirectoryExists( Name ) then
  19118. Result := TRUE
  19119. else
  19120. begin
  19121. FH := Windows.FindFirstFile( PChar( IncludeTrailingPathDelimiter( Name )
  19122. + Mask ), FD );
  19123. if FH = INVALID_HANDLE_VALUE then
  19124. Result := TRUE
  19125. else
  19126. begin
  19127. Result := TRUE;
  19128. repeat
  19129. if not StrIn( FD.cFileName, ['.','..'] ) then
  19130. begin
  19131. if SubDirsOnly and LongBool(FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)
  19132. or not SubDirsOnly then
  19133. begin
  19134. Result := FALSE;
  19135. break;
  19136. end;
  19137. end;
  19138. until not Windows.FindNextFile( FH, FD );
  19139. Windows.FindClose( FH );
  19140. end;
  19141. end;
  19142. end;
  19143. //[function DirectoryEmpty]
  19144. function DirectoryEmpty(const Name: String): Boolean;
  19145. begin
  19146. Result := CheckDirectoryContent( Name, FALSE, '*.*' );
  19147. end;
  19148. {-}
  19149. //[function DirectorySize]
  19150. function DirectorySize( const Path: String ): I64;
  19151. var DirList: PDirList;
  19152. I: Integer;
  19153. begin
  19154. Result := MakeInt64( 0, 0 );
  19155. DirList := NewDirList( Path, '*.*', 0 );
  19156. for I := 0 to DirList.Count-1 do
  19157. begin
  19158. if LongBool( DirList.Items[ I ].dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY ) then
  19159. Result := Add64( Result, DirectorySize( DirList.Path + DirList.Names[ I ] ) )
  19160. else
  19161. Result := Add64( Result, MakeInt64( DirList.Items[ I ].nFileSizeLow,
  19162. DirList.Items[ I ].nFileSizeHigh ) );
  19163. end;
  19164. DirList.Free;
  19165. end;
  19166. {+}
  19167. //[function DirectoryHasSubdirs]
  19168. function DirectoryHasSubdirs( const Path: String ): Boolean;
  19169. begin
  19170. Result := not CheckDirectoryContent( Path, TRUE, '*.*' );
  19171. end;
  19172. //[function GetFileList]
  19173. function GetFileList(const dir: string): PStrList;
  19174. var
  19175. Srch: TWin32FindData;
  19176. flag: Integer;
  19177. succ: boolean;
  19178. begin
  19179. result := nil;
  19180. flag := FindFirstFile(PChar(dir), Srch);
  19181. //succ := flag <> 0; //---------------------------------------
  19182. succ := flag <> Integer(INVALID_HANDLE_VALUE); // M.V.Chirikov
  19183. while succ do begin
  19184. if (not (Srch.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY > 0))then begin
  19185. if Result = nil then begin
  19186. Result := NewStrList;
  19187. end;
  19188. Result.Add(Srch.cFileName);
  19189. end;
  19190. succ := FindNextFile(Flag, Srch);
  19191. end;
  19192. FindClose(Flag);
  19193. end;
  19194. //[function ExcludeTrailingChar]
  19195. function ExcludeTrailingChar( const S: String; C: Char ): String;
  19196. begin
  19197. Result := S;
  19198. if Result <> '' then
  19199. if Result[ Length( Result ) ] = C then
  19200. Delete( Result, Length( Result ), 1 );
  19201. end;
  19202. //[function IncludeTrailingChar]
  19203. function IncludeTrailingChar( const S: String; C: Char ): String;
  19204. begin
  19205. Result := S;
  19206. if (Result = '') or (Result[ Length( Result ) ] <> C) then
  19207. Result := Result + C;
  19208. end;
  19209. //---------------------------------------------------------
  19210. // Following functions/procedures are created by Edward Aretino:
  19211. // IncludeTrailingPathDelimiter, ExcludeTrailingPathDelimiter,
  19212. // ForceDirectories, CreateDir, ChangeFileExt
  19213. //---------------------------------------------------------
  19214. //[function IncludeTrailingPathDelimiter]
  19215. function IncludeTrailingPathDelimiter(const S: string): string;
  19216. begin
  19217. {if CopyTail(S, 1) <> '\' then
  19218. Result := S + '\'
  19219. else
  19220. Result := S;}
  19221. Result := IncludeTrailingChar( S, '\' );
  19222. end;
  19223. //[function ExcludeTrailingPathDelimiter]
  19224. function ExcludeTrailingPathDelimiter(const S: string): string;
  19225. begin
  19226. {Result := S;
  19227. if Length(Result) = 0 then Exit;
  19228. if (CopyTail(Result, 1) = '\') then
  19229. DeleteTail(Result, 1);}
  19230. Result := ExcludeTrailingChar( S, '\' );
  19231. end;
  19232. //[function ForceDirectories]
  19233. function ForceDirectories(Dir: string): Boolean;
  19234. begin
  19235. Result := Length(Dir) > 0; {Centronix}
  19236. If not Result then Exit;
  19237. Dir := ExcludeTrailingPathDelimiter(Dir);
  19238. If (Length(Dir) < 3) or DirectoryExists(Dir) or
  19239. (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
  19240. Result := ForceDirectories(ExtractFilePath(Dir)) and CreateDir(Dir);
  19241. end;
  19242. //[function CreateDir]
  19243. function CreateDir(const Dir: string): Boolean;
  19244. begin
  19245. Result := Windows.CreateDirectory(PChar(Dir), nil);
  19246. end;
  19247. //[function ChangeFileExt]
  19248. function ChangeFileExt(FileName: String; const Extension: string): string;
  19249. var
  19250. FileExt: String;
  19251. begin
  19252. FileExt := ExtractFileExt(FileName);
  19253. DeleteTail(FileName, Length(FileExt));
  19254. Result := FileName+ Extension;
  19255. end;
  19256. {$IFDEF ASM_VERSION}
  19257. {$IFNDEF _D2}
  19258. {$DEFINE ASM_LStrFromPCharLen}
  19259. {$ENDIF}
  19260. {$ENDIF ASM_VERSION}
  19261. {$IFDEF ASM_LStrFromPCharLen}
  19262. {$DEFINE ASM_DIRDelimiters}
  19263. {$ENDIF}
  19264. {$IFDEF ASM_VERSION}
  19265. {$DEFINE ASM_DIRDelimiters}
  19266. {$ENDIF ASM_VERSION}
  19267. {$IFDEF ASM_DIRDelimiters}
  19268. const
  19269. DirDelimiters: PChar = ':\';
  19270. {$ENDIF}
  19271. //[FUNCTION ExtractFileName]
  19272. {$IFDEF ASM_VERSION}
  19273. function ExtractFileName( const Path : String ) : String;
  19274. asm
  19275. PUSH EDX
  19276. PUSH EAX
  19277. MOV EDX, [DirDelimiters]
  19278. CALL __DelimiterLast
  19279. POP EDX
  19280. CMP byte ptr [EAX], 0
  19281. JZ @@1
  19282. XCHG EDX, EAX
  19283. INC EDX
  19284. @@1: POP EAX
  19285. CALL System.@LStrFromPChar
  19286. end;
  19287. {$ELSE ASM_VERSION} //Pascal
  19288. function ExtractFileName( const Path : String ) : String;
  19289. var P: PChar;
  19290. begin
  19291. P := __DelimiterLast( PChar( Path ), ':\' );
  19292. if P^ = #0 then
  19293. Result := Path
  19294. else
  19295. Result := P + 1;
  19296. end;
  19297. {$ENDIF ASM_VERSION}
  19298. //[END ExtractFileName]
  19299. //[FUNCTION ExtractFilePath]
  19300. {$IFDEF ASM_LStrFromPCharLen} // LStrFromPCharLen - there are no in D2
  19301. function ExtractFilePath( const Path : String ) : String;
  19302. asm
  19303. PUSH EDX
  19304. MOV EDX, [DirDelimiters]
  19305. CALL EAX2PChar
  19306. PUSH EAX
  19307. CALL __DelimiterLast
  19308. XCHG EDX, EAX
  19309. XOR ECX, ECX
  19310. POP EAX
  19311. CMP byte ptr [EDX], CL
  19312. JZ @@ret_0
  19313. SUB EDX, EAX
  19314. INC EDX
  19315. XCHG EDX, EAX
  19316. XCHG ECX, EAX
  19317. @@ret_0:
  19318. POP EAX
  19319. CALL System.@LStrFromPCharLen
  19320. end;
  19321. {$ELSE} //Pascal
  19322. function ExtractFilePath( const Path : String ) : String;
  19323. //var I : Integer;
  19324. var P, P0: PChar;
  19325. begin
  19326. P0 := PChar( Path );
  19327. P := __DelimiterLast( P0, ':\' );
  19328. if P^ = #0 then
  19329. Result := ''
  19330. else
  19331. Result := Copy( Path, 1, P - P0 + 1 );
  19332. end;
  19333. {$ENDIF}
  19334. //[function ExtractFileNameWOext]
  19335. function ExtractFileNameWOext( const Path : String ) : String;
  19336. begin
  19337. Result := ExtractFileName( Path );
  19338. Result := Copy( Result, 1, Length( Result ) - Length( ExtractFileExt( Result ) ) );
  19339. end;
  19340. {$IFDEF ASM_VERSION}
  19341. const
  19342. ExtDelimeters: PChar = '.';
  19343. //[function ExtractFileExt]
  19344. function ExtractFileExt( const Path : String ) : String;
  19345. asm
  19346. PUSH EDX
  19347. MOV EDX, [ExtDelimeters]
  19348. CALL EAX2PChar
  19349. CALL __DelimiterLast
  19350. @@1: XCHG EDX, EAX
  19351. POP EAX
  19352. CALL System.@LStrFromPChar
  19353. end;
  19354. {$ELSE ASM_VERSION} //Pascal
  19355. function ExtractFileExt( const Path : String ) : String;
  19356. var P: PChar;
  19357. begin
  19358. P := __DelimiterLast( PChar( Path ), '.' );
  19359. Result := P;
  19360. end;
  19361. {$ENDIF ASM_VERSION}
  19362. //[END ExtractFilePath]
  19363. //[function ReplaceFileExt]
  19364. function ReplaceFileExt( const Path, NewExt: String ): String;
  19365. begin
  19366. Result := ExtractFilePath( Path ) +
  19367. ExtractFileNameWOext( ExtractFileName( Path ) ) +
  19368. NewExt;
  19369. end;
  19370. //[function ExtractShortPathName]
  19371. function ExtractShortPathName( const Path: String ): String;
  19372. var
  19373. Buffer: array[0..MAX_PATH - 1] of Char;
  19374. begin
  19375. SetString(Result, Buffer,
  19376. GetShortPathName(PChar(Path), Buffer, SizeOf(Buffer)));
  19377. end;
  19378. //[function FilePathShortened]
  19379. function FilePathShortened( const Path: String; MaxLen: Integer ): String;
  19380. begin
  19381. Result := FilePathShortenPixels( Path, 0, MaxLen );
  19382. end;
  19383. //[function PixelsLength]
  19384. function PixelsLength( DC: HDC; const Text: String ): Integer;
  19385. var Sz: TSize;
  19386. begin
  19387. if DC = 0 then
  19388. Result := Length( Text )
  19389. else
  19390. begin
  19391. Windows.GetTextExtentPoint32( DC, PChar( Text ), Length( Text ), Sz );
  19392. Result := Sz.cx;
  19393. end;
  19394. end;
  19395. //[function FilePathShortenPixels]
  19396. function FilePathShortenPixels( const Path: String; DC: HDC; MaxPixels: Integer ): String;
  19397. var L0, L1: Integer;
  19398. Prev: String;
  19399. begin
  19400. Result := Path;
  19401. L0 := PixelsLength( DC, Result );
  19402. while L0 > MaxPixels do
  19403. begin
  19404. Prev := Result;
  19405. L1 := pos( '\...\', Result );
  19406. if L1 <= 0 then
  19407. Result := ExcludeTrailingPathDelimiter( ExtractFilePath( Result ) )
  19408. else
  19409. Result := Copy( Result, 1, L1 - 1 );
  19410. if Result <> '' then
  19411. Result := IncludeTrailingPathDelimiter( ExtractFilePath( Result ) ) + '...\' + ExtractFileName( Path );
  19412. if (Result = '') or (Result = Prev) then
  19413. begin
  19414. L1 := Length( ExtractFilePath( Result ) );
  19415. while (PixelsLength( DC, Result ) > MaxPixels) and (L1 > 1) do
  19416. begin
  19417. Dec( L1 );
  19418. Result := Copy( Result, 1, L1 ) + '...\' + ExtractFileName( Result );
  19419. end;
  19420. if PixelsLength( DC, Result ) > MaxPixels then
  19421. begin
  19422. L1 := MaxPixels + 1;
  19423. while ((MaxPixels > 0) and (L1 > 1) or (MaxPixels = 0) and (L1 > 0)) and
  19424. (PixelsLength( DC, Result ) > MaxPixels) do
  19425. begin
  19426. Dec( L1 );
  19427. Result := Copy( ExtractFileName( Path ), 1, L1 ) + '...';
  19428. end;
  19429. end;
  19430. break;
  19431. end;
  19432. L0 := PixelsLength( DC, Result );
  19433. end;
  19434. end;
  19435. //[procedure CutFirstDirectory]
  19436. procedure CutFirstDirectory(var S: String);
  19437. var
  19438. Root: Boolean;
  19439. P: Integer;
  19440. begin
  19441. if S = '\' then
  19442. S := ''
  19443. else
  19444. begin
  19445. if S[1] = '\' then
  19446. begin
  19447. Root := True;
  19448. Delete(S, 1, 1);
  19449. end
  19450. else
  19451. Root := False;
  19452. if S[1] = '.' then
  19453. Delete(S, 1, 4);
  19454. P := pos('\',S);
  19455. if P <> 0 then
  19456. begin
  19457. Delete(S, 1, P);
  19458. S := '...\' + S;
  19459. end
  19460. else
  19461. S := '';
  19462. if Root then
  19463. S := '\' + S;
  19464. end;
  19465. end;
  19466. //[function MinimizeName]
  19467. function MinimizeName( const Path: String; DC: HDC; MaxPixels: Integer ): String;
  19468. var
  19469. Drive, Dir, Name: String;
  19470. begin
  19471. Result := Path;
  19472. Dir := ExtractFilePath(Result);
  19473. Name := ExtractFileName(Result);
  19474. if (Length(Dir) >= 2) and (Dir[2] = ':') then
  19475. begin
  19476. Drive := Copy(Dir, 1, 2);
  19477. Delete(Dir, 1, 2);
  19478. end
  19479. else
  19480. Drive := '';
  19481. while ((Dir <> '') or (Drive <> '')) and (PixelsLength(DC, Result) > MaxPixels) do
  19482. begin
  19483. if Dir = '\...\' then
  19484. begin
  19485. Drive := '';
  19486. Dir := '...\';
  19487. end
  19488. else if Dir = '' then
  19489. Drive := ''
  19490. else
  19491. CutFirstDirectory(Dir);
  19492. Result := Drive + Dir + Name;
  19493. end;
  19494. end;
  19495. //[FUNCTION FileSize]
  19496. {$IFDEF ASM_VERSION}
  19497. function FileSize( const Path : String ) : Integer;
  19498. const size_TWin32FindData = sizeof( TWin32FindData );
  19499. asm
  19500. ADD ESP, - size_TWin32FindData
  19501. PUSH ESP
  19502. //CALL System.@LStrToPChar // Path must not be ''
  19503. PUSH EAX
  19504. CALL FindFirstFile
  19505. INC EAX
  19506. JZ @@exit
  19507. DEC EAX
  19508. PUSH EAX
  19509. CALL FindClose
  19510. MOV EAX, [ESP].TWin32FindData.nFileSizeLow
  19511. @@exit:
  19512. ADD ESP, size_TWin32FindData
  19513. end;
  19514. {$ELSE ASM_VERSION} //Pascal
  19515. function FileSize( const Path : String ) : Integer;
  19516. var FD : TWin32FindData;
  19517. FH : THandle;
  19518. begin
  19519. FH := FindFirstFile( PChar( Path ), FD );
  19520. Result := 0;
  19521. if FH = INVALID_HANDLE_VALUE then exit;
  19522. Result := FD.nFileSizeLow;
  19523. if ((FD.nFileSizeLow and $80000000) <> 0) or
  19524. (FD.nFileSizeHigh <> 0) then Result := -1;
  19525. FindClose( FH );
  19526. end;
  19527. {$ENDIF ASM_VERSION}
  19528. //[END FileSize]
  19529. //*
  19530. //[function FileTimeCompare]
  19531. function FileTimeCompare( const FT1, FT2 : TFileTime ) : Integer;
  19532. var ST1, ST2 : TSystemTime;
  19533. begin
  19534. FileTimeToSystemTime( FT1, ST1 );
  19535. FileTimeToSystemTime( FT2, ST2 );
  19536. Result := CompareSystemTime( ST1, ST2 );
  19537. end;
  19538. //[function GetSystemDir]
  19539. function GetSystemDir: String;
  19540. var Buf: array[ 0..MAX_PATH ] of Char;
  19541. begin
  19542. GetSystemDirectory( @ Buf[ 0 ], MAX_PATH + 1 );
  19543. Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
  19544. end;
  19545. //*
  19546. //[function GetWindowsDir]
  19547. function GetWindowsDir : string;
  19548. var Buf : array[ 0..MAX_PATH ] of Char;
  19549. begin
  19550. GetWindowsDirectory( @Buf[ 0 ], MAX_PATH + 1 );
  19551. Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
  19552. end;
  19553. //[function GetWorkDir]
  19554. function GetWorkDir : string;
  19555. var Buf: array[ 0..MAX_PATH ] of Char;
  19556. begin
  19557. GetCurrentDirectory( MAX_PATH + 1, @ Buf[ 0 ] );
  19558. Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
  19559. end;
  19560. //*
  19561. //[function GetTempDir]
  19562. function GetTempDir : string;
  19563. var Buf : array[ 0..MAX_PATH ] of Char;
  19564. begin
  19565. Windows.GetTempPath( MAX_PATH + 1, @Buf[ 0 ] );
  19566. Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
  19567. end;
  19568. //[function CreateTempFile]
  19569. function CreateTempFile( const DirPath, Prefix: String ): String;
  19570. var Buf: array[ 0..MAX_PATH ] of Char;
  19571. begin
  19572. GetTempFileName( PChar( DirPath ), PChar( Prefix ), 0, Buf );
  19573. Result := Buf;
  19574. end;
  19575. //[function GetFileListStr]
  19576. function GetFileListStr(FPath{e.g.'c:\tmp\'}, FMask{e.g.'*.*'}: string): string;
  19577. {* List of files in string, separating each path from others with semicolon (';').
  19578. E.g.: 'c:\tmp\unit1.dcu;c:\tmp\unit1.~pa' (for use with DeleteFile2Recycle())}
  19579. var
  19580. Srch: TWin32FindData;
  19581. flag: Integer;
  19582. succ: boolean;
  19583. dir:string;
  19584. begin
  19585. result := '';
  19586. if (FPath<>'') and (FPath[length(FPath)]<>'\') then FPath:=FPath+'\';
  19587. if (FMask<>'') and (FMask[1]='\') then FMask:=CopyEnd(FMask,2);
  19588. dir:=FPath+FMask;
  19589. flag := FindFirstFile(PChar(dir), Srch);
  19590. succ := flag <> Integer(INVALID_HANDLE_VALUE);
  19591. while succ do begin
  19592. if (not (Srch.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY > 0))then begin
  19593. if Result<>''then Result:=Result+';';
  19594. Result:=Result+FPath+Srch.cFileName;
  19595. end;
  19596. succ := FindNextFile(Flag, Srch);
  19597. end;
  19598. FindClose(Flag);
  19599. end;
  19600. //[function DeleteFiles]
  19601. function DeleteFiles( const DirPath: String ): Boolean;
  19602. var Files, Name: String;
  19603. begin
  19604. Files := GetFileListStr( ExtractFilePath( DirPath ), ExtractFileName( DirPath ) );
  19605. Result := TRUE;
  19606. while Files <> '' do
  19607. begin
  19608. Name := Parse( Files, ';' );
  19609. Result := Result and DeleteFile( PChar( Name ) );
  19610. end;
  19611. end;
  19612. //*
  19613. //[function DeleteFile2Recycle]
  19614. function DeleteFile2Recycle( const Filename : String ) : Boolean;
  19615. var FOS : TSHFileOpStruct;
  19616. Buf : PChar;
  19617. L : Integer;
  19618. begin
  19619. L := Length( Filename );
  19620. GetMem( Buf, L + 2 );
  19621. StrCopy( Buf, PChar( Filename ) );
  19622. Buf[ L + 1 ] := #0;
  19623. for L := L downto 0 do
  19624. if Buf[ L ] = ';' then Buf[ L ] := #0;
  19625. FillChar( FOS, Sizeof( FOS ), 0 );
  19626. if Applet <> nil then
  19627. FOS.Wnd := Applet.Handle;
  19628. FOS.wFunc := FO_DELETE;
  19629. FOS.pFrom := Buf;
  19630. FOS.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION;
  19631. FOS.fAnyOperationsAborted := True;
  19632. FOS.lpszProgressTitle := PChar( 'Delete ' + Filename + ' to Recycle bin' );
  19633. Result := SHFileOperation( FOS ) = 0;
  19634. if Result then
  19635. Result := not FOS.fAnyOperationsAborted;
  19636. FreeMem( Buf );
  19637. end;
  19638. //[function CopyMoveFiles]
  19639. function CopyMoveFiles( const FromList, ToList: String; Move: Boolean ): Boolean;
  19640. var FOS : TSHFileOpStruct;
  19641. Buf : PChar;
  19642. L : Integer;
  19643. begin
  19644. L := Length( FromList );
  19645. GetMem( Buf, L + 2 );
  19646. StrCopy( Buf, PChar( FromList ) );
  19647. Buf[ L + 1 ] := #0;
  19648. for L := L downto 0 do
  19649. if Buf[ L ] = ';' then Buf[ L ] := #0;
  19650. FillChar( FOS, Sizeof( FOS ), 0 );
  19651. if Applet <> nil then
  19652. FOS.Wnd := Applet.Handle;
  19653. if Move then
  19654. begin
  19655. FOS.wFunc := FO_MOVE;
  19656. FOS.lpszProgressTitle := PChar( 'Move files' );
  19657. end
  19658. else
  19659. begin
  19660. FOS.wFunc := FO_COPY;
  19661. FOS.lpszProgressTitle := PChar( 'Copy files' );
  19662. end;
  19663. FOS.pFrom := Buf;
  19664. FOS.pTo := PChar( ToList + #0 );
  19665. FOS.fFlags := FOF_ALLOWUNDO;
  19666. FOS.fAnyOperationsAborted := True;
  19667. Result := SHFileOperation( FOS ) = 0;
  19668. if Result then
  19669. Result := not FOS.fAnyOperationsAborted;
  19670. FreeMem( Buf );
  19671. end;
  19672. {-}
  19673. //[function DiskFreeSpace]
  19674. function DiskFreeSpace( const Path: String ): I64;
  19675. type TGetDFSEx = function( Path: PChar; CallerFreeBytes, TotalBytes, FreeBytes: Pointer )
  19676. : Bool; stdcall;
  19677. var GetDFSEx: TGetDFSEx;
  19678. Kern32: THandle;
  19679. V: TOSVersionInfo;
  19680. Ex: Boolean;
  19681. SpC, BpS, NFC, TNC: DWORD;
  19682. FBA, TNB: I64;
  19683. begin
  19684. GetDFSEx := nil;
  19685. V.dwOSVersionInfoSize := Sizeof( V );
  19686. GetVersionEx( V );
  19687. Ex := FALSE;
  19688. if V.dwPlatformId = VER_PLATFORM_WIN32_NT then
  19689. begin
  19690. Ex := V.dwMajorVersion >= 4;
  19691. end
  19692. else
  19693. if V.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS then
  19694. begin
  19695. Ex := V.dwMajorVersion > 4;
  19696. if not Ex then
  19697. if V.dwMajorVersion = 4 then
  19698. begin
  19699. Ex := V.dwMinorVersion > 0;
  19700. if not Ex then
  19701. Ex := LoWord( V.dwBuildNumber ) >= $1111;
  19702. end;
  19703. end;
  19704. if Ex then
  19705. begin
  19706. Kern32 := GetModuleHandle( 'kernel32.dll' );
  19707. GetDFSEx := GetProcAddress( Kern32, 'GetDiskFreeSpaceExA' );
  19708. end;
  19709. if Assigned( GetDFSEx ) then
  19710. GetDFSEx( PChar( Path ), @ FBA, @ TNB, @Result )
  19711. else
  19712. begin
  19713. GetDiskFreeSpace( PChar( Path ), SpC, BpS, NFC, TNC );
  19714. Result := Mul64i( MakeInt64( SpC * BpS, 0 ), NFC );
  19715. end;
  19716. end;
  19717. {+}
  19718. //*
  19719. //[function GetUniqueFilename]
  19720. function GetUniqueFilename( PathName: string ) : String;
  19721. var Path, Nam, Ext : String;
  19722. I, J, K : Integer;
  19723. begin
  19724. Result := PathName;
  19725. Path := ExtractFilePath( PathName );
  19726. if not DirectoryExists( Path ) then Exit;
  19727. Nam := ExtractFileNameWOext( PathName );
  19728. if Nam = '' then
  19729. begin
  19730. if Path[ Length( Path ) ] = '\' then
  19731. Path := Copy( Path, 1, Length( Path ) - 1 );
  19732. PathName := Path;
  19733. Result := Path;
  19734. end;
  19735. Nam := ExtractFileNameWOext( PathName );
  19736. Ext := ExtractFileExt( PathName );
  19737. I := Length( Nam );
  19738. for J := I downto 1 do
  19739. if not (Nam[ J ] in [ '0'..'9' ]) then
  19740. begin
  19741. I := J;
  19742. break;
  19743. end;
  19744. K := Str2Int( CopyEnd( Nam, I + 1 ) );
  19745. while FileExists( Result ) do
  19746. begin
  19747. Inc( K );
  19748. Result := Path + Copy( Nam, 1, I ) + Int2Str( K ) + Ext;
  19749. end;
  19750. end;
  19751. //[FUNCTION GetStartDir]
  19752. {$IFDEF ASM_VERSION}
  19753. function GetStartDir : String;
  19754. asm
  19755. PUSH EBX
  19756. MOV EBX, EAX
  19757. XOR EAX, EAX
  19758. MOV AH, 2
  19759. SUB ESP, EAX
  19760. MOV EDX, ESP
  19761. PUSH EAX
  19762. PUSH EDX
  19763. PUSH 0
  19764. CALL GetModuleFileName
  19765. LEA EDX, [ESP + EAX]
  19766. @@1: DEC EDX
  19767. CMP byte ptr [EDX], '\'
  19768. JNZ @@1
  19769. INC EDX
  19770. MOV byte ptr [EDX], 0
  19771. MOV EAX, EBX
  19772. MOV EDX, ESP
  19773. CALL System.@LStrFromPChar
  19774. ADD ESP, 200h
  19775. POP EBX
  19776. end;
  19777. {$ELSE ASM_VERSION} //Pascal
  19778. function GetStartDir : String;
  19779. var Buffer:array[0..260] of Char;
  19780. I : Integer;
  19781. begin
  19782. I := GetModuleFileName( 0, Buffer, Sizeof( Buffer ) );
  19783. for I := I downto 0 do
  19784. if Buffer[ I ] = '\' then
  19785. begin
  19786. Buffer[ I + 1 ] := #0;
  19787. break;
  19788. end;
  19789. Result := Buffer;
  19790. end;
  19791. {$ENDIF ASM_VERSION}
  19792. //[END GetStartDir]
  19793. //[END FILES]
  19794. { TDirList }
  19795. //[function NewDirList]
  19796. function NewDirList( const DirPath, Filter: String; Attr: DWORD ): PDirList;
  19797. begin
  19798. {-}
  19799. New( Result, Create );
  19800. {+}{++}(*Result := PDirList.Create;*){--}
  19801. Result.ScanDirectory( DirPath, Filter, Attr );
  19802. end;
  19803. //[END NewDirList]
  19804. //[function NewDirListEx]
  19805. function NewDirListEx( const DirPath, Filters: String; Attr: DWORD ): PDirList;
  19806. begin
  19807. {-}
  19808. New( Result, Create );
  19809. {+}{++}(*Result := PDirList.Create;*){--}
  19810. Result.ScanDirectoryEx( DirPath, Filters, Attr );
  19811. end;
  19812. //[END NewDirListEx]
  19813. {$IFDEF ASM_VERSION}
  19814. //[procedure TDirList.Clear]
  19815. procedure TDirList.Clear;
  19816. asm
  19817. XOR ECX, ECX
  19818. XCHG ECX, [EAX].fList
  19819. JECXZ @@exit
  19820. XCHG EAX, ECX
  19821. CALL TList.Release
  19822. @@exit:
  19823. end;
  19824. {$ELSE ASM_VERSION} //Pascal
  19825. procedure TDirList.Clear;
  19826. begin
  19827. if FList <> nil then
  19828. FList.Release;
  19829. FList := nil;
  19830. end;
  19831. {$ENDIF ASM_VERSION}
  19832. {$IFDEF ASM_VERSION}
  19833. //[destructor TDirList.Destroy]
  19834. destructor TDirList.Destroy;
  19835. asm
  19836. PUSH EBX
  19837. MOV EBX, EAX
  19838. CALL Clear
  19839. LEA EAX, [EBX].FPath
  19840. CALL System.@LStrClr
  19841. XCHG EAX, EBX
  19842. CALL TObj.Destroy
  19843. POP EBX
  19844. end;
  19845. {$ELSE ASM_VERSION} //Pascal
  19846. destructor TDirList.Destroy;
  19847. begin
  19848. Clear;
  19849. FPath := '';
  19850. inherited;
  19851. end;
  19852. {$ENDIF ASM_VERSION}
  19853. //[FUNCTION FindFilter]
  19854. {$IFDEF ASM_VERSION}
  19855. function FindFilter( const Filter: String): String;
  19856. asm
  19857. XCHG EAX, EDX
  19858. PUSH EAX
  19859. CALL System.@LStrAsg
  19860. POP EAX
  19861. CMP dword ptr [EAX], 0
  19862. JNE @@exit
  19863. LEA EDX, @@mask_all
  19864. JE System.@LStrFromPChar
  19865. @@mask_all: DB '*.*',0
  19866. @@exit:
  19867. end;
  19868. {$ELSE ASM_VERSION} //Pascal
  19869. function FindFilter(const Filter: String): String;
  19870. begin
  19871. Result := Filter;
  19872. if Result = '' then Result := '*.*';
  19873. end;
  19874. {$ENDIF ASM_VERSION}
  19875. //[END FindFilter]
  19876. //+
  19877. //[function TDirList.Get]
  19878. function TDirList.Get(Idx: Integer): PWin32FindData;
  19879. begin
  19880. Result := FList.fItems[ Idx ];
  19881. end;
  19882. {$IFDEF ASM_VERSION}
  19883. //[function TDirList.GetCount]
  19884. function TDirList.GetCount: Integer;
  19885. asm
  19886. MOV EAX, [EAX].fList
  19887. TEST EAX, EAX
  19888. {$IFDEF USE_CMOV}
  19889. CMOVNZ EAX, [EAX].TList.fCount
  19890. {$ELSE}
  19891. JZ @@exit
  19892. MOV EAX, [EAX].TList.fCount
  19893. @@exit: {$ENDIF}
  19894. end;
  19895. {$ELSE ASM_VERSION} //Pascal
  19896. function TDirList.GetCount: Integer;
  19897. begin
  19898. Result := 0;
  19899. if FList = nil then Exit;
  19900. Result := FList.Count;
  19901. end;
  19902. {$ENDIF ASM_VERSION}
  19903. {$IFDEF ASM_VERSION}
  19904. //[function TDirList.GetNames]
  19905. function TDirList.GetNames(Idx: Integer): string;
  19906. asm
  19907. MOV EAX, [EAX].fList
  19908. MOV EAX, [EAX].TList.fItems
  19909. MOV EDX, [EAX + EDX*4]
  19910. //*/////////////////////////////////////////////////////
  19911. // ADD EDX, TWin32FindData.cFileName
  19912. //*/////////////////////////////////////////////////////
  19913. ADD EDX, offset TWin32FindData.cFileName //
  19914. //*/////////////////////////////////////////////////////
  19915. MOV EAX, ECX
  19916. CALL System.@LStrFromPChar
  19917. end;
  19918. {$ELSE ASM_VERSION} //Pascal
  19919. function TDirList.GetNames(Idx: Integer): string;
  19920. begin
  19921. Result := PChar(@PWin32FindData(fList.fItems[ Idx ]).cFileName[0]);
  19922. //Result := PChar(@Items[Idx].cFileName[0]);
  19923. end;
  19924. {$ENDIF ASM_VERSION}
  19925. //[function TDirList.GetIsDirectory]
  19926. function TDirList.GetIsDirectory(Idx: Integer): Boolean;
  19927. begin
  19928. Result := LongBool( Items[ Idx ].dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY );
  19929. end;
  19930. {$IFDEF ASM_noVERSION}
  19931. //[function TDirList.SatisfyFilter]
  19932. function TDirList.SatisfyFilter(FileName: PChar; FileAttr,
  19933. FindAttr: DWord): Boolean;
  19934. asm
  19935. PUSH EBX
  19936. PUSH ESI
  19937. PUSH EDI
  19938. XCHG EBX, EAX // EBX = @ Self
  19939. MOV EAX, [FindAttr]
  19940. MOV EDI, EDX // EDI = FileName
  19941. MOV EDX, EAX
  19942. AND EDX, ECX
  19943. CMP EDX, EAX
  19944. JE @@1
  19945. TEST AL, FILE_ATTRIBUTE_NORMAL
  19946. JZ @@ret_false
  19947. @@1:
  19948. CMP word ptr [EDI], '.'
  19949. JE @@1_1
  19950. CMP word ptr [EDI], '..'
  19951. JNE @@1_1
  19952. CMP byte ptr [EDI+2], 0
  19953. JNE @@1_1
  19954. @@1_0:
  19955. MOV ECX, [FindAttr]
  19956. TEST CL, FILE_ATTRIBUTE_NORMAL
  19957. JZ @@1_1
  19958. CMP ECX, FILE_ATTRIBUTE_NORMAL
  19959. JE @@1_1
  19960. TEST AL, FILE_ATTRIBUTE_DIRECTORY
  19961. JZ @@1_1
  19962. TEST CL, FILE_ATTRIBUTE_DIRECTORY
  19963. JNZ @@ret_true
  19964. @@1_1:
  19965. MOV ECX, [EBX].fFilters
  19966. JECXZ @@ret_false //?
  19967. MOV ESI, [ECX].TStrList.fList
  19968. MOV ESI, [ESI].TList.fItems
  19969. MOV ECX, [ECX].TStrList.fCount
  19970. JECXZ @@ret_false
  19971. @@2:
  19972. LODSD
  19973. TEST EAX, EAX
  19974. JZ @@nx_filter
  19975. PUSHAD
  19976. MOV EDX, [EAX]
  19977. CMP DX, $002E
  19978. JE @@F_d_dd
  19979. AND EDX, $FFFFFF
  19980. CMP EDX, $002E2E
  19981. JE @@F_d_dd
  19982. MOV EDX, [EDI]
  19983. CMP DX, $002E
  19984. JE @@4
  19985. AND EDX, $FFFFFF
  19986. CMP EDX, $002E2E
  19987. JE @@4
  19988. JMP @@chk_anti
  19989. @@F_d_dd:
  19990. MOV EDX, EDI
  19991. PUSH EAX
  19992. CALL StrComp
  19993. TEST EAX, EAX
  19994. POP EAX
  19995. JZ @@popad_ret_true
  19996. @@chk_anti:
  19997. XCHG EDX, EAX // EDX = filter[ i ]
  19998. MOV EAX, EDI // EAX = FileName
  19999. CMP byte ptr [EDX], '^'
  20000. JNE @@3
  20001. INC EDX
  20002. CALL _2StrSatisfy
  20003. TEST AL, AL
  20004. JZ @@4
  20005. POPAD
  20006. JMP @@ret_false
  20007. @@3: CALL _2StrSatisfy
  20008. TEST AL, AL
  20009. JZ @@4
  20010. @@popad_ret_true:
  20011. POPAD
  20012. @@ret_true:
  20013. MOV AL, 1
  20014. JMP @@exit
  20015. @@4: POPAD
  20016. @@nx_filter:
  20017. LOOP @@2
  20018. @@ret_false:
  20019. XOR EAX, EAX
  20020. @@exit:
  20021. POP EDI
  20022. POP ESI
  20023. POP EBX
  20024. end;
  20025. {$ELSE ASM_VERSION} //Pascal
  20026. function TDirList.SatisfyFilter(FileName: PChar; FileAttr,
  20027. FindAttr: DWord): Boolean;
  20028. {$IFDEF F_P}
  20029. const Dot: String = '.';
  20030. {$ENDIF F_P}
  20031. var I: Integer;
  20032. F: PChar;
  20033. HasOnlyNegFilters: Boolean;
  20034. begin
  20035. Result := (((FileAttr and FindAttr) = FindAttr) or
  20036. LongBool(FindAttr and FILE_ATTRIBUTE_NORMAL));
  20037. if not Result then Exit;
  20038. if (FileName <> {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}) and
  20039. (FileName <> '..') then
  20040. if LongBool( FindAttr and FILE_ATTRIBUTE_NORMAL ) and
  20041. (FindAttr <> FILE_ATTRIBUTE_NORMAL) then
  20042. if LongBool( FindAttr and FILE_ATTRIBUTE_DIRECTORY ) and
  20043. LongBool( FileAttr and FILE_ATTRIBUTE_DIRECTORY ) then Exit;
  20044. HasOnlyNegFilters := TRUE;
  20045. for I := 0 to fFilters.fCount - 1 do
  20046. begin
  20047. F := PChar(fFilters.fList.fItems[ I ]);
  20048. if F = '' then continue;
  20049. if (F = {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}) or (F = '..') then
  20050. begin
  20051. if FileName = F then
  20052. Exit;
  20053. end
  20054. else
  20055. if (Filename = {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}) or (FileName = '..') then
  20056. begin
  20057. //Result := FALSE;
  20058. continue;
  20059. end;
  20060. if F[ 0 ] = '^' then
  20061. begin
  20062. if StrSatisfy( FileName, PChar(@F[ 1 ]) ) then
  20063. begin
  20064. Result := False;
  20065. Exit;
  20066. end;
  20067. end
  20068. else
  20069. begin
  20070. HasOnlyNegFilters := FALSE;
  20071. if StrSatisfy( FileName, F ) then
  20072. begin
  20073. Result := True;
  20074. Exit;
  20075. end;
  20076. end;
  20077. end;
  20078. Result := HasOnlyNegFilters and
  20079. (FileName <> {$IFDEF F_P}Dot{$ELSE}'.'{$ENDIF}) and
  20080. (FileName <> '..');
  20081. end;
  20082. {$ENDIF ASM_VERSION}
  20083. {$IFDEF ASM_VERSION}
  20084. //[procedure TDirList.ScanDirectory]
  20085. procedure TDirList.ScanDirectory(const DirPath, Filter: String;
  20086. Attr: DWord);
  20087. const sz_win32finddata = sizeof(TWin32FindData);
  20088. asm
  20089. PUSH EBX
  20090. PUSH EDI
  20091. MOV EBX, EAX
  20092. PUSHAD
  20093. CALL Clear
  20094. CALL NewList
  20095. MOV [EBX].fList, EAX
  20096. POPAD
  20097. PUSHAD
  20098. LEA EAX, [EBX].fPath
  20099. CALL System.@LStrAsg
  20100. POPAD
  20101. MOV EAX, [EBX].fPath
  20102. TEST EAX, EAX
  20103. JE @@exit
  20104. PUSHAD
  20105. LEA EDX, [EBX].fPath
  20106. MOV EAX, [EDX]
  20107. CALL IncludeTrailingPathDelimiter
  20108. MOV EAX, [EBX].fFilters
  20109. TEST EAX, EAX
  20110. JNZ @@1
  20111. CALL NewStrList
  20112. MOV [EBX].fFilters, EAX
  20113. POPAD
  20114. PUSHAD
  20115. PUSH ECX
  20116. XCHG EAX, ECX
  20117. MOV EDX, offset[@@star_d_star]
  20118. CALL StrComp
  20119. TEST AL, AL
  20120. POP EDX
  20121. JNZ @@asg_Filter
  20122. MOV EDX, offset[@@star]
  20123. @@asg_Filter:
  20124. MOV EAX, [EBX].fFilters
  20125. CALL TStrList.Add
  20126. JMP @@1
  20127. @@star_d_star:
  20128. DB '*.*', 0
  20129. DD -1, 1
  20130. @@star: DB '*', 0
  20131. @@1:
  20132. POPAD
  20133. ADD ESP, -sz_win32finddata
  20134. XOR EDX, EDX
  20135. PUSH EDX
  20136. PUSH EDX
  20137. XCHG EAX, ECX
  20138. MOV EDX, ESP
  20139. CALL FindFilter
  20140. LEA EAX, [ESP+4]
  20141. MOV EDX, [EBX].fPath
  20142. POP ECX
  20143. PUSH ECX
  20144. CALL System.@LStrCat3
  20145. CALL RemoveStr
  20146. POP EAX
  20147. MOV EDX, ESP
  20148. PUSH EAX
  20149. PUSH EDX
  20150. PUSH EAX
  20151. CALL FindFirstFile
  20152. MOV EDI, EAX
  20153. INC EAX
  20154. MOV EAX, ESP
  20155. PUSHFD
  20156. CALL System.@LStrClr
  20157. POPFD
  20158. POP ECX
  20159. JZ @@fin
  20160. @@loop:
  20161. MOV ECX, [ESP].TWin32FindData.dwFileAttributes
  20162. PUSH [Attr]
  20163. LEA EDX, [ESP+4].TWin32FindData.cFileName
  20164. MOV EAX, EBX
  20165. CALL SatisfyFilter
  20166. TEST AL, AL
  20167. JZ @@next
  20168. MOV ECX, [EBX].fOnItem.TMethod.Code
  20169. JECXZ @@accept
  20170. MOV EAX, [EBX].fOnItem.TMethod.Data
  20171. MOV ECX, ESP
  20172. PUSH 1
  20173. MOV EDX, ESP
  20174. PUSH EDX
  20175. MOV EDX, EBX
  20176. CALL dword ptr [EBX].fOnItem.TMethod.Code
  20177. POP ECX
  20178. JECXZ @@next
  20179. LOOP @@fin
  20180. @@accept:
  20181. MOV EAX, sz_win32finddata
  20182. PUSH EAX
  20183. CALL System.@GetMem
  20184. PUSH EAX
  20185. XCHG EDX, EAX
  20186. MOV EAX, [EBX].fList
  20187. CALL TList.Add
  20188. POP EDX
  20189. POP ECX
  20190. MOV EAX, ESP
  20191. CALL System.Move
  20192. @@next:
  20193. PUSH ESP
  20194. PUSH EDI
  20195. CALL FindNextFile
  20196. TEST EAX, EAX
  20197. JNZ @@loop
  20198. PUSH EDI
  20199. CALL FindClose
  20200. @@fin:
  20201. ADD ESP, sz_win32finddata
  20202. @@exit:
  20203. XOR EAX, EAX
  20204. XCHG EAX, [EBX].fFilters
  20205. CALL TObj.Free
  20206. POP EDI
  20207. POP EBX
  20208. end;
  20209. {$ELSE ASM_VERSION} //Pascal
  20210. procedure TDirList.ScanDirectory(const DirPath, Filter: String;
  20211. Attr: DWord);
  20212. var FindData : TWin32FindData;
  20213. E : PWin32FindData;
  20214. FindHandle : THandle;
  20215. Action: TDirItemAction;
  20216. begin
  20217. Clear;
  20218. FList := NewList;
  20219. FPath := DirPath;
  20220. if FPath = '' then Exit;
  20221. FPath := IncludeTrailingPathDelimiter( FPath );
  20222. if fFilters = nil then
  20223. begin
  20224. fFilters := NewStrList;
  20225. if Filter = '*.*' then
  20226. fFilters.Add( '*' )
  20227. else
  20228. fFilters.Add( Filter );
  20229. end;
  20230. FindHandle := FindFirstFile( PChar( FPath + FindFilter( Filter ) ),
  20231. FindData );
  20232. if FindHandle = INVALID_HANDLE_VALUE then Exit;
  20233. while True do
  20234. begin
  20235. if SatisfyFilter( PChar(@FindData.cFileName[0]),
  20236. FindData.dwFileAttributes, Attr ) then
  20237. begin
  20238. Action := diAccept;
  20239. if Assigned( OnItem ) then
  20240. OnItem( @Self, FindData, Action );
  20241. CASE Action OF
  20242. diSkip: ;
  20243. diAccept:
  20244. begin
  20245. GetMem( E, Sizeof( FindData ) );
  20246. E^ := FindData;
  20247. FList.Add( E );
  20248. end;
  20249. diCancel: break;
  20250. END;
  20251. end;
  20252. if not FindNextFile( FindHandle, FindData ) then break;
  20253. end;
  20254. FindClose( FindHandle );
  20255. fFilters.Free;
  20256. fFilters := nil;
  20257. end;
  20258. {$ENDIF ASM_VERSION}
  20259. {$IFDEF ASM_VERSION}
  20260. //[procedure TDirList.ScanDirectoryEx]
  20261. procedure TDirList.ScanDirectoryEx(const DirPath, Filters: String;
  20262. Attr: DWord);
  20263. asm
  20264. PUSH EBX
  20265. MOV EBX, EAX
  20266. PUSHAD
  20267. CALL NewStrList
  20268. MOV [EBX].fFilters, EAX
  20269. POPAD
  20270. PUSHAD
  20271. PUSH 0
  20272. MOV EAX, ESP
  20273. MOV EDX, ECX
  20274. CALL System.@LStrLAsg
  20275. @@1: MOV ECX, [ESP]
  20276. JECXZ @@2
  20277. MOV EAX, ESP
  20278. MOV EDX, offset[@@semicolon]
  20279. PUSH 0
  20280. MOV ECX, ESP
  20281. CALL Parse
  20282. MOV EAX, [ESP]
  20283. MOV EDX, ESP
  20284. CALL Trim
  20285. POP EDX
  20286. PUSH EDX
  20287. TEST EDX, EDX
  20288. JZ @@filt_added
  20289. MOV EAX, [EBX].fFilters
  20290. CALL TStrList.Add
  20291. @@filt_added:
  20292. CALL RemoveStr
  20293. JMP @@1
  20294. // ';' string literal
  20295. DD -1, 1
  20296. @@semicolon:
  20297. DB ';',0
  20298. @@2: POP ECX
  20299. POPAD
  20300. XOR ECX, ECX
  20301. PUSH [Attr]
  20302. CALL ScanDirectory
  20303. {XOR EAX, EAX
  20304. XCHG EAX, [EBX].fFilters
  20305. CALL TObj.Free}
  20306. POP EBX
  20307. @@exit:
  20308. end;
  20309. {$ELSE ASM_VERSION} //Pascal
  20310. procedure TDirList.ScanDirectoryEx(const DirPath, Filters: String;
  20311. Attr: DWord);
  20312. var F, FF: String;
  20313. begin
  20314. FF := Filters;
  20315. fFilters := NewStrList;
  20316. while FF <> '' do
  20317. begin
  20318. F := Trim( Parse( FF, ';' ) );
  20319. if F <> '' then
  20320. fFilters.Add( F );
  20321. end;
  20322. ScanDirectory( DirPath, '', Attr );
  20323. end;
  20324. {$ENDIF ASM_VERSION}
  20325. type
  20326. PSortDirData = ^TSortDirData;
  20327. TSortDirData = packed Record
  20328. FoldersFirst, CaseSensitive : Boolean;
  20329. Rules : array[ 0..11 ] of TSortDirRules;
  20330. Dir : PDirList;
  20331. end;
  20332. //[FUNCTION CompareDirItems]
  20333. {$IFDEF ASM_noVERSION}
  20334. function CompareDirItems( const Data : PSortDirData; const e1, e2 : DWORD ) : Integer;
  20335. asm
  20336. PUSH EBX
  20337. PUSH ESI
  20338. PUSH EDI
  20339. XCHG EBX, EAX
  20340. MOV EAX, [EBX].TSortDirData.Dir
  20341. MOV EAX, [EAX].TDirList.fList
  20342. MOV EAX, [EAX].TList.fItems
  20343. MOV ESI, [EAX+EDX*4]
  20344. MOV EDI, [EAX+ECX*4]
  20345. MOV DL, byte ptr[ESI].TWin32FindData.dwFileAttributes
  20346. MOV DH, byte ptr[EDI].TWin32FindData.dwFileAttributes
  20347. AND DX, 2020h
  20348. XOR EAX, EAX
  20349. CMP DL, DH
  20350. JE @@1
  20351. CMP [EBX].TSortDirData.FoldersFirst, AL
  20352. JE @@1
  20353. OR AL, DL
  20354. JNE @@exit_near
  20355. DEC EAX
  20356. //JMP @@exit
  20357. @@exit_near:
  20358. POP EDI
  20359. POP ESI
  20360. POP EBX
  20361. RET
  20362. @@sdrByDateChanged:
  20363. LEA EAX, [ESI].TWin32FindData.ftLastWriteTime
  20364. LEA EDX, [EDI].TWin32FindData.ftLastWriteTime
  20365. JMP @@sdrByDate1
  20366. @@sdrByDateAccessed:
  20367. LEA EAX, [ESI].TWin32FindData.ftLastAccessTime
  20368. LEA EDX, [EDI].TWin32FindData.ftLastAccessTime
  20369. JMP @@sdrByDate1
  20370. @@jmp_table:
  20371. DD offset[@@exit1], offset[@@2], offset[@@2]
  20372. DD offset[@@sdrByName], offset[@@sdrByExt]
  20373. DD offset[@@sdrBySize], offset[@@sdrBySize]
  20374. DD offset[@@sdrByDateCreate], offset[@@sdrByDateChanged]
  20375. DD offset[@@sdrByDateAccessed]
  20376. @@1:
  20377. LEA EDX, [EBX].TSortDirData.Rules
  20378. PUSH EDX
  20379. @@2:
  20380. POP EDX
  20381. XOR EAX, EAX
  20382. MOV AL, [EDX]
  20383. INC EDX
  20384. PUSH EDX
  20385. JMP dword ptr [@@jmp_table+EAX*4]
  20386. //////// ///////////////////
  20387. @@sdrByDateCreate:
  20388. LEA EAX, [ESI].TWin32FindData.ftCreationTime
  20389. LEA EDX, [EDI].TWin32FindData.ftCreationTime
  20390. @@sdrByDate1:
  20391. PUSH EDX
  20392. PUSH EAX
  20393. CALL CompareFileTime
  20394. TEST EAX, EAX
  20395. JE @@2
  20396. JMP @@exit1
  20397. @@sdrBySize:
  20398. MOV EAX, [ESI].TWin32FindData.nFileSizeHigh
  20399. SUB EAX, [EDI].TWin32FindData.nFileSizeHigh
  20400. JNE @@sdrBySize1
  20401. MOV EAX, [ESI].TWin32FindData.nFileSizeLow
  20402. SUB EAX, [EDI].TWin32FindData.nFileSizeLow
  20403. @@to_2:
  20404. JE @@2
  20405. @@sdrBySize1:
  20406. POP EDX
  20407. DEC EDX
  20408. CMP byte ptr[EDX], sdrBySizeDescending
  20409. JNE @@sdrBySize2
  20410. NEG EAX
  20411. @@sdrBySize2:
  20412. JNE @@exit
  20413. //////// ///////////////////
  20414. DD -1, 1
  20415. @@point:DB '.',0
  20416. @@sdrByExt:
  20417. LEA EAX, [EDI].TWin32FindData.cFileName
  20418. MOV EDX, offset[@@point]
  20419. PUSH EDX
  20420. CALL __DelimiterLast
  20421. POP EDX
  20422. PUSH EAX
  20423. LEA EAX, [ESI].TWin32FindData.cFileName
  20424. CALL __DelimiterLast
  20425. POP EDX
  20426. JMP @@sdrByName0
  20427. @@sdrByName:
  20428. LEA EAX, [ESI].TWin32FindData.cFileName
  20429. LEA EDX, [EDI].TWin32FindData.cFileName
  20430. @@sdrByName0:
  20431. CMP [EBX].TSortDirData.CaseSensitive, 0
  20432. JNE @@sdrByName1
  20433. CALL _AnsiCompareStrNoCase
  20434. JMP @@sdrByName2
  20435. @@sdrByName1:
  20436. CALL _AnsiCompareStr
  20437. @@sdrByName2:
  20438. TEST EAX, EAX
  20439. JE @@to_2
  20440. //JMP @@exit1
  20441. @@exit1:
  20442. POP EDX
  20443. @@exit:
  20444. POP EDI
  20445. POP ESI
  20446. POP EBX
  20447. end;
  20448. {$ELSE ASM_VERSION} //Pascal
  20449. function CompareDirItems( const Data : PSortDirData; const e1, e2 : DWORD ) : Integer;
  20450. var I : Integer;
  20451. Item1, Item2 : PWin32FindData;
  20452. S1, S2 : PChar;
  20453. IsDir1, IsDir2 : Boolean;
  20454. Date1, Date2 : PFileTime;
  20455. begin
  20456. Item1 := Data.Dir.fList.fItems[ e1 ];
  20457. Item2 := Data.Dir.fList.fItems[ e2 ];
  20458. Result := 0;
  20459. IsDir1 := (Item1.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0;
  20460. IsDir2 := (Item2.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0;
  20461. if (IsDir1 <> IsDir2) and Data.FoldersFirst then
  20462. begin
  20463. if IsDir1 then Result := -1 else Result := 1;
  20464. exit;
  20465. end;
  20466. for I := 0 to High(Data.Rules) do
  20467. begin
  20468. case Data.Rules[ I ] of
  20469. sdrByName:
  20470. begin
  20471. S1 := Item1.cFileName;
  20472. S2 := Item2.cFileName;
  20473. if not Data.CaseSensitive then
  20474. Result := _AnsiCompareStrNoCase( S1, S2 )
  20475. else
  20476. Result := _AnsiCompareStr( S1, S2 );
  20477. end;
  20478. sdrByExt:
  20479. begin
  20480. S1 := Item1.cFileName;
  20481. S2 := Item2.cFileName;
  20482. S1 := __DelimiterLast( S1, '.' );
  20483. S2 := __DelimiterLast( S2, '.' );
  20484. if not Data.CaseSensitive then
  20485. Result := _AnsiCompareStrNoCase( S1, S2 )
  20486. else
  20487. Result := _AnsiCompareStr( S1, S2 );
  20488. end;
  20489. sdrBySize, sdrBySizeDescending:
  20490. begin
  20491. if Item1.nFileSizeHigh < Item2.nFileSizeHigh then
  20492. Result := -1
  20493. else
  20494. if Item1.nFileSizeHigh > Item2.nFileSizeHigh then
  20495. Result := 1
  20496. else
  20497. if Item1.nFileSizeLow < Item2.nFileSizeLow then
  20498. Result := -1
  20499. else
  20500. if Item1.nFileSizeLow > Item2.nFileSizeLow then
  20501. Result := 1;
  20502. if Data.Rules[ I ] = sdrBySizeDescending then
  20503. Result := -Result;
  20504. end;
  20505. sdrByDateCreate:
  20506. begin
  20507. Date1 := @Item1.ftCreationTime;
  20508. Date2 := @Item2.ftCreationTime;
  20509. Result := CompareFileTime( Date1^, Date2^ );
  20510. end;
  20511. sdrByDateChanged:
  20512. begin
  20513. Date1 := @Item1.ftLastWriteTime;
  20514. Date2 := @Item2.ftLastWriteTime;
  20515. Result := CompareFileTime( Date1^, Date2^ );
  20516. end;
  20517. sdrByDateAccessed:
  20518. begin
  20519. Date1 := @Item1.ftLastAccessTime;
  20520. Date2 := @Item2.ftLastAccessTime;
  20521. Result := CompareFileTime( Date1^, Date2^ );
  20522. end;
  20523. end; {case}
  20524. if Result <> 0 then break;
  20525. end;
  20526. end;
  20527. {$ENDIF ASM_VERSION}
  20528. //[END CompareDirItems]
  20529. //[PROCEDURE SwapDirItems]
  20530. {$IFDEF ASM_VERSION}
  20531. procedure SwapDirItems( const Data : PSortDirData; const e1, e2 : DWORD );
  20532. asm
  20533. MOV EAX, [EAX].TSortDirData.Dir
  20534. MOV EAX, [EAX].TDirList.fList
  20535. MOV EAX, [EAX].TList.fItems
  20536. LEA EDX, [EAX+EDX*4]
  20537. LEA ECX, [EAX+ECX*4]
  20538. MOV EAX, [EDX]
  20539. XCHG EAX, [ECX]
  20540. MOV [EDX], EAX
  20541. end;
  20542. {$ELSE ASM_VERSION} //Pascal
  20543. procedure SwapDirItems( const Data : PSortDirData; const e1, e2 : DWORD );
  20544. var Tmp : Pointer;
  20545. begin
  20546. Tmp := Data.Dir.FList.fItems[ e1 ];
  20547. Data.Dir.FList.fItems[ e1 ] := Data.Dir.FList.fItems[ e2 ];
  20548. Data.Dir.FList.fItems[ e2 ] := Tmp;
  20549. end;
  20550. {$ENDIF ASM_VERSION}
  20551. //[END SwapDirItems]
  20552. {
  20553. TSortDirData = packed Record
  20554. FoldersFirst, CaseSensitive : Boolean;
  20555. Rules : array[ 0..11 ] of TSortDirRules;
  20556. Dir : PDirList;
  20557. end;
  20558. }
  20559. {$IFDEF ASM_VERSION}
  20560. procedure TDirList.Sort(Rules: array of TSortDirRules);
  20561. const high_DefSortDirRules = High( DefSortDirRules );
  20562. asm
  20563. PUSH EBX
  20564. PUSH ESI
  20565. XOR EBX,EBX
  20566. CMP [EAX].fList, EBX
  20567. JE @@exit
  20568. PUSH EAX // prepare Dir = @Self
  20569. XOR EAX, EAX
  20570. PUSH EAX
  20571. PUSH EAX
  20572. PUSH EAX
  20573. MOV ESI, ESP
  20574. INC ECX // ECX = High(Rules)
  20575. JZ @@2
  20576. @@1: MOV AH, [EDX] // AH = Rules[ I ]
  20577. INC EDX
  20578. CALL @@add_rule
  20579. LOOP @@1
  20580. @@2: LEA EDX, [DefSortDirRules]
  20581. MOV CL, high_DefSortDirRules + 1
  20582. @@21: MOV AH, [EDX]
  20583. INC EDX
  20584. CALL @@add_rule
  20585. LOOP @@21
  20586. PUSH BX // prepare FoldersFirst(BL), CaseSensitive(BH)
  20587. MOV EBX, [ESP].TSortDirData.Dir
  20588. MOV EAX, ESP
  20589. PUSH offset[SwapDirItems]
  20590. MOV ECX, offset[CompareDirItems]
  20591. MOV EDX, [EBX].fList
  20592. MOV EDX, [EDX].TList.fCount
  20593. CALL SortData
  20594. ADD ESP, 18
  20595. JMP @@exit
  20596. @@add_rule:
  20597. PUSH ESI
  20598. PUSH ECX
  20599. MOV CL, 11
  20600. @@a1: LODSB
  20601. TEST AL, AL
  20602. JZ @@a2
  20603. CMP AL, AH
  20604. JE @@a3
  20605. LOOP @@a1
  20606. @@a2: DEC ESI
  20607. MOV [ESI], AH
  20608. CMP AH, sdrFoldersFirst
  20609. JNE @@a4
  20610. INC BL
  20611. @@a4: CMP AH, sdrCaseSensitive
  20612. JNE @@a3
  20613. INC BH
  20614. @@a3: POP ECX
  20615. POP ESI
  20616. RET
  20617. @@exit:
  20618. POP ESI
  20619. POP EBX
  20620. end;
  20621. {$ELSE ASM_VERSION} //Pascal
  20622. procedure TDirList.Sort(Rules: array of TSortDirRules);
  20623. var SortDirData : TSortDirData;
  20624. I, J : Integer;
  20625. function RulePresent( Rule : TSortDirRules ) : Boolean;
  20626. var K : Integer;
  20627. begin
  20628. Result := True;
  20629. for K := J - 1 downto 0 do
  20630. if Rule = SortDirData.Rules[ K ] then exit;
  20631. Result := False;
  20632. end;
  20633. procedure AddRule( Rule : TSortDirRules );
  20634. begin
  20635. if J > High( SortDirData.Rules ) then exit;
  20636. if RulePresent( Rule ) then exit;
  20637. SortDirData.Rules[ J ] := Rule;
  20638. Inc( J );
  20639. end;
  20640. begin
  20641. if fList = nil then Exit;
  20642. J := 0;
  20643. for I := 0 to High(Rules) do
  20644. AddRule( Rules[ I ] );
  20645. for I := 0 to High(DefSortDirRules) do
  20646. AddRule( DefSortDirRules[ I ] );
  20647. while J < High( SortDirData.Rules ) do
  20648. begin
  20649. SortDirData.Rules[ J ] := sdrNone;
  20650. Inc( J );
  20651. end;
  20652. SortDirData.Dir := @Self;
  20653. SortDirData.FoldersFirst := RulePresent( sdrFoldersFirst );
  20654. SortDirData.CaseSensitive := RulePresent( sdrCaseSensitive );
  20655. SortData( Pointer( @SortDirData ), fList.fCount, @CompareDirItems, @SwapDirItems );
  20656. end;
  20657. {$ENDIF ASM_VERSION}
  20658. //[function TDirList.FileList]
  20659. function TDirList.FileList(const Separator: String; Dirs,
  20660. FullPaths: Boolean): String;
  20661. var I: Integer;
  20662. begin
  20663. Result := '';
  20664. for I := 0 to Count-1 do
  20665. begin
  20666. if not Dirs and IsDirectory[ I ] then Continue;
  20667. if FullPaths then
  20668. Result := Result + Path;
  20669. Result := Result + Names[ I ] + Separator;
  20670. end;
  20671. end;
  20672. ////////////////////////////////////////////////////////////////////////
  20673. //
  20674. //
  20675. // R E G I S T R Y
  20676. //
  20677. //
  20678. ////////////////////////////////////////////////////////////////////////
  20679. {++}(*
  20680. function RegSetValueEx; external advapi32 name 'RegSetValueExA';
  20681. *){--}
  20682. { -- registry -- }
  20683. //[function RegKeyOpenRead]
  20684. function RegKeyOpenRead( Key: HKey; const SubKey: String ): HKey;
  20685. begin
  20686. if RegOpenKeyEx( Key, PChar( SubKey ), 0, KEY_READ, Result ) <> ERROR_SUCCESS then
  20687. Result := 0;
  20688. end;
  20689. //[function RegKeyOpenWrite]
  20690. function RegKeyOpenWrite( Key: HKey; const SubKey: String ): HKey;
  20691. begin
  20692. if RegOpenKeyEx( Key, PChar( SubKey ), 0, KEY_READ or KEY_WRITE, Result ) <> ERROR_SUCCESS then
  20693. Result := 0;
  20694. end;
  20695. //[function RegKeyOpenCreate]
  20696. function RegKeyOpenCreate( Key: HKey; const SubKey: String ): HKey;
  20697. var dwDisp: DWORD;
  20698. begin
  20699. if RegCreateKeyEx( Key, PChar( SubKey ), 0, nil, 0, KEY_ALL_ACCESS, nil, Result,
  20700. @dwDisp ) <> ERROR_SUCCESS then
  20701. Result := 0;
  20702. end;
  20703. //[function RegKeyGetDw]
  20704. function RegKeyGetDw( Key: HKey; const ValueName: String ): DWORD;
  20705. var dwType, dwSize: DWORD;
  20706. begin
  20707. dwSize := sizeof( DWORD );
  20708. Result := 0;
  20709. if (Key = 0) or
  20710. (RegQueryValueEx( Key, PChar( ValueName ), nil, @dwType, PByte( @Result ), @dwSize ) <> ERROR_SUCCESS)
  20711. or (dwType <> REG_DWORD) then Result := 0;
  20712. end;
  20713. //[function RegKeyGetStr]
  20714. function RegKeyGetStr( Key: HKey; const ValueName: String ): String;
  20715. var dwType, dwSize: DWORD;
  20716. Buffer: PChar;
  20717. function Query: Boolean;
  20718. begin
  20719. Result := RegQueryValueEx( Key, PChar( ValueName ), nil, @dwType,
  20720. Pointer( Buffer ), @dwSize ) = ERROR_SUCCESS;
  20721. end;
  20722. begin
  20723. Result := '';
  20724. if Key = 0 then Exit;
  20725. dwSize := 0;
  20726. Buffer := nil;
  20727. if not Query or (dwType <> REG_SZ) then Exit;
  20728. GetMem( Buffer, dwSize );
  20729. if Query then
  20730. Result := Buffer;
  20731. FreeMem( Buffer );
  20732. end;
  20733. //[function RegKeyGetStrEx]
  20734. function RegKeyGetStrEx( Key: HKey; const ValueName: String ): String;
  20735. var dwType, dwSize: DWORD;
  20736. Buffer, Buffer2: PChar;
  20737. Sz: Integer;
  20738. function Query: Boolean;
  20739. begin
  20740. Result := RegQueryValueEx( Key, PChar( ValueName ), nil, @dwType,
  20741. Pointer( Buffer ), @dwSize ) = ERROR_SUCCESS;
  20742. end;
  20743. begin
  20744. Result := '';
  20745. if Key = 0 then Exit;
  20746. dwSize := 0;
  20747. Buffer := nil;
  20748. if not Query or ((dwType <> REG_SZ) and (dwtype <> REG_EXPAND_SZ)) then Exit;
  20749. GetMem( Buffer, dwSize );
  20750. if Query then
  20751. begin
  20752. if dwtype = REG_EXPAND_SZ then
  20753. begin
  20754. //------------------------------------------------------ by Dmitry Zharov
  20755. // Sz := ExpandEnvironmentStrings(Buffer,nil,0); 18-Aug-2004
  20756. // SetLength( Result, Sz );
  20757. // ExpandEnvironmentStrings(Buffer, PChar(Result), Sz);
  20758. //---------------------------------------------//
  20759. Sz := ExpandEnvironmentStrings(Buffer,nil,0); // bug in size detection! sometimes we get an additional 2 bytes at the end...
  20760. GetMem(Buffer2,Sz); //
  20761. ExpandEnvironmentStrings(Buffer, Buffer2, Sz); //
  20762. Result:=Buffer2; //
  20763. FreeMem(Buffer2); //
  20764. //---------------------------------------------//
  20765. end
  20766. else
  20767. Result := Buffer;
  20768. end;
  20769. FreeMem( Buffer );
  20770. end;
  20771. //[function RegKeySetDw]
  20772. function RegKeySetDw( Key: HKey; const ValueName: String; Value: DWORD ): Boolean;
  20773. begin
  20774. Result := (Key <> 0) and (RegSetValueEx( Key, PChar( ValueName ), 0, REG_DWORD, @Value, sizeof( DWORD ) )
  20775. = ERROR_SUCCESS);
  20776. end;
  20777. //[function RegKeySetStr]
  20778. function RegKeySetStr( Key: HKey; const ValueName: String; const Value: String ): Boolean;
  20779. begin
  20780. Result := (Key <> 0) and (RegSetValueEx( Key, PChar( ValueName ), 0,
  20781. REG_SZ, PChar(Value),
  20782. Length( Value ) + 1 ) = ERROR_SUCCESS);
  20783. end;
  20784. //[function RegKeySetStrEx]
  20785. function RegKeySetStrEx( Key: HKey; const ValueName: string; const Value: string;
  20786. expand: boolean): Boolean;
  20787. var dwType: DWORD;
  20788. begin
  20789. dwType := REG_SZ;
  20790. if expand then
  20791. dwType := REG_EXPAND_SZ;
  20792. Result := (Key <> 0) and (RegSetValueEx(Key, PChar(ValueName), 0, dwType,
  20793. PChar(Value), Length(Value) + 1) = ERROR_SUCCESS);
  20794. end;
  20795. //[procedure RegKeyClose]
  20796. procedure RegKeyClose( Key: HKey );
  20797. begin
  20798. if Key <> 0 then
  20799. RegCloseKey( Key );
  20800. end;
  20801. //[function RegKeyDelete]
  20802. function RegKeyDelete( Key: HKey; const SubKey: String ): Boolean;
  20803. begin
  20804. Result := FALSE;
  20805. if Key <> 0 then
  20806. Result := RegDeleteKey( Key, PChar( SubKey ) ) = ERROR_SUCCESS;
  20807. end;
  20808. //[function RegKeyDeleteValue]
  20809. function RegKeyDeleteValue( Key: HKey; const SubKey: String ): Boolean;
  20810. begin
  20811. Result := FALSE;
  20812. if Key <> 0 then
  20813. Result := RegDeleteValue( Key, PChar( SubKey ) ) = ERROR_SUCCESS;
  20814. end;
  20815. //[function RegKeyExists]
  20816. function RegKeyExists( Key: HKey; const SubKey: String ): Boolean;
  20817. var K: Integer;
  20818. begin
  20819. if Key = 0 then
  20820. begin
  20821. Result := FALSE;
  20822. Exit;
  20823. end;
  20824. K := RegKeyOpenRead( Key, SubKey );
  20825. Result := K <> 0;
  20826. if K <> 0 then
  20827. RegKeyClose( K );
  20828. end;
  20829. //[function RegKeyValExists]
  20830. function RegKeyValExists( Key: HKey; const ValueName: String ): Boolean;
  20831. var dwType, dwSize: DWORD;
  20832. begin
  20833. Result := (Key <> 0) and
  20834. (RegQueryValueEx( Key, PChar( ValueName ), nil,
  20835. @dwType, nil, @dwSize ) = ERROR_SUCCESS);
  20836. end;
  20837. //[function RegKeyValueSize]
  20838. function RegKeyValueSize( Key: HKey; const ValueName: String ): Integer;
  20839. begin
  20840. Result := 0;
  20841. if Key = 0 then Exit;
  20842. RegQueryValueEx( Key, PChar( ValueName ), nil, nil, nil, @ DWORD( Result ) );
  20843. end;
  20844. //[function RegKeyGetBinary]
  20845. function RegKeyGetBinary( Key: HKey; const ValueName: String; var Buffer; Count: Integer ): Integer;
  20846. begin
  20847. Result := 0;
  20848. if Key = 0 then Exit;
  20849. Result := Count;
  20850. RegQueryValueEx( Key, PChar( ValueName ), nil, nil, @ Buffer, @ Result );
  20851. end;
  20852. //[function RegKeySetBinary]
  20853. function RegKeySetBinary( Key: HKey; const ValueName: String; const Buffer; Count: Integer ): Boolean;
  20854. begin
  20855. Result := (Key <> 0) and (RegSetValueEx( Key, PChar( ValueName ), 0,
  20856. REG_BINARY, @ Buffer, Count ) = ERROR_SUCCESS);
  20857. end;
  20858. //[function RegKeyGetDateTime]
  20859. function RegKeyGetDateTime(Key: HKey; const ValueName: String): TDateTime;
  20860. begin
  20861. RegKeyGetBinary( Key, ValueName, Result, Sizeof( Result ) );
  20862. end;
  20863. //[function RegKeySetDateTime]
  20864. function RegKeySetDateTime(Key: HKey; const ValueName: String; DateTime: TDateTime): Boolean;
  20865. begin
  20866. Result := RegKeySetBinary( Key, ValueName, DateTime, Sizeof( DateTime ) );
  20867. end;
  20868. //-----------------------------------------------
  20869. // functions by Valerian Luft <luft@valerian.de>
  20870. //-----------------------------------------------
  20871. //[function RegKeyGetSubKeys]
  20872. function RegKeyGetSubKeys( const Key: HKEY; List: PStrList) : Boolean;
  20873. var
  20874. I, Size, NumSubKeys, MaxSubKeyLen : DWORD;
  20875. KeyName: String;
  20876. begin
  20877. Result := False;
  20878. List.Clear ;
  20879. if RegQueryInfoKey(Key, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil,
  20880. nil, nil) = ERROR_SUCCESS then
  20881. begin
  20882. if NumSubKeys > 0 then begin
  20883. for I := 0 to NumSubKeys-1 do
  20884. begin
  20885. Size := MaxSubKeyLen+1;
  20886. SetLength(KeyName, Size);
  20887. //FillChar(KeyName[1],Size,#0);
  20888. RegEnumKeyEx(Key, I, @KeyName[1], Size, nil, nil, nil, nil);
  20889. SetLength(KeyName, lstrlen(@KeyName[1]));
  20890. List.Add(KeyName);
  20891. end;
  20892. end;
  20893. Result:= True;
  20894. end;
  20895. end;
  20896. //[function RegKeyGetValueNames]
  20897. function RegKeyGetValueNames(const Key: HKEY; List: PStrList): Boolean;
  20898. var
  20899. I, Size, NumSubKeys, NumValueNames, MaxValueNameLen: DWORD;
  20900. ValueName: String;
  20901. begin
  20902. List.Clear ;
  20903. Result:=False;
  20904. if RegQueryInfoKey(Key, nil, nil, nil, @NumSubKeys, nil, nil, @NumValueNames,
  20905. @MaxValueNameLen, nil, nil, nil) = ERROR_SUCCESS then
  20906. begin
  20907. if NumValueNames > 0 then
  20908. for I := 0 to NumValueNames - 1 do begin
  20909. Size := MaxValueNameLen + 1;
  20910. SetLength(ValueName, Size);
  20911. //FillChar(ValueName[1],Size,#0);
  20912. RegEnumValue(Key, I, @ValueName[1], Size, nil, nil, nil, nil);
  20913. SetLength(ValueName, lstrlen(@ValueName[1]));
  20914. List.Add(ValueName);
  20915. end;
  20916. Result := True;
  20917. end ;
  20918. end;
  20919. //[function RegKeyGetValueTyp]
  20920. function RegKeyGetValueTyp (const Key:HKEY; const ValueName: String) : DWORD;
  20921. begin
  20922. Result:= Key ;
  20923. if Key <> 0 then
  20924. RegQueryValueEx (Key,@ValueName[1],NIL,@Result,NIL,NIL)
  20925. end;
  20926. //////////////////////////////////////////////////////////////////////
  20927. //
  20928. //
  20929. // D A T E A N D T I M E
  20930. //
  20931. //
  20932. //////////////////////////////////////////////////////////////////////
  20933. { -- date and time utilities -- }
  20934. {* This part of the unit contains date-time routines. It is not a simple compilation
  20935. of Delphi VCL date-time. E.g., TDateTime type is not based on 31-Dec-1899,
  20936. but it is based on 31-Dec-0000 instead, allowing easy manipulating of dates
  20937. at all Christian era, and all other historical era too. }
  20938. //[procedure DivMod]
  20939. procedure DivMod(Dividend: Integer; Divisor: Word;
  20940. var Result, Remainder: Word);
  20941. {$IFDEF F_P}
  20942. begin
  20943. Result := Dividend div Divisor;
  20944. Remainder := Dividend mod Divisor;
  20945. end;
  20946. {$ELSE DELPHI}
  20947. asm
  20948. PUSH EBX
  20949. MOV EBX,EDX
  20950. MOV EDX,EAX
  20951. SHR EDX,16
  20952. DIV BX
  20953. MOV EBX,Remainder
  20954. MOV [ECX],AX
  20955. MOV [EBX],DX
  20956. POP EBX
  20957. end;
  20958. {$ENDIF}
  20959. {++}(*
  20960. //[API GetLocalTime, GetSystemTime]
  20961. procedure GetLocalTime; external kernel32 name 'GetLocalTime';
  20962. procedure GetSystemTime; external kernel32 name 'GetSystemTime';
  20963. *){--}
  20964. //*
  20965. //[function Now]
  20966. function Now : TDateTime;
  20967. var SystemTime : TSystemTime;
  20968. begin
  20969. GetLocalTime( SystemTime );
  20970. SystemTime2DateTime( SystemTime, Result );
  20971. end;
  20972. //[function Date]
  20973. function Date: TDateTime;
  20974. begin
  20975. Result := Trunc( Now );
  20976. end;
  20977. //[procedure DecodeDateFully]
  20978. procedure DecodeDateFully( DateTime: TDateTime; var Year, Month, Day, DayOfWeek: WORD );
  20979. var ST: TSystemTime;
  20980. begin
  20981. DateTime2SystemTime( DateTime, ST );
  20982. Year := ST.wYear;
  20983. Month := ST.wMonth;
  20984. Day := ST.wDay;
  20985. DayOfWeek := ST.wDayOfWeek;
  20986. end;
  20987. //[procedure DecodeDate]
  20988. procedure DecodeDate( DateTime: TDateTime; var Year, Month, Day: WORD );
  20989. var Dummy: Word;
  20990. begin
  20991. DecodeDateFully( DateTime, Year, Month, Day, Dummy );
  20992. end;
  20993. //[function EncodeDate]
  20994. function EncodeDate( Year, Month, Day: WORD; var DateTime: TDateTime ): Boolean;
  20995. var ST: TSystemTime;
  20996. begin
  20997. FillChar( ST, Sizeof( ST ), 0 );
  20998. ST.wYear := Year;
  20999. ST.wMonth := Month;
  21000. ST.wDay := Day;
  21001. Result := SystemTime2DateTime( ST, DateTime );
  21002. end;
  21003. //[FUNCTION CompareSystemTime]
  21004. {$IFDEF ASM_VERSION}
  21005. function CompareSystemTime( const D1, D2 : TSystemTime) : Integer; assembler;
  21006. asm
  21007. PUSH ESI
  21008. PUSH EBX
  21009. MOV ESI, EAX
  21010. XOR EAX, EAX
  21011. XOR ECX, ECX
  21012. MOV CL, 8 // 8 words: wYear, wMonth,..., wMilliseconds
  21013. @@loo:
  21014. LODSW
  21015. MOV BX, [EDX]
  21016. INC EDX
  21017. INC EDX
  21018. CMP CL, 6
  21019. JE @@cont // skip compare DayOfWeek
  21020. SUB AX, BX
  21021. JNE @@calc
  21022. @@cont:
  21023. LOOP @@loo
  21024. JMP @@exit
  21025. @@calc:
  21026. SBB EAX, EAX
  21027. {$IFDEF PARANOIA}
  21028. DB $0C, 1
  21029. {$ELSE}
  21030. OR AL, 1
  21031. {$ENDIF}
  21032. @@exit:
  21033. POP EBX
  21034. POP ESI
  21035. end;
  21036. {$ELSE ASM_VERSION} //Pascal
  21037. function CompareSystemTime(const D1, D2 : TSystemTime) : Integer;
  21038. var R: Integer;
  21039. procedure CompareFields(const F1, F2 : Integer);
  21040. begin
  21041. if R <> 0 then Exit;
  21042. if F1 = F2 then Exit;
  21043. if F1 < F2 then
  21044. R := -1
  21045. else
  21046. R := 1;
  21047. end;
  21048. begin
  21049. R := 0;
  21050. CompareFields( D1.wYear, D2.wYear );
  21051. CompareFields( D1.wMonth, D2.wMonth );
  21052. CompareFields( D1.wDay, D2.wDay );
  21053. CompareFields( D1.wHour, D2.wHour );
  21054. CompareFields( D1.wMinute, D2.wMinute );
  21055. CompareFields( D1.wSecond, D2.wSecond );
  21056. CompareFields( D1.wMilliseconds, D2.wMilliseconds );
  21057. Result := R;
  21058. end;
  21059. {$ENDIF ASM_VERSION}
  21060. //[END CompareSystemTime]
  21061. //*
  21062. //[procedure IncDays]
  21063. procedure IncDays( var SystemTime : TSystemTime; DaysNum : Integer );
  21064. var DateTime : TDateTime;
  21065. begin
  21066. SystemTime2DateTime( SystemTime, DateTime );
  21067. DateTime := DateTime + DaysNum;
  21068. DateTime2SystemTime( DateTime, SystemTime );
  21069. end;
  21070. //*
  21071. //[procedure IncMonths]
  21072. procedure IncMonths( var SystemTime : TSystemTime; MonthsNum : Integer );
  21073. var M : Integer;
  21074. DateTime : TDateTime;
  21075. begin
  21076. M := SystemTime.wMonth + MonthsNum - 1;
  21077. Inc( SystemTime.wYear, M div 12 );
  21078. SystemTime.wMonth := M mod 12 + 1;
  21079. // Normalize wDayOfWeek field:
  21080. SystemTime2DateTime( SystemTime, DateTime );
  21081. DateTime2SystemTime( DateTime, SystemTime );
  21082. end;
  21083. //*
  21084. //[function IsLeapYear]
  21085. function IsLeapYear(Year: Word): Boolean;
  21086. begin
  21087. Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
  21088. end;
  21089. //*
  21090. //[function SystemTime2DateTime]
  21091. function SystemTime2DateTime(const SystemTime : TSystemTime; var DateTime : TDateTime ) : Boolean;
  21092. var I : Integer;
  21093. Day : Integer;
  21094. DayTable: PDayTable;
  21095. begin
  21096. Result := False;
  21097. DateTime := 0.0;
  21098. DayTable := @MonthDays[IsLeapYear(SystemTime.wYear)];
  21099. with SystemTime do
  21100. //-------- by Vadim Petrov ----------------------------------------------------------------
  21101. //if (wYear >= 1) and (wYear <= 9999) and (wMonth >= 1) and (wMonth <= 12) and
  21102. // (wDay >= 1) and (wDay <= DayTable^[wMonth]) and
  21103. // (wHour < 24) and (wMinute < 60) and (wSecond < 60) and (wMilliSeconds < 1000) then
  21104. //---------------------------------------------------------------------------------------//
  21105. if {(wYear >= 0) !always true! and} (wYear <= 9999) and
  21106. {(wMonth >= 0) !always true! and} (wMonth <= 12) and
  21107. {(wDay >= 0) !always true! and} (wDay <= DayTable^[wMonth]) and //
  21108. (wHour < 24) and (wMinute < 60) and (wSecond < 60) and (wMilliSeconds < 1000) then //
  21109. //---------------------------------------------------------------------------------------//
  21110. begin
  21111. Day := wDay;
  21112. for I := 1 to wMonth - 1 do
  21113. Inc(Day, DayTable^[I]);
  21114. I := wYear - 1;
  21115. //--------------- by Vadim Petrov ------++
  21116. if I<0 then i := 0; //
  21117. //--------------------------------------++
  21118. DateTime := I * 365 + I div 4 - I div 100 + I div 400 + Day
  21119. + (wHour * 3600000 + wMinute * 60000 + wSecond * 1000 + wMilliSeconds) / MSecsPerDay;
  21120. Result := True;
  21121. end;
  21122. end;
  21123. //*
  21124. //[function DayOfWeek]
  21125. function DayOfWeek(Date: TDateTime): Integer;
  21126. begin
  21127. Result := (Trunc( Date ) + 6) mod 7 + 1;
  21128. end;
  21129. //*
  21130. //[function DateTime2SystemTime]
  21131. function DateTime2SystemTime(const DateTime : TDateTime; var SystemTime : TSystemTime ) : Boolean;
  21132. const
  21133. D1 = 365;
  21134. D4 = D1 * 4 + 1;
  21135. D100 = D4 * 25 - 1;
  21136. D400 = D100 * 4 + 1;
  21137. var Days : Integer;
  21138. Y, M, D, I: Word;
  21139. MSec : Integer;
  21140. DayTable: PDayTable;
  21141. MinCount, MSecCount: Word;
  21142. begin
  21143. Days := Trunc( DateTime );
  21144. MSec := Round((DateTime - Days) * MSecsPerDay);
  21145. Result := False;
  21146. with SystemTime do
  21147. if Days > 0 then
  21148. begin
  21149. Dec(Days);
  21150. Y := 1;
  21151. while Days >= D400 do
  21152. begin
  21153. Dec(Days, D400);
  21154. Inc(Y, 400);
  21155. end;
  21156. DivMod(Days, D100, I, D);
  21157. if I = 4 then
  21158. begin
  21159. Dec(I);
  21160. Inc(D, D100);
  21161. end;
  21162. Inc(Y, I * 100);
  21163. DivMod(D, D4, I, D);
  21164. Inc(Y, I * 4);
  21165. DivMod(D, D1, I, D);
  21166. if I = 4 then
  21167. begin
  21168. Dec(I);
  21169. Inc(D, D1);
  21170. end;
  21171. Inc(Y, I);
  21172. DayTable := @MonthDays[IsLeapYear(Y)];
  21173. M := 1;
  21174. while True do
  21175. begin
  21176. I := DayTable^[M];
  21177. if D < I then Break;
  21178. Dec(D, I);
  21179. Inc(M);
  21180. end;
  21181. wYear := Y;
  21182. wMonth := M;
  21183. wDay := D + 1;
  21184. wDayOfWeek := DayOfWeek( DateTime );
  21185. DivMod(MSec, 60000, MinCount, MSecCount);
  21186. DivMod(MinCount, 60, wHour, wMinute);
  21187. DivMod(MSecCount, 1000, wSecond, wMilliSeconds);
  21188. Result := True;
  21189. end;
  21190. end;
  21191. function DateTime_DiffSysLoc: TDateTime;
  21192. var ST, LT: TSystemTime;
  21193. FT, FT1: TFileTime;
  21194. D1, D2: TDateTime;
  21195. begin
  21196. GetSystemTime( ST );
  21197. SystemTimeToFileTime( ST, FT );
  21198. FileTimeToLocalFileTime( FT, FT1 );
  21199. FileTimeToSystemTime( FT1, LT );
  21200. SystemTime2DateTime( ST, D1 );
  21201. SystemTime2DateTime( LT, D2 );
  21202. Result := D2 - D1;
  21203. end;
  21204. //[function DateTime_System2Local]
  21205. function DateTime_System2Local( DTSys: TDateTime ): TDateTime;
  21206. begin
  21207. Result := DTSys + DateTime_DiffSysLoc;
  21208. end;
  21209. //[function DateTime_Local2System]
  21210. function DateTime_Local2System( DTLoc: TDateTime ): TDateTime;
  21211. begin
  21212. Result := DTLoc - DateTime_DiffSysLoc;
  21213. end;
  21214. //*
  21215. //[function CatholicEaster]
  21216. function CatholicEaster( nYear: Integer ): TDateTime;
  21217. var
  21218. nMoon, nEpact, nSunday, nGold, nCent, nCorx, nCorz: Integer;
  21219. SystemTime : TSystemTime;
  21220. begin
  21221. FillChar( SystemTime, Sizeof( SystemTime ), 0 );
  21222. with SystemTime do
  21223. begin
  21224. wYear := nYear;
  21225. { The Golden Number of the year in the 19 year Metonic Cycle }
  21226. nGold := ( ( wYear mod 19 ) + 1 );
  21227. { Calculate the Century }
  21228. nCent := ( ( wYear div 100 ) + 1 );
  21229. { No. of Years in which leap year was dropped in order to keep in step
  21230. with the sun }
  21231. nCorx := ( ( 3 * nCent ) div 4 - 12 );
  21232. { Special Correction to Syncronize Easter with the moon's orbit }
  21233. nCorz := ( ( 8 * nCent + 5 ) div 25 - 5 );
  21234. { Find Sunday }
  21235. nSunday := ( ( 5 * wYear ) div 4 - nCorx - 10 );
  21236. { Set Epact (specifies occurance of full moon }
  21237. nEpact := ( ( 11 * nGold + 20 + nCorz - nCorx ) mod 30 );
  21238. if ( nEpact < 0 ) then
  21239. nEpact := nEpact + 30;
  21240. if ( ( nEpact = 25 ) and ( nGold > 11 ) ) or ( nEpact = 24 ) then
  21241. nEpact := nEpact + 1;
  21242. { Find Full Moon }
  21243. nMoon := 44 - nEpact;
  21244. if ( nMoon < 21 ) then
  21245. nMoon := nMoon + 30;
  21246. { Advance to Sunday }
  21247. nMoon := ( nMoon + 7 - ( ( nSunday + nMoon ) mod 7 ) );
  21248. if ( nMoon > 31 ) then
  21249. begin
  21250. wMonth := 4;
  21251. wDay := ( nMoon - 31 );
  21252. end
  21253. else
  21254. begin
  21255. wMonth := 3;
  21256. wDay := nMoon;
  21257. end;
  21258. end;
  21259. SystemTime2DateTime( SystemTime, Result );
  21260. end;
  21261. //*
  21262. //[function SystemDate2Str]
  21263. function SystemDate2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  21264. const DfltDateFormat : TDateFormat; const DateFormat : PChar ) : String;
  21265. var Buf : PChar;
  21266. Sz : Integer;
  21267. Flags : DWORD;
  21268. begin
  21269. Sz := 100;
  21270. Buf := nil;
  21271. Result := '';
  21272. Flags := 0;
  21273. if DateFormat = nil then
  21274. if DfltDateFormat = dfShortDate then
  21275. Flags := DATE_SHORTDATE
  21276. else
  21277. Flags := DATE_LONGDATE;
  21278. while True do
  21279. begin
  21280. if Buf <> nil then
  21281. FreeMem( Buf );
  21282. GetMem( Buf, Sz );
  21283. if Buf = nil then Exit;
  21284. if GetDateFormat( LocaleID, Flags, @SystemTime, DateFormat, Buf, Sz )
  21285. = 0 then
  21286. begin
  21287. if GetLastError = ERROR_INSUFFICIENT_BUFFER then
  21288. Sz := Sz * 2
  21289. else
  21290. break;
  21291. end
  21292. else
  21293. begin
  21294. Result := Buf;
  21295. break;
  21296. end;
  21297. end;
  21298. if Buf <> nil then
  21299. FreeMem( Buf );
  21300. end;
  21301. //*
  21302. //[function SystemTime2Str]
  21303. function SystemTime2Str( const SystemTime : TSystemTime; const LocaleID : DWORD;
  21304. const Flags : TTimeFormatFlags; const TimeFormat : PChar ) : String;
  21305. var Buf : PChar;
  21306. Sz : Integer;
  21307. Flg : DWORD;
  21308. begin
  21309. Sz := 100;
  21310. Buf := nil;
  21311. Result := '';
  21312. Flg := 0;
  21313. if tffNoMinutes in Flags then
  21314. Flg := TIME_NOMINUTESORSECONDS
  21315. else
  21316. if tffNoSeconds in Flags then
  21317. Flg := TIME_NOSECONDS;
  21318. if tffNoMarker in Flags then
  21319. Flg := Flg or TIME_NOTIMEMARKER;
  21320. if tffForce24 in Flags then
  21321. Flg := Flg or TIME_FORCE24HOURFORMAT;
  21322. while True do
  21323. begin
  21324. if Buf <> nil then
  21325. FreeMem( Buf );
  21326. GetMem( Buf, Sz );
  21327. if Buf = nil then Exit;
  21328. if GetTimeFormat( LocaleID, Flg, @SystemTime, TimeFormat, Buf, Sz )
  21329. = 0 then
  21330. begin
  21331. if GetLastError = ERROR_INSUFFICIENT_BUFFER then
  21332. Sz := Sz * 2
  21333. else
  21334. break;
  21335. end
  21336. else
  21337. begin
  21338. Result := Buf;
  21339. break;
  21340. end;
  21341. end;
  21342. if Buf <> nil then
  21343. FreeMem( Buf );
  21344. end;
  21345. //[function Date2StrFmt]
  21346. function Date2StrFmt( const Fmt: String; D: TDateTime ): String;
  21347. var ST: TSystemTime;
  21348. lpFmt: PChar;
  21349. begin
  21350. DateTime2SystemTime( D, ST );
  21351. lpFmt := nil;
  21352. if Fmt <> '' then lpFmt := PChar( Fmt );
  21353. Result := SystemDate2Str( ST, LOCALE_USER_DEFAULT, dfShortDate, lpFmt );
  21354. end;
  21355. //[function Time2StrFmt]
  21356. function Time2StrFmt( const Fmt: String; D: TDateTime ): String;
  21357. var ST: TSystemTime;
  21358. lpFmt: PChar;
  21359. begin
  21360. if D < 1 then D := D + 1;
  21361. DateTime2SystemTime( D, ST );
  21362. lpFmt := nil;
  21363. if Fmt <> '' then lpFmt := PChar( Fmt );
  21364. Result := SystemTime2Str( ST, LOCALE_USER_DEFAULT, [], lpFmt );
  21365. end;
  21366. //[function DateTime2StrShort]
  21367. function DateTime2StrShort( D: TDateTime ): String;
  21368. var ST: TSystemTime;
  21369. begin
  21370. //--------- by Vadim Petrov --------++
  21371. if D < 1 then D := D + 1; //
  21372. //----------------------------------++
  21373. DateTime2SystemTime( D, ST );
  21374. Result := SystemDate2Str( ST, LOCALE_USER_DEFAULT {GetUserDefaultLCID}, dfShortDate, nil ) + ' ' +
  21375. SystemTime2Str( ST, LOCALE_USER_DEFAULT {GetUserDefaultLCID}, [], nil );
  21376. end;
  21377. //[function Str2DateTimeFmt]
  21378. function Str2DateTimeFmt( const sFmtStr, sS: String ): TDateTime;
  21379. var h12, hAM: Boolean;
  21380. FmtStr, S: PChar;
  21381. function GetNum( var S: PChar; NChars: Integer ): Integer;
  21382. begin
  21383. Result := 0;
  21384. while (S^ <> #0) and (NChars <> 0) do
  21385. begin
  21386. Dec( NChars );
  21387. if S^ in ['0'..'9'] then
  21388. begin
  21389. Result := Result * 10 + Ord(S^) - Ord('0');
  21390. Inc( S );
  21391. end
  21392. else
  21393. break;
  21394. end;
  21395. end;
  21396. function GetYear( var S: PChar; NChars: Integer ): Integer;
  21397. var STNow: TSystemTime;
  21398. OldDate: Boolean;
  21399. begin
  21400. Result := GetNum( S, NChars );
  21401. GetSystemTime( STNow );
  21402. OldDate := Result < 50;
  21403. Result := Result + STNow.wYear - STNow.wYear mod 100;
  21404. if OldDate then Dec( Result, 100 );
  21405. end;
  21406. function GetMonth( const fmt: String; var S: PChar ): Integer;
  21407. var SD: TSystemTime;
  21408. M: Integer;
  21409. C, MonthStr: String;
  21410. begin
  21411. GetSystemTime( SD );
  21412. for M := 1 to 12 do
  21413. begin
  21414. SD.wMonth := M;
  21415. C := SystemDate2Str( SD, LOCALE_USER_DEFAULT, dfLongDate, PChar( fmt + '/dd/yyyy/' ) );
  21416. MonthStr := Parse( C, '/' );
  21417. if AnsiCompareStrNoCase( MonthStr, Copy( S, 1, Length( MonthStr ) ) ) = 0 then
  21418. begin
  21419. Result := M;
  21420. Inc( S, Length( MonthStr ) );
  21421. Exit;
  21422. end;
  21423. end;
  21424. Result := 1;
  21425. end;
  21426. procedure SkipDayOfWeek( const fmt: String; var S: PChar );
  21427. var SD: TSystemTime;
  21428. Dt: TDateTime;
  21429. D: Integer;
  21430. C, DayWeekStr: String;
  21431. begin
  21432. GetSystemTime( SD );
  21433. SystemTime2DateTime( SD, Dt );
  21434. Dt := Dt - SD.wDayOfWeek;
  21435. for D := 0 to 6 do
  21436. begin
  21437. DateTime2SystemTime( Dt, SD );
  21438. C := SystemDate2Str( SD, LOCALE_USER_DEFAULT, dfLongDate, PChar( fmt + '/MM/yyyy/' ) );
  21439. DayWeekStr := Parse( C, '/' );
  21440. if AnsiCompareStrNoCase( DayWeekStr, Copy( S, 1, Length( DayWeekStr ) ) ) = 0 then
  21441. begin
  21442. Inc( S, Length( DayWeekStr ) );
  21443. Exit;
  21444. end;
  21445. Dt := Dt + 1.0;
  21446. end;
  21447. end;
  21448. procedure GetTimeMark( const fmt: String; var S: PChar );
  21449. var SD: TSystemTime;
  21450. AM: Boolean;
  21451. C, TimeMarkStr: String;
  21452. begin
  21453. GetSystemTime( SD );
  21454. SD.wHour := 0;
  21455. for AM := FALSE to TRUE do
  21456. begin
  21457. C := SystemDate2Str( SD, LOCALE_USER_DEFAULT, dfLongDate, PChar( fmt + '/HH/mm' ) );
  21458. TimeMarkStr := Parse( C, '/' );
  21459. if AnsiCompareStrNoCase( TimeMarkStr, Copy( S, 1, Length( TimeMarkStr ) ) ) = 0 then
  21460. begin
  21461. Inc( S, Length( TimeMarkStr ) );
  21462. hAM := AM;
  21463. Exit;
  21464. end;
  21465. SD.wHour := 13;
  21466. end;
  21467. Result := 1;
  21468. end;
  21469. function FmtIs1( S: PChar ): Boolean;
  21470. begin
  21471. if StrIsStartingFrom( FmtStr, S ) then
  21472. begin
  21473. Inc( FmtStr, StrLen( S ) );
  21474. Result := TRUE;
  21475. end
  21476. else
  21477. Result := FALSE;
  21478. end;
  21479. function FmtIs( S1, S2: PChar ): Boolean;
  21480. begin
  21481. Result := FmtIs1( S1 ) or FmtIs1( S2 );
  21482. end;
  21483. var ST: TSystemTime;
  21484. begin
  21485. FmtStr := PChar( sFmtStr);
  21486. S := PChar( sS );
  21487. FillChar( ST, Sizeof( ST ), 0 );
  21488. h12 := FALSE;
  21489. hAM := FALSE;
  21490. while (FmtStr^ <> #0) and (S^ <> #0) do
  21491. begin
  21492. if (FmtStr^ in ['a'..'z','A'..'Z']) and (S^ in ['0'..'9']) then
  21493. begin
  21494. if FmtIs1( 'yyyy' ) then ST.wYear := GetNum( S, 4 )
  21495. else if FmtIs1( 'yy' ) then ST.wYear := GetYear( S, 2 )
  21496. else if FmtIs1( 'y' ) then ST.wYear := GetYear( S, -1 )
  21497. else if FmtIs( 'dd', 'd' ) then ST.wDay := GetNum( S, 2 )
  21498. else if FmtIs( 'MM', 'M' ) then ST.wMonth := GetNum( S, 2 )
  21499. else if FmtIs( 'HH', 'H' ) then ST.wHour := GetNum( S, 2 )
  21500. else if FmtIs( 'hh', 'h' ) then begin ST.wHour := GetNum( S, 2 ); h12 := TRUE end
  21501. else if FmtIs( 'mm', 'm' ) then ST.wMinute := GetNum( S, 2 )
  21502. else if FmtIs( 'ss', 's' ) then ST.wSecond := GetNum( S, 2 )
  21503. else break; // + ECM
  21504. end
  21505. else
  21506. if (FmtStr^ in [ 'M', 'd', 'g' ]) then
  21507. begin
  21508. if FmtIs1( 'MMMM' ) then ST.wMonth := GetMonth( 'MMMM', S )
  21509. else if FmtIs1( 'MMM' ) then ST.wMonth := GetMonth( 'MMM', S )
  21510. else if FmtIs1( 'dddd' ) then SkipDayOfWeek( 'dddd', S )
  21511. else if FmtIs1( 'ddd' ) then SkipDayOfWeek( 'ddd', S )
  21512. else if FmtIs1( 'tt' ) then GetTimeMark( 'tt', S )
  21513. else if FmtIs1( 't' ) then GetTimeMark( 't', S )
  21514. else break; // + ECM
  21515. end
  21516. else
  21517. begin
  21518. if FmtStr^ = S^ then
  21519. Inc( FmtStr );
  21520. Inc( S );
  21521. end;
  21522. end;
  21523. if h12 then
  21524. if hAM then
  21525. Inc( ST.wHour, 12 );
  21526. SystemTime2DateTime( ST, Result );
  21527. end;
  21528. var FmtBuf: PChar;
  21529. DateSeparator : Char = #0; // + ECM
  21530. //[function Str2DateTimeShort]
  21531. function Str2DateTimeShort( const S: String ): TDateTime;
  21532. var FmtStr, FmtStr2: String;
  21533. function EnumDateFmt( lpstrFmt: PChar ): Boolean; stdcall;
  21534. begin
  21535. GetMem( FmtBuf, StrLen( lpstrFmt ) + 1 );
  21536. StrCopy( FmtBuf, lpstrFmt );
  21537. Result := FALSE;
  21538. end;
  21539. begin
  21540. FmtStr := 'dd.MM.yyyy';
  21541. FmtBuf := nil;
  21542. EnumDateFormats( @ EnumDateFmt, LOCALE_USER_DEFAULT, DATE_SHORTDATE );
  21543. if FmtBuf <> nil then
  21544. begin
  21545. FmtStr := FmtBuf;
  21546. FreeMem( FmtBuf );
  21547. end;
  21548. FmtStr2 := 'H:mm:ss';
  21549. FmtBuf := nil;
  21550. EnumTimeFormats( @ EnumDateFmt, LOCALE_USER_DEFAULT, 0 );
  21551. if FmtBuf <> nil then
  21552. begin
  21553. FmtStr2 := FmtBuf;
  21554. FreeMem( FmtBuf );
  21555. end;
  21556. Result := Str2DateTimeFmt( FmtStr + ' ' + FmtStr2, S );
  21557. end;
  21558. // + ECM
  21559. //[function Str2DateTimeShortEx]
  21560. function Str2DateTimeShortEx( const S: String ): TDateTime;
  21561. var St: String;
  21562. Buff: Array[0..1] of Char;
  21563. begin
  21564. if DateSeparator = #0 then
  21565. begin
  21566. if GetLocaleInfo(GetThreadLocale,LOCALE_SDATE,Buff,2) > 0 then
  21567. DateSeparator := Buff[0];
  21568. end;
  21569. St := S;
  21570. if Pos(DateSeparator,S) = 0 then
  21571. St := '0.0.0 '+S;
  21572. Result := Str2DateTimeShort(St);
  21573. end;
  21574. ///////////////////////////////////////////////////////////////////////
  21575. //
  21576. //
  21577. // T H R E A D S
  21578. //
  21579. //
  21580. ///////////////////////////////////////////////////////////////////////
  21581. { -- Thread -- }
  21582. //[function ThreadFunc]
  21583. function ThreadFunc(Thread: PThread): integer; stdcall;
  21584. begin
  21585. Result := Thread.Execute;
  21586. end;
  21587. {$IFDEF USE_CONSTRUCTORS}
  21588. //[function NewThread]
  21589. function NewThread: PThread;
  21590. begin
  21591. new( Result, ThreadCreate );
  21592. end;
  21593. //[END NewThread]
  21594. {$ELSE not_USE_CONSTRUCTORS}
  21595. //*
  21596. //[function NewThread]
  21597. function NewThread: PThread;
  21598. begin
  21599. {$IFNDEF FPC105ORBELOW}
  21600. IsMultiThread := True;
  21601. {$ENDIF}
  21602. {-}
  21603. New( Result, Create );
  21604. {+}
  21605. {++}(*Result := PThread.Create;*){--}
  21606. Result.FSuspended := True;
  21607. Result.FHandle := CreateThread( nil, // no security
  21608. 0, // the same stack size
  21609. @ThreadFunc, // thread entry point
  21610. Result, // parameter to pass to ThreadFunc
  21611. CREATE_SUSPENDED, // always SUSPENDED
  21612. Result.FThreadID ); // receive thread ID
  21613. end;
  21614. //[END NewThread]
  21615. {$ENDIF USE_CONSTRUCTORS}
  21616. {$IFDEF USE_CONSTRUCTORS}
  21617. //[function NewThreadEx]
  21618. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  21619. begin
  21620. new( Result, ThreadCreateEx( Proc ) );
  21621. end;
  21622. {$ELSE not_USE_CONSTRUCTORS}
  21623. //[FUNCTION NewThreadEx]
  21624. {$IFDEF ASM_VERSION}
  21625. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  21626. asm
  21627. CALL NewThread
  21628. POP EBP
  21629. POP ECX
  21630. POP EDX
  21631. MOV [EAX].TThread.fOnExecute.TMethod.Code, EDX
  21632. POP EDX
  21633. MOV [EAX].TThread.fOnExecute.TMethod.Data, EDX
  21634. PUSH ECX
  21635. PUSH EAX
  21636. CALL TThread.Resume
  21637. POP EAX
  21638. RET
  21639. end;
  21640. {$ELSE ASM_VERSION} //Pascal
  21641. function NewThreadEx( const Proc: TOnThreadExecute ): PThread;
  21642. begin
  21643. Result := NewThread;
  21644. Result.OnExecute := {++}(*{$IFDEF F_P} @ {$ENDIF}*){--}Proc;
  21645. Result.Resume;
  21646. end;
  21647. {$ENDIF ASM_VERSION}
  21648. //[END NewThreadEx]
  21649. {$ENDIF USE_CONSTRUCTORS}
  21650. //[function NewThreadAutoFree]
  21651. function NewThreadAutoFree( const Proc: TOnThreadExecute ): PThread;
  21652. begin
  21653. Result := NewThread;
  21654. Result.OnExecute := {++}(*{$IFDEF F_P} @ {$ENDIF}*){--}Proc;
  21655. Result.F_AutoFree := TRUE;
  21656. if Assigned( Proc ) then
  21657. Result.Resume;
  21658. end;
  21659. { TThread }
  21660. {$IFDEF ASM_VERSION}
  21661. //[destructor TThread.Destroy]
  21662. destructor TThread.Destroy;
  21663. asm
  21664. PUSH EBX
  21665. MOV EBX, EAX
  21666. CMP [EAX].FTerminated, 0
  21667. JNZ @@1
  21668. CALL Terminate
  21669. MOV EAX, EBX
  21670. CALL WaitFor
  21671. @@1: MOV ECX, [EBX].FHandle
  21672. JECXZ @@2
  21673. PUSH ECX
  21674. CALL CloseHandle
  21675. @@2: POP EAX
  21676. XCHG EBX, EAX
  21677. JMP TObj.Destroy
  21678. end;
  21679. {$ELSE ASM_VERSION} //Pascal
  21680. destructor TThread.Destroy;
  21681. begin
  21682. if not FTerminated then
  21683. begin
  21684. Terminate;
  21685. WaitFor;
  21686. end;
  21687. if (FHandle <> 0) then
  21688. CloseHandle(FHandle);
  21689. inherited;
  21690. end;
  21691. {$ENDIF ASM_VERSION}
  21692. //*
  21693. //[function TThread.Execute]
  21694. function TThread.Execute: integer;
  21695. begin
  21696. Result := 0;
  21697. if Assigned( FOnExecute ) then
  21698. Result := FOnExecute( @Self );
  21699. if F_AutoFree then
  21700. begin
  21701. FTerminated := TRUE; // fake thread object (to prevent terminating while freeing)
  21702. Free;
  21703. end;
  21704. end;
  21705. //*
  21706. //[function TThread.GetPriorityCls]
  21707. function TThread.GetPriorityCls: Integer;
  21708. begin
  21709. Result := GetPriorityClass(FHandle);
  21710. end;
  21711. //*
  21712. //[function TThread.GetThrdPriority]
  21713. function TThread.GetThrdPriority: Integer;
  21714. begin
  21715. Result := GetThreadPriority(FHandle);
  21716. end;
  21717. //*
  21718. //[procedure TThread.Resume]
  21719. procedure TThread.Resume;
  21720. begin
  21721. FSuspended := False;
  21722. if (ResumeThread(FHandle) > 1) then
  21723. FSuspended := True
  21724. else
  21725. if Assigned(FOnResume) then
  21726. FOnResume(@Self);
  21727. end;
  21728. //*
  21729. //[procedure TThread.SetPriorityCls]
  21730. procedure TThread.SetPriorityCls(Value: Integer);
  21731. begin
  21732. {$IFDEF DEBUG}
  21733. if not SetPriorityClass(GetCurrentProcess, Value) then
  21734. begin
  21735. ShowMessage( SysErrorMessage( GetLastError ) );
  21736. end;
  21737. {$ELSE}
  21738. SetPriorityClass(GetCurrentProcess, Value);
  21739. {$ENDIF}
  21740. end;
  21741. //*
  21742. //[procedure TThread.SetThrdPriority]
  21743. procedure TThread.SetThrdPriority(Value: Integer);
  21744. begin
  21745. SetThreadPriority(FHandle, Value);
  21746. end;
  21747. //*
  21748. //[procedure TThread.Suspend]
  21749. procedure TThread.Suspend;
  21750. begin
  21751. FSuspended := TRUE;
  21752. if Assigned(FOnSuspend) then
  21753. Synchronize( FOnSuspend );
  21754. SuspendThread(FHandle);
  21755. end;
  21756. //*
  21757. //[procedure CallSynchronized]
  21758. procedure CallSynchronized( Sender: PObj; Param: Pointer );
  21759. var Thread: PThread;
  21760. begin
  21761. Thread := PThread( Sender );
  21762. if Param <> nil then
  21763. Thread.FMethodEx( Thread, Param )
  21764. else
  21765. Thread.FMethod( );
  21766. end;
  21767. //*
  21768. //[procedure TThread.Synchronize]
  21769. procedure TThread.Synchronize(Method: TThreadMethod);
  21770. begin
  21771. Global_Synchronized := CallSynchronized;
  21772. FMethod := Method;
  21773. if Applet <> nil then
  21774. SendMessage( Applet.fHandle, CM_EXECPROC, 0, Integer( @Self ) );
  21775. end;
  21776. //[procedure TThread.SynchronizeEx]
  21777. procedure TThread.SynchronizeEx( Method: TThreadMethodEx; Param: Pointer );
  21778. begin
  21779. Assert( Param <> nil, 'Parameter must not be NIL' );
  21780. Global_Synchronized := CallSynchronized;
  21781. FMethodEx := Method;
  21782. SendMessage( Applet.fHandle, CM_EXECPROC, Integer( Param ), Integer( @Self ) );
  21783. end;
  21784. //*
  21785. //[procedure TThread.Terminate]
  21786. procedure TThread.Terminate;
  21787. begin
  21788. TerminateThread(FHandle,0);
  21789. FTerminated := True;
  21790. end;
  21791. //*
  21792. //[function TThread.WaitFor]
  21793. function TThread.WaitFor: Integer;
  21794. begin
  21795. RefInc;
  21796. Result := -1;
  21797. if FHandle = 0 then Exit;
  21798. WaitForSingleObject(FHandle, INFINITE);
  21799. GetExitCodeThread(FHandle, DWORD(Result));
  21800. RefDec;
  21801. end;
  21802. { TStream }
  21803. {* This part of the unit contains implementation of streams for KOL. Please note,
  21804. that both stream types (file stream and memory stream) are incapsulated
  21805. by a single object type TStream. To avoid including unnedeed code,
  21806. use constructing functions NewReadFileStream and NewWriteFileStream
  21807. to work with file streams, which do not require both types of operation. }
  21808. {* To create new type of stream, define your own methods, and in your
  21809. constructing function, pass it to _NewStream function (through
  21810. TStreamMethods record). In a field Custom, You can store a reference to
  21811. your own data of any type (but do not forget to define correct releasing
  21812. of such data in your fClose procedure). }
  21813. //[function TStream.GetPosition]
  21814. function TStream.GetPosition: DWord;
  21815. begin
  21816. Result := Seek( 0, spCurrent );
  21817. end;
  21818. //[procedure TStream.SetPosition]
  21819. procedure TStream.SetPosition(Value: DWord);
  21820. begin
  21821. Seek( Value, spBegin );
  21822. end;
  21823. {$IFDEF ASM_VERSION}
  21824. //[function TStream.GetSize]
  21825. function TStream.GetSize: DWord;
  21826. asm
  21827. CALL [EAX].fMethods.fGetSiz
  21828. end;
  21829. {$ELSE ASM_VERSION} //Pascal
  21830. function TStream.GetSize: DWord;
  21831. begin
  21832. Result := fMethods.fGetSiz( @Self );
  21833. end;
  21834. {$ENDIF ASM_VERSION}
  21835. {$IFDEF ASM_VERSION}
  21836. //[procedure TStream.SetSize]
  21837. procedure TStream.SetSize(NewSize: DWord);
  21838. asm
  21839. CALL [EAX].fMethods.fSetSiz
  21840. end;
  21841. {$ELSE ASM_VERSION} //Pascal
  21842. procedure TStream.SetSize(NewSize: DWord);
  21843. begin
  21844. fMethods.fSetSiz( @Self, NewSize );
  21845. end;
  21846. {$ENDIF ASM_VERSION}
  21847. //[function TStream.GetFileStreamHandle]
  21848. function TStream.GetFileStreamHandle: THandle;
  21849. begin
  21850. Result := fData.fHandle;
  21851. end;
  21852. {$IFDEF ASM_VERSION}
  21853. //[function TStream.Read]
  21854. function TStream.Read(var Buffer; Count: DWord): DWord;
  21855. asm
  21856. CALL [EAX].fMethods.fRead
  21857. end;
  21858. {$ELSE ASM_VERSION} //Pascal
  21859. function TStream.Read(var Buffer; Count: DWord): DWord;
  21860. begin
  21861. Result := fMethods.fRead( @Self, Buffer, Count );
  21862. end;
  21863. {$ENDIF ASM_VERSION}
  21864. //[function TStream.GetCapacity]
  21865. function TStream.GetCapacity: DWORD;
  21866. begin
  21867. Result := fData.fCapacity;
  21868. end;
  21869. //[procedure TStream.SetCapacity]
  21870. procedure TStream.SetCapacity(const Value: DWORD);
  21871. var OldSize: DWORD;
  21872. begin
  21873. if fData.fCapacity >= Value then Exit;
  21874. OldSize := Size;
  21875. Size := Value;
  21876. Size := OldSize;
  21877. end;
  21878. //[function TStream.Busy]
  21879. function TStream.Busy: Boolean;
  21880. begin
  21881. Result := Assigned( fData.fThread );
  21882. end;
  21883. //[function TStream.DoAsyncRead]
  21884. function TStream.DoAsyncRead( Sender: PThread ): Integer;
  21885. begin
  21886. Read( Pointer( fParam1 )^, fParam2 );
  21887. fData.fThread := nil;
  21888. Result := 0;
  21889. end;
  21890. //[procedure TStream.ReadAsync]
  21891. procedure TStream.ReadAsync(var Buffer; Count: DWord);
  21892. begin
  21893. if Busy then Wait;
  21894. fData.fThread := NewThreadAutoFree( nil );
  21895. fData.fThread.OnExecute := DoAsyncRead;
  21896. fParam1 := DWORD( @ Buffer );
  21897. fParam2 := Count;
  21898. fData.fThread.Resume;
  21899. end;
  21900. //[function TStream.DoAsyncSeek]
  21901. function TStream.DoAsyncSeek( Sender: PThread ): Integer;
  21902. begin
  21903. Seek( fParam1, TMoveMethod( fParam2 ) );
  21904. fData.fThread := nil;
  21905. Result := 0;
  21906. end;
  21907. //[procedure TStream.SeekAsync]
  21908. procedure TStream.SeekAsync(MoveTo: Integer; MoveMethod: TMoveMethod);
  21909. begin
  21910. if Busy then Wait;
  21911. fData.fThread := NewThreadAutoFree( nil );
  21912. fData.fThread.OnExecute := DoAsyncSeek;
  21913. fParam1 := MoveTo;
  21914. fParam2 := Ord( MoveMethod );
  21915. fData.fThread.Resume;
  21916. end;
  21917. //[function TStream.DoAsyncWrite]
  21918. function TStream.DoAsyncWrite( Sender: PThread ): Integer;
  21919. begin
  21920. Write( Pointer( fParam1 )^, fParam2 );
  21921. fData.fThread := nil;
  21922. Result := 0;
  21923. end;
  21924. //[procedure TStream.WriteAsync]
  21925. procedure TStream.WriteAsync(var Buffer; Count: DWord);
  21926. begin
  21927. if Busy then Wait;
  21928. fData.fThread := NewThreadAutoFree( nil );
  21929. fData.fThread.OnExecute := DoAsyncWrite;
  21930. fParam1 := DWORD( @ Buffer );
  21931. fParam2 := Count;
  21932. fData.fThread.Resume;
  21933. end;
  21934. //[procedure TStream.Wait]
  21935. procedure TStream.Wait;
  21936. begin
  21937. if not Assigned( fData.fThread ) then Exit;
  21938. if Assigned( fMethods.fWait ) then
  21939. fMethods.fWait( @Self )
  21940. else
  21941. fData.fThread.WaitFor;
  21942. end;
  21943. {$IFDEF ASM_VERSION}
  21944. //[function TStream.Write]
  21945. function TStream.Write(var Buffer; Count: DWord): DWord;
  21946. asm
  21947. CALL [EAX].fMethods.fWrite
  21948. end;
  21949. {$ELSE ASM_VERSION} //Pascal
  21950. function TStream.Write(var Buffer; Count: DWord): DWord;
  21951. begin
  21952. Result := fMethods.fWrite( @Self, Buffer, Count );
  21953. end;
  21954. {$ENDIF ASM_VERSION}
  21955. //[function TStream.WriteStr]
  21956. function TStream.WriteStr(S: String): DWORD;
  21957. begin
  21958. if S <> '' then
  21959. Result := fMethods.fWrite( @Self, S[1], Length( S ) )
  21960. else
  21961. Result := 0;
  21962. end;
  21963. //[function TStream.ReadStrZ]
  21964. function TStream.ReadStrZ: String;
  21965. var C: Char;
  21966. begin
  21967. Result := '';
  21968. REPEAT
  21969. C := #0;
  21970. Read( C, 1 );
  21971. if C <> #0 then Result := Result + C;
  21972. UNTIL C = #0;
  21973. end;
  21974. //[function TStream.ReadStr]
  21975. function TStream.ReadStr: String;
  21976. var C: Char;
  21977. begin
  21978. Result := '';
  21979. REPEAT
  21980. C := #0;
  21981. Read( C, 1 );
  21982. if C <> #0 then
  21983. begin
  21984. if C = #13 then
  21985. begin
  21986. C := #0;
  21987. Read( C, 1 );
  21988. if C <> #10 then Position := Position - 1;
  21989. C := #13;
  21990. end
  21991. else
  21992. if C = #10 then
  21993. C := #13;
  21994. if C <> #13 then
  21995. Result := Result + C;
  21996. end;
  21997. UNTIL C in [ #13, #0 ];
  21998. end;
  21999. //[function TStream.WriteStrZ]
  22000. function TStream.WriteStrZ(S: String): DWORD;
  22001. var C: Char;
  22002. begin
  22003. if S = '' then
  22004. begin
  22005. C := #0;
  22006. Result := Write( C, 1 );
  22007. end
  22008. else
  22009. Result := Write( S[ 1 ], Length( S ) + 1 );
  22010. end;
  22011. //[function TStream.WriteStrEx]
  22012. function TStream.WriteStrEx(S: String): DWord;
  22013. var L: DWORD;
  22014. begin
  22015. L := length(s);
  22016. result:=fmethods.fwrite(@self,L,Sizeof(DWORD));
  22017. if result = Sizeof(DWORD) then
  22018. Inc( result, fmethods.fwrite(@self,s[1],L) );
  22019. end;
  22020. //[function TStream.ReadStrExVar]
  22021. function TStream.ReadStrExVar(var S: String): DWord;
  22022. begin
  22023. fmethods.fread(@self,result,Sizeof(DWORD));
  22024. setlength(s,result);
  22025. if result<>0 then result:=fmethods.fread(@self,s[1],result);
  22026. end;
  22027. //[function TStream.ReadStrEx]
  22028. function TStream.ReadStrEx: String;
  22029. begin
  22030. readstrexvar(result);
  22031. end;
  22032. //[function TStream.WriteStrPas]
  22033. function TStream.WriteStrPas( S: String ): DWORD;
  22034. var L: Integer;
  22035. begin
  22036. Result := 0;
  22037. L := Length( S );
  22038. if L > 255 then L := 255;
  22039. if Write( L, 1 ) < 1 then Exit;
  22040. Result := 1;
  22041. if L > 0 then
  22042. Result := Write( S[ 1 ], L ) + 1;
  22043. end;
  22044. //[function TStream.ReadStrPas]
  22045. function TStream.ReadStrPas: String;
  22046. var L: Byte;
  22047. begin
  22048. Result := '';
  22049. if Read( L, 1 ) < 1 then Exit;
  22050. SetLength( Result, L );
  22051. L := Read( Result[ 1 ], L );
  22052. Result := Copy( Result, 1, L );
  22053. end;
  22054. {$IFDEF ASM_VERSION}
  22055. //[function TStream.Seek]
  22056. function TStream.Seek(MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  22057. asm
  22058. CALL [EAX].fMethods.fSeek
  22059. end;
  22060. {$ELSE ASM_VERSION} //Pascal
  22061. function TStream.Seek(MoveTo: integer; MoveMethod: TMoveMethod): DWord;
  22062. begin
  22063. Result := fMethods.fSeek( @Self, MoveTo, MoveMethod );
  22064. end;
  22065. {$ENDIF ASM_VERSION}
  22066. {$IFDEF ASM_VERSION}
  22067. //[destructor TStream.Destroy]
  22068. destructor TStream.Destroy;
  22069. asm
  22070. PUSH EAX
  22071. PUSH [EAX].fData.fThread
  22072. CALL [EAX].fMethods.fClose
  22073. POP EAX
  22074. CALL TObj.Free
  22075. POP EAX
  22076. CALL TObj.Destroy
  22077. end;
  22078. {$ELSE ASM_VERSION} //Pascal
  22079. destructor TStream.Destroy;
  22080. begin
  22081. fMethods.fClose( @Self );
  22082. fData.fThread.Free;
  22083. inherited;
  22084. end;
  22085. {$ENDIF ASM_VERSION}
  22086. //+-
  22087. //[function _NewStream]
  22088. function _NewStream( const StreamMethods: TStreamMethods ): PStream;
  22089. begin
  22090. {-}
  22091. New( Result, Create );
  22092. {+}{++}(*Result := PStream.Create;*){--}
  22093. Move( StreamMethods, Result.fMethods, Sizeof( TStreamMethods ) );
  22094. Result.fPMethods := @Result.fMethods;
  22095. end;
  22096. //+
  22097. //[function SeekFileStream]
  22098. function SeekFileStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  22099. begin
  22100. Result := FileSeek( Strm.fData.fHandle, MoveTo, MoveFrom );
  22101. end;
  22102. //+
  22103. //[function GetSizeFileStream]
  22104. function GetSizeFileStream( Strm: PStream ): DWORD;
  22105. begin
  22106. Result := GetFileSize( Strm.fData.fHandle, nil );
  22107. if Result = DWORD( -1 ) then Result := 0;
  22108. end;
  22109. //[procedure DummySetSize]
  22110. procedure DummySetSize( Strm: PStream; Value: DWORD );
  22111. begin
  22112. end;
  22113. //[procedure DummyStreamProc]
  22114. procedure DummyStreamProc(Strm: PStream);
  22115. begin
  22116. end;
  22117. //[function DummyReadWrite]
  22118. function DummyReadWrite( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22119. asm
  22120. XOR EAX, EAX
  22121. end;
  22122. //[function ReadFileStream]
  22123. function ReadFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22124. begin
  22125. Result := FileRead( Strm.fData.fHandle, Buffer, Count );
  22126. end;
  22127. //[function WriteFileStream]
  22128. function WriteFileStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22129. begin
  22130. Result := FileWrite( Strm.fData.fHandle, Buffer, Count );
  22131. end;
  22132. //[FUNCTION WriteFileStreamEOF]
  22133. {$IFDEF ASM_VERSION}
  22134. function WriteFileStreamEOF( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22135. asm
  22136. PUSH EBX
  22137. PUSH [EAX].TStream.fData.fHandle
  22138. CALL WriteFileStream
  22139. XCHG EBX, EAX
  22140. CALL SetEndOfFile
  22141. XCHG EAX, EBX
  22142. POP EBX
  22143. end;
  22144. {$ELSE ASM_VERSION} //Pascal
  22145. function WriteFileStreamEOF( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22146. begin
  22147. Result := WriteFileStream( Strm, Buffer, Count );
  22148. SetEndOfFile( Strm.fData.fHandle );
  22149. end;
  22150. {$ENDIF ASM_VERSION}
  22151. //[END WriteFileStreamEOF]
  22152. //[procedure CloseFileStream]
  22153. procedure CloseFileStream( Strm: PStream );
  22154. begin
  22155. FileClose( Strm.fData.fHandle );
  22156. end;
  22157. //[FUNCTION SeekMemStream]
  22158. {$IFDEF ASM_VERSION}
  22159. function SeekMemStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  22160. asm
  22161. PUSH EBX
  22162. MOV EBX, EDX
  22163. AND ECX, $FF
  22164. LOOP @@not_from_cur
  22165. ADD EBX, [EAX].TStream.fData.fPosition
  22166. @@not_from_cur:
  22167. LOOP @@not_from_end
  22168. ADD EBX, [EAX].TStream.fData.fSize
  22169. @@not_from_end:
  22170. CMP EBX, [EAX].TStream.fData.fSize
  22171. JLE @@space_ok
  22172. PUSH EAX
  22173. MOV EDX, EBX
  22174. CALL TStream.SetSize
  22175. POP EAX
  22176. @@space_ok:
  22177. XCHG EAX, EBX
  22178. MOV [EBX].TStream.fData.fPosition, EAX
  22179. POP EBX
  22180. end;
  22181. {$ELSE ASM_VERSION} //Pascal
  22182. function SeekMemStream( Strm: PStream; MoveTo: Integer; MoveFrom: TMoveMethod ): DWORD;
  22183. var NewPos: DWORD;
  22184. begin
  22185. case MoveFrom of
  22186. spBegin: NewPos := MoveTo;
  22187. spCurrent: NewPos := Strm.fData.fPosition + DWORD( MoveTo );
  22188. else //spEnd:
  22189. NewPos := Strm.fData.fSize + DWORD( MoveTo );
  22190. end;
  22191. if NewPos > Strm.fData.fSize then
  22192. Strm.SetSize( NewPos );
  22193. Strm.fData.fPosition := NewPos;
  22194. Result := NewPos;
  22195. end;
  22196. {$ENDIF ASM_VERSION}
  22197. //[END SeekMemStream]
  22198. //[function GetSizeMemStream]
  22199. function GetSizeMemStream( Strm: PStream ): DWORD;
  22200. begin
  22201. Result := Strm.fData.fSize;
  22202. end;
  22203. //[PROCEDURE SetSizeMemStream]
  22204. {$IFDEF ASM_VERSION}
  22205. procedure SetSizeMemStream( Strm: PStream; NewSize: DWORD );
  22206. asm
  22207. CMP [EAX].TStream.fData.fCapacity, EDX
  22208. JGE @@cap_ok
  22209. PUSH EDX
  22210. PUSH EAX
  22211. MOV ECX, [EAX].TStream.fMemory
  22212. JECXZ @@get_mem
  22213. TEST EDX, EDX
  22214. JZ @@free_mem
  22215. LEA EAX, [EAX].TStream.fMemory
  22216. CALL System.@ReallocMem
  22217. JMP @@1
  22218. @@get_mem:
  22219. XCHG EAX, EDX
  22220. CALL System.@GetMem
  22221. XCHG EDX, EAX
  22222. POP EAX
  22223. MOV [EAX].TStream.fMemory, EDX
  22224. JMP @@2
  22225. @@free_mem:
  22226. XCHG EDX, [EAX].TStream.fMemory
  22227. XCHG EAX, EDX
  22228. CALL System.@FreeMem
  22229. @@1:
  22230. POP EAX
  22231. @@2:
  22232. POP EDX
  22233. @@cap_ok:
  22234. MOV [EAX].TStream.fData.fSize, EDX
  22235. CMP [EAX].TStream.fData.fPosition, EDX
  22236. JLE @@exit
  22237. MOV [EAX].TStream.fData.fPosition, EDX
  22238. @@exit:
  22239. end;
  22240. {$ELSE ASM_VERSION} //Pascal
  22241. procedure SetSizeMemStream( Strm: PStream; NewSize: DWORD );
  22242. var S: PStream;
  22243. begin
  22244. S := Strm;
  22245. if S.fData.fCapacity < NewSize then
  22246. begin
  22247. if S.fMemory = nil then
  22248. begin
  22249. if NewSize <> 0 then
  22250. GetMem( S.fMemory, NewSize );
  22251. end
  22252. else
  22253. if NewSize = 0 then
  22254. begin
  22255. FreeMem( S.fMemory );
  22256. S.fMemory := nil;
  22257. end
  22258. else
  22259. ReallocMem( S.fMemory, NewSize );
  22260. S.fData.fCapacity := NewSize;
  22261. end;
  22262. S.fData.fSize := NewSize;
  22263. if S.fData.fPosition > S.fData.fSize then
  22264. S.fData.fPosition := S.fData.fSize;
  22265. end;
  22266. {$ENDIF ASM_VERSION}
  22267. //[END SetSizeMemStream]
  22268. //[FUNCTION ReadMemStream]
  22269. {$IFDEF ASM_VERSION}
  22270. function ReadMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22271. asm
  22272. PUSH EBX
  22273. XCHG EBX, EAX
  22274. MOV EAX, [EBX].TStream.fData.fPosition
  22275. ADD EAX, ECX
  22276. CMP EAX, [EBX].TStream.fData.fSize
  22277. JLE @@count_ok
  22278. MOV ECX, [EBX].TStream.fData.fSize
  22279. SUB ECX, [EBX].TStream.fData.fPosition
  22280. @@count_ok:
  22281. PUSH ECX
  22282. MOV EAX, [EBX].TStream.fMemory
  22283. ADD EAX, [EBX].TStream.fData.fPosition
  22284. CALL System.Move
  22285. POP EAX
  22286. ADD [EBX].TStream.fData.fPosition, EAX
  22287. POP EBX
  22288. end;
  22289. {$ELSE ASM_VERSION} //Pascal
  22290. function ReadMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22291. var S: PStream;
  22292. begin
  22293. S := Strm;
  22294. if Count + S.fData.fPosition > S.fData.fSize then
  22295. Count := S.fData.fSize - S.fData.fPosition;
  22296. Result := Count;
  22297. Move( Pointer( DWORD(S.fMemory) + S.fData.fPosition )^, Buffer, Result );
  22298. Inc( S.fData.fPosition, Result );
  22299. end;
  22300. {$ENDIF ASM_VERSION}
  22301. //[END ReadMemStream]
  22302. //[FUNCTION WriteMemStream]
  22303. {$IFDEF ASM_VERSION}
  22304. function WriteMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22305. asm
  22306. PUSH EBX
  22307. XCHG EBX, EAX
  22308. MOV EAX, [EBX].TStream.fData.fPosition
  22309. ADD EAX, ECX
  22310. CMP EAX, [EBX].TStream.fData.fSize
  22311. PUSH EDX
  22312. PUSH ECX
  22313. JLE @@count_ok
  22314. XCHG EDX, EAX
  22315. MOV EAX, EBX
  22316. CALL TStream.SetSize
  22317. @@count_ok:
  22318. POP ECX
  22319. POP EAX
  22320. MOV EDX, [EBX].TStream.fMemory
  22321. ADD EDX, [EBX].TStream.fData.fPosition
  22322. PUSH ECX
  22323. CALL System.Move
  22324. POP EAX
  22325. ADD [EBX].TStream.fData.fPosition, EAX
  22326. POP EBX
  22327. end;
  22328. {$ELSE ASM_VERSION} //Pascal
  22329. function WriteMemStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22330. var S: PStream;
  22331. begin
  22332. S := Strm;
  22333. if Count + S.fData.fPosition > S.fData.fSize then
  22334. S.SetSize( S.fData.fPosition + Count );
  22335. Result := Count;
  22336. Move( Buffer, Pointer( DWORD(S.fMemory) + S.fData.fPosition )^, Result );
  22337. Inc( S.fData.fPosition, Result );
  22338. end;
  22339. {$ENDIF ASM_VERSION}
  22340. //[END WriteMemStream]
  22341. //[PROCEDURE CloseMemStream]
  22342. {$IFDEF ASM_VERSION}
  22343. procedure CloseMemStream( Strm: PStream );
  22344. asm
  22345. MOV ECX, [EAX].TStream.fMemory
  22346. JECXZ @@exit
  22347. XCHG EAX, ECX
  22348. CALL System.@FreeMem
  22349. @@exit:
  22350. end;
  22351. {$ELSE ASM_VERSION} //Pascal
  22352. procedure CloseMemStream( Strm: PStream );
  22353. var S: PStream;
  22354. begin
  22355. S := Strm;
  22356. if S.fMemory <> nil then
  22357. FreeMem( S.fMemory );
  22358. end;
  22359. {$ENDIF ASM_VERSION}
  22360. //[END CloseMemStream]
  22361. const
  22362. BaseFileMethods: TStreamMethods = (
  22363. fSeek: SeekFileStream;
  22364. fGetSiz: GetSizeFileStream;
  22365. fSetSiz: DummySetSize;
  22366. fRead: DummyReadWrite;
  22367. fWrite: DummyReadWrite;
  22368. fClose: CloseFileStream;
  22369. fCustom: nil;
  22370. );
  22371. MemoryMethods: TStreamMethods = (
  22372. fSeek: SeekMemStream;
  22373. fGetSiz: GetSizeMemStream;
  22374. fSetSiz: SetSizeMemStream;
  22375. fRead: ReadMemStream;
  22376. fWrite: WriteMemStream;
  22377. fClose: CloseMemStream;
  22378. fCustom: nil;
  22379. );
  22380. // by Roman Vorobets:
  22381. //[procedure SetSizeFileStream]
  22382. procedure SetSizeFileStream( Strm: PStream; NewSize: DWORD );
  22383. var
  22384. P: DWORD;
  22385. begin
  22386. P:=Strm.Position;
  22387. Strm.Position:=NewSize;
  22388. SetEndOfFile(Strm.Handle);
  22389. if P < NewSize then
  22390. Strm.Position:=P;
  22391. end;
  22392. //[function NewFileStream]
  22393. function NewFileStream( const FileName: String; Options: DWORD ): PStream;
  22394. begin
  22395. Result := _NewStream( BaseFileMethods );
  22396. Result.fMethods.fRead := ReadFileStream;
  22397. Result.fMethods.fWrite := WriteFileStream; // not WriteStreamEOF, Àëåêñåé Øóâàëîâ
  22398. Result.fMethods.fSetSiz := SetSizeFileStream;
  22399. Result.fData.fHandle := FileCreate( FileName, Options );
  22400. end;
  22401. //[FUNCTION NewReadFileStream]
  22402. {$IFDEF ASM_VERSION}
  22403. function NewReadFileStream( const FileName: String ): PStream;
  22404. asm
  22405. PUSH EBX
  22406. XCHG EBX, EAX
  22407. MOV EAX, offset[BaseFileMethods]
  22408. CALL _NewStream
  22409. MOV [EAX].TStream.fMethods.fRead, offset[ReadFileStream]
  22410. XCHG EBX, EAX
  22411. MOV EDX, ofOpenRead or ofOpenExisting or ofShareDenyWrite
  22412. CALL FileCreate
  22413. MOV [EBX].TStream.fData.fHandle, EAX
  22414. XCHG EAX, EBX
  22415. POP EBX
  22416. end;
  22417. {$ELSE ASM_VERSION} //Pascal
  22418. function NewReadFileStream( const FileName: String ): PStream;
  22419. begin
  22420. Result := _NewStream( BaseFileMethods );
  22421. Result.fMethods.fRead := ReadFileStream;
  22422. Result.fData.fHandle := FileCreate( FileName,
  22423. ofOpenRead or ofShareDenyWrite or ofOpenExisting );
  22424. end;
  22425. {$ENDIF ASM_VERSION}
  22426. //[END NewReadFileStream]
  22427. //[FUNCTION NewWriteFileStream]
  22428. {$IFDEF ASM_VERSION}
  22429. function NewWriteFileStream( const FileName: String ): PStream;
  22430. asm
  22431. PUSH EBX
  22432. XCHG EBX, EAX
  22433. MOV EAX, offset[BaseFileMethods]
  22434. CALL _NewStream
  22435. MOV [EAX].TStream.fMethods.fWrite, offset[WriteFileStreamEOF]
  22436. MOV [EAX].TStream.fMethods.fSetSiz, offset[SetSizeFileStream]
  22437. XCHG EBX, EAX
  22438. MOV EDX, ofOpenWrite or ofCreateAlways or ofShareDenyWrite
  22439. CALL FileCreate
  22440. MOV [EBX].TStream.fData.fHandle, EAX
  22441. XCHG EAX, EBX
  22442. POP EBX
  22443. end;
  22444. {$ELSE ASM_VERSION} //Pascal
  22445. function NewWriteFileStream( const FileName: String ): PStream;
  22446. begin
  22447. Result := _NewStream( BaseFileMethods );
  22448. Result.fMethods.fWrite := WriteFileStreamEOF;
  22449. Result.fMethods.fSetSiz := SetSizeFileStream;
  22450. Result.fData.fHandle := FileCreate( FileName,
  22451. ofOpenWrite or ofCreateAlways or ofShareDenyWrite );
  22452. end;
  22453. {$ENDIF ASM_VERSION}
  22454. //[END NewWriteFileStream]
  22455. //[FUNCTION NewReadWriteFileStream]
  22456. {$IFDEF ASM_noVERSION}
  22457. function NewReadWriteFileStream( const FileName: String ): PStream;
  22458. asm
  22459. PUSH EBX
  22460. XCHG EBX, EAX
  22461. MOV EAX, offset[BaseFileMethods]
  22462. CALL _NewStream
  22463. MOV [EAX].TStream.fMethods.fRead, offset[ReadFileStream]
  22464. MOV [EAX].TStream.fMethods.fWrite, offset[WriteFileStream]
  22465. MOV [EAX].TStream.fMethods.fSetSiz, offset[SetSizeFileStream]
  22466. XCHG EBX, EAX
  22467. PUSH EAX
  22468. CALL FileExists
  22469. MOV EDX, ofOpenReadWrite or ofCreateAlways or ofShareDenyWrite
  22470. ADD DH, AL // $200 (ofCreateAlways) -> $300 (ofCreateExisting)
  22471. POP EAX
  22472. CALL FileCreate
  22473. MOV [EBX].TStream.fData.fHandle, EAX
  22474. XCHG EAX, EBX
  22475. POP EBX
  22476. end;
  22477. {$ELSE ASM_VERSION} //Pascal
  22478. function NewReadWriteFileStream( const FileName: String ): PStream;
  22479. var Creation: DWORD;
  22480. begin
  22481. Result := _NewStream( BaseFileMethods );
  22482. Result.fMethods.fRead := ReadFileStream;
  22483. Result.fMethods.fWrite := WriteFileStream;
  22484. Result.fMethods.fSetSiz := SetSizeFileStream;
  22485. Creation := ofCreateAlways;
  22486. if FileExists( FileName ) then Creation := ofOpenExisting;
  22487. Result.fData.fHandle := FileCreate( FileName,
  22488. ofOpenReadWrite or Creation or ofShareDenyWrite );
  22489. end;
  22490. {$ENDIF ASM_VERSION}
  22491. //[END NewReadWriteFileStream]
  22492. //[function NewMemoryStream]
  22493. function NewMemoryStream: PStream;
  22494. begin
  22495. Result := _NewStream( MemoryMethods );
  22496. end;
  22497. //[FUNCTION WriteExMemoryStream]
  22498. {$IFDEF ASM_VERSION}
  22499. function WriteExMemoryStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22500. asm
  22501. PUSH EBX
  22502. XCHG EBX, EAX
  22503. MOV EAX, [EBX].TStream.fData.fSize
  22504. SUB EAX, [EBX].TStream.fData.fPosition
  22505. CMP EAX, ECX
  22506. JGE @@1
  22507. XCHG ECX, EAX
  22508. @@1:
  22509. PUSH EDX
  22510. PUSH ECX
  22511. JLE @@count_ok
  22512. XCHG EDX, EAX
  22513. MOV EAX, EBX
  22514. CALL TStream.SetSize
  22515. @@count_ok:
  22516. POP ECX
  22517. POP EAX
  22518. MOV EDX, [EBX].TStream.fMemory
  22519. ADD EDX, [EBX].TStream.fData.fPosition
  22520. PUSH ECX
  22521. CALL System.Move
  22522. POP EAX
  22523. ADD [EBX].TStream.fData.fPosition, EAX
  22524. POP EBX
  22525. end;
  22526. {$ELSE ASM_VERSION}
  22527. function WriteExMemoryStream( Strm: PStream; var Buffer; Count: DWORD ): DWORD;
  22528. var S: PStream;
  22529. begin
  22530. S := Strm;
  22531. if Count + S.fData.fPosition > S.fData.fSize then
  22532. Count := S.fData.fSize - S.fData.fPosition;
  22533. Result := Count;
  22534. Move( Buffer, Pointer( DWORD(S.fMemory) + S.fData.fPosition )^, Result );
  22535. Inc( S.fData.fPosition, Result );
  22536. end;
  22537. {$ENDIF ASM_VERSION}
  22538. //[END WriteExMemoryStream]
  22539. //[procedure DummyClose_ExMemStream]
  22540. procedure DummyClose_ExMemStream( Strm: PStream );
  22541. begin
  22542. // nothing to do - ignore call (memory is not released by any way)
  22543. end;
  22544. //[function NewExMemoryStream]
  22545. function NewExMemoryStream( ExistingMem: Pointer; Size: DWORD ): PStream;
  22546. begin
  22547. Result := NewMemoryStream;
  22548. Result.fMemory := ExistingMem;
  22549. Result.fData.fCapacity := Size;
  22550. Result.fData.fSize := Size;
  22551. Result.fMethods.fWrite := WriteExMemoryStream;
  22552. Result.fMethods.fSetSiz := DummySetSize;
  22553. Result.fMethods.fClose := DummyClose_ExMemStream;
  22554. end;
  22555. //*
  22556. //[function Stream2Stream]
  22557. function Stream2Stream( Dst, Src: PStream; Count: DWORD ): DWORD;
  22558. var Buf: Pointer;
  22559. begin
  22560. if Src.fMemory <> nil then
  22561. begin
  22562. if Src.fData.fPosition + Count > Src.fData.fSize then
  22563. Count := Src.fData.fSize - Src.fData.fPosition;
  22564. Result := Dst.Write( Pointer(DWORD(Src.fMemory)+Src.fData.fPosition)^,
  22565. Count );
  22566. Inc( Src.fData.fPosition, Result );
  22567. end
  22568. else
  22569. if Dst.fMemory <> nil then
  22570. begin
  22571. if Dst.fData.fPosition + Count > Dst.fData.fSize then
  22572. Dst.SetSize( Dst.fData.fPosition + Count );
  22573. Result := Src.Read( Pointer( DWORD( Dst.fMemory ) + Dst.fData.fPosition )^,
  22574. Count );
  22575. Inc( Dst.fData.fPosition, Result );
  22576. end
  22577. else
  22578. begin
  22579. GetMem( Buf, Count );
  22580. Count := Src.Read( Buf^, Count );
  22581. Result := Dst.Write( Buf^, Count );
  22582. FreeMem( Buf );
  22583. end;
  22584. end;
  22585. //[function Stream2StreamEx]
  22586. function Stream2StreamEx( Dst, Src: PStream; Count: DWORD ): DWORD;
  22587. begin
  22588. Result := Stream2StreamExBufSz( Dst, Src, Count, 65536 );
  22589. end;
  22590. //[function Stream2StreamExBufSz]
  22591. function Stream2StreamExBufSz( Dst, Src: PStream; Count, BufSz: DWORD ): DWORD;
  22592. var
  22593. buf:pointer;
  22594. rd, wr:dword;
  22595. begin
  22596. if count=0 then result:=0 else
  22597. begin
  22598. result:=0;
  22599. BufSz := Min( BufSz, Count );
  22600. if BufSz = 0 then BufSz := Count;
  22601. getmem(buf,BufSz);
  22602. repeat
  22603. if count<BufSz then rd:=count else rd:=BufSz;
  22604. rd:=src.read(buf^,rd);
  22605. wr := dst.write(buf^,rd);
  22606. inc(result,wr);
  22607. dec(Count, rd);
  22608. until (rd<>BufSz) or (Count=0);
  22609. freemem(buf);
  22610. end;
  22611. end;
  22612. //[FUNCTION Resource2Stream]
  22613. {$IFDEF ASM_VERSION}
  22614. function Resource2Stream( DestStrm : PStream; Inst : HInst;
  22615. ResName : PChar; ResType : PChar ): Integer;
  22616. asm
  22617. PUSH EBX
  22618. PUSH ESI
  22619. MOV EBX, EDX // EBX = Inst
  22620. PUSH EAX // DestStrm
  22621. PUSH ResType
  22622. PUSH ECX
  22623. PUSH EDX
  22624. CALL FindResource
  22625. TEST EAX, EAX
  22626. JZ @@exit0
  22627. PUSH EAX
  22628. PUSH EBX
  22629. PUSH EAX
  22630. PUSH EBX
  22631. CALL SizeofResource
  22632. XCHG EBX, EAX
  22633. CALL LoadResource
  22634. TEST EAX, EAX
  22635. JZ @@exit0
  22636. XCHG ESI, EAX
  22637. PUSH ESI
  22638. CALL GlobalLock
  22639. TEST EAX, EAX
  22640. JNZ @@P_ok
  22641. CALL GetLastError
  22642. CMP EAX, ERROR_INVALID_HANDLE
  22643. JNZ @@exit_00
  22644. MOV EAX, ESI
  22645. @@P_ok:
  22646. XCHG EDX, EAX
  22647. POP EAX // DestStrm
  22648. PUSH EDX
  22649. MOV ECX, EBX
  22650. CALL TStream.Write
  22651. //EAX = Result (length of written data)
  22652. XCHG EBX, EAX
  22653. POP EAX
  22654. CMP ESI, EAX
  22655. JE @@not_unlock
  22656. PUSH ESI
  22657. CALL GlobalUnlock
  22658. @@not_unlock:
  22659. XCHG EAX, EBX
  22660. JMP @@exit
  22661. @@exit_00:
  22662. XOR EAX, EAX
  22663. @@exit0:
  22664. POP ECX
  22665. @@exit:
  22666. POP ESI
  22667. POP EBX
  22668. end;
  22669. {$ELSE ASM_VERSION} //Pascal
  22670. function Resource2Stream( DestStrm : PStream; Inst : HInst;
  22671. ResName : PChar; ResType : PChar ): Integer;
  22672. var R : HRSRC;
  22673. G : HGlobal;
  22674. P : PChar;
  22675. Sz : DWORD;
  22676. E : Integer;
  22677. begin
  22678. Result := 0;
  22679. R := FindResource( Inst, ResName, ResType );
  22680. if R <> 0 then
  22681. begin
  22682. Sz := SizeofResource( Inst, R );
  22683. G := LoadResource( Inst, R );
  22684. if G <> 0 then
  22685. begin
  22686. P := GlobalLock( G );
  22687. if P = nil then
  22688. begin
  22689. E := GetLastError;
  22690. if E = ERROR_INVALID_HANDLE then
  22691. P := Pointer( G )
  22692. else
  22693. Exit;
  22694. end;
  22695. Result := DestStrm.Write( P^, Sz );
  22696. if P <> Pointer( G ) then
  22697. GlobalUnlock( G );
  22698. //FreeResource( G );
  22699. { from Win32.hlp: "You do not need to call the FreeResource
  22700. function to free a resource loaded by using the LoadResource
  22701. function." }
  22702. end;
  22703. end;
  22704. end;
  22705. {$ENDIF ASM_VERSION}
  22706. //[END Resource2Stream]
  22707. ///////////////////////////////////////////////////////////////////////////
  22708. //
  22709. //
  22710. // I N I - F I L E S
  22711. //
  22712. //
  22713. ///////////////////////////////////////////////////////////////////////////
  22714. { TIniFile }
  22715. {$IFDEF ASM_VERSION}
  22716. //[destructor TIniFile.Destroy]
  22717. destructor TIniFile.Destroy;
  22718. asm //cmd //opd
  22719. PUSH EAX
  22720. LEA EDX, [EAX].fFileName
  22721. PUSH EDX
  22722. LEA EAX, [EAX].fSection
  22723. CALL System.@LStrClr
  22724. POP EAX
  22725. CALL System.@LStrClr
  22726. POP EAX
  22727. CALL TObj.Destroy
  22728. end;
  22729. {$ELSE ASM_VERSION} //Pascal
  22730. destructor TIniFile.Destroy;
  22731. begin
  22732. fFileName := '';
  22733. fSection := '';
  22734. inherited;
  22735. end;
  22736. {$ENDIF ASM_VERSION}
  22737. {$IFNDEF _D5orHigher}
  22738. // Place here correct definition for WritePrivateProfileStruct
  22739. // and GetPrivateProfileStruct (a bug in Delphi2, Delphi3 and Delphi4)
  22740. //[API WritePrivateProfileStruct]
  22741. function WritePrivateProfileStruct(lpszSection, lpszKey: PChar;
  22742. lpStruct: Pointer; uSizeStruct: UINT; szFile: PChar): BOOL; stdcall;
  22743. external kernel32 name 'WritePrivateProfileStructA';
  22744. //[API GetPrivateProfileStruct]
  22745. function GetPrivateProfileStruct(lpszSection, lpszKey: PAnsiChar;
  22746. lpStruct: Pointer; uSizeStruct: UINT; szFile: PAnsiChar): BOOL; stdcall;
  22747. external kernel32 name 'GetPrivateProfileStructA';
  22748. // + by Slava A. Gavrik:
  22749. ////////////////////////////////////////////////////////////////////////////
  22750. //[function WritePrivateProfileSection]
  22751. function WritePrivateProfileSection(lpAppName, lpString,
  22752. lpFileName: PChar): BOOL; stdcall;
  22753. external kernel32 name 'WritePrivateProfileSectionA';
  22754. //[function GetPrivateProfileSection]
  22755. function GetPrivateProfileSection(lpAppName: PChar; lpReturnedString: PChar;
  22756. nSize: DWORD; lpFileName: PChar): DWORD; stdcall;
  22757. external kernel32 name 'GetPrivateProfileSectionA';
  22758. //[function GetPrivateProfileSectionNames]
  22759. function GetPrivateProfileSectionNames(lpszReturnBuffer: PChar; nSize:
  22760. DWORD;
  22761. lpFileName: PChar): DWORD; stdcall;
  22762. external kernel32 name 'GetPrivateProfileSectionNamesA';
  22763. ////////////////////////////////////////////////////////////////////////////
  22764. {$ENDIF}
  22765. //[procedure TIniFile.ClearAll]
  22766. procedure TIniFile.ClearAll;
  22767. begin
  22768. WritePrivateProfileString( nil, nil, nil,
  22769. PChar( fFileName ) );
  22770. end;
  22771. //[procedure TIniFile.ClearKey]
  22772. procedure TIniFile.ClearKey(const Key: String);
  22773. begin
  22774. WritePrivateProfileString( PChar( fSection ), PChar( Key ), nil,
  22775. PChar( fFileName ) );
  22776. end;
  22777. //[procedure TIniFile.ClearSection]
  22778. procedure TIniFile.ClearSection;
  22779. begin
  22780. WritePrivateProfileString( PChar( fSection ), nil, nil,
  22781. PChar( fFileName ) );
  22782. end;
  22783. //[function TIniFile.ValueBoolean]
  22784. function TIniFile.ValueBoolean(const Key: String; Value: Boolean): Boolean;
  22785. begin
  22786. if fMode = ifmRead then
  22787. Result := GetPrivateProfileInt( PChar( fSection ), PChar( Key ),
  22788. Integer( Value ), PChar( fFileName ) ) <> 0
  22789. else
  22790. begin
  22791. WritePrivateProfileString( PChar( fSection ), PChar( Key ),
  22792. PChar( Int2Str( Integer( Value ) ) ), PChar( fFileName ) );
  22793. Result := Value;
  22794. end;
  22795. end;
  22796. //[function TIniFile.ValueData]
  22797. function TIniFile.ValueData(const Key: String; Value: Pointer;
  22798. Count: Integer): Boolean;
  22799. begin
  22800. if fMode = ifmRead then
  22801. Result := GetPrivateProfileStruct( PChar( fSection ), PChar( Key ),
  22802. Value, Count, PChar( fFileName ) )
  22803. else
  22804. Result := WritePrivateProfileStruct( PChar( fSection ), PChar( Key ),
  22805. Value, Count, PChar( fFileName ) );
  22806. end;
  22807. //[function TIniFile.ValueInteger]
  22808. function TIniFile.ValueInteger(const Key: String; Value: Integer): Integer;
  22809. begin
  22810. if fMode = ifmRead then
  22811. Result := GetPrivateProfileInt( PChar( fSection ), PChar( Key ),
  22812. Integer( Value ), PChar( fFileName ) )
  22813. else
  22814. begin
  22815. Result := Value;
  22816. WritePrivateProfileString( PChar( fSection ), PChar( Key ),
  22817. PChar( Int2Str( Value ) ), PChar( fFileName ) );
  22818. end;
  22819. end;
  22820. //[function TIniFile.ValueString]
  22821. function TIniFile.ValueString(const Key, Value: String): String;
  22822. var
  22823. Buffer: array[0..2047] of Char;
  22824. begin
  22825. if fMode = ifmRead then
  22826. begin
  22827. Buffer[ 0 ] := #0;
  22828. GetPrivateProfileString(PChar(fSection),
  22829. PChar(Key), PChar(Value), Buffer, SizeOf(Buffer), PChar(fFileName));
  22830. Result := Buffer;
  22831. end
  22832. else
  22833. begin
  22834. Result := Value;
  22835. WritePrivateProfileString( PChar( fSection ), PChar( Key ),
  22836. PChar( Value ), PChar( fFileName ) );
  22837. end;
  22838. end;
  22839. //[function OpenIniFile]
  22840. function OpenIniFile( const FileName: String ): PIniFile;
  22841. begin
  22842. {-}
  22843. New( Result, Create );
  22844. {+}{++}(*Result := PIniFile.Create;*){--}
  22845. Result.fFileName := FileName;
  22846. end;
  22847. /////////////////////////////////////////////////// GetSectionNames, SectionData
  22848. // - by Vyacheslav A. Gavrik :
  22849. const
  22850. IniBufferSize = 32767;
  22851. IniBufferStrSize = IniBufferSize+4; /// äëÿ ìàõèíàöèé :)
  22852. {$IFDEF ASM_VERSION}
  22853. //[procedure _FillStrList]
  22854. procedure _FillStrList; // Ýòà ÷àñòü êîäà îáùàÿ äëÿ äâóõ ñëåäóþùèõ ïðîöåäóð
  22855. asm
  22856. ///////////////////////////////
  22857. OR EAX,0
  22858. JE @@EXIT //ERROR
  22859. // LEA EAX,[EAX-IniBufferSize]
  22860. // JE @@EXIT
  22861. // âîçìîæíà íåõâàòêà Áóôåðà... â ïðèíöèïå íå îøèáêà :)
  22862. // âîçâðàùàåì ÷òî âëåçëî...
  22863. //////////////////////////////
  22864. @@LOOP:
  22865. LEA EAX,[ESI+4]
  22866. CALL StrLen
  22867. MOV [ESI],EAX
  22868. LEA EDX,[ESI+4]
  22869. INC EAX
  22870. ADD ESI,EAX
  22871. MOV EAX,EDI
  22872. CALL TStrList.ADD
  22873. CMP byte ptr [ESI+4],0
  22874. JNE @@LOOP
  22875. @@EXIT:
  22876. POP EAX
  22877. CALL System.@FreeMem
  22878. POP ECX
  22879. POP EBX
  22880. POP EDI
  22881. POP ESI
  22882. end;
  22883. //[procedure TIniFile.GetSectionNames]
  22884. procedure TIniFile.GetSectionNames(Names: PStrList);
  22885. asm
  22886. PUSH ESI
  22887. PUSH EDI
  22888. PUSH EBX
  22889. PUSH ECX
  22890. MOV EBX,EAX
  22891. MOV EAX, IniBufferStrSize
  22892. MOV EDI,EDX
  22893. CALL System.@GetMem
  22894. MOV ESI,EAX
  22895. PUSH EAX
  22896. PUSH [EBX].fFileName
  22897. MOV EAX,IniBufferSize
  22898. PUSH EAX
  22899. LEA EAX,[ESI+4]
  22900. PUSH EAX
  22901. CALL GetPrivateProfileSectionNames
  22902. JMP _FillStrList
  22903. end;
  22904. //[procedure TIniFile.SectionData]
  22905. procedure TIniFile.SectionData(Names: PStrList);
  22906. asm
  22907. PUSH ESI
  22908. PUSH EDI
  22909. PUSH EBX
  22910. PUSH ECX
  22911. MOV EBX,EAX
  22912. MOV EAX, IniBufferStrSize
  22913. MOV EDI,EDX
  22914. CALL System.@GetMem
  22915. MOV ESI,EAX
  22916. PUSH EAX
  22917. OR [EBX].fMode,0
  22918. JNE @@DOWrite
  22919. PUSH [EBX].fFileName
  22920. MOV EAX,IniBufferSize
  22921. PUSH EAX
  22922. LEA EAX,[ESI+4]
  22923. PUSH EAX
  22924. PUSH [EBX].fSection
  22925. CALL GetPrivateProfileSection
  22926. JMP _FillStrList
  22927. @@DOWrite:
  22928. PUSH EBX
  22929. PUSH ESI
  22930. PUSH EDX
  22931. PUSH EBP
  22932. MOV EDX,0
  22933. MOV EBP,[EDI].TStrList.fCount
  22934. MOV EBX,IniBufferSize-2 // îñòàâèì ìåñòî äëÿ #0#0
  22935. {ECM+++>} OR EBP,EBP // otherwise GetPChars when StrList.Count = 0 crashed
  22936. @@LOOP:
  22937. JE @@ENDLOOP
  22938. OR EBX,EBX
  22939. JE @@ENDLOOP
  22940. PUSH EDX
  22941. MOV EAX,EDI
  22942. CALL TStrList.GetPChars
  22943. PUSH EAX
  22944. CALL StrLen
  22945. POP EAX
  22946. XOR ECX,-1
  22947. MOV EDX,ESI
  22948. SUB EBX,ECX
  22949. JA @@L1
  22950. ADD ECX,EBX
  22951. XOR EBX,EBX
  22952. @@L1:
  22953. ADD ESI,ECX
  22954. CALL MOVE
  22955. @@L2:
  22956. POP EDX
  22957. INC EDX
  22958. DEC EBP
  22959. JMP @@LOOP
  22960. @@ENDLOOP:
  22961. MOV WORD PTR [ESI],0
  22962. POP EBP
  22963. POP EDX
  22964. POP ESI
  22965. POP EBX
  22966. ///////////////////////////////////
  22967. MOV EAX,EBX // íîäî î÷èùàòü
  22968. CALL ClearSection
  22969. //////////////////////////////////
  22970. PUSH [EBX].fFileName
  22971. PUSH ESI
  22972. PUSH [EBX].fSection
  22973. CALL WritePrivateProfileSection
  22974. POP EAX
  22975. CALL System.@FreeMem
  22976. POP ECX
  22977. POP EBX
  22978. POP EDI
  22979. POP ESI
  22980. end;
  22981. {$ELSE ASM_VERSION} //Pascal
  22982. //[procedure TIniFile.GetSectionNames]
  22983. procedure TIniFile.GetSectionNames(Names: PStrList);
  22984. var
  22985. i:integer;
  22986. Pc:PChar;
  22987. PcEnd:PChar;
  22988. Buffer:Pointer;
  22989. begin
  22990. GetMem(Buffer,IniBufferSize);
  22991. Pc:=Buffer;
  22992. i := GetPrivateProfileSectionNames(Buffer, IniBufferSize, PChar(fFileName));
  22993. PcEnd:=Pc+i;
  22994. repeat
  22995. Names.Add(Pc);
  22996. Pc:=PC+Length(PC)+1;
  22997. until PC>=PcEnd;
  22998. FreeMem(Buffer);
  22999. end;
  23000. //[procedure TIniFile.SectionData]
  23001. procedure TIniFile.SectionData(Names: PStrList);
  23002. var
  23003. i:integer;
  23004. Pc:PChar;
  23005. PcEnd:PChar;
  23006. Buffer:Pointer;
  23007. begin
  23008. GetMem(Buffer,IniBufferSize);
  23009. Pc:=Buffer;
  23010. if fMode = ifmRead then
  23011. begin
  23012. i:=GetPrivateProfileSection(PChar(fSection), Buffer, IniBufferSize, PChar(fFileName));
  23013. PcEnd:=Pc+i;
  23014. while PC < PcEnd do // Chg by ECM from REPEAT-UNTIL: i=0 (empty section) => Names.Count=1
  23015. begin
  23016. Names.Add(Pc);
  23017. Pc:=PC+Length(PC)+1;
  23018. end;
  23019. end else
  23020. begin
  23021. for i:= 0 to Names.Count-1 do
  23022. begin
  23023. StrCopy(Pc,Names.ItemPtrs[i]);
  23024. Pc:=PC+Length(PC)+1;
  23025. end;
  23026. Pc[0]:=#0;
  23027. ClearSection;
  23028. WritePrivateProfileSection(PChar(fSection), Buffer, PChar(fFileName));
  23029. end;
  23030. FreeMem(Buffer);
  23031. end;
  23032. {$ENDIF ASM_VERSION}
  23033. //////////////////////////////////////////////////////////////////////
  23034. /////////////////////////////////////////////////////////////////////////
  23035. //
  23036. //
  23037. // M E N U
  23038. //
  23039. //
  23040. /////////////////////////////////////////////////////////////////////////
  23041. { -- Menu implementation -- }
  23042. //[FUNCTION MakeAccelerator]
  23043. {$IFDEF ASM_VERSION}
  23044. function MakeAccelerator( fVirt: Byte; Key: Word ): TMenuAccelerator;
  23045. asm
  23046. MOVZX EAX, AL
  23047. PUSH EAX
  23048. MOV [ESP+1], DX
  23049. POP EAX
  23050. end;
  23051. {$ELSE ASM_VERSION} //Pascal
  23052. function MakeAccelerator( fVirt: Byte; Key: Word ): TMenuAccelerator;
  23053. begin
  23054. Result.fVirt := fVirt;
  23055. Result.Key := Key;
  23056. end;
  23057. {$ENDIF ASM_VERSION}
  23058. //[END MakeAccelerator]
  23059. //[FUNCTION GetAcceleratorText]
  23060. function GetAcceleratorText( const Accelerator: TMenuAccelerator ): string;
  23061. var
  23062. KeyName: array[0..255] of Char;
  23063. procedure AddKeyName( Code: Integer );
  23064. begin
  23065. Code := MapVirtualKey(Code, 0);
  23066. if Code = 0 then exit;
  23067. if GetKeyNameText(Code shl 16, KeyName, SizeOf(KeyName)) > 0 then begin
  23068. if Result <> '' then
  23069. Result := Result + '+';
  23070. Result := Result + KeyName;
  23071. end;
  23072. end;
  23073. begin
  23074. Result := '';
  23075. with Accelerator do begin
  23076. if fVirt and FCONTROL <> 0 then
  23077. AddKeyName(VK_CONTROL);
  23078. if fVirt and FSHIFT <> 0 then
  23079. AddKeyName(VK_SHIFT);
  23080. if fVirt and FALT <> 0 then
  23081. AddKeyName(VK_ALT);
  23082. if fVirt and $20 <> 0 then
  23083. AddKeyName(VK_LWIN);
  23084. if fVirt and $40 <> 0 then
  23085. AddKeyName(VK_RWIN);
  23086. AddKeyName(Key);
  23087. end;
  23088. end;
  23089. //[END GetAcceleratorText]
  23090. const
  23091. MIDATA_CHECKITEM = $40000000;
  23092. MIDATA_RADIOITEM = $80000000;
  23093. //[function WndProcMenu]
  23094. {$IFNDEF NEW_MENU_ACCELL}
  23095. function WndProcMenu( Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  23096. var M, M1: PMenu;
  23097. Idx: Integer;
  23098. Id: Integer;
  23099. begin
  23100. Result := False;
  23101. if Msg.message = WM_COMMAND then
  23102. begin
  23103. if (Msg.lParam = 0) and (HIWORD( Msg.wParam ) <= 1) then
  23104. begin
  23105. M := PMenu( Sender.fMenuObj );
  23106. while M <> nil do
  23107. begin
  23108. Id := LoWord( Msg.wParam );
  23109. M1 := M.Items[ Id ];
  23110. if M1 <> nil then
  23111. begin
  23112. Result := True;
  23113. Rslt := 0;
  23114. Idx := M.IndexOf( M1 );
  23115. M.fByAccel := HiWord( Msg.wParam ) <> 0;
  23116. if M1.FRadioGroup <> 0 then
  23117. M1.RadioCheckItem
  23118. else
  23119. if M1.FIsCheckItem then
  23120. M1.Checked := not M1.Checked;
  23121. if Assigned(M1.FOnMenuItem) then
  23122. M1.FOnMenuItem( M, Idx )
  23123. else if Assigned( M.FOnMenuItem ) then
  23124. M.FOnMenuItem( M, Idx );
  23125. //M.FProcessed := True;
  23126. break;
  23127. end;
  23128. M := M.fNextMenu;
  23129. end;
  23130. end;
  23131. end;
  23132. end;
  23133. {$ELSE}
  23134. function WndProcMenu( Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  23135. function ProcessMenuItem(M: PMenu; Id: Integer): Boolean;
  23136. var
  23137. M1: PMenu;
  23138. Idx: Integer;
  23139. begin
  23140. M1 := M.Items[ Id ];
  23141. Result := (M1 <> nil);
  23142. if Result then
  23143. begin
  23144. Idx := M.IndexOf( M1 );
  23145. M.fByAccel := HiWord( Msg.wParam ) <> 0;
  23146. if M1.FRadioGroup <> 0 then
  23147. M1.RadioCheckItem
  23148. else
  23149. if M1.FIsCheckItem then
  23150. M1.Checked := not M1.Checked;
  23151. if Assigned(M1.FOnMenuItem) then begin
  23152. {$IFDEF USE_MENU_CURCTL} // fixed
  23153. M.fCurCtl := Sender; // fixed
  23154. {$ENDIF} // fixed
  23155. M1.FOnMenuItem( M, Idx )
  23156. end
  23157. else if Assigned( M.FOnMenuItem ) then
  23158. M.FOnMenuItem( M, Idx );
  23159. end;
  23160. end;
  23161. var
  23162. M: PMenu;
  23163. Id: Integer;
  23164. begin
  23165. Result := False;
  23166. if Msg.message = WM_COMMAND then
  23167. if (Msg.lParam = 0) and (HIWORD( Msg.wParam ) <= 1) then begin
  23168. Id := LoWord(Msg.wParam);
  23169. M := PMenu(Sender.fAutoPopupMenu);
  23170. if (M <> nil) and ProcessMenuItem(M, Id) then begin
  23171. Result := True;
  23172. Rslt := 0;
  23173. end
  23174. else begin
  23175. M := PMenu(Sender.fMenuObj);
  23176. while M <> nil do begin
  23177. if ProcessMenuItem(M, Id) then begin
  23178. Result := True;
  23179. Rslt := 0;
  23180. Break;
  23181. end;
  23182. M := M.fNextMenu;
  23183. end;
  23184. end;
  23185. end;
  23186. end;
  23187. {$ENDIF}
  23188. var FDynamicMenuID: DWORD = $1000;
  23189. //[function NewMenu]
  23190. function NewMenu( AParent : PControl; MaxCmdReserve : DWORD; const Template : array of PChar;
  23191. aOnMenuItem: TOnMenuItem ): PMenu;
  23192. var M: PMenu;
  23193. {$IFDEF INITIALFORMSIZE_FIXMENU}
  23194. R: TRect;
  23195. {$ENDIF}
  23196. begin
  23197. {-}
  23198. New( Result, Create );
  23199. {+}{++}(*Result := PMenu.Create;*){--}
  23200. Result.FVisible := TRUE;
  23201. Result.FPopupFlags := TPM_LEFTALIGN or TPM_LEFTBUTTON;
  23202. Result.FItems := NewList;
  23203. Result.FOnMenuItem := aOnMenuItem;
  23204. if (High(Template)>=0) and (Template[0] <> nil) then
  23205. begin
  23206. if (AParent <> nil) and (AParent.fMenuObj = nil) and not AParent.fIsControl then
  23207. Result.FHandle := CreateMenu
  23208. else
  23209. Result.FHandle := CreatePopupMenu;
  23210. Result.FillMenuItems( Result.FHandle, 0, Template );
  23211. end;
  23212. if assigned( AParent ) then
  23213. begin
  23214. Result.FControl := AParent;
  23215. if AParent.fMenuObj <> nil then
  23216. begin
  23217. // add popup menu to the end of menu chain
  23218. M := PMenu( AParent.fMenuObj );
  23219. while M.fNextMenu <> nil do
  23220. M := M.fNextMenu;
  23221. M.fNextMenu := Result;
  23222. end
  23223. else
  23224. begin
  23225. if not AParent.fIsControl then
  23226. begin
  23227. {$IFDEF INITIALFORMSIZE_FIXMENU}
  23228. R := AParent.ClientRect;
  23229. {$ENDIF}
  23230. AParent.Menu := Result.FHandle;
  23231. {$IFDEF INITIALFORMSIZE_FIXMENU}
  23232. AParent.SetClientSize( R.Right, R.Bottom );
  23233. {$ENDIF}
  23234. end;
  23235. AParent.fMenuObj := Result;
  23236. AParent.AttachProc( WndProcMenu );
  23237. end;
  23238. end;
  23239. end;
  23240. //[END NewMenu]
  23241. //[function NewMenuEx]
  23242. function NewMenuEx( AParent : PControl; FirstCmd : Integer; const Template : array of PChar;
  23243. aOnMenuItems: array of TOnMenuItem ): PMenu;
  23244. begin
  23245. Result := NewMenu( AParent, FirstCmd, Template, nil );
  23246. Result.AssignEvents( 0, aOnMenuItems );
  23247. end;
  23248. //[END NewMenuEx]
  23249. { TMenu }
  23250. const
  23251. Breaks: array[ TMenuBreak ] of DWORD = ( 0, MFT_MENUBREAK, MFT_MENUBARBREAK );
  23252. { + by AK - Andrzej Kubaszek }
  23253. //[function MenuStructSize]
  23254. function MenuStructSize: Integer;
  23255. begin
  23256. Result := 44;
  23257. if not( WinVer in [wv31, wv95, wvNT] ) then
  23258. Result := {48=} Sizeof( TMenuItemInfo );
  23259. end;
  23260. //[destructor TMenu.Destroy]
  23261. destructor TMenu.Destroy;
  23262. var Next, Prnt: PMenu;
  23263. begin
  23264. if Count > 0 then
  23265. begin
  23266. FItems.ReleaseObjects;
  23267. FItems := NewList;
  23268. end;
  23269. if FParent <> nil then
  23270. begin
  23271. Prnt := FParent;
  23272. FParent := nil;
  23273. Next := Prnt.RemoveSubMenu( FId );
  23274. Prnt.FItems.Remove( @ Self );
  23275. if Next = nil then Exit;
  23276. end;
  23277. if (FControl <> nil) and (FControl.fMenu = FHandle) and (FHandle <> 0) then
  23278. begin
  23279. //if FControl.fHandle <> 0 then
  23280. begin
  23281. Windows.SetMenu( FControl.fHandle, 0 );
  23282. // this removes main menu from window, but does not destroy it
  23283. end;
  23284. FControl.fMenu := 0;
  23285. Next := PMenu( FControl.fMenuObj );
  23286. while Next <> nil do
  23287. begin
  23288. if Next.fNextMenu = @Self then
  23289. begin
  23290. Next.fNextMenu := fNextMenu;
  23291. break;
  23292. end;
  23293. Next := Next.fNextMenu;
  23294. end;
  23295. end;
  23296. Next := fNextMenu;
  23297. if FBitmap <> 0 then
  23298. Bitmap := 0;
  23299. if FHandle <> 0 then
  23300. DestroyMenu( FHandle );
  23301. FCaption := '';
  23302. FItems.Free;
  23303. inherited;
  23304. Next.Free;
  23305. // all later created (popup) menus (of the same control)
  23306. // are destroyed too
  23307. end;
  23308. //[function TMenu.GetInfo]
  23309. function TMenu.GetInfo( var MII: TMenuItemInfo ): Boolean;
  23310. begin
  23311. MII.cbSize := MenuStructSize;
  23312. Result := GetMenuItemInfo( Parent.FHandle, FId, FALSE,
  23313. Windows.PMenuitemInfo( @ MII )^ );
  23314. end;
  23315. //[procedure TMenu.RedrawFormMenuBar]
  23316. procedure TMenu.RedrawFormMenuBar;
  23317. var C: PControl;
  23318. begin
  23319. C := TopParent.FControl;
  23320. if not AppletTerminated then
  23321. if (C <> nil) and (Pointer( C.fMenuObj ) = Pointer( TopParent )) then
  23322. DrawMenuBar( C.FHandle );
  23323. end;
  23324. //[function TMenu.SetInfo]
  23325. function TMenu.SetInfo( var MII: TMenuItemInfo ): Boolean;
  23326. var H: THandle;
  23327. begin
  23328. MII.cbSize := MenuStructSize;
  23329. H := FHandle;
  23330. if FParent <> nil then
  23331. H := FParent.FHandle;
  23332. Result := SetMenuItemInfo( H, FId, FALSE, Windows.PMenuitemInfo( @ MII )^ );
  23333. if Result and ((FParent = nil) or (FParent.FParent = nil)) then {YS}
  23334. RedrawFormMenuBar;
  23335. end;
  23336. //[function TMenu.SetTypeInfo]
  23337. function TMenu.SetTypeInfo( var MII: TMenuItemInfo ): Boolean;
  23338. begin
  23339. if not FIsSeparator then
  23340. begin
  23341. if FBmpItem = 0 then
  23342. MII.dwTypeData := PChar( FCaption )
  23343. else
  23344. MII.dwTypeData := Pointer( FBmpItem );
  23345. MII.cch := Length( FCaption );
  23346. end;
  23347. Result := SetInfo( MII );
  23348. end;
  23349. //[function TMenu.GetTopParent]
  23350. function TMenu.GetTopParent: PMenu;
  23351. begin
  23352. Result := @ Self;
  23353. while Result.FParent <> nil do
  23354. Result := Result.FParent;
  23355. end;
  23356. //[function TMenu.GetControl]
  23357. function TMenu.GetControl: PControl;
  23358. begin
  23359. Result := TopParent.FControl;
  23360. end;
  23361. //[function TMenu.GetItems]
  23362. function TMenu.GetItems( Id: HMenu ): PMenu;
  23363. function SearchItems( ParentMenu: PMenu; var FromIdx: Integer ): PMenu;
  23364. var I: Integer;
  23365. begin
  23366. Result := ParentMenu;
  23367. if Id = HMenu( FromIdx ) then Exit;
  23368. if (Id >= 4096) and (DWORD( ParentMenu.FId ) = Id) then Exit;
  23369. if ParentMenu.FItems = nil then Exit;
  23370. for I := 0 to ParentMenu.FItems.FCount-1 do
  23371. begin
  23372. Inc( FromIdx );
  23373. Result := SearchItems( ParentMenu.FItems.Items[ I ], FromIdx );
  23374. if Result <> nil then Exit;
  23375. end;
  23376. Result := nil;
  23377. end;
  23378. var I: Integer;
  23379. begin
  23380. I := -1;
  23381. Result := SearchItems( @ Self, I );
  23382. end;
  23383. //[function TMenu.GetCount]
  23384. function TMenu.GetCount: Integer;
  23385. var I: Integer;
  23386. SubM: PMenu;
  23387. begin
  23388. Result := FItems.FCount;
  23389. for I := 0 to Result-1 do
  23390. begin
  23391. SubM := FItems.Items[ I ];
  23392. Result := Result + SubM.Count;
  23393. end;
  23394. end;
  23395. //[function TMenu.IndexOf]
  23396. function TMenu.IndexOf( Item: PMenu ): Integer;
  23397. function SearchMenu( ParentMenu: PMenu; var FromIdx: Integer ): PMenu;
  23398. var I: Integer;
  23399. begin
  23400. Result := ParentMenu;
  23401. if Result = Item then Exit;
  23402. for I := 0 to ParentMenu.FItems.FCount-1 do
  23403. begin
  23404. Inc( FromIdx );
  23405. Result := SearchMenu( ParentMenu.FItems.Items[ I ], FromIdx );
  23406. if Result <> nil then Exit;
  23407. end;
  23408. Result := nil;
  23409. end;
  23410. begin
  23411. Result := -1;
  23412. if SearchMenu( @ Self, Result ) = nil then
  23413. Result := -2;
  23414. end;
  23415. //[function TMenu.GetState]
  23416. function TMenu.GetState( const Index: Integer ): Boolean;
  23417. var MII: TMenuItemInfo;
  23418. begin
  23419. if FVisible then
  23420. begin
  23421. MII.fMask := MIIM_STATE;
  23422. if GetInfo( MII ) then
  23423. FSavedState := MII.fState;
  23424. end;
  23425. Result := LongBool( FSavedState and Index );
  23426. if Index < 0 then
  23427. Result := not Result;
  23428. end;
  23429. //[procedure TMenu.SetState]
  23430. procedure TMenu.SetState( const Index: Integer; Value: Boolean );
  23431. var MII: TMenuItemInfo;
  23432. begin
  23433. GetState( 0 );
  23434. if Value xor (Index < 0) then
  23435. FSavedState := FSavedState or DWORD( Index and $7FFFFFFF )
  23436. else
  23437. FSavedState := FSavedState and not DWORD( Index );
  23438. if FVisible then
  23439. begin
  23440. MII.fMask := MIIM_STATE;
  23441. if GetInfo( MII ) then
  23442. begin
  23443. MII.fState := FSavedState;
  23444. SetInfo( MII );
  23445. end;
  23446. end;
  23447. end;
  23448. //[procedure TMenu.SetData]
  23449. procedure TMenu.SetData( Value: Pointer );
  23450. var MII: TMenuItemInfo;
  23451. begin
  23452. MII.fMask := MIIM_DATA;
  23453. MII.dwItemData := DWORD( Value );
  23454. SetInfo( MII );
  23455. FData := Value;
  23456. end;
  23457. //[procedure TMenu.ClearBitmaps]
  23458. procedure TMenu.ClearBitmaps;
  23459. begin
  23460. if FBitmap <> 0 then
  23461. DeleteObject( FBitmap );
  23462. if FBmpChecked <> 0 then
  23463. DeleteObject( FBmpChecked );
  23464. if FBmpItem <> 0 then
  23465. DeleteObject( FBmpItem );
  23466. end;
  23467. //[procedure TMenu.SetBitmap]
  23468. procedure TMenu.SetBitmap( Value: HBitmap );
  23469. var MII: TMenuItemInfo;
  23470. begin
  23471. if not FClearBitmaps then
  23472. begin
  23473. FClearBitmaps := TRUE;
  23474. Add2AutoFreeEx( ClearBitmaps );
  23475. end;
  23476. if Value = FBitmap then Exit;
  23477. if FBitmap <> 0 then
  23478. DeleteObject( FBitmap ); // seems not necessary.
  23479. FBitmap := Value;
  23480. MII.fMask := MIIM_CHECKMARKS;
  23481. MII.hbmpChecked := FBmpChecked;
  23482. MII.hbmpUnchecked := FBitmap;
  23483. SetInfo( MII );
  23484. end;
  23485. //[procedure TMenu.SetBmpChecked]
  23486. procedure TMenu.SetBmpChecked( Value: HBitmap );
  23487. var MII: TMenuItemInfo;
  23488. begin
  23489. if not FClearBitmaps then
  23490. begin
  23491. FClearBitmaps := TRUE;
  23492. Add2AutoFreeEx( ClearBitmaps );
  23493. end;
  23494. if Value = FBmpChecked then Exit;
  23495. if FBmpChecked <> 0 then
  23496. DeleteObject( FBmpChecked );
  23497. FBmpChecked := Value;
  23498. MII.fMask := MIIM_CHECKMARKS;
  23499. MII.hbmpChecked := FBmpChecked;
  23500. MII.hbmpUnchecked := FBitmap;
  23501. SetInfo( MII );
  23502. end;
  23503. //[procedure TMenu.SetBmpItem]
  23504. procedure TMenu.SetBmpItem( Value: HBitmap );
  23505. var MII: TMenuItemInfo;
  23506. begin
  23507. if not FClearBitmaps then
  23508. begin
  23509. FClearBitmaps := TRUE;
  23510. Add2AutoFreeEx( ClearBitmaps );
  23511. end;
  23512. if Value = FBmpItem then Exit;
  23513. if FBmpItem <> 0 then
  23514. DeleteObject( FBmpItem );
  23515. FBmpItem := Value;
  23516. if WinVer >= wv98 then {AK}
  23517. begin {AK}
  23518. MII.fMask := $80 {MIIM_BITMAP} ; {AK}
  23519. MII.hbmpItem:=Value; {AK}
  23520. end {AK}
  23521. else {AK}
  23522. begin//I haven't possibility to test it in Win95 {AK}
  23523. MII.fType := MFT_BITMAP;
  23524. MII.dwItemData := Value;
  23525. end; {AK}
  23526. SetInfo( MII );
  23527. end;
  23528. //[procedure TMenu.SetAccelerator]
  23529. {$IFNDEF NEW_MENU_ACCELL}
  23530. procedure TMenu.SetAccelerator(const Value: TMenuAccelerator);
  23531. const MaxAccel = 1000;
  23532. type TAccTab = array[0..10000] of TAccel;
  23533. PAccTab = ^TAccTab;
  23534. //TSetAcceleratorProc = procedure( Self_: PMenu; Idx: Integer; const Value: TMenuAccelerator );
  23535. var AccTab: PAccTab;
  23536. I, N : Integer;
  23537. M, SubM: PMenu;
  23538. C: PControl;
  23539. Main: Boolean;
  23540. begin
  23541. //SetAcceleratorProc := TSetAcceleratorProc( MakeMethod( nil, @TMenu.SetAccelerator ).Code );
  23542. if (FAccelerator.fVirt = Value.fVirt) and (FAccelerator.Key = Value.Key) then Exit;
  23543. FAccelerator := Value;
  23544. C := TopParent.FControl;
  23545. if C = nil then Exit;
  23546. if C.fAccelTable <> 0 then
  23547. DestroyAcceleratorTable( C.fAccelTable );
  23548. C.fAccelTable := 0;
  23549. GetMem( AccTab, sizeof( TAccel ) * MaxAccel );
  23550. N := 0;
  23551. M := PMenu( C.fMenuObj );
  23552. Main := TRUE;
  23553. while M <> nil do
  23554. begin
  23555. if Main or M.Visible then
  23556. begin
  23557. for I := 0 to MaxInt-1 do
  23558. begin
  23559. SubM := M.Items[ I ];
  23560. if SubM = nil then break;
  23561. if SubM.FVisible then
  23562. if (SubM.FAccelerator.Key <> 0) or (SubM.FAccelerator.fVirt <> 0) then
  23563. begin
  23564. AccTab[ N ].fVirt := SubM.FAccelerator.fVirt;
  23565. AccTab[ N ].key := SubM.FAccelerator.Key;
  23566. AccTab[ N ].cmd := WORD( SubM.FId );
  23567. Inc( N );
  23568. if N > MaxAccel then break;
  23569. end;
  23570. end;
  23571. end;
  23572. if N > MaxAccel then break;
  23573. M := M.fNextMenu;
  23574. end;
  23575. if N > 0 then
  23576. begin
  23577. C.fAccelTable := CreateAcceleratorTable( AccTab[ 0 ], N );
  23578. C := C.ParentForm;
  23579. if C <> nil then
  23580. C.SupportMnemonics;
  23581. end;
  23582. FreeMem( AccTab );
  23583. end;
  23584. {$ELSE NEW_MENU_ACCELL}
  23585. procedure TMenu.SetAccelerator(const Value: TMenuAccelerator);
  23586. var
  23587. C: PControl;
  23588. M: PMenu;
  23589. begin
  23590. if (FAccelerator.fVirt = Value.fVirt) and (FAccelerator.Key = Value.Key) then Exit;
  23591. FAccelerator := Value;
  23592. C := FControl;
  23593. M := @Self;
  23594. while (C = nil) and (M <> nil) do begin
  23595. M := M.Parent;
  23596. if (M <> nil) then
  23597. C := M.FControl;
  23598. end;
  23599. if (C <> nil) then
  23600. C.SupportMnemonics;
  23601. end;
  23602. {$ENDIF NEW_MENU_ACCELL}
  23603. //[procedure TMenu.SetMenuItemCaption]
  23604. procedure TMenu.SetMenuItemCaption( const Value: String );
  23605. var MII: TMenuItemInfo;
  23606. begin
  23607. FCaption := Value;
  23608. {AK}if not (WinVer in [wv95,wvNT]) then
  23609. {AK} MII.fMask := $40 {MIIM_STRING}
  23610. {AK}else begin
  23611. MII.fMask := MIIM_TYPE;
  23612. MII.fType := MFT_STRING;
  23613. {AK}end;
  23614. //+++++++++++++++++++ to fix turning radio mark to check mark in NT4
  23615. MII.cch := 0;
  23616. GetInfo( MII );
  23617. //------------------------------------------------------------------
  23618. MII.dwTypeData := PChar( Value );
  23619. MII.cch := Length( Value );
  23620. SetInfo( MII );
  23621. end;
  23622. //[procedure TMenu.SetMenuBreak]
  23623. procedure TMenu.SetMenuBreak( Value: TMenuBreak );
  23624. var MII: TMenuItemInfo;
  23625. begin
  23626. if FId = 0 then Exit;
  23627. if FMenuBreak = Value then Exit;
  23628. FMenuBreak := Value;
  23629. FillChar( MII, Sizeof( MII ), 0 );
  23630. MII.fMask := MIIM_TYPE;
  23631. MII.dwTypeData := nil;
  23632. if GetInfo( MII ) then
  23633. begin
  23634. MII.fType := MII.fType and not( MFT_MENUBREAK or MFT_MENUBARBREAK ) or
  23635. Breaks[ Value ];
  23636. SetTypeInfo( MII );
  23637. end;
  23638. end;
  23639. //[procedure TMenu.SetVisible]
  23640. procedure TMenu.SetVisible( Value: Boolean );
  23641. var I, J: Integer;
  23642. M: PMenu;
  23643. Before: Integer;
  23644. ByPosition: Boolean;
  23645. MII: TMenuItemInfo;
  23646. begin
  23647. if Value then
  23648. if FParent <> nil then
  23649. FParent.Visible := TRUE;
  23650. if Value = FVisible then Exit;
  23651. FVisible := Value;
  23652. if (FControl <> nil) and (FControl.fMenuObj = @ Self) then
  23653. begin
  23654. FControl.GetWindowHandle;
  23655. if Value then
  23656. SetMenu( FControl.fHandle, FHandle )
  23657. else
  23658. SetMenu( FControl.fHandle, 0 );
  23659. Exit;
  23660. end;
  23661. if FId = 0 then Exit;
  23662. if FParent = nil then Exit;
  23663. if Value then
  23664. begin // show menu item inserting it again into appropriate position
  23665. Before := -1;
  23666. ByPosition := TRUE;
  23667. I := FParent.FItems.IndexOf( @ Self );
  23668. for J := I + 1 to FParent.FItems.FCount-1 do
  23669. begin
  23670. M := FParent.FItems.Items[ J ];
  23671. if M.FVisible then
  23672. begin
  23673. Before := M.FId;
  23674. ByPosition := FALSE;
  23675. break;
  23676. end;
  23677. end;
  23678. FillChar( MII, Sizeof( MII ), 0 );
  23679. MII.cbSize := MenuStructSize;
  23680. MII.fMask := MIIM_CHECKMARKS or MIIM_ID or MIIM_STATE or
  23681. MIIM_TYPE;
  23682. MII.fType := Breaks[ FMenuBreak ];
  23683. MII.fState := FSavedState;
  23684. MII.wID := FId;
  23685. MII.dwItemData := DWORD( FData );
  23686. if not FIsSeparator then
  23687. begin
  23688. MII.fType := MII.fType or MFT_STRING;
  23689. MII.dwTypeData := PChar( FCaption );
  23690. MII.cch := Length( FCaption );
  23691. end
  23692. else
  23693. MII.fType := MII.fType or MFT_SEPARATOR;
  23694. if FRadioGroup <> 0 then
  23695. MII.fType := MII.fType or MFT_RADIOCHECK;
  23696. if FOwnerDraw then
  23697. MII.fType := MII.fType or MFT_OWNERDRAW;
  23698. if FBitmap <> 0 then
  23699. begin
  23700. MII.fMask := MII.fMask or MIIM_CHECKMARKS;
  23701. MII.hbmpUnchecked := FBitmap;
  23702. end;
  23703. if FHandle <> 0 then
  23704. begin
  23705. MII.fMask := MII.fMask or MIIM_SUBMENU;
  23706. MII.hSubMenu := FHandle;
  23707. end;
  23708. InsertMenuItem( FParent.FHandle, Before, ByPosition,
  23709. Windows.PMenuitemInfo( @ MII )^ );
  23710. end
  23711. else
  23712. begin // hide menu item removing it
  23713. GetState( 0 ); // store menu item state in FSavedState to allow
  23714. // changing its state while it is not attached to
  23715. // a menu
  23716. RemoveMenu( TopParent.FHandle, FId, MF_BYCOMMAND );
  23717. end;
  23718. if (FControl <> nil) or (FParent <> nil) and (FParent.FControl <> nil) then
  23719. RedrawFormMenuBar;
  23720. end;
  23721. //[procedure TMenu.RadioCheckItem]
  23722. procedure TMenu.RadioCheckItem;
  23723. var I, J: Integer;
  23724. M, First, Last: PMenu;
  23725. begin
  23726. if (FParent <> nil) and (FRadioGroup <> 0) then
  23727. begin
  23728. I := FParent.FItems.IndexOf( @ Self );
  23729. if I >= 0 then
  23730. begin
  23731. First := @ Self;
  23732. Last := @ Self;
  23733. for J := I-1 downto 0 do
  23734. begin
  23735. M := FParent.FItems.Items[ J ];
  23736. if M.FRadioGroup <> FRadioGroup then break;
  23737. if M.FVisible then
  23738. First := M;
  23739. end;
  23740. for J := I+1 to FParent.FItems.FCount-1 do
  23741. begin
  23742. M := FParent.FItems.Items[ J ];
  23743. if M.FRadioGroup <> FRadioGroup then break;
  23744. if M.FVisible then
  23745. Last := M;
  23746. end;
  23747. if First <> Last then
  23748. begin
  23749. CheckMenuRadioItem( FParent.FHandle, First.FId, Last.FId,
  23750. FId, MF_BYCOMMAND {or MF_CHECKED} );
  23751. Exit;
  23752. end;
  23753. end;
  23754. end;
  23755. Checked := TRUE;
  23756. end;
  23757. //[function TMenu.FillMenuItems]
  23758. function TMenu.FillMenuItems(AHandle: HMenu; StartIdx: Integer;
  23759. const Template: array of PChar): Integer;
  23760. var S, S1: PChar;
  23761. I: Integer;
  23762. MII: TMenuItemInfo;
  23763. Item, PrevItem: PMenu;
  23764. begin
  23765. PrevItem := nil;
  23766. I := StartIdx;
  23767. while I <= High( Template ) do
  23768. begin
  23769. S := Template[ I ];
  23770. if (S = nil) or (S^ = #0) then break;
  23771. if S = {$IFDEF F_P}'' +{$ENDIF} ')' then
  23772. begin
  23773. Result := I + 1;
  23774. Exit;
  23775. end;
  23776. {-}
  23777. new( Item, Create );
  23778. {+}{++}(*Item := PMenu.Create;*){--}
  23779. Item.FVisible := TRUE;
  23780. Item.FParent := @ Self;
  23781. Item.FItems := NewList;
  23782. FItems.Add( Item );
  23783. FillChar( MII, Sizeof( MII ), 0 );
  23784. MII.cbSize := MenuStructSize;
  23785. MII.fMask := MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE;
  23786. if S <> {$IFDEF F_P}'' +{$ENDIF} '-' then
  23787. begin
  23788. if (S^ = {$IFDEF F_P}'' +{$ENDIF} '-') or
  23789. (S^ = {$IFDEF F_P}'' +{$ENDIF} '+') then
  23790. begin
  23791. Item.FIsCheckItem := TRUE;
  23792. MII.dwItemData := MIDATA_CHECKITEM;
  23793. if S^ <> {$IFDEF F_P}'' +{$ENDIF} '-' then
  23794. MII.fState := MII.fState or MFS_CHECKED;
  23795. Inc( S );
  23796. if S^ = {$IFDEF F_P}'' +{$ENDIF} '!' then
  23797. begin
  23798. MII.fType := MII.fType or MFT_RADIOCHECK;
  23799. MII.dwItemData := MII.dwItemData or MIDATA_RADIOITEM;
  23800. Inc( S );
  23801. if PrevItem <> nil then
  23802. begin
  23803. if PrevItem.FRadioGroup <> 0 then
  23804. Item.FRadioGroup := PrevItem.FRadioGroup;
  23805. end;
  23806. if Item.FRadioGroup = 0 then
  23807. Inc( Item.FRadioGroup );
  23808. if S^ = {$IFDEF F_P}'' +{$ENDIF} '!' then
  23809. begin
  23810. Inc( S );
  23811. Inc( Item.FRadioGroup );
  23812. end;
  23813. end;
  23814. end;
  23815. Item.FCaption := S;
  23816. end
  23817. else
  23818. begin
  23819. Item.FIsSeparator := TRUE;
  23820. MII.fType := MFT_SEPARATOR;
  23821. MII.fState := MFS_GRAYED;
  23822. MII.wID := 0;
  23823. end;
  23824. Item.FId := FDynamicMenuID;
  23825. Inc( FDynamicMenuID );
  23826. MII.wID := Item.FId;
  23827. if I <> High( Template ) then //YS
  23828. begin //YS
  23829. S1 := Template[ I + 1 ];
  23830. if S1 = {$IFDEF F_P}'' +{$ENDIF} '(' then Item.FHandle := CreatePopupMenu;
  23831. end; //YS
  23832. MII.hSubMenu := Item.FHandle;
  23833. MII.dwTypeData := PChar( S );
  23834. MII.cch := StrLen( S );
  23835. InsertMenuItem( AHandle, DWORD(-1), True, Windows.PMenuitemInfo( @ MII )^ );
  23836. if Item.FHandle <> 0 then
  23837. I := Item.FillMenuItems( Item.FHandle, I + 2, Template )
  23838. else
  23839. Inc( I );
  23840. PrevItem := Item;
  23841. end;
  23842. Result := I;
  23843. end;
  23844. //[procedure TMenu.AssignEvents]
  23845. procedure TMenu.AssignEvents(StartIdx: Integer;
  23846. Events: array of TOnMenuItem);
  23847. var I: Integer;
  23848. M: PMenu;
  23849. begin
  23850. for I := 0 to High(Events) do
  23851. begin
  23852. M := Items[ StartIdx ];
  23853. if M = nil then break;
  23854. M.FOnMenuItem := Events[ I ];
  23855. Inc( StartIdx );
  23856. end;
  23857. end;
  23858. //[procedure TMenu.Popup]
  23859. function TMenu.Popup(X, Y: Integer): Integer;
  23860. begin
  23861. if Assigned( fOnPopup ) then fOnPopup( @Self );
  23862. if not FNotPopup then
  23863. Result := Integer( TrackPopupMenu( FHandle, FPopupFlags, {*ecm}
  23864. X, Y, 0, FControl.Handle, nil ) ) {*ecm}
  23865. else Result := 0; {*ecm}
  23866. end;
  23867. //[procedure TMenu.PopupEx]
  23868. function TMenu.PopupEx( X, Y: Integer ): Integer;
  23869. var OldBounds: TRect;
  23870. WasVisible: Boolean;
  23871. begin
  23872. WasVisible := TRUE;
  23873. if FControl <> nil then
  23874. begin
  23875. OldBounds := FControl.BoundsRect;
  23876. if not FControl.fIsControl then
  23877. begin
  23878. WasVisible := FControl.Visible;
  23879. if not WasVisible then
  23880. FControl.Top := ScreenHeight + 50;
  23881. FControl.Show;
  23882. end;
  23883. end;
  23884. // -- by Martin Larsen: -----------------------\
  23885. FControl.ProcessMessage; // specific for Win9x |
  23886. //---------------------------------------------/
  23887. Result := Popup( X, Y ); {*ecm}
  23888. if FControl <> nil then
  23889. begin
  23890. if FControl.Top = ScreenHeight + 50 then
  23891. begin
  23892. if not WasVisible then
  23893. FControl.Visible := FALSE;
  23894. FControl.BoundsRect := OldBounds;
  23895. end;
  23896. end;
  23897. end;
  23898. //[function TMenu.GetItemChecked]
  23899. function TMenu.GetItemChecked( Item : Integer ) : Boolean;
  23900. begin
  23901. Result := Items[ Item ].Checked;
  23902. end;
  23903. //[procedure TMenu.SetItemChecked]
  23904. procedure TMenu.SetItemChecked( Item : Integer; Value : Boolean );
  23905. begin
  23906. Items[ Item ].Checked := Value;
  23907. end;
  23908. //[function TMenu.GetMenuItemHandle]
  23909. function TMenu.GetMenuItemHandle( Idx : Integer ): DWORD;
  23910. begin
  23911. Result := Items[ Idx ].FId;
  23912. end;
  23913. //[procedure TMenu.RadioCheck]
  23914. procedure TMenu.RadioCheck( Idx : Integer );
  23915. begin
  23916. Items[ Idx ].RadioCheckItem;
  23917. end;
  23918. //[function TMenu.GetItemBitmap]
  23919. function TMenu.GetItemBitmap(Idx: Integer): HBitmap;
  23920. begin
  23921. Result := Items[ Idx ].Bitmap;
  23922. end;
  23923. //[procedure TMenu.SetItemBitmap]
  23924. procedure TMenu.SetItemBitmap(Idx: Integer; const Value: HBitmap);
  23925. begin
  23926. Items[ Idx ].Bitmap := Value;
  23927. end;
  23928. //[procedure TMenu.AssignBitmaps]
  23929. procedure TMenu.AssignBitmaps(StartIdx: Integer; Bitmaps: array of HBitmap);
  23930. var I: Integer;
  23931. begin
  23932. for I := 0 to High(Bitmaps) do
  23933. ItemBitmap[ I + StartIdx ] := Bitmaps[ I ];
  23934. end;
  23935. //[function TMenu.GetItemText]
  23936. function TMenu.GetItemText(Idx: Integer): String;
  23937. begin
  23938. Result := Items[ Idx ].FCaption;
  23939. end;
  23940. //[procedure TMenu.SetItemText]
  23941. procedure TMenu.SetItemText(Idx: Integer; const Value: String);
  23942. begin
  23943. Items[ Idx ].Caption := Value;
  23944. end;
  23945. //[function TMenu.GetItemEnabled]
  23946. function TMenu.GetItemEnabled(Idx: Integer): Boolean;
  23947. begin
  23948. Result := Items[ Idx ].Enabled;
  23949. end;
  23950. //[procedure TMenu.SetItemEnabled]
  23951. procedure TMenu.SetItemEnabled(Idx: Integer; const Value: Boolean);
  23952. begin
  23953. Items[ Idx ].Enabled := Value;
  23954. end;
  23955. //[function TMenu.GetItemVisible]
  23956. function TMenu.GetItemVisible(Idx: Integer): Boolean;
  23957. begin
  23958. Result := Items[ Idx ].Visible;
  23959. end;
  23960. //[procedure TMenu.SetItemVisible]
  23961. procedure TMenu.SetItemVisible(Idx: Integer; const Value: Boolean);
  23962. begin
  23963. Items[ Idx ].Visible := Value;
  23964. end;
  23965. //[function TMenu.ParentItem]
  23966. function TMenu.ParentItem( Idx: Integer ): Integer;
  23967. begin
  23968. Result := TopParent.IndexOf( Items[ Idx ].FParent );
  23969. end;
  23970. //[function TMenu.GetItemAccelerator]
  23971. function TMenu.GetItemAccelerator(Idx: Integer): TMenuAccelerator;
  23972. begin
  23973. Result := Items[ Idx ].Accelerator;
  23974. end;
  23975. //[procedure TMenu.SetItemAccelerator]
  23976. procedure TMenu.SetItemAccelerator(Idx: Integer; const Value: TMenuAccelerator);
  23977. begin
  23978. Items[ Idx ].Accelerator := Value;
  23979. end;
  23980. //[function TMenu.GetItemSubMenu]
  23981. function TMenu.GetItemSubMenu( Idx: Integer ): HMenu;
  23982. begin
  23983. Result := Items[ Idx ].SubMenu;
  23984. end;
  23985. //[function WndProcHelp FORWARD DECLARATION]
  23986. function WndProcHelp( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  23987. forward;
  23988. //[procedure TMenu.SetHelpContext]
  23989. procedure TMenu.SetHelpContext( Value: Integer );
  23990. var Form, C: PControl;
  23991. begin
  23992. if TopParent <> @ Self then Exit;
  23993. // Help context can not be associated with individual menu items
  23994. FHelpContext := Value;
  23995. C := FControl;
  23996. if C = nil then Exit;
  23997. Form := C.ParentForm;
  23998. Form.AttachProc( WndProcHelp );
  23999. SetMenuContextHelpID( FHandle, Value );
  24000. end;
  24001. //[procedure TMenu.SetSubmenu]
  24002. procedure TMenu.SetSubmenu( Value: HMenu );
  24003. var MII: TMenuItemInfo;
  24004. begin
  24005. MII.fMask := MIIM_SUBMENU;
  24006. MII.hSubMenu := Value;
  24007. SetInfo( MII );
  24008. FHandle := Value;
  24009. end;
  24010. //[function WndProcMeasureItem]
  24011. function WndProcMeasureItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  24012. var MIS: PMeasureItemStruct;
  24013. M, SM: PMenu;
  24014. H, I: Integer;
  24015. begin
  24016. Result := FALSE;
  24017. if (Msg.message = WM_MEASUREITEM) and (Msg.wParam = 0) then
  24018. begin
  24019. MIS := Pointer( Msg.lParam );
  24020. if MIS.CtlType = ODT_MENU then
  24021. begin
  24022. M := Pointer( Sender.fMenuObj );
  24023. while M <> nil do
  24024. begin
  24025. SM := M.Items[ MIS.itemID ];
  24026. if SM <> nil then
  24027. begin
  24028. Sender.CallDefWndProc( Msg );
  24029. I := M.IndexOf( SM );
  24030. if Assigned( SM.OnMeasureItem ) then
  24031. M := SM;
  24032. if not Assigned( M.OnMeasureItem ) then
  24033. Exit;
  24034. H := M.OnMeasureItem( M, I );
  24035. if HiWord( H ) <> 0 then
  24036. MIS.itemWidth := HiWord( H );
  24037. if LoWord( H ) <> 0 then
  24038. MIS.itemHeight := LoWord( H );
  24039. Rslt := 1;
  24040. Result := TRUE;
  24041. break;
  24042. end;
  24043. M := M.fNextMenu;
  24044. end;
  24045. end;
  24046. end;
  24047. end;
  24048. //[procedure TMenu.SetOnMeasureItem]
  24049. procedure TMenu.SetOnMeasureItem( const Value: TOnMeasureItem );
  24050. var C: PControl;
  24051. begin
  24052. FOnMeasureItem := Value;
  24053. C := TopParent.FControl;
  24054. if C <> nil then
  24055. C.AttachProc( WndProcMeasureItem );
  24056. end;
  24057. //[function WndProcDrawItem]
  24058. function WndProcDrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  24059. type PDrawAction = ^TDrawAction;
  24060. PDrawState = ^TDrawState;
  24061. var DIS: PDrawItemStruct;
  24062. M, SM: PMenu;
  24063. I: Integer;
  24064. begin
  24065. Result := FALSE;
  24066. if (Msg.message = WM_DRAWITEM) and (Msg.wParam = 0) then
  24067. begin
  24068. DIS := Pointer( Msg.lParam );
  24069. if DIS.CtlType = ODT_MENU then
  24070. begin
  24071. M := Pointer( Sender.fMenuObj );
  24072. while M <> nil do
  24073. begin
  24074. SM := M.Items[ DIS.itemID ];
  24075. if SM <> nil then
  24076. begin
  24077. I := M.IndexOf( SM );
  24078. if Assigned( SM.OnDrawItem ) then
  24079. M := SM;
  24080. if Assigned( M.OnDrawItem ) then
  24081. begin
  24082. if not M.OnDrawItem( M, DIS.hDC, DIS.rcItem, I,
  24083. PDrawAction( @ DIS.itemAction )^,
  24084. PDrawState( @ DIS.itemState )^ ) then Exit;
  24085. end
  24086. else Exit;
  24087. Rslt := 1;
  24088. Result := TRUE;
  24089. break;
  24090. end;
  24091. M := M.fNextMenu;
  24092. end;
  24093. end;
  24094. end;
  24095. end;
  24096. //[procedure TMenu.SetOnDrawItem]
  24097. procedure TMenu.SetOnDrawItem( const Value: TOnDrawItem );
  24098. var C: PControl;
  24099. begin
  24100. FOnDrawItem := Value;
  24101. C := TopParent.FControl;
  24102. if C <> nil then
  24103. C.AttachProc( WndProcDrawItem );
  24104. end;
  24105. //[procedure TMenu.SetOwnerDraw]
  24106. procedure TMenu.SetOwnerDraw( Value: Boolean );
  24107. const Masks: array[ Boolean ] of DWORD = ( 0, $FFFFFFFF );
  24108. var MII: TMenuItemInfo;
  24109. begin
  24110. FOwnerDraw := Value;
  24111. FillChar( MII, Sizeof( MII ), 0 );
  24112. MII.fMask := MIIM_TYPE;
  24113. MII.dwTypeData := nil;
  24114. if GetInfo( MII ) then
  24115. begin
  24116. MII.fType := MII.fType and not MFT_OWNERDRAW or
  24117. (MFT_OWNERDRAW and Masks[ Value ]);
  24118. SetTypeInfo( MII );
  24119. end;
  24120. end;
  24121. //[function TMenu.Insert]
  24122. function TMenu.Insert(InsertBefore: Integer; ACaption: PChar; Event: TOnMenuItem;
  24123. Options: TMenuOptions): PMenu;
  24124. const
  24125. MenuStateFlags: array[TMenuOption] of Integer = (MFS_DEFAULT, MFS_DISABLED, MFS_CHECKED, 0, 0,
  24126. MFS_DISABLED, 0, 0, 0, 0);
  24127. MenuTypeFlags: array[TMenuOption] of Integer = (0, 0, 0, 0, MFT_RADIOCHECK, MFT_SEPARATOR, MFT_BITMAP, 0,
  24128. MFT_MENUBREAK, MFT_MENUBARBREAK);
  24129. var M: PMenu;
  24130. MII: TMenuItemInfo;
  24131. begin
  24132. {-}
  24133. new( Result, Create );
  24134. {+}{++}(*Result := PMenu.Create;*){--}
  24135. Result.FVisible := TRUE;
  24136. Result.FParent := @ Self;
  24137. Result.FItems := NewList;
  24138. Result.FIsSeparator := moSeparator in Options;
  24139. if FHandle = 0 then
  24140. SetSubMenu( CreatePopupMenu );
  24141. M := nil;
  24142. if (InsertBefore >= 0) and (InsertBefore < 4096) then
  24143. begin
  24144. M := Items[ InsertBefore ];
  24145. if M <> nil then
  24146. begin
  24147. InsertBefore := M.FId;
  24148. M.Parent.FItems.Insert( M.Parent.FItems.IndexOf( M ), Result );
  24149. end;
  24150. end;
  24151. if M = nil then
  24152. begin
  24153. InsertBefore := -1;
  24154. FItems.Add( Result );
  24155. end;
  24156. Result.FOnMenuItem := Event;
  24157. FillChar( MII, Sizeof( MII ), 0 );
  24158. MII.cbSize := MenuStructSize;
  24159. MII.fMask := MIIM_DATA or MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE;
  24160. MII.fState := MakeFlags( Pointer( @Options ), MenuStateFlags);
  24161. MII.fType := MakeFlags( Pointer( @Options ), MenuTypeFlags);
  24162. Result.FId := FDynamicMenuID;
  24163. Inc( FDynamicMenuID );
  24164. MII.wID := Result.FId;
  24165. if moSubMenu in Options
  24166. then begin
  24167. Result.FHandle := CreatePopupMenu;
  24168. MII.hSubMenu := Result.FHandle;
  24169. end;
  24170. MII.dwTypeData := ACaption;
  24171. if not (moBitmap in Options) then MII.cch := StrLen( ACaption );
  24172. InsertMenuItem( FHandle, InsertBefore, InsertBefore = -1,
  24173. Windows.PMenuItemInfo( @ MII )^ );
  24174. if moBitmap in Options then
  24175. begin
  24176. Result.BitmapItem := DWORD( ACaption );
  24177. end
  24178. else
  24179. Result.FCaption := ACaption;
  24180. RedrawFormMenuBar;
  24181. end;
  24182. //[function TMenu.AddItem]
  24183. function TMenu.AddItem(ACaption: PChar; Event: TOnMenuItem; Options: TMenuOptions): Integer;
  24184. begin
  24185. Result := InsertItem( -1, ACaption, Event, Options );
  24186. end;
  24187. //[function TMenu.InsertItem]
  24188. function TMenu.InsertItem( InsertBefore: Integer; ACaption: PChar; Event: TOnMenuItem;
  24189. Options: TMenuOptions): Integer;
  24190. begin
  24191. Result := InsertItemEx( InsertBefore, ACaption, Event, Options, FALSE );
  24192. end;
  24193. //[function TMenu.InsertItemEx]
  24194. function TMenu.InsertItemEx(InsertBefore: Integer; ACaption: PChar;
  24195. Event: TOnMenuItem; Options: TMenuOptions; ByPosition: Boolean): Integer;
  24196. var M: PMenu;
  24197. begin
  24198. M := Insert( InsertBefore, ACaption, Event, Options );
  24199. Result := M.FId;
  24200. end;
  24201. //[procedure TMenu.InsertSubMenu]
  24202. procedure TMenu.InsertSubMenu( SubMenuToInsert: PMenu; InsertBefore: Integer );
  24203. var AFlags: DWORD;
  24204. M: PMenu;
  24205. MII: TMenuItemInfo;
  24206. begin
  24207. if SubMenuToInsert.FParent <> nil then
  24208. SubMenuToInsert := SubMenuToInsert.FParent.RemoveSubMenu( SubMenuToInsert.FId );
  24209. if SubMenuToInsert = nil then Exit;
  24210. AFlags := MF_BYPOSITION;
  24211. M := nil;
  24212. if (InsertBefore >= 0) and (InsertBefore < 4096) then
  24213. begin
  24214. M := Items[ InsertBefore ];
  24215. if M = nil then
  24216. InsertBefore := -1
  24217. else
  24218. InsertBefore := M.FId;
  24219. end;
  24220. if M = nil then
  24221. begin
  24222. FItems.Add( SubMenuToInsert );
  24223. SubMenuToInsert.FParent := @ Self;
  24224. end
  24225. else
  24226. begin
  24227. M.FParent.FItems.Insert( M.FParent.FItems.IndexOf( M ), SubMenuToInsert );
  24228. SubMenuToInsert.FParent := M.FParent;
  24229. end;
  24230. if InsertBefore > 0 then
  24231. AFlags := MF_BYCOMMAND;
  24232. if SubMenuToInsert.FBmpItem <> 0 then
  24233. InsertMenu( FHandle, InsertBefore, AFlags or MF_BITMAP or MF_POPUP, SubMenuToInsert.FHandle,
  24234. PChar( SubMenuToInsert.FBmpItem ) )
  24235. else
  24236. InsertMenu( FHandle, InsertBefore, AFlags or MF_STRING or MF_POPUP, SubMenuToInsert.FHandle,
  24237. PChar( SubMenuToInsert.Caption ) );
  24238. if SubMenuToInsert.FId = 0 then
  24239. begin
  24240. SubMenuToInsert.FId := FDynamicMenuID;
  24241. Inc( FDynamicMenuID );
  24242. MII.cbSize := MenuStructSize;
  24243. MII.fMask := MIIM_ID;
  24244. MII.wID := SubMenuToInsert.FId;
  24245. SetMenuItemInfo( SubMenuToInsert.FParent.FHandle, SubMenuToInsert.FParent.FItems.IndexOf( SubMenuToInsert ),
  24246. TRUE, Windows.PMenuItemInfo( @ MII )^ );
  24247. end;
  24248. RedrawFormMenuBar;
  24249. end;
  24250. //[function TMenu.RemoveSubMenu]
  24251. function TMenu.RemoveSubMenu( ItemToRemove: Integer ): PMenu;
  24252. {$IFDEF DEBUG_MENU}var OK: Boolean; {$ENDIF}
  24253. begin
  24254. Result := Items[ ItemToRemove ];
  24255. if Result = nil then Exit;
  24256. if Result.FParent <> nil then
  24257. {$IFDEF DEBUG_MENU} OK := {$ENDIF}
  24258. RemoveMenu( Result.FParent.FHandle, Result.FId, MF_BYCOMMAND )
  24259. else
  24260. {$IFDEF DEBUG_MENU} OK := {$ENDIF}
  24261. RemoveMenu( FHandle, Result.FId, MF_BYCOMMAND );
  24262. {$IFDEF DEBUG_MENU}
  24263. if not OK then
  24264. ShowMessage( 'Error removing menu: ' + Int2Str( GetLastError ) + ' - ' +
  24265. SysErrorMessage( GetLastError ) );
  24266. {$ENDIF}
  24267. if Count = 0 then
  24268. begin
  24269. Result.Free;
  24270. Result := nil;
  24271. end;
  24272. RedrawFormMenuBar;
  24273. end;
  24274. //[procedure ClearText]
  24275. procedure ClearText( Sender: PControl );
  24276. begin
  24277. Sender.Caption := '';
  24278. end;
  24279. //[procedure ClearListbox]
  24280. procedure ClearListbox( Sender: PControl );
  24281. begin
  24282. Sender.Perform( LB_RESETCONTENT, 0, 0 );
  24283. end;
  24284. //[procedure ClearCombobox]
  24285. procedure ClearCombobox( Sender: PControl );
  24286. begin
  24287. Sender.Perform( CB_RESETCONTENT, 0, 0 );
  24288. end;
  24289. //[procedure ClearListView]
  24290. procedure ClearListView( Sender: PControl );
  24291. begin
  24292. Sender.Perform( LVM_DELETEALLITEMS, 0, 0 );
  24293. end;
  24294. //[procedure ClearToolbar]
  24295. procedure ClearToolbar( Sender: PControl );
  24296. begin
  24297. while Sender.TBButtonCount > 0 do
  24298. Sender.TBDeleteButton( Sender.TBIndex2Item( 0 ) );
  24299. Sender.Perform( TB_SETBITMAPSIZE, 0, 0 );
  24300. end;
  24301. { -- Constructor of canvas -- }
  24302. //[function NewCanvas]
  24303. function NewCanvas( DC: HDC ): PCanvas;
  24304. begin
  24305. {-}
  24306. New( Result, Create );
  24307. {+}
  24308. {++}(*
  24309. Result := PCanvas.Create;
  24310. *){--}
  24311. Result.ModeCopy := cmSrcCopy;
  24312. if DC <> 0 then
  24313. begin
  24314. Result.SetHandle( DC );
  24315. //Result.fIsPaintDC := True; // If Canvas will be destroyed, DC will not be deleted
  24316. end;
  24317. end;
  24318. //[END NewCanvas]
  24319. { -- Contructors of controls -- }
  24320. {$IFDEF ASM_VERSION}
  24321. //[FUNCTION _NewTControl]
  24322. function _NewTControl( AParent: PControl ): PControl;
  24323. begin
  24324. New( Result, CreateParented( AParent ) );
  24325. end;
  24326. //[END _NewTControl]
  24327. //[function _NewWindowed]
  24328. function _NewWindowed( AParent: PControl; ControlClassName: PChar; Ctl3D: Boolean ): PControl;
  24329. asm
  24330. PUSH EBX
  24331. PUSH ESI
  24332. PUSH EDI
  24333. PUSH ECX // Ctl3D
  24334. PUSH EDX // ControlClassName
  24335. MOV ESI, EAX // ESI = AParent
  24336. CALL _NewTControl
  24337. XCHG EBX, EAX // EBX = Result
  24338. POP [EBX].TControl.fControlClassName
  24339. INC [EBX].TControl.fWindowed
  24340. INC EAX
  24341. POP EDX // DL = parameter Ctl3D
  24342. TEST ESI, ESI
  24343. JZ @@no_parent
  24344. LEA ESI, [ESI].TControl.fWndProcResizeFlicks
  24345. LEA EDI, [EBX].TControl.fWndProcResizeFlicks
  24346. MOVSD // fWndProcResizeFlicks
  24347. MOVSD // fGotoControl
  24348. //MOVSW // fDoubleBuffered, fTransparent
  24349. LODSB // fCtl3Dchild
  24350. STOSB
  24351. DEC AL
  24352. LODSB // fCtl3D
  24353. JZ @@passed3D
  24354. XOR EDX, EDX
  24355. @@passed3D:
  24356. XCHG EAX, EDX
  24357. STOSB // fCtl3D
  24358. MOVSD // fTextColor
  24359. LODSD
  24360. XCHG EDX, EAX
  24361. XOR EAX, EAX
  24362. PUSH EDX
  24363. CALL TGraphicTool.Assign
  24364. STOSD // fFont
  24365. POP EDX
  24366. XCHG ECX, EAX
  24367. JECXZ @@no_font
  24368. MOV [ECX].TGraphicTool.fParentGDITool, EDX
  24369. MOV [ECX].TGraphicTool.fOnChange.TMethod.Code, offset[TControl.FontChanged]
  24370. MOV [ECX].TGraphicTool.fOnChange.TMethod.Data, EBX
  24371. MOV EAX, EBX
  24372. MOV EDX, ECX
  24373. CALL TControl.FontChanged
  24374. @@no_font:
  24375. MOVSD // fColor
  24376. LODSD
  24377. XCHG EDX, EAX
  24378. XOR EAX, EAX
  24379. PUSH EDX
  24380. CALL TGraphicTool.Assign
  24381. STOSD // fBrush
  24382. POP EDX
  24383. XCHG ECX, EAX
  24384. JECXZ @@no_brush
  24385. MOV [ECX].TGraphicTool.fParentGDITool, EDX
  24386. MOV [ECX].TGraphicTool.fOnChange.TMethod.Code, offset[TControl.BrushChanged]
  24387. MOV [ECX].TGraphicTool.fOnChange.TMethod.Data, EBX
  24388. MOV EAX, EBX
  24389. MOV EDX, ECX
  24390. CALL TControl.BrushChanged
  24391. @@no_brush:
  24392. LODSD
  24393. STOSD // fMargin
  24394. STOSD // fBoundsRect.Left
  24395. PUSH EAX
  24396. ADD EAX, [ESI+16] // AParent.fClientTop
  24397. STOSD // fBoundsRect.Top
  24398. POP EAX
  24399. ADD EAX, 64
  24400. STOSD // fBoundsRect.Right
  24401. STOSD // fBoundsRect.Bottom
  24402. @@no_parent:
  24403. XCHG EAX, EBX
  24404. //DEC byte ptr [EAX].TControl.fAlphaBlend
  24405. //INC byte ptr [EAX].TControl.fEraseUpdRgn
  24406. POP EDI
  24407. POP ESI
  24408. POP EBX
  24409. end;
  24410. {$ELSE ASM_VERSION} //Pascal
  24411. function _NewWindowed( AParent: PControl; ControlClassName: PChar; Ctl3D: Boolean ): PControl;
  24412. begin
  24413. {-}
  24414. New( Result, CreateParented( AParent ) );
  24415. {+}{++}(*Result := PControl.CreateParented( AParent );*){--}
  24416. Result.fControlClassName := ControlClassName;
  24417. if AParent <> nil then
  24418. begin
  24419. Result.fWndProcResizeFlicks := AParent.fWndProcResizeFlicks;
  24420. Result.fGotoControl := AParent.fGotoControl;
  24421. //Result.fDoubleBuffered := AParent.fDoubleBuffered;
  24422. //Result.fTransparent := AParent.fTransparent;
  24423. Result.fCtl3Dchild := AParent.fCtl3Dchild;
  24424. if AParent.fCtl3Dchild then
  24425. Result.fCtl3D := Ctl3D
  24426. else
  24427. Result.fCtl3D := False;
  24428. Result.fMargin := AParent.fMargin;
  24429. with Result.fBoundsRect do
  24430. begin
  24431. Left := AParent.fMargin + AParent.fClientLeft;
  24432. Top := AParent.fMargin + AParent.fClientTop;
  24433. Right := Left + 64;
  24434. Bottom := Top + 64;
  24435. end;
  24436. Result.fTextColor := AParent.fTextColor;
  24437. Result.fFont := Result.fFont.Assign( AParent.fFont );
  24438. if Result.fFont <> nil then
  24439. begin
  24440. Result.fFont.fParentGDITool := AParent.fFont;
  24441. Result.fFont.fOnChange := Result.FontChanged;
  24442. Result.FontChanged( Result.fFont );
  24443. end;
  24444. Result.fColor := AParent.fColor;
  24445. Result.fBrush := Result.fBrush.Assign( AParent.fBrush );
  24446. if Result.fBrush <> nil then
  24447. begin
  24448. Result.fBrush.fParentGDITool := AParent.fBrush;
  24449. Result.fBrush.fOnChange := Result.BrushChanged;
  24450. Result.BrushChanged( Result.fBrush );
  24451. end;
  24452. end;
  24453. //Result.fAlphaBlend := 255;
  24454. //Result.fEraseUpdRgn := TRUE;
  24455. end;
  24456. //[END _NewWindowed]
  24457. {$ENDIF ASM_VERSION}
  24458. //===================== Form ========================//
  24459. {$IFDEF USE_CONSTRUCTORS}
  24460. //[function NewForm]
  24461. function NewForm( AParent: PControl; const Caption: String ): PControl;
  24462. begin
  24463. new( Result, CreateForm( AParent, Caption ) );
  24464. end;
  24465. //[END NewForm]
  24466. {$ELSE not_USE_CONSTRUCTORS}
  24467. //[FUNCTION NewForm]
  24468. {$IFDEF ASM_VERSION}
  24469. function NewForm( AParent: PControl; const Caption: String ): PControl;
  24470. const FormClass: array[ 0..4 ] of Char = ( 'F', 'o', 'r', 'm', #0 );
  24471. asm
  24472. PUSH EBX
  24473. PUSH EDX
  24474. MOV EDX, offset[FormClass]
  24475. MOV CL, 1
  24476. CALL _NewWindowed
  24477. MOV EBX, EAX
  24478. INC [EBX].TControl.fSizeGrip
  24479. OR byte ptr [EBX].TControl.fClsStyle, CS_DBLCLKS
  24480. MOV EDX, offset[WndProcForm]
  24481. CALL TControl.AttachProc
  24482. MOV EDX, offset[WndProcDoEraseBkgnd]
  24483. MOV EAX, EBX
  24484. CALL TControl.AttachProc
  24485. POP EDX
  24486. MOV EAX, EBX
  24487. CALL TControl.SetCaption
  24488. INC [EBX].TControl.fSizeGrip
  24489. INC [EBX].TControl.fIsForm
  24490. XCHG EAX, EBX
  24491. POP EBX
  24492. end;
  24493. {$ELSE ASM_VERSION} //Pascal
  24494. function NewForm( AParent: PControl; const Caption: String ): PControl;
  24495. begin
  24496. Result := _NewWindowed( AParent, 'Form', True );
  24497. Result.fClsStyle := Result.fClsStyle or CS_DBLCLKS;
  24498. Result.AttachProc( WndProcForm );
  24499. Result.AttachProc( WndProcDoEraseBkgnd );
  24500. Result.Caption := Caption;
  24501. Result.fSizeGrip := TRUE;
  24502. Result.fIsForm := TRUE;
  24503. end;
  24504. {$ENDIF ASM_VERSION}
  24505. //[END NewForm]
  24506. {$ENDIF USE_CONSTRUCTORS}
  24507. //===================== Applet button ========================//
  24508. //{$DEFINE WNDPROCAPP_USED}
  24509. {$IFDEF WNDPROCAPP_USED}
  24510. //[FUNCTION WndProcApp]
  24511. {$IFDEF ASM_VERSION}
  24512. {$IFDEF WNDPROCAPP_ASM_USED}
  24513. function WndProcApp(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  24514. asm
  24515. CMP word ptr [EDX].TMsg.message, WM_SETFOCUS
  24516. JNZ @@chk_CLOSE
  24517. MOV ECX, [EAX].TControl.FCurrentControl
  24518. JECXZ @@ret_false
  24519. XCHG EAX, ECX
  24520. PUSH EAX
  24521. CALL CallTControlCreateWindow
  24522. TEST AL, AL
  24523. POP EAX
  24524. JZ @@1
  24525. PUSH [EAX].TControl.fHandle
  24526. CALL SetFocus
  24527. @@1: MOV AL, 1
  24528. RET
  24529. @@chk_CLOSE:
  24530. CMP word ptr [EDX].TMsg.message, WM_SYSCOMMAND
  24531. JNZ @@ret_false
  24532. MOV EDX, dword ptr [EDX].TMsg.wParam
  24533. AND DX, $FFF0
  24534. CMP DX, SC_CLOSE
  24535. JNZ @@ret_false
  24536. PUSH ECX
  24537. MOV ECX, [EAX].TControl.fChildren
  24538. JECXZ @@ret_false1
  24539. XCHG EAX, ECX
  24540. MOV ECX, [EAX].TList.fCount
  24541. JECXZ @@ret_false1
  24542. MOV EAX, [EAX].TList.fItems
  24543. MOV ECX, dword ptr [EAX]
  24544. JECXZ @@ret_false1
  24545. XCHG EAX, ECX
  24546. PUSH EAX
  24547. CALL TControl.IsMainWindow
  24548. TEST EAX, EAX
  24549. POP EAX
  24550. JZ @@ret_false1
  24551. CALL TControl.Close
  24552. POP ECX
  24553. XOR EAX, EAX
  24554. MOV dword ptr [ECX], EAX
  24555. INC EAX
  24556. JMP @@exit
  24557. @@ret_false1:
  24558. POP ECX
  24559. @@ret_false:
  24560. XOR EAX, EAX
  24561. @@exit:
  24562. end;
  24563. {$ENDIF}
  24564. {$ELSE ASM_VERSION} //Pascal
  24565. function WndProcApp(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  24566. begin
  24567. Result := False;
  24568. case Msg.message of
  24569. WM_SETFOCUS:
  24570. {$IFDEF NEW_MODAL}
  24571. if Self_.fModalForm <> nil then
  24572. SetFocus( Self_.fModalForm.fHandle )
  24573. else if ( Self_.FCurrentControl <> nil ) and not
  24574. ( Self_.fCurrentControl.IsForm xor Self_.fIsApplet ) then
  24575. {$ELSE not_NEW_MODAL}
  24576. if Self_.FCurrentControl <> nil then
  24577. {$ENDIF NEW_MODAL}
  24578. begin
  24579. if Self_.FCurrentControl.CreateWindow then
  24580. SetFocus( Self_.FCurrentControl.fHandle );
  24581. Result := True;
  24582. end;
  24583. WM_SYSCOMMAND:
  24584. if Msg.wParam and $FFF0 = SC_CLOSE then
  24585. if (Self_.fChildren <> nil) and (Self_.fChildren.fCount > 0) and
  24586. PControl( Self_.fChildren.fItems[ 0 ] ).IsMainWindow then
  24587. begin
  24588. PControl( Self_.fChildren.fItems[ 0 ] ).Close;
  24589. Rslt := 0;
  24590. Result := TRUE;
  24591. end;
  24592. end;
  24593. end;
  24594. {$ENDIF ASM_VERSION}
  24595. //[END WndProcApp]
  24596. {$ENDIF WNDPROCAPP_USED}
  24597. {$IFDEF USE_CONSTRUCTORS}
  24598. {$DEFINE CREATEAPPBUTTON_USED}
  24599. //[function NewApplet]
  24600. function NewApplet( const Caption: String ): PControl;
  24601. begin
  24602. new( Result, CreateApplet( Caption ) );
  24603. end;
  24604. //[END NewApplet]
  24605. {$ELSE not_USE_CONSTRUCTORS}
  24606. //[FUNCTION NewApplet]
  24607. {$IFDEF ASM_VERSION}
  24608. function NewApplet( const Caption: String ): PControl;
  24609. const AppClass: array[ 0..3 ] of Char = ( 'A', 'p', 'p', #0 );
  24610. asm
  24611. XOR ECX, ECX
  24612. INC ECX
  24613. MOV [AppButtonUsed], CL
  24614. PUSH EAX
  24615. MOV EDX, offset[AppClass]
  24616. XOR EAX, EAX
  24617. CALL _NewWindowed
  24618. INC [EAX].TControl.FIsApplet
  24619. MOV word ptr [EAX].TControl.fStyle + 2, $90CA //WS_VISIBLE or WS_SYSMENU or WS_POPUP or WS_MINIMIZEBOX or WS_CAPTION
  24620. MOV byte ptr [EAX].TControl.fExStyle + 2, WS_EX_APPWINDOW shr 16 // WS_EX_APPWINDOW = $40000
  24621. CALL @@newapp1
  24622. // BODY of CreateAppButton here:
  24623. PUSH ESI
  24624. PUSH 0
  24625. PUSH [EAX].TControl.fHandle
  24626. CALL GetSystemMenu
  24627. MOV ESI, offset[DeleteMenu]
  24628. XCHG ECX, EAX
  24629. MOV EAX, SC_MAXIMIZE
  24630. CDQ
  24631. PUSH EDX
  24632. PUSH EAX
  24633. PUSH ECX
  24634. PUSH EDX
  24635. {$IFDEF PARANOIA}
  24636. DB $2C, $20
  24637. {$ELSE}
  24638. SUB AL, $20 // SC_MOVE
  24639. {$ENDIF}
  24640. PUSH EAX
  24641. PUSH ECX
  24642. PUSH EDX
  24643. {$IFDEF PARANOIA}
  24644. DB $2C, $10
  24645. {$ELSE}
  24646. SUB AL, $10 // SC_SIZE
  24647. {$ENDIF}
  24648. PUSH EAX
  24649. PUSH ECX
  24650. PUSH 1 // MF_GRAYED or MF_BYCOMMAND
  24651. MOV AX, SC_RESTORE
  24652. PUSH EAX
  24653. PUSH ECX
  24654. CALL EnableMenuItem
  24655. CALL ESI
  24656. CALL ESI
  24657. CALL ESI
  24658. POP ESI
  24659. @@ret_false:
  24660. XOR EAX, EAX
  24661. RET
  24662. @@chk_CLOSE:
  24663. CMP word ptr [EDX].TMsg.message, WM_SYSCOMMAND
  24664. JNZ @@ret_false
  24665. MOV EDX, dword ptr [EDX].TMsg.wParam
  24666. AND DX, $FFF0
  24667. CMP DX, SC_CLOSE
  24668. JNZ @@ret_false
  24669. PUSH ECX
  24670. MOV ECX, [EAX].TControl.fChildren
  24671. JECXZ @@ret_false1
  24672. XCHG EAX, ECX
  24673. MOV ECX, [EAX].TList.fCount
  24674. JECXZ @@ret_false1
  24675. MOV EAX, [EAX].TList.fItems
  24676. MOV ECX, dword ptr [EAX]
  24677. JECXZ @@ret_false1
  24678. XCHG EAX, ECX
  24679. PUSH EAX
  24680. CALL TControl.IsMainWindow
  24681. TEST EAX, EAX
  24682. POP EAX
  24683. JZ @@ret_false1
  24684. CALL TControl.Close
  24685. POP ECX
  24686. XOR EAX, EAX
  24687. MOV dword ptr [ECX], EAX
  24688. INC EAX
  24689. RET
  24690. @@ret_false1:
  24691. POP ECX
  24692. JMP @@ret_false
  24693. @@newapp1:
  24694. //MOV [EAX].TControl.FCreateWndExt, offset[CreateAppButton]
  24695. POP [EAX].TControl.FCreateWndExt
  24696. PUSH EAX
  24697. CALL @@newapp2
  24698. // BODY of WndProcApp here:
  24699. CMP word ptr [EDX].TMsg.message, WM_SETFOCUS
  24700. JNZ @@chk_CLOSE
  24701. MOV ECX, [EAX].TControl.FCurrentControl
  24702. JECXZ @@ret_false
  24703. XCHG EAX, ECX
  24704. PUSH EAX
  24705. CALL CallTControlCreateWindow
  24706. POP EAX
  24707. PUSH [EAX].TControl.fHandle
  24708. CALL SetFocus
  24709. MOV AL, 1
  24710. RET
  24711. @@newapp2:
  24712. POP EDX
  24713. CALL TControl.AttachProc
  24714. POP EAX
  24715. POP EDX
  24716. PUSH EAX
  24717. CALL TControl.SetCaption
  24718. POP EAX
  24719. end;
  24720. {$ELSE ASM_VERSION} //Pascal
  24721. //[procedure CreateAppButton]
  24722. procedure CreateAppButton( App: PControl );
  24723. var M: HMenu;
  24724. begin
  24725. M := GetSystemMenu( App.fHandle, False );
  24726. DeleteMenu( M, SC_MAXIMIZE, MF_BYCOMMAND );
  24727. DeleteMenu( M, SC_MOVE, MF_BYCOMMAND );
  24728. DeleteMenu( M, SC_SIZE, MF_BYCOMMAND );
  24729. EnableMenuItem( M, SC_RESTORE, MF_GRAYED or MF_BYCOMMAND );
  24730. end;
  24731. //[function NewApplet]
  24732. function NewApplet( const Caption: String ): PControl;
  24733. begin
  24734. AppButtonUsed := True;
  24735. Result := _NewWindowed( nil, 'App', True );
  24736. Result.FIsApplet := TRUE;
  24737. Result.fStyle := WS_VISIBLE or WS_SYSMENU or WS_POPUP or WS_MINIMIZEBOX or WS_CAPTION;
  24738. Result.fExStyle := WS_EX_APPWINDOW;
  24739. Result.FCreateWndExt := CreateAppButton;
  24740. Result.AttachProc( WndProcApp );
  24741. Result.Caption := Caption;
  24742. end;
  24743. {$ENDIF ASM_VERSION}
  24744. //[END NewApplet]
  24745. {$ENDIF USE_CONSTRUCTORS}
  24746. {$IFDEF CREATEAPPBUTTON_USED}
  24747. procedure CreateAppButton( App: PControl );
  24748. asm
  24749. {$IFDEF F_P}
  24750. MOV EAX, [App]
  24751. {$ENDIF F_P}
  24752. PUSH ESI
  24753. PUSH 0
  24754. PUSH [EAX].TControl.fHandle
  24755. CALL GetSystemMenu
  24756. MOV ESI, offset[DeleteMenu]
  24757. XCHG ECX, EAX
  24758. MOV EAX, SC_MAXIMIZE
  24759. CDQ
  24760. PUSH EDX
  24761. PUSH EAX
  24762. PUSH ECX
  24763. PUSH EDX
  24764. {$IFDEF PARANOIA}
  24765. DB $2C, $20
  24766. {$ELSE}
  24767. SUB AL, $20 // SC_MOVE
  24768. {$ENDIF}
  24769. PUSH EAX
  24770. PUSH ECX
  24771. PUSH EDX
  24772. {$IFDEF PARANOIA}
  24773. DB $2C, $10
  24774. {$ELSE}
  24775. SUB AL, $10 // SC_SIZE
  24776. {$ENDIF}
  24777. PUSH EAX
  24778. PUSH ECX
  24779. PUSH 1 // MF_GRAYED or MF_BYCOMMAND
  24780. MOV AX, SC_RESTORE
  24781. PUSH EAX
  24782. PUSH ECX
  24783. CALL EnableMenuItem
  24784. CALL ESI
  24785. CALL ESI
  24786. CALL ESI
  24787. POP ESI
  24788. end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};
  24789. {$ENDIF CREATEAPPBUTTON_USED}
  24790. var CtlIdCount: WORD = $8000;
  24791. {-}
  24792. {$IFNDEF ASM_VERSION}
  24793. //{$DEFINE CREATEPARAMS2_USED}
  24794. {$ENDIF}
  24795. {$IFDEF USE_CONSTRUCTORS}
  24796. //{$DEFINE CREATEPARAMS2_USED}
  24797. {$ENDIF}
  24798. {+}
  24799. {$IFDEF CREATEPARAMS2_USED} // seems not needed more
  24800. //[procedure CreateParams2]
  24801. procedure CreateParams2( Self_: PControl; var Params: TCreateParams);
  24802. begin
  24803. Self_.CreateSubclass( Params, Self_.fControlClassName );
  24804. end;
  24805. {$ENDIF}
  24806. //[FUNCTION _NewControl]
  24807. {$IFDEF ASM_VERSION}
  24808. function _NewControl( AParent: PControl; ControlClassName: PChar;
  24809. Style: DWORD; Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  24810. const szActions = sizeof(TCommandActions);
  24811. asm
  24812. PUSH EBX
  24813. PUSH EAX // push AParent
  24814. PUSH ECX // push Style
  24815. MOVZX ECX, Ctl3D
  24816. CALL _NewWindowed
  24817. XCHG EBX, EAX
  24818. INC [EBX].TControl.fIsControl
  24819. INC [EBX].TControl.fVerticalAlign
  24820. MOV EAX, Actions
  24821. TEST EAX, EAX
  24822. JZ @@noActions
  24823. LEA EDX, [EBX].TControl.fCommandActions
  24824. XOR ECX, ECX
  24825. MOV CL, szActions
  24826. CALL System.Move
  24827. @@noActions:
  24828. POP EDX // pop Style
  24829. OR EDX, WS_CLIPSIBLINGS or WS_CLIPCHILDREN
  24830. MOV byte ptr [EBX].TControl.fLookTabKeys, $0F
  24831. CMP [EBX].TControl.fCtl3D, 0
  24832. JZ @@noCtl3D
  24833. AND EDX, not WS_BORDER
  24834. OR byte ptr [EBX].TControl.fExStyle + 1, WS_EX_CLIENTEDGE shr 8
  24835. @@noCtl3D:
  24836. MOV [EBX].TControl.fStyle, EDX
  24837. TEST EDX, WS_VISIBLE
  24838. SETNZ AL
  24839. MOV [EBX].TControl.fVisible, AL
  24840. TEST EDX, WS_TABSTOP
  24841. POP ECX // pop AParent
  24842. PUSHFD
  24843. JECXZ @@noParent
  24844. MOV EAX, [ECX].TControl.fCursor
  24845. MOV [EBX].TControl.fCursor, EAX
  24846. XCHG EAX, ECX
  24847. CALL TControl.ParentForm
  24848. XCHG ECX, EAX
  24849. JECXZ @@noParent
  24850. INC [ECX].TControl.fTabOrder
  24851. MOV EDX, [ECX].TControl.fTabOrder
  24852. MOV [EBX].TControl.fTabOrder, EDX
  24853. @@noParent:
  24854. POPFD
  24855. JZ @@noTabStop
  24856. INC [EBX].TControl.fTabstop
  24857. JECXZ @@noTabstop
  24858. XCHG EAX, ECX
  24859. MOV ECX, [EAX].TControl.FCurrentControl
  24860. INC ECX
  24861. LOOP @@noTabStop
  24862. MOV [EAX].TControl.FCurrentControl, EBX
  24863. @@noTabStop:
  24864. MOVZX EDX, [CtlIdCount]
  24865. INC [CtlIdCount]
  24866. MOV [EBX].TControl.fMenu, EDX
  24867. MOV EDX, offset[WndProcCtrl]
  24868. MOV EAX, EBX
  24869. CALL TControl.AttachProc
  24870. XCHG EAX, EBX
  24871. POP EBX
  24872. end;
  24873. {$ELSE ASM_VERSION} //Pascal
  24874. function _NewControl( AParent: PControl; ControlClassName: PChar;
  24875. Style: DWORD; Ctl3D: Boolean; Actions: PCommandActions ): PControl;
  24876. var Form: PControl;
  24877. begin
  24878. Result := _NewWindowed( AParent, ControlClassName, Ctl3D );
  24879. if Actions <> nil then
  24880. Result.fCommandActions := Actions^;
  24881. Result.fIsControl := True;
  24882. Result.fStyle := Style or WS_CLIPSIBLINGS or WS_CLIPCHILDREN;
  24883. Result.fVerticalAlign := vaTop;
  24884. Result.fVisible := (Style and WS_VISIBLE) <> 0;
  24885. Result.fTabstop := (Style and WS_TABSTOP) <> 0;
  24886. if (AParent <> nil) then
  24887. begin
  24888. Inc( AParent.ParentForm.fTabOrder );
  24889. Result.fTabOrder := AParent.ParentForm.fTabOrder;
  24890. Result.fCursor := AParent.fCursor;
  24891. end;
  24892. Result.fLookTabKeys := [ tkTab, tkLeftRight, tkUpDown, tkPageUpPageDn ];
  24893. if Result.fCtl3D then
  24894. begin
  24895. Result.fStyle := Result.fStyle and not WS_BORDER;
  24896. Result.fExStyle := Result.fExStyle or WS_EX_CLIENTEDGE;
  24897. end;
  24898. if (Style and WS_TABSTOP) <> 0 then
  24899. begin
  24900. Form := Result.ParentForm;
  24901. if Form <> nil then
  24902. if Form.FCurrentControl = nil then
  24903. Form.FCurrentControl := Result;
  24904. end;
  24905. //Result.fCreateParamsExt := CreateParams2;
  24906. Result.fMenu := CtlIdCount;
  24907. Inc( CtlIdCount );
  24908. Result.AttachProc( WndProcCtrl );
  24909. end;
  24910. {$ENDIF ASM_VERSION}
  24911. //[END _NewControl]
  24912. //===================== Button ========================//
  24913. //[function TControl.SetButtonIcon]
  24914. function TControl.SetButtonIcon(aIcon: HIcon): PControl;
  24915. var PrevImg: THandle;
  24916. begin
  24917. Style := Style or BS_ICON;
  24918. fButtonIcon := aIcon;
  24919. PrevImg := Perform( BM_SETIMAGE, IMAGE_ICON, aIcon );
  24920. if PrevImg <> 0 then
  24921. DeleteObject( PrevImg );
  24922. Result := @ Self;
  24923. end;
  24924. //[function TControl.SetButtonBitmap]
  24925. function TControl.SetButtonBitmap(aBmp: HBitmap): PControl;
  24926. var PrevImg: THandle;
  24927. begin
  24928. Style := Style or BS_BITMAP;
  24929. PrevImg := Perform( BM_SETIMAGE, IMAGE_BITMAP, aBmp );
  24930. if PrevImg <> 0 then
  24931. DeleteObject( PrevImg );
  24932. Result := @ Self;
  24933. end;
  24934. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  24935. //[function WndProcBtnReturnClick]
  24936. function WndProcBtnReturnClick( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  24937. begin
  24938. Result := FALSE;
  24939. if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP) or
  24940. (Msg.message = WM_CHAR)) and (Msg.wParam = 13) then
  24941. Msg.wParam := 32;
  24942. end;
  24943. {$ENDIF}
  24944. //[function AutoMinimizeApplet]
  24945. function AutoMinimizeApplet(Self_: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
  24946. begin
  24947. if (msg.Message=WM_SYSCOMMAND) and (msg.wParam=SC_MINIMIZE) then begin
  24948. AppletMinimize;
  24949. Result := True;
  24950. end else
  24951. Result := False;
  24952. end;
  24953. {$IFDEF USE_CONSTRUCTORS}
  24954. //[function NewButton]
  24955. function NewButton( AParent: PControl; const Caption: String ): PControl;
  24956. begin
  24957. new( Result, CreateButton( AParent, Caption ) );
  24958. end;
  24959. {$ELSE USE_CONSTRUCTORS}
  24960. {$IFDEF ASM_VERSION}
  24961. const ButtonClass: array[ 0..6 ] of Char = ( 'B','U','T','T','O','N',#0 );
  24962. {$ENDIF ASM_VERSION}
  24963. //[FUNCTION NewButton]
  24964. {$IFDEF ASM_VERSION}
  24965. function NewButton( AParent: PControl; const Caption: String ): PControl;
  24966. const szActions = sizeof(TCommandActions);
  24967. asm
  24968. PUSH EDX
  24969. PUSH 0
  24970. PUSH offset[ButtonActions]
  24971. MOV EDX, offset[ButtonClass]
  24972. MOV ECX, WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or WS_TABSTOP
  24973. CALL _NewControl
  24974. INC [EAX].TControl.fIgnoreDefault
  24975. MOV EDX, [EAX].TControl.fBoundsRect.Top
  24976. ADD EDX, 22
  24977. MOV [EAX].TControl.fBoundsRect.Bottom, EDX
  24978. MOV [EAX].TControl.fTextAlign, taCenter
  24979. INC [EAX].TControl.fIsButton
  24980. POP EDX
  24981. PUSH EAX
  24982. CALL TControl.SetCaption
  24983. POP EAX
  24984. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  24985. PUSH EAX
  24986. MOV EDX, offset[WndProcBtnReturnClick]
  24987. CALL TControl.AttachProc
  24988. POP EAX
  24989. {$ENDIF}
  24990. end;
  24991. {$ELSE ASM_VERSION} //Pascal
  24992. function NewButton( AParent: PControl; const Caption: String ): PControl;
  24993. begin
  24994. Result := _NewControl( AParent, 'BUTTON',
  24995. WS_VISIBLE or WS_CHILD or
  24996. BS_PUSHLIKE or WS_TABSTOP, False, @ButtonActions );
  24997. Result.fIgnoreDefault := TRUE;
  24998. Result.fCtl3D := TRUE;
  24999. with Result.fBoundsRect do
  25000. Bottom := Top + 22;
  25001. Result.fTextAlign := taCenter;
  25002. Result.Caption := Caption;
  25003. Result.fIsButton := TRUE;
  25004. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  25005. Result.AttachProc( WndProcBtnReturnClick );
  25006. {$ENDIF}
  25007. end;
  25008. {$ENDIF ASM_VERSION}
  25009. //[END NewButton]
  25010. {$ENDIF USE_CONSTRUCTORS}
  25011. //----------------- BitBtn -----------------------
  25012. //[FUNCTION WndProc_DrawItem]
  25013. {$IFDEF ASM_VERSION}
  25014. function WndProc_DrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  25015. : Boolean;
  25016. asm //cmd //opd
  25017. CMP word ptr [EDX].TMsg.message, WM_DRAWITEM
  25018. JNZ @@ret_false
  25019. MOV EAX, [EDX].TMsg.lParam
  25020. MOV ECX, [EAX].TDrawItemStruct.hwndItem
  25021. JECXZ @@ret_false
  25022. PUSH EDX
  25023. PUSH offset[ID_SELF]
  25024. PUSH ECX
  25025. CALL GetProp
  25026. POP EDX
  25027. TEST EAX, EAX
  25028. JZ @@ret_false
  25029. PUSH [EDX].TMsg.lParam
  25030. PUSH [EDX].TMsg.wParam
  25031. PUSH CN_DRAWITEM
  25032. PUSH EAX
  25033. CALL TControl.Perform
  25034. MOV AL, 1
  25035. RET
  25036. @@ret_false:
  25037. XOR EAX, EAX
  25038. end;
  25039. {$ELSE ASM_VERSION} //Pascal
  25040. function WndProc_DrawItem( Sender: PControl; var Msg: TMsg; var Rslt: Integer )
  25041. : Boolean;
  25042. var DI: PDrawItemStruct;
  25043. Control: PControl;
  25044. begin
  25045. Result := FALSE;
  25046. if Msg.message = WM_DRAWITEM then
  25047. begin
  25048. DI := Pointer( Msg.lParam );
  25049. Control := Pointer( GetProp( DI.hwndItem, ID_SELF ) );
  25050. if Control <> nil then
  25051. begin
  25052. {Rslt := Integer(
  25053. Control.OnDrawItem( Control, DI.hDC, DI.rcItem, DI.itemID,
  25054. TDrawAction( Byte( DI.itemAction ) ),
  25055. TDrawState( Word( DI.itemState ) ) ) );}
  25056. Rslt := Control.Perform( CN_DRAWITEM, Msg.wParam, Msg.lParam );
  25057. Result := TRUE;
  25058. end;
  25059. //else Rslt := 0;
  25060. end;
  25061. end;
  25062. {$ENDIF ASM_VERSION}
  25063. //[END WndProc_DrawItem]
  25064. //[function ExcludeAmpersands]
  25065. function ExcludeAmpersands( Self_: PControl; const S: String ): String;
  25066. var I: Integer;
  25067. begin
  25068. Result := S;
  25069. if not Self_.FBitBtnDrawMnemonic then Exit;
  25070. for I := Length( Result ) downto 1 do
  25071. begin
  25072. if Result[ I ] = '&' then
  25073. Delete( Result, I, 1 );
  25074. end;
  25075. end;
  25076. //[procedure BitBtnExtDraw]
  25077. procedure BitBtnExtDraw( Self_: PControl; DC: HDC; X, Y: Integer; const R: TRect;
  25078. const CapText, CapTxtOrig: String; Color: TColor );
  25079. var I, J, W, H: Integer;
  25080. Sz: TSize;
  25081. Pen, OldPen: HPen;
  25082. begin
  25083. if not Self_.FBitBtnDrawMnemonic then Exit;
  25084. J := 0;
  25085. for I := 1 to Length( CapTxtOrig ) do
  25086. begin
  25087. if CapTxtOrig[ I ] <> '&' then
  25088. Inc( J )
  25089. else
  25090. begin
  25091. Windows.GetTextExtentPoint32( DC, PChar( CapText ), J, Sz );
  25092. W := Sz.cx;
  25093. Windows.GetTextExtentPoint32( DC, '_', 1, Sz );
  25094. H := Sz.cy - 1;
  25095. Windows.GetTextExtentPoint32( DC, @ CapTxtOrig[ I + 1 ], 1, Sz );
  25096. Windows.MoveToEx( DC, X + W, Y + H, nil );
  25097. Pen := CreatePen( PS_SOLID, 0, Color2RGB( Color ) );
  25098. OldPen := SelectObject( DC, Pen );
  25099. Windows.LineTo( DC, X + W + Sz.cx, Y + H );
  25100. SelectObject( DC, OldPen );
  25101. DeleteObject( Pen );
  25102. end;
  25103. end;
  25104. end;
  25105. //[procedure TControl.SetBitBtnDrawMnemonic]
  25106. procedure TControl.SetBitBtnDrawMnemonic(const Value: Boolean);
  25107. begin
  25108. FBitBtnDrawMnemonic := Value;
  25109. FBitBtnGetCaption := ExcludeAmpersands;
  25110. FBitBtnExtDraw := BitBtnExtDraw;
  25111. Invalidate;
  25112. end;
  25113. //[function TControl.GetBitBtnImgIdx]
  25114. function TControl.GetBitBtnImgIdx: Integer;
  25115. begin
  25116. Result := LoWord( fGlyphCount );
  25117. end;
  25118. //[procedure TControl.SetBitBtnImgIdx]
  25119. procedure TControl.SetBitBtnImgIdx(const Value: Integer);
  25120. begin
  25121. if not( bboImageList in fBitBtnOptions ) then Exit;
  25122. fGlyphCount := HiWord( fGlyphCount ) or (Value and $FFFF);
  25123. Invalidate;
  25124. end;
  25125. //[function TControl.GetBitBtnImageList]
  25126. function TControl.GetBitBtnImageList: THandle;
  25127. begin
  25128. Result := 0;
  25129. if bboImageList in fBitBtnOptions then
  25130. Result := fGlyphBitmap;
  25131. end;
  25132. //[procedure TControl.SetBitBtnImageList]
  25133. procedure TControl.SetBitBtnImageList(const Value: THandle);
  25134. begin
  25135. fGlyphBitmap := Value;
  25136. if Value <> 0 then
  25137. begin
  25138. fBitBtnOptions := fBitBtnOptions + [ bboImageList ];
  25139. ImageList_GetIconSize( Value, fGlyphWidth, fGlyphHeight );
  25140. end
  25141. else
  25142. fBitBtnOptions := fBitBtnOptions - [ bboImageList ];
  25143. Invalidate;
  25144. end;
  25145. //[FUNCTION WndProcBitBtn]
  25146. {$IFDEF ASM_noVERSION} // remove &-s from view //+ TextShift & if Y < 0 then Y := 0; // + glyph + TextShift if not glyphOver
  25147. function WndProcBitBtn( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  25148. const szBitmapInfo = sizeof(TBitmapInfo);
  25149. asm
  25150. CMP word ptr [EDX].TMsg.message, WM_LBUTTONDBLCLK
  25151. JNZ @@noWM_LBUTTONDBLCLK
  25152. PUSH ECX
  25153. PUSH [EDX].TMsg.wParam
  25154. PUSH [EDX].TMsg.lParam
  25155. PUSH WM_LBUTTONDOWN
  25156. PUSH EAX
  25157. CALL TControl.Perform
  25158. POP ECX
  25159. MOV [ECX], EAX
  25160. MOV AL, 1
  25161. RET
  25162. @@noWM_LBUTTONDBLCLK:
  25163. PUSH EBX
  25164. CMP [EDX].TMsg.message, CN_DRAWITEM
  25165. JNZ @@noCN_DRAWITEM
  25166. PUSH EDI
  25167. PUSH ESI
  25168. XCHG EDI, EAX // EDI = @Self
  25169. MOV dword ptr [ECX], 1
  25170. MOV ESI, [EDX].TMsg.lParam // ESI = DIS
  25171. XOR EBX, EBX // G = 0
  25172. MOV EAX, [ESI].TDrawItemStruct.itemState
  25173. TEST byte ptr [EDI].TControl.fBitBtnOptions, 8 //1 shl Ord(bboFixed)
  25174. JNZ @@fixed_in_options
  25175. {$IFDEF PARANOIA}
  25176. DB $A8, ODS_SELECTED
  25177. {$ELSE}
  25178. TEST AL, ODS_SELECTED
  25179. {$ENDIF}
  25180. JZ @@not1
  25181. JMP @@1
  25182. @@fixed_in_options:
  25183. TEST byte ptr [EDI].TControl.fChecked, 1
  25184. JZ @@not1
  25185. @@1: INC EBX
  25186. @@not1:
  25187. {$IFDEF PARANOIA}
  25188. DB $A8, ODS_DISABLED
  25189. {$ELSE}
  25190. TEST AL, ODS_DISABLED
  25191. {$ENDIF}
  25192. JZ @@not2
  25193. MOV BL, 2
  25194. @@not2: TEST EBX, EBX
  25195. JNZ @@not3
  25196. {$IFDEF PARANOIA}
  25197. DB $A8, ODS_FOCUS
  25198. {$ELSE}
  25199. TEST AL, ODS_FOCUS
  25200. {$ENDIF}
  25201. JZ @@not3
  25202. MOV BL, 3
  25203. @@not3: CMP [EDI].TControl.fMouseInControl, BH
  25204. JZ @@not4
  25205. TEST EBX, EBX
  25206. JZ @@4
  25207. CMP BL, 3
  25208. JNZ @@not4
  25209. @@4: MOV BL, 4
  25210. @@not4: MOV ECX, [EDI].TControl.fOnBitBtnDraw.TMethod.Code
  25211. TEST ECX, ECX
  25212. JZ @@noOnBitBtnDraw
  25213. //JECXZ @@noOnBitBtnDraw
  25214. MOV EAX, [EDI].TControl.fCanvas
  25215. PUSH EAX
  25216. TEST EAX, EAX
  25217. JZ @@noCanvas
  25218. MOV EDX, [ESI].TDrawItemStruct.hDC
  25219. CALL TCanvas.SetHandle
  25220. @@noCanvas:
  25221. MOV EAX, [EDI].TControl.fOnBitBtnDraw.TMethod.Data
  25222. MOV EDX, EDI
  25223. PUSH EBX
  25224. XCHG ECX, EBX
  25225. CALL EBX
  25226. POP EBX
  25227. POP ECX // Canvas
  25228. PUSH EAX
  25229. JECXZ @@noCanvas2
  25230. XCHG EAX, ECX
  25231. XOR EDX, EDX
  25232. CALL TCanvas.SetHandle
  25233. @@noCanvas2:
  25234. POP EAX
  25235. TEST AL, AL
  25236. JNZ @@exit_draw
  25237. @@noOnBitBtnDraw:
  25238. TEST byte ptr [EDI].TControl.fBitBtnOptions, 2 //1 shl Ord(bboNoBorder)
  25239. JNZ @@noborder
  25240. TEST byte ptr [ESI].TDrawItemStruct.itemState, ODS_FOCUS
  25241. JZ @@noDefaultBorder
  25242. PUSH BLACK_BRUSH
  25243. CALL GetStockObject
  25244. LEA EDX, [ESI].TDrawItemStruct.rcItem
  25245. OR ECX, -1
  25246. PUSH ECX
  25247. PUSH ECX
  25248. PUSH EDX
  25249. PUSH EAX
  25250. PUSH EDX
  25251. PUSH [ESI].TDrawItemStruct.hDC
  25252. CALL Windows.FrameRect
  25253. CALL InflateRect
  25254. XOR ECX, ECX
  25255. JMP @@noFlat
  25256. @@noDefaultBorder:
  25257. MOVZX ECX, [EDI].TControl.fFlat
  25258. JECXZ @@noFlat
  25259. AND CL, [EDI].TControl.fMouseInControl
  25260. JZ @@noborder
  25261. @@noFlat:
  25262. TEST byte ptr [ESI].TDrawItemStruct.itemState, ODS_SELECTED
  25263. MOV CL, BDR_SUNKENOUTER or BDR_SUNKENINNER
  25264. JNZ @@border_sunken
  25265. MOV CL, BDR_RAISEDOUTER or BDR_RAISEDINNER
  25266. @@border_sunken:
  25267. LEA EDX, [ESI].TDrawItemStruct.rcItem
  25268. OR EAX, -1
  25269. PUSH EAX
  25270. PUSH EAX
  25271. PUSH EDX
  25272. PUSH BF_ADJUST or BF_RECT
  25273. PUSH ECX
  25274. PUSH EDX
  25275. PUSH [ESI].TDrawItemStruct.hDC
  25276. CALL DrawEdge
  25277. CALL InflateRect
  25278. @@noborder:
  25279. PUSH [ESI].TDrawItemStruct.rcItem.Bottom
  25280. PUSH [ESI].TDrawItemStruct.rcItem.Right
  25281. PUSH [ESI].TDrawItemStruct.rcItem.Top
  25282. PUSH [ESI].TDrawItemStruct.rcItem.Left
  25283. MOV EAX, [EDI].TControl.fGlyphWidth
  25284. MOV EDX, [EDI].TControl.fGlyphHeight
  25285. TEST EAX, EAX
  25286. JLE @@noglyph
  25287. TEST EDX, EDX
  25288. JLE @@noglyph
  25289. PUSH EBP
  25290. MOV EBP, ESP
  25291. // [EBP+4] = TxRect
  25292. PUSH EDX // ImgH -> [EBP-4]
  25293. PUSH EAX // ImgW -> [EBP-8]
  25294. PUSH EDX // OutH -> [EBP-12]
  25295. PUSH EAX // OutW -> [EBP-16]
  25296. MOV EAX, [ESI].TDrawItemStruct.rcItem.Left // X = DIS.rcItem.Left
  25297. MOV EDX, [ESI].TDrawItemStruct.rcItem.Top // Y = DIS.rcItem.Top
  25298. MOV ECX, [ESI].TDrawItemStruct.rcItem.Bottom
  25299. SUB ECX, EDX
  25300. PUSH ECX // H -> [EBP-20]
  25301. MOV ECX, [ESI].TDrawItemStruct.rcItem.Right
  25302. SUB ECX, EAX
  25303. PUSH ECX // W -> [EBP-24]
  25304. MOVZX ECX, [EDI].TControl.fGlyphLayout
  25305. PUSH EBX
  25306. INC ECX
  25307. LOOP @@noGlyphLeft
  25308. MOV EBX, EAX // X
  25309. ADD EBX, [EBP-16] // +OutW
  25310. MOV [EBP+4].TRect.Left, EBX // TxRect.Left = X+OutW
  25311. JMP @@centerY
  25312. @@noGlyphLeft:
  25313. LOOP @@noGlyphTop
  25314. MOV EBX, EDX // Y
  25315. ADD EBX, [EBP-12] // +OutH
  25316. MOV [EBP+4].TRect.Top, EBX // TxRect.Top = Y+OutH
  25317. LOOP @@centerX // always JMP, ECX := -1
  25318. @@noGlyphTop:
  25319. LOOP @@noGlyphRight
  25320. MOV EAX, [ESI].TDrawItemStruct.rcItem.Right
  25321. SUB EAX, [EBP-16] // -OutW -> X
  25322. MOV [EBP+4].TRect.Right, EAX
  25323. @@centerY:
  25324. MOV EBX, [EBP-20] // H
  25325. SUB EBX, [EBP-12] // -OutH
  25326. JLE @@noGlyphRight
  25327. SAR EBX, 1
  25328. ADD EDX, EBX // Y = Y + (H-OutH)/2
  25329. @@noGlyphRight:
  25330. LOOP @@noGlyphBottom
  25331. MOV EDX, [ESI].TDrawItemStruct.rcItem.Bottom
  25332. SUB EDX, [EBP-12] // -OutH -> Y
  25333. MOV [EBP+4].TRect.Bottom, EDX
  25334. LOOP @@centerX // always JMP, ECX := -1
  25335. @@noGlyphBottom:
  25336. LOOP @@noGlyphOver
  25337. @@centerX:
  25338. MOV EBX, [EBP-24] // W
  25339. SUB EBX, [EBP-16] // -OutW
  25340. SHR EBX, 1 // /2
  25341. ADD EAX, EBX // +EAX, X = X + (W-OutW)/2
  25342. JECXZ @@centerY
  25343. @@noGlyphOver:
  25344. MOV ECX, [ESI].TDrawItemStruct.rcItem.Left
  25345. CMP EAX, ECX
  25346. JGE @@ok1
  25347. XCHG EAX, ECX
  25348. @@ok1: CMP EDX, [ESI].TDrawItemStruct.rcItem.Top
  25349. {$IFDEF USE_CMOV}
  25350. CMOVL EDX, [ESI].TDrawItemStruct.rcItem.Top
  25351. {$ELSE}
  25352. JGE @@ok2
  25353. MOV EDX, [ESI].TDrawItemStruct.rcItem.Top
  25354. @@ok2: {$ENDIF}
  25355. MOV ECX, [ESI].TDrawItemStruct.rcItem.Right
  25356. SUB ECX, EAX
  25357. CMP [EBP-16], ECX
  25358. JLE @@ok3
  25359. MOV [EBP-16], ECX // OutW := rcItem.Right - X;
  25360. @@ok3: MOV ECX, [ESI].TDrawItemStruct.rcItem.Bottom
  25361. SUB ECX, EDX
  25362. CMP ECX, [EBP-12]
  25363. JGE @@ok4
  25364. MOV [EBP-12], ECX // OutH := rcItem.Bottom - Y;
  25365. @@ok4:
  25366. POP EBX // EBX = G
  25367. TEST byte ptr [EDI].TControl.fBitBtnOptions, 1 //1 shl Ord(bboImageList)
  25368. JZ @@draw_bitmap
  25369. MOVZX ECX, word ptr [EDI].TControl.fGlyphCount
  25370. CMP word ptr [EDI].TControl.fGlyphCount + 2, BX
  25371. JLE @@no_add_glyphIdx
  25372. ADD ECX, EBX
  25373. @@no_add_glyphIdx:
  25374. XOR EBX, EBX
  25375. PUSH ILD_TRANSPARENT // Flags = 1 (ILD_TRANSPARENT)
  25376. PUSH EBX // Blend = 0
  25377. PUSH -1 // Bk = CLR_NONE
  25378. PUSH EBX // 0
  25379. PUSH EBX // 0
  25380. PUSH EDX
  25381. PUSH EAX
  25382. PUSH [ESI].TDrawItemStruct.hDC
  25383. PUSH ECX
  25384. PUSH [EDI].TControl.fGlyphBitmap
  25385. CMP [EDI].TControl.fTransparent, BL
  25386. JNZ @@imgl_transp
  25387. MOV EAX, [EDI].TControl.fColor
  25388. CALL Color2RGB
  25389. MOV [ESP+32], EAX // Bk = Color2RGB(fColor)
  25390. MOV [ESP+40], EBX // Flags = 0
  25391. @@imgl_transp:
  25392. INC EBX
  25393. CMP word ptr [EDI].TControl.fGlyphCount + 2, BX
  25394. JNZ @@draw_imagelist
  25395. DEC byte ptr [ESP+36+3] // $FF, CLR_DEFAULT = $FF000000
  25396. TEST byte ptr [ESI].TDrawItemStruct.itemState, ODS_FOCUS
  25397. JZ @@draw_imagelist
  25398. OR byte ptr [ESP+40], ILD_BLEND25 // Flags != 2
  25399. @@draw_imagelist:
  25400. CALL ImageList_DrawEx
  25401. JMP @@glyph_drawn
  25402. @@draw_bitmap:
  25403. PUSH EAX // PlaceHold for DC
  25404. PUSH EAX // PlaceHold for OldBmp
  25405. PUSH SRCCOPY
  25406. PUSH dword ptr [EBP-4] // ImgH
  25407. PUSH dword ptr [EBP-8] // ImgW
  25408. PUSH 0
  25409. PUSH EAX // PlaceHold for I
  25410. PUSH EAX // PlaceHold for DC
  25411. PUSH dword ptr [EBP-12] // OutH
  25412. PUSH dword ptr [EBP-16] // OutW
  25413. PUSH EDX // Y
  25414. PUSH EAX // X
  25415. PUSH [ESI].TDrawItemStruct.hDC
  25416. PUSH 0
  25417. CALL CreateCompatibleDC
  25418. MOV [ESP+48], EAX // save DC
  25419. MOV [ESP+20], EAX // place DC
  25420. PUSH [EDI].TControl.fGlyphBitmap
  25421. PUSH EAX
  25422. CALL SelectObject
  25423. MOV [ESP+44], EAX // save OldBitmap
  25424. XOR EAX, EAX
  25425. CMP [EDI].TControl.fGlyphCount, EBX
  25426. JLE @@no_incGlyIdx
  25427. MOV EAX, [EBP-8] // ImgW
  25428. IMUL EBX
  25429. @@no_incGlyIdx:
  25430. MOV [ESP+24], EAX // place I
  25431. CALL StretchBlt
  25432. CALL FinishDC
  25433. @@glyph_drawn:
  25434. MOV ESP, EBP
  25435. POP EBP
  25436. @@noglyph:
  25437. TEST byte ptr[EDI].TControl.fBitBtnOptions, 4 //1 shl Ord(bboNoCaption)
  25438. JNZ @@noCaption
  25439. POP EAX
  25440. PUSH EAX
  25441. MOV EDX, [ESP].TRect.Right
  25442. CMP EDX, EAX
  25443. JLE @@noCaption
  25444. MOV EDX, [ESP].TRect.Bottom
  25445. CMP EDX, [ESP].TRect.Top
  25446. JLE @@noCaption
  25447. XOR EBX, EBX
  25448. PUSH EBX // > CapText
  25449. MOV EDX, ESP
  25450. MOV EAX, EDI
  25451. CALL TControl.GetCaption
  25452. PUSH EBX // > Bk
  25453. PUSH EBX // > Blend
  25454. CMP [EDI].TControl.fTransparent, BL
  25455. MOV BL, ETO_CLIPPED
  25456. JNZ @@drwTxTransparent
  25457. CMP [EDI].TControl.fGlyphLayout, glyphOver
  25458. JNZ @@drwTxOpaque
  25459. @@drwTxTransparent:
  25460. PUSH TRANSPARENT
  25461. PUSH [ESI].TDrawItemStruct.hDC
  25462. CALL SetBkMode
  25463. MOV [ESP+4], EAX // Bk := SetBkMode( DIS.hDC, TRANSPARENT )
  25464. JMP @@drwTx1
  25465. @@drwTxOpaque:
  25466. MOV BL, ETO_CLIPPED or ETO_OPAQUE
  25467. MOV EAX, [EDI].TControl.fColor
  25468. CALL Color2RGB
  25469. PUSH EAX
  25470. PUSH [ESI].TDrawItemStruct.hDC
  25471. CALL SetBkColor
  25472. POP ECX
  25473. PUSH EAX // Blend := SetBkColor(DIS.hDC,fColor)
  25474. @@drwTx1:
  25475. PUSH 0 // > OldFont
  25476. PUSH 0 // > OldTextColor
  25477. PUSH 0 // push <nil>
  25478. MOV EDX, [ESP+20] // CapText
  25479. CALL EDX2PChar
  25480. PUSH dword ptr [EDX-4] // push Length(CapText)
  25481. PUSH EDX // push PChar(CapText)
  25482. LEA EAX, [ESP+32]
  25483. PUSH EAX // push @TxRect
  25484. PUSH EBX // push Flags
  25485. MOV EBX, [ESI].TDrawItemStruct.hDC
  25486. MOV ECX, [EDI].TControl.fFont
  25487. JECXZ @@drwTx_noFont
  25488. XCHG EAX, ECX
  25489. CALL TGraphicTool.GetHandle
  25490. PUSH EAX
  25491. PUSH EBX
  25492. CALL SelectObject
  25493. MOV [ESP+24], EAX // OldFont := SelectObject...
  25494. @@drwTx_noFont:
  25495. MOV EAX, [EDI].TControl.fTextColor
  25496. CALL Color2RGB
  25497. PUSH EAX
  25498. PUSH EBX
  25499. CALL SetTextColor
  25500. MOV [ESP+20], EAX // OldTextColor := SetTextColor...
  25501. PUSH EAX
  25502. PUSH EAX
  25503. PUSH ESP
  25504. MOV ECX, [ESP+48] // ECX = CapText
  25505. XOR EAX, EAX
  25506. JECXZ @@drwTx0
  25507. MOV EAX, [ECX-4] // EAX = Length(CapText)
  25508. @@drwTx0:
  25509. PUSH EAX
  25510. PUSH ECX
  25511. PUSH EBX
  25512. CALL GetTextExtentPoint32
  25513. POP ECX // ECX = TextSz.cx
  25514. POP EDX // EDX = TextSz.cy
  25515. MOV EAX, [ESP+40].TRect.Bottom
  25516. SUB EAX, [ESP+40].TRect.Top
  25517. SUB EAX, EDX
  25518. JGE @@yOk
  25519. XOR EAX, EAX
  25520. @@yOk: SHR EAX, 1
  25521. ADD EAX, [ESP+40].TRect.Top
  25522. PUSH EAX // push Y
  25523. MOV EDX, [ESP+44].TRect.Right
  25524. MOV EAX, [ESP+44].TRect.Left // EAX = TxRect.Left
  25525. SUB EDX, EAX // EDX = W
  25526. PUSH EAX
  25527. CMP [EDI].TControl.fTextAlign, taRight
  25528. JL @@chk_X
  25529. JE @@alignR
  25530. SUB ECX, EDX
  25531. SAR ECX, 1
  25532. JMP @@alignC
  25533. @@alignR:
  25534. ADD EAX, EDX
  25535. @@alignC:
  25536. SUB EAX, ECX
  25537. @@chk_X:POP EDX
  25538. CMP EAX, EDX
  25539. JGE @@xOk
  25540. XCHG EAX, EDX
  25541. @@xOk: PUSH EAX // push X
  25542. PUSH EBX // push hDC
  25543. CALL ExtTextOut
  25544. PUSH EBX
  25545. CALL SetTextColor
  25546. POP ECX
  25547. JECXZ @@noRestoreFont
  25548. PUSH ECX
  25549. PUSH EBX
  25550. CALL SelectObject
  25551. @@noRestoreFont:
  25552. POP ECX // Blend
  25553. JECXZ @@restoreBk
  25554. PUSH ECX
  25555. PUSH EBX
  25556. CALL SetBkColor
  25557. POP ECX
  25558. JMP @@delCaption
  25559. @@restoreBk:
  25560. PUSH EBX
  25561. CALL SetBkMode
  25562. @@delCaption:
  25563. CALL RemoveStr
  25564. @@noCaption:
  25565. ADD ESP, 16
  25566. @@exit_draw:
  25567. POP ESI
  25568. POP EDI
  25569. POP EBX
  25570. MOV AL, 1
  25571. RET
  25572. @@noCN_DRAWITEM:
  25573. CMP word ptr [EDX].TMsg.message, WM_LBUTTONDOWN
  25574. JZ @@doDown
  25575. CMP word ptr [EDX].TMsg.message, WM_KEYDOWN
  25576. JNZ @@noWM_LBUTTONDOWN
  25577. CMP [EDX].TMsg.wParam, 32
  25578. JNZ @@noWM_LBUTTONDOWN
  25579. @@doDown:
  25580. PUSH EDX
  25581. XCHG EBX, EAX
  25582. CALL @@fixed_proc
  25583. MOV ECX, [EBX].TControl.fRepeatInterval
  25584. JECXZ @@exit_LBUTTONDOWN
  25585. //MOV EAX, EBX
  25586. //CALL TControl.DoClick
  25587. POP EDX
  25588. PUSH EDX
  25589. CMP word ptr [EDX].TMsg.message, WM_KEYDOWN
  25590. JZ @@not_SetTimer
  25591. PUSH 0
  25592. PUSH [EBX].TControl.fRepeatInterval
  25593. PUSH 1
  25594. PUSH [EBX].TControl.fHandle
  25595. CALL SetTimer
  25596. @@exit_LBUTTONDOWN:
  25597. @@not_SetTimer:
  25598. POP EDX
  25599. JMP @@invalidate
  25600. @@noWM_LBUTTONDOWN:
  25601. CMP word ptr [EDX].TMsg.message, WM_TIMER
  25602. JNZ @@noWM_TIMER
  25603. XCHG EBX, EAX
  25604. PUSH 0
  25605. PUSH 0
  25606. PUSH BM_GETSTATE
  25607. PUSH EBX
  25608. CALL TControl.Perform
  25609. {$IFDEF PARANOIA}
  25610. DB $A8, 4
  25611. {$ELSE}
  25612. TEST AL, BST_PUSHED
  25613. {$ENDIF}
  25614. JNZ @@pushed
  25615. PUSH 1
  25616. PUSH [EBX].TControl.fHandle
  25617. CALL KillTimer
  25618. CALL ReleaseCapture
  25619. JMP @@noWM_TIMER
  25620. @@fixed_proc:
  25621. TEST byte ptr [EBX].TControl.fBitBtnOptions, 8 // bboFixed
  25622. JZ @@not_fixed
  25623. XOR [EBX].TControl.fChecked, 1
  25624. MOV ECX, [EBX].TControl.fOnChange.TMethod.Code
  25625. JECXZ @@not_fixed
  25626. MOV EAX, [EBX].TControl.fOnChange.TMethod.Data
  25627. MOV EDX, EBX
  25628. JMP ECX
  25629. @@pushed:
  25630. CALL @@fixed_proc
  25631. MOV EAX, EBX
  25632. CALL TControl.DoClick
  25633. @@invalidate:
  25634. XCHG EAX, EBX
  25635. CALL TControl.Invalidate
  25636. @@noWM_TIMER:
  25637. XOR EAX, EAX
  25638. POP EBX
  25639. @@not_fixed:
  25640. end;
  25641. {$ELSE ASM_VERSION} //Pascal
  25642. function WndProcBitBtn( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  25643. var DIS: PDrawItemStruct;
  25644. IsDown, IsDefault, IsDisabled: Boolean;
  25645. Flags: Integer;
  25646. X, Y, W, H, ImgW, ImgH, OutW, OutH, I, G, Bk, Blend: Integer;
  25647. //BI: TBitmapInfo;
  25648. //Dib: TDibSection;
  25649. TxRect: TRect;
  25650. OldFont: HFont;
  25651. OldTextColor: TColor;
  25652. CapText, CapTxtOrig: String;
  25653. TextSz: TSize;
  25654. DC: HDC;
  25655. OldBmp: HBitmap;
  25656. Handled: Boolean;
  25657. //Br: HBrush;
  25658. begin
  25659. Result := False;
  25660. if (Msg.message = WM_LBUTTONDBLCLK) then
  25661. begin
  25662. Rslt := Self_.Perform( WM_LBUTTONDOWN, Msg.wParam, Msg.lParam );
  25663. Result := True;
  25664. Exit;
  25665. end;
  25666. if (Msg.message = CN_DRAWITEM) then
  25667. begin
  25668. Result := True;
  25669. Rslt := 1;
  25670. DIS := Pointer( Msg.lParam );
  25671. //IsDown := DIS.itemState and ODS_SELECTED <> 0;
  25672. IsDown := (DIS.itemState and ODS_SELECTED <> 0) or
  25673. ({(bboFixed in Self_.fBitBtnOptions) and} Self_.fChecked);
  25674. IsDefault := DIS.itemState and ODS_FOCUS <> 0;
  25675. IsDisabled := DIS.itemState and ODS_DISABLED <> 0;
  25676. G := 0;
  25677. if IsDown {and not(bboFixed in Self_.fBitBtnOptions)
  25678. or (bboFixed in Self_.fBitBtnOptions) and Self_.fChecked} then
  25679. G := 1;
  25680. if IsDisabled then
  25681. G := 2;
  25682. if (G = 0) and IsDefault then
  25683. G := 3;
  25684. if ((G = 0) or (G = 3)) and Self_.MouseInControl then
  25685. G := 4;
  25686. if Assigned( Self_.fOnBitBtnDraw ) then
  25687. begin
  25688. if Assigned( Self_.fCanvas ) then
  25689. Self_.fCanvas.SetHandle( DIS.hDC );
  25690. Handled := Self_.fOnBitBtnDraw( Self_, G );
  25691. if Assigned( Self_.fCanvas ) then
  25692. Self_.fCanvas.SetHandle( 0 );
  25693. if Handled then Exit;
  25694. end;
  25695. if not ( bboNoBorder in Self_.fBitBtnOptions ) then
  25696. begin
  25697. if IsDefault then
  25698. begin
  25699. Windows.FrameRect( DIS.hDC, DIS.rcItem, GetStockObject( BLACK_BRUSH ) );
  25700. InflateRect( DIS.rcItem, -1, -1 );
  25701. end;
  25702. if not Self_.fFlat or Self_.fMouseInControl or IsDefault then
  25703. begin
  25704. if IsDown then
  25705. Flags := BDR_SUNKENOUTER or BDR_SUNKENINNER
  25706. else
  25707. Flags := BDR_RAISEDOUTER or BDR_RAISEDINNER;
  25708. DrawEdge( DIS.hDC, DIS.rcItem, Flags, BF_ADJUST or BF_RECT );
  25709. InflateRect( DIS.rcItem, -1, -1 );
  25710. end;
  25711. end;
  25712. TxRect := DIS.rcItem;
  25713. if Self_.fGlyphBitmap <> 0 then
  25714. begin
  25715. ImgW := Self_.fGlyphWidth;
  25716. ImgH := Self_.fGlyphHeight;
  25717. if (ImgW > 0) and (ImgH > 0) then
  25718. begin
  25719. OutW := ImgW;
  25720. OutH := ImgH;
  25721. W := DIS.rcItem.Right - DIS.rcItem.Left;
  25722. H := DIS.rcItem.Bottom - DIS.rcItem.Top;
  25723. X := DIS.rcItem.Left;
  25724. Y := DIS.rcItem.Top;
  25725. if isDown and (Self_.fGlyphLayout <> glyphOver) then
  25726. begin
  25727. Inc( X, Self_.TextShiftX );
  25728. Inc( Y, Self_.TextShiftY );
  25729. end;
  25730. case Self_.fGlyphLayout of
  25731. glyphLeft:
  25732. begin
  25733. Y := Y + (H - OutH) div 2;
  25734. TxRect.Left := X + OutW;
  25735. end;
  25736. glyphTop:
  25737. begin
  25738. X := X + (W - OutW) div 2;
  25739. TxRect.Top := Y + OutH;
  25740. end;
  25741. glyphRight:
  25742. begin
  25743. X := DIS.rcItem.Right - OutW;
  25744. TxRect.Right := X;
  25745. Y := Y + (H - OutH) div 2;
  25746. end;
  25747. glyphBottom:
  25748. begin
  25749. Y := DIS.rcItem.Bottom - OutH;
  25750. TxRect.Bottom := Y;
  25751. X := X + (W - OutW) div 2;
  25752. end;
  25753. glyphOver:
  25754. begin
  25755. X := X + (W - OutW) div 2;
  25756. Y := Y + (H - OutH) div 2;
  25757. end;
  25758. end;
  25759. if X < DIS.rcItem.Left then
  25760. X := DIS.rcItem.Left;
  25761. if Y < DIS.rcItem.Top then
  25762. Y := DIS.rcItem.Top;
  25763. if X + OutW > DIS.rcItem.Right then
  25764. OutW := DIS.rcItem.Right - X;
  25765. if Y + OutH > DIS.rcItem.Bottom then
  25766. OutH := DIS.rcItem.Bottom - Y;
  25767. //Br := CreateSolidBrush( Color2RGB( Self_.fColor ) );
  25768. //Windows.FillRect( DIS.hDC, MakeRect( X, DIS.rcItem.Top, X + OutW, DIS.rcItem.Bottom ), Br );
  25769. //DeleteObject( Br );
  25770. if bboImageList in Self_.fBitBtnOptions then
  25771. begin
  25772. I := LoWord( Self_.fGlyphCount );
  25773. if //(HiWord( Self_.fGlyphCount ) > 1) and
  25774. (HiWord( Self_.fGlyphCount ) > G) then
  25775. I := I + G;
  25776. Flags := 0; // ILD_NORMAL
  25777. Blend := 0;
  25778. if not Self_.fTransparent then
  25779. Bk := Color2RGB( Self_.fColor )
  25780. else
  25781. begin
  25782. Bk := Integer(CLR_NONE);
  25783. Flags := ILD_TRANSPARENT;
  25784. end;
  25785. if HiWord( Self_.fGlyphCount ) = 1 then
  25786. begin
  25787. Blend := Integer(CLR_DEFAULT);
  25788. if IsDefault then
  25789. Flags := Flags or ILD_BLEND25;
  25790. end;
  25791. ImageList_DrawEx( Self_.fGlyphBitmap, I, DIS.hDC, X, Y, 0, 0,
  25792. Bk, Blend, Flags );
  25793. end
  25794. else
  25795. begin
  25796. DC := CreateCompatibleDC( 0 );
  25797. OldBmp := SelectObject( DC, Self_.fGlyphBitmap );
  25798. I := 0;
  25799. if Self_.fGlyphCount > G then
  25800. I := I + G * ImgW;
  25801. StretchBlt( DIS.hDC, X, Y, OutW, OutH, DC, I, 0, ImgW, ImgH, SRCCOPY );
  25802. SelectObject( DC, OldBmp );
  25803. DeleteDC( DC );
  25804. end;
  25805. end;
  25806. end;
  25807. if not (bboNoCaption in Self_.fBitBtnOptions) then
  25808. //if (Self_.Text <> '') then
  25809. if (TxRect.Right > TxRect.Left) and (TxRect.Bottom > TxRect.Top) then
  25810. begin
  25811. CapText := Self_.Caption;
  25812. ///////////////////////////////////////////// added 19 Nov 2001
  25813. CapTxtOrig := CapText;
  25814. if Assigned( Self_.FBitBtnGetCaption ) then
  25815. CapText := Self_.FBitBtnGetCaption( Self_, CapText );
  25816. /////////////////////////////////////////////
  25817. Bk := 0;
  25818. Blend := 0;
  25819. Flags := ETO_CLIPPED;
  25820. if Self_.fTransparent or (Self_.fGlyphLayout = glyphOver) then
  25821. Bk := SetBkMode( DIS.hDC, TRANSPARENT )
  25822. else
  25823. begin
  25824. Flags := Flags or ETO_OPAQUE;
  25825. Blend := SetBkColor( DIS.hDC, Color2RGB( Self_.fColor ) );
  25826. end;
  25827. // Returned previous BkMode is either OPAQUE=1 or TRANSPARENT=2
  25828. OldFont := 0;
  25829. if assigned( Self_.fFont ) then
  25830. OldFont := SelectObject( DIS.hDC, Self_.fFont.Handle );
  25831. OldTextColor := SetTextColor( DIS.hDC, Color2RGB( Self_.fTextColor ) );
  25832. Windows.GetTextExtentPoint32( DIS.hDC, PChar( CapText ), Length( CapText ),
  25833. TextSz );
  25834. W := TxRect.Right - TxRect.Left;
  25835. H := TxRect.Bottom - TxRect.Top;
  25836. Y := TxRect.Top + (H - TextSz.cy) div 2;
  25837. case Self_.fTextAlign of
  25838. taLeft: X := TxRect.Left;
  25839. taCenter: X := TxRect.Left + (W - TextSz.cx) div 2;
  25840. else {taRight:} X := TxRect.Right - TextSz.cx;
  25841. end;
  25842. if isDown then
  25843. begin
  25844. Inc( X, Self_.TextShiftX );
  25845. Inc( Y, Self_.TextShiftY );
  25846. end;
  25847. if Y < 0 then
  25848. Y := 0;
  25849. if X < TxRect.Left then
  25850. X := TxRect.Left;
  25851. Windows.ExtTextOut( DIS.hDC, X, Y, Flags, @TxRect,
  25852. PChar( CapText ), Length( CapText ), nil );
  25853. //////////////////////////////////////////////////////////////////////////
  25854. // added 19 Nov 2001 to provide underlying mnemonic characters
  25855. if Assigned( Self_.FBitBtnExtDraw ) then
  25856. Self_.FBitBtnExtDraw( Self_, DIS.hDC, X, Y, TxRect, CapText, CapTxtOrig,
  25857. OldTextColor );
  25858. //////////////////////////////////////////////////////////////////////////
  25859. SetTextColor( DIS.hDC, OldTextColor );
  25860. if OldFont <> 0 then
  25861. SelectObject( DIS.hDC, OldFont );
  25862. if Blend = 0 then
  25863. SetBkMode( DIS.hDC, Bk )
  25864. else
  25865. SetBkColor( DIS.hDC, Blend );
  25866. end;
  25867. end;
  25868. if (Msg.message = WM_LBUTTONDOWN) or (Msg.message = WM_KEYDOWN) and (Msg.wParam = 32) then
  25869. begin
  25870. if bboFixed in Self_.fBitBtnOptions then
  25871. begin
  25872. Self_.fChecked := not Self_.fChecked;
  25873. if Assigned( Self_.fOnChange ) then
  25874. Self_.fOnChange( Self_ );
  25875. end;
  25876. if Self_.fRepeatInterval > 0 then
  25877. begin
  25878. if Msg.message <> WM_KEYDOWN then
  25879. SetTimer( Self_.fHandle, 1, Self_.fRepeatInterval, nil );
  25880. Self_.Invalidate;
  25881. end;
  25882. end;
  25883. // added 15 Aug 2002 to repaint when focus lost:
  25884. if Msg.message = WM_KILLFOCUS then
  25885. Self_.Invalidate;
  25886. if Msg.message = WM_TIMER then
  25887. begin
  25888. if Self_.Perform( BM_GETSTATE, 0, 0 ) and BST_PUSHED = 0 then
  25889. begin
  25890. KillTimer( Self_.fHandle, 1 );
  25891. ReleaseCapture;
  25892. end
  25893. else
  25894. begin
  25895. if bboFixed in Self_.fBitBtnOptions then
  25896. begin
  25897. Self_.fChecked := not Self_.fChecked;
  25898. if Assigned( Self_.fOnChange ) then
  25899. Self_.fOnChange( Self_ );
  25900. end;
  25901. Self_.DoClick;
  25902. Self_.Invalidate;
  25903. end;
  25904. end;
  25905. end;
  25906. {$ENDIF ASM_VERSION}
  25907. //[END WndProcBitBtn]
  25908. {$IFDEF USE_CONSTRUCTORS}
  25909. //[function NewBitBtn]
  25910. function NewBitBtn( AParent: PControl; const Caption: String;
  25911. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap;
  25912. GlyphCount: Integer ): PControl;
  25913. begin
  25914. new( Result, CreateBitBtn( AParent, Caption, Options, Layout, GlyphBitmap, GlyphCount ) );
  25915. end;
  25916. //[END NewBitBtn]
  25917. {$ELSE not_USE_CONSTRUCTORS}
  25918. //[FUNCTION NewBitBtn]
  25919. {$IFDEF ASM_VERSION}
  25920. function NewBitBtn( AParent: PControl; const Caption: String;
  25921. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap; GlyphCount: Integer ): PControl;
  25922. const szBitmapInfo = sizeof(TBitmapInfo);
  25923. asm
  25924. PUSH EBX
  25925. PUSH EDX
  25926. PUSH ECX
  25927. PUSH 0
  25928. PUSH offset[ButtonActions]
  25929. MOV EDX, offset[ButtonClass]
  25930. MOV ECX, WS_VISIBLE or WS_CHILD or WS_TABSTOP or BS_OWNERDRAW
  25931. CALL _NewControl
  25932. XCHG EBX, EAX
  25933. INC [EBX].TControl.fIgnoreDefault
  25934. INC [EBX].TControl.fIsButton
  25935. MOV byte ptr [EBX].TControl.fCommandActions.aAutoSzX, 8
  25936. MOV byte ptr [EBX].TControl.fCommandActions.aAutoSzY, 8
  25937. POP EAX
  25938. MOV [EBX].TControl.fBitBtnOptions, AL
  25939. MOVZX EDX, Layout
  25940. MOV [EBX].TControl.fGlyphLayout, DL
  25941. MOV ECX, GlyphBitmap
  25942. MOV [EBX].TControl.fGlyphBitmap, ECX
  25943. MOV EDX, [EBX].TControl.fBoundsRect.Top
  25944. ADD EDX, 22
  25945. MOV [EBX].TControl.fBoundsRect.Bottom, EDX
  25946. TEST ECX, ECX
  25947. JZ @@noGlyphWH
  25948. {$IFDEF PARANOIA}
  25949. DB $A8, 01
  25950. {$ELSE}
  25951. TEST AL, bboImageList
  25952. {$ENDIF}
  25953. JZ @@getBmpWH
  25954. PUSH EAX
  25955. MOV EAX, ESP
  25956. PUSH EAX
  25957. MOV EDX, ESP
  25958. PUSH EAX
  25959. PUSH EDX
  25960. PUSH ECX
  25961. CALL ImageList_GetIconSize
  25962. POP EAX
  25963. POP EDX
  25964. MOV ECX, GlyphCount
  25965. JMP @@WHready
  25966. @@getBmpWH:
  25967. ADD ESP, -szBitmapInfo
  25968. PUSH ESP
  25969. PUSH szBitmapInfo
  25970. PUSH ECX
  25971. CALL GetObject
  25972. XCHG ECX, EAX
  25973. POP EAX
  25974. POP EAX
  25975. POP EDX
  25976. ADD ESP, szBitmapInfo-12
  25977. TEST ECX, ECX
  25978. JZ @@noGlyphWH
  25979. MOV ECX, GlyphCount
  25980. INC ECX
  25981. LOOP @@GlyphCountOK
  25982. PUSH EAX
  25983. PUSH EDX
  25984. XCHG EDX, ECX
  25985. DIV ECX
  25986. XCHG ECX, EAX
  25987. POP EDX
  25988. POP EAX
  25989. @@GlyphCountOK:
  25990. CMP ECX, 1
  25991. JLE @@WHReady
  25992. PUSH EDX
  25993. CDQ
  25994. IDIV ECX
  25995. POP EDX
  25996. @@WHReady:
  25997. MOV [EBX].TControl.fGlyphWidth, EAX
  25998. MOV [EBX].TControl.fGlyphHeight, EDX
  25999. MOV [EBX].TControl.fGlyphCount, ECX
  26000. POP ECX // ECX = @ Caption[ 1 ]
  26001. PUSH ECX
  26002. PUSH EDX
  26003. PUSH EAX
  26004. TEST EAX, EAX
  26005. JLE @@noWidthResize
  26006. JECXZ @@addWLeft
  26007. CMP [Layout], glyphOver
  26008. JE @@addWLeft
  26009. MOVZX ECX, byte ptr[ECX]
  26010. JECXZ @@addWLeft
  26011. // else
  26012. CMP [Layout], glyphLeft
  26013. JZ @@addWRight
  26014. CMP [Layout], glyphRight
  26015. JNZ @@noWidthResize
  26016. @@addWRight:
  26017. ADD [EBX].TControl.fBoundsRect.Right, EAX
  26018. ADD [EBX].TControl.fCommandActions.aAutoSzX, AX
  26019. JMP @@noWidthResize
  26020. @@addWLeft:
  26021. // then
  26022. ADD EAX, [EBX].TControl.fBoundsRect.Left
  26023. MOV [EBX].TControl.fBoundsRect.Right, EAX
  26024. MOV byte ptr [EBX].TControl.fCommandActions.aAutoSzX, 0
  26025. @@noWidthResize:
  26026. TEST EDX, EDX
  26027. JLE @@noHeightResize
  26028. CMP [Layout], glyphTop
  26029. JE @@addHBottom
  26030. CMP [Layout], glyphBottom
  26031. JNE @@addHTop
  26032. @@addHBottom:
  26033. ADD [EBX].TControl.fBoundsRect.Bottom, EDX
  26034. ADD [EBX].TControl.fCommandActions.aAutoSzY, DX
  26035. JMP @@noHeightResize
  26036. @@addHTop:
  26037. ADD EDX, [EBX].TControl.fBoundsRect.Top
  26038. MOV [EBX].TControl.fBoundsRect.Bottom, EDX
  26039. MOV [EBX].TControl.fCommandActions.aAutoSzY, 0
  26040. @@noHeightResize:
  26041. POP ECX
  26042. POP EAX
  26043. CDQ
  26044. MOV DL, 4
  26045. TEST [EBX].TControl.fBitBtnOptions, 2 //1 shl bboNoBorder
  26046. JNZ @@noBorderResize
  26047. JECXZ @@noBorderWinc
  26048. ADD [EBX].TControl.fBoundsRect.Right, EDX
  26049. CMP [EBX].TControl.fCommandActions.aAutoSzX, 0
  26050. JZ @@noBorderWinc
  26051. ADD [EBX].TControl.fCommandActions.aAutoSzX, DX
  26052. @@noBorderWinc:
  26053. TEST EAX, EAX
  26054. JLE @@noBorderResize
  26055. ADD [EBX].TControl.fBoundsRect.Bottom, EDX
  26056. CMP [EBX].TControl.fCommandActions.aAutoSzY, 0
  26057. JZ @@noBorderResize
  26058. ADD [EBX].TControl.fCommandActions.aAutoSzY, DX
  26059. @@noBorderResize:
  26060. @@noGlyphWH:
  26061. MOV ECX, [EBX].TControl.fParent
  26062. JECXZ @@notAttach2Parent
  26063. XCHG EAX, ECX
  26064. MOV EDX, offset[WndProc_DrawItem]
  26065. CALL TControl.AttachProc
  26066. @@notAttach2Parent:
  26067. MOV EAX, EBX
  26068. MOV EDX, offset[WndProcBitBtn]
  26069. CALL TControl.AttachProc
  26070. MOV EAX, EBX
  26071. POP EDX
  26072. CALL TControl.SetCaption
  26073. MOV [EBX].TControl.fTextAlign, taCenter
  26074. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  26075. MOV EAX, EBX
  26076. MOV EDX, offset[WndProcBtnReturnClick]
  26077. CALL TControl.AttachProc
  26078. {$ENDIF}
  26079. XCHG EAX, EBX
  26080. POP EBX
  26081. end;
  26082. {$ELSE ASM_VERSION} //Pascal
  26083. function NewBitBtn( AParent: PControl; const Caption: String;
  26084. Options: TBitBtnOptions; Layout: TGlyphLayout; GlyphBitmap: HBitmap;
  26085. GlyphCount: Integer ): PControl;
  26086. var
  26087. B: TBitmapInfo;
  26088. W, H: Integer;
  26089. begin
  26090. Result := _NewControl( AParent, 'BUTTON', WS_VISIBLE or WS_CHILD or
  26091. WS_TABSTOP or BS_OWNERDRAW, False, @ButtonActions );
  26092. Result.fIgnoreDefault := TRUE;
  26093. Result.fIsButton := TRUE;
  26094. Result.fCommandActions.aAutoSzX := 8;
  26095. Result.fCommandActions.aAutoSzY := 8;
  26096. //Result.fExStyle := Result.fExStyle and not WS_EX_CONTROLPARENT;
  26097. Result.fBitBtnOptions := Options;
  26098. Result.fGlyphLayout := Layout;
  26099. Result.fGlyphBitmap := GlyphBitmap;
  26100. with Result.fBoundsRect do
  26101. begin
  26102. Bottom := Top + 22;
  26103. W := 0; H := 0;
  26104. if GlyphBitmap <> 0 then
  26105. begin
  26106. if bboImageList in Options then
  26107. ImageList_GetIconSize( GlyphBitmap, W, H )
  26108. else
  26109. begin
  26110. if GetObject( GlyphBitmap, Sizeof(B), @B ) > 0 then
  26111. begin
  26112. W := B.bmiHeader.biWidth;
  26113. H := B.bmiHeader.biHeight;
  26114. if GlyphCount = 0 then
  26115. GlyphCount := W div H;
  26116. if GlyphCount > 1 then
  26117. W := W div GlyphCount;
  26118. end;
  26119. end;
  26120. if W > 0 then
  26121. begin
  26122. if (Caption = '') or (Layout = glyphOver) then
  26123. begin
  26124. Right := Left + W;
  26125. Result.fCommandActions.aAutoSzX := 0;
  26126. end
  26127. else
  26128. if Layout in [ glyphLeft, glyphRight ] then
  26129. begin
  26130. Right := Right + W;
  26131. Inc( Result.fCommandActions.aAutoSzX, W );
  26132. end;
  26133. end;
  26134. if H > 0 then
  26135. begin
  26136. if Layout in [ glyphTop, glyphBottom ] then
  26137. begin
  26138. Bottom := Bottom + H;
  26139. Inc( Result.fCommandActions.aAutoSzY, H );
  26140. end
  26141. else
  26142. begin
  26143. Bottom := Top + H;
  26144. Result.fCommandActions.aAutoSzY := 0;
  26145. end;
  26146. end;
  26147. if not ( bboNoBorder in Options ) then
  26148. begin
  26149. if W > 0 then
  26150. begin
  26151. Inc( Right, 4 );
  26152. if Result.fCommandActions.aAutoSzX > 0 then
  26153. Inc( Result.fCommandActions.aAutoSzX, 4 );
  26154. end;
  26155. if H > 0 then
  26156. begin
  26157. Inc( Bottom, 4 );
  26158. if Result.fCommandActions.aAutoSzY > 0 then
  26159. Inc( Result.fCommandActions.aAutoSzY, 4 );
  26160. end;
  26161. end;
  26162. end;
  26163. Result.fGlyphWidth := W;
  26164. Result.fGlyphHeight := H;
  26165. end;
  26166. Result.fGlyphCount := GlyphCount;
  26167. if AParent <> nil then
  26168. AParent.AttachProc( WndProc_DrawItem );
  26169. Result.AttachProc( WndProcBitBtn );
  26170. //Result.AttachProc( WndProcDoEraseBkgnd );
  26171. Result.fTextAlign := taCenter;
  26172. Result.Caption := Caption;
  26173. {$IFDEF ALL_BUTTONS_RESPOND_TO_ENTER}
  26174. Result.AttachProc( WndProcBtnReturnClick );
  26175. {$ENDIF}
  26176. end;
  26177. {$ENDIF ASM_VERSION}
  26178. //[END NewBitBtn]
  26179. {$ENDIF USE_CONSTRUCTORS}
  26180. //===================== Check box ========================//
  26181. {$IFDEF USE_CONSTRUCTORS}
  26182. //[function NewCheckbox]
  26183. function NewCheckbox( AParent: PControl; const Caption: String ): PControl;
  26184. begin
  26185. new( Result, CreateCheckbox( AParent, Caption ) );
  26186. end;
  26187. //[END NewCheckbox]
  26188. {$ELSE not_USE_CONSTRUCTORS}
  26189. //[FUNCTION NewCheckbox]
  26190. {$IFDEF ASM_VERSION}
  26191. function NewCheckbox( AParent: PControl; const Caption: String ): PControl;
  26192. asm
  26193. CALL NewButton
  26194. MOV EDX, [EAX].TControl.fBoundsRect.Left
  26195. ADD EDX, 72
  26196. MOV [EAX].TControl.fBoundsRect.Right, EDX
  26197. MOV [EAX].TControl.fStyle, WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP
  26198. MOV [EAX].TControl.fCommandActions.aAutoSzX, 24
  26199. end;
  26200. {$ELSE ASM_VERSION} //Pascal
  26201. function NewCheckbox( AParent: PControl; const Caption: String ): PControl;
  26202. begin
  26203. Result := NewButton( AParent, Caption );
  26204. with Result.fBoundsRect do
  26205. begin
  26206. Right := Left + 72;
  26207. end;
  26208. Result.fStyle := WS_VISIBLE or WS_CHILD or
  26209. BS_AUTOCHECKBOX or WS_TABSTOP;
  26210. Result.fCommandActions.aAutoSzX := 24;
  26211. end;
  26212. {$ENDIF ASM_VERSION}
  26213. //[END NewCheckbox]
  26214. {$ENDIF USE_CONSTRUCTORS}
  26215. //[function NewCheckBox3State]
  26216. function NewCheckBox3State( AParent: PControl; const Caption: String ): PControl;
  26217. begin
  26218. Result := NewCheckbox( AParent, Caption );
  26219. Result.fStyle := Result.fStyle and not BS_AUTOCHECKBOX or BS_AUTO3STATE;
  26220. end;
  26221. //===================== Radiobox ========================//
  26222. //[FUNCTION ClickRadio]
  26223. {$IFDEF ASM_VERSION}
  26224. procedure ClickRadio( Sender:PObj );
  26225. asm
  26226. MOV ECX, [EAX].TControl.fParent
  26227. JECXZ @@exit
  26228. PUSH [EAX].TControl.fMenu
  26229. PUSH [ECX].TControl.fRadioLast
  26230. PUSH [ECX].TControl.fRadio1st
  26231. PUSH [ECX].TControl.fHandle
  26232. CALL CheckRadioButton
  26233. @@exit:
  26234. end;
  26235. {$ELSE ASM_VERSION} //Pascal
  26236. procedure ClickRadio( Sender:PObj );
  26237. var Self_:PControl;
  26238. begin
  26239. Self_ := PControl( Sender );
  26240. if Self_.FParent <> nil then
  26241. CheckRadioButton( Self_.fParent.fHandle,
  26242. Self_.fParent.fRadio1st,
  26243. Self_.fParent.fRadioLast,
  26244. Self_.fMenu );
  26245. end;
  26246. {$ENDIF ASM_VERSION}
  26247. //[END ClickRadio]
  26248. {$IFDEF USE_CONSTRUCTORS}
  26249. //[function NewRadiobox]
  26250. function NewRadiobox( AParent: PControl; const Caption: String ): PControl;
  26251. begin
  26252. new( Result, CreateRadiobox( AParent, Caption ) );
  26253. end;
  26254. //[END NewRadiobox]
  26255. {$ELSE not_USE_CONSTRUCTORS}
  26256. //[FUNCTION NewRadiobox]
  26257. {$IFDEF ASM_VERSION}
  26258. function NewRadiobox( AParent: PControl; const Caption: String ): PControl;
  26259. const
  26260. RadioboxStyles = WS_VISIBLE or WS_CHILD or BS_RADIOBUTTON or
  26261. WS_TABSTOP or WS_GROUP or BS_NOTIFY;
  26262. asm
  26263. PUSH EBX
  26264. PUSH EAX
  26265. CALL NewCheckbox
  26266. XCHG EBX, EAX
  26267. MOV [EBX].TControl.fStyle, RadioboxStyles
  26268. MOV [EBX].TControl.fControlClick, offset[ClickRadio]
  26269. POP ECX
  26270. JECXZ @@exit
  26271. MOV EDX, [EBX].TControl.fMenu
  26272. MOV [ECX].TControl.fRadioLast, EDX
  26273. MOV EAX, [ECX].TControl.fRadio1st
  26274. TEST EAX, EAX
  26275. JNZ @@exit
  26276. MOV [ECX].TControl.fRadio1st, EDX
  26277. MOV EAX, EBX
  26278. CALL TControl.SetRadioChecked
  26279. @@exit: XCHG EAX, EBX
  26280. POP EBX
  26281. end;
  26282. {$ELSE ASM_VERSION} //Pascal
  26283. function NewRadiobox( AParent: PControl; const Caption: String ): PControl;
  26284. begin
  26285. Result := NewCheckbox( AParent, Caption );
  26286. Result.fStyle := WS_VISIBLE or WS_CHILD or
  26287. BS_RADIOBUTTON or WS_TABSTOP or WS_GROUP or BS_NOTIFY;
  26288. Result.fControlClick := ClickRadio;
  26289. if AParent <> nil then
  26290. begin
  26291. AParent.fRadioLast := Result.fMenu;
  26292. if AParent.fRadio1st = 0 then
  26293. begin
  26294. AParent.fRadio1st := Result.fMenu;
  26295. Result.SetRadioChecked;
  26296. end;
  26297. end;
  26298. end;
  26299. {$ENDIF ASM_VERSION}
  26300. //[END NewRadiobox]
  26301. {$ENDIF USE_CONSTRUCTORS}
  26302. //===================== Label ========================//
  26303. {$IFNDEF USE_CONSTRUCTORS}
  26304. {$IFDEF ASM_VERSION}
  26305. const StaticClass: array[0..6]of Char=('S','T','A','T','I','C',#0);
  26306. {$ENDIF ASM_VERSION}
  26307. {$ENDIF USE_CONSTRUCTORS}
  26308. {$IFDEF USE_CONSTRUCTORS}
  26309. //[function NewLabel]
  26310. function NewLabel( AParent: PControl; const Caption: String ): PControl;
  26311. begin
  26312. new( Result, CreateLabel( AParent, Caption ) );
  26313. end;
  26314. //[END NewLabel]
  26315. {$ELSE not_USE_CONSTRUCTORS}
  26316. //[FUNCTION NewLabel]
  26317. {$IFDEF ASM_VERSION}
  26318. function NewLabel( AParent: PControl; const Caption: String ): PControl;
  26319. asm
  26320. PUSH EDX
  26321. PUSH 0
  26322. PUSH offset[LabelActions]
  26323. MOV ECX, WS_VISIBLE or WS_CHILD or SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_NOTIFY
  26324. MOV EDX, offset[StaticClass]
  26325. CALL _NewControl
  26326. INC [EAX].TControl.fIsStaticControl
  26327. INC [EAX].TControl.fSizeRedraw
  26328. MOV EDX, [EAX].TControl.fBoundsRect.Top
  26329. ADD EDX, 22
  26330. MOV [EAX].TControl.fBoundsRect.Bottom, EDX
  26331. POP EDX
  26332. PUSH EAX
  26333. CALL TControl.SetCaption
  26334. POP EAX
  26335. end;
  26336. {$ELSE ASM_VERSION} //Pascal
  26337. function NewLabel( AParent: PControl; const Caption: String ): PControl;
  26338. begin
  26339. Result := _NewControl( AParent, 'STATIC', WS_VISIBLE or WS_CHILD or
  26340. SS_LEFTNOWORDWRAP or SS_NOPREFIX or SS_NOTIFY,
  26341. False, @LabelActions );
  26342. Inc( Result.fIsStaticControl );
  26343. Result.fSizeRedraw := True;
  26344. with Result.fBoundsRect do
  26345. begin
  26346. //Right := Left + 64;
  26347. Bottom := Top + 22;
  26348. end;
  26349. Result.Caption := Caption;
  26350. end;
  26351. {$ENDIF ASM_VERSION}
  26352. //[END NewLabel]
  26353. {$ENDIF USE_CONSTRUCTORS}
  26354. //===================== word wrap Label ========================//
  26355. {$IFDEF USE_CONSTRUCTORS}
  26356. //[function NewWordWrapLabel]
  26357. function NewWordWrapLabel( AParent: PControl; const Caption: String ): PControl;
  26358. begin
  26359. new( Result, CreateWordWrapLabel( AParent, Caption ) );
  26360. end;
  26361. //[END NewWordWrapLabel]
  26362. {$ELSE not_USE_CONSTRUCTORS}
  26363. //[FUNCTION NewWordWrapLabel]
  26364. {$IFDEF ASM_VERSION}
  26365. function NewWordWrapLabel( AParent: PControl; const Caption: String ): PControl;
  26366. asm
  26367. CALL NewLabel
  26368. MOV EDX, [EAX].TControl.fBoundsRect.Top
  26369. ADD EDX, 44
  26370. MOV [EAX].TControl.fBoundsRect.Bottom, EDX
  26371. INC [EAX].TControl.fWordWrap
  26372. AND byte ptr [EAX].TControl.fStyle, not SS_LEFTNOWORDWRAP
  26373. end;
  26374. {$ELSE ASM_VERSION} //Pascal
  26375. function NewWordWrapLabel( AParent: PControl; const Caption: String ): PControl;
  26376. begin
  26377. Result := NewLabel( AParent, Caption );
  26378. Result.fWordWrap := TRUE;
  26379. with Result.fBoundsRect do
  26380. begin
  26381. Bottom := Top + 44;
  26382. end;
  26383. Result.fStyle := Result.fStyle and not SS_LEFTNOWORDWRAP;
  26384. end;
  26385. {$ENDIF ASM_VERSION}
  26386. //[END NewWordWrapLabel]
  26387. {$ENDIF USE_CONSTRUCTORS}
  26388. //===================== Label Effect ========================//
  26389. {$IFDEF USE_CONSTRUCTORS}
  26390. function NewLabelEffect( AParent: PControl; const Caption: String; ShadowDeep: Integer ): PControl;
  26391. begin
  26392. new( Result, CreateLabelEffect( AParent, Caption, ShadowDeep ) );
  26393. end;
  26394. {$ELSE not_USE_CONSTRUCTORS}
  26395. //[FUNCTION NewLabelEffect]
  26396. {$IFDEF ASM_VERSION}
  26397. function NewLabelEffect( AParent: PControl; const Caption: String; ShadowDeep: Integer ): PControl;
  26398. asm
  26399. PUSH EBX
  26400. PUSH ECX
  26401. PUSH EDX
  26402. XOR EDX, EDX
  26403. CALL NewLabel
  26404. MOV EBX, EAX
  26405. DEC [EBX].TControl.fIsStaticControl // ñíîâà 0 !
  26406. MOV EDX, offset[WndProcLabelEffect]
  26407. CALL TControl.AttachProc
  26408. //MOV EAX, EBX
  26409. //CALL TControl.GetWindowHandle
  26410. POP EDX
  26411. MOV EAX, EBX
  26412. CALL TControl.SetCaption
  26413. MOV EDX, offset[WndProcDoEraseBkgnd]
  26414. MOV EAX,EBX
  26415. CALL TControl.AttachProc
  26416. MOV [EBX].TControl.fTextAlign, taCenter
  26417. MOV [EBX].TControl.fTextColor, clWindowText
  26418. POP [EBX].TControl.fShadowDeep
  26419. INC [EBX].TControl.fIgnoreWndCaption
  26420. ADD [EBX].TControl.fBoundsRect.Bottom, 40 - 22
  26421. MOV [EBX].TControl.fColor2, clNone
  26422. XCHG EAX, EBX
  26423. POP EBX
  26424. end;
  26425. {$ELSE ASM_VERSION} //Pascal
  26426. function NewLabelEffect( AParent: PControl; const Caption: String; ShadowDeep: Integer ): PControl;
  26427. begin
  26428. Result := NewLabel( AParent, '' );
  26429. Dec( Result.fIsStaticControl ); // ñíîâà 0 !
  26430. Result.AttachProc( WndProcLabelEffect );
  26431. //Result.GetWindowHandle;
  26432. Result.Caption := Caption;
  26433. Result.AttachProc( WndProcDoEraseBkgnd );
  26434. Result.fTextAlign := taCenter;
  26435. Result.fTextColor := clWindowText;
  26436. Result.fShadowDeep := ShadowDeep;
  26437. Result.fIgnoreWndCaption := True;
  26438. with Result.fBoundsRect do
  26439. begin
  26440. Bottom := Top + 40;
  26441. end;
  26442. Result.fColor2 := clNone;
  26443. end;
  26444. {$ENDIF ASM_VERSION}
  26445. //[END NewLabelEffect]
  26446. {$ENDIF USE_CONSTRUCTORS}
  26447. //===================== Paint box ========================//
  26448. {$IFDEF USE_CONSTRUCTORS}
  26449. //[function NewPaintbox]
  26450. function NewPaintbox( AParent: PControl ): PControl;
  26451. begin
  26452. new( Result, CreatePaintBox( AParent ) );
  26453. end;
  26454. {$ELSE not_USE_CONSTRUCTORS}
  26455. //[FUNCTION NewPaintbox]
  26456. {$IFDEF ASM_VERSION}
  26457. function NewPaintbox( AParent: PControl ): PControl;
  26458. asm
  26459. XOR EDX, EDX
  26460. CALL NewLabel
  26461. //PUSH EAX
  26462. //MOV EDX, offset[WndProcPaintBox]
  26463. //CALL TControl.AttachProc
  26464. //POP EAX
  26465. ADD [EAX].TControl.fBoundsRect.Right, 40-64
  26466. ADD [EAX].TControl.fBoundsRect.Bottom, 40-22
  26467. end;
  26468. {$ELSE ASM_VERSION} //Pascal
  26469. function NewPaintbox( AParent: PControl ): PControl;
  26470. begin
  26471. Result := NewLabel( AParent, '' );
  26472. //Result.AttachProc( WndProcPaintBox );
  26473. with Result.fBoundsRect do
  26474. begin
  26475. Right := Left + 40;
  26476. Bottom := Top + 40;
  26477. end;
  26478. end;
  26479. {$ENDIF ASM_VERSION}
  26480. //[END NewPaintbox]
  26481. {$ENDIF USE_CONSTRUCTORS}
  26482. {$IFDEF _D2}
  26483. //[API SetBrushOrgEx]
  26484. function SetBrushOrgEx(DC: HDC; X, Y: Integer; PrevPt: PPoint): BOOL; stdcall;
  26485. external gdi32 name 'SetBrushOrgEx';
  26486. {$ENDIF}
  26487. //[FUNCTION WndProcDoEraseBkgnd]
  26488. {$IFDEF ASM_VERSION}
  26489. function WndProcDoEraseBkgnd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26490. asm // //
  26491. CMP word ptr [EDX].TMsg.message, WM_ERASEBKGND
  26492. JNE @@ret_false
  26493. MOV byte ptr [ECX], 1
  26494. PUSH EBX
  26495. PUSH EDI
  26496. MOV EBX, EAX
  26497. MOV EDI, [EDX].TMsg.wParam
  26498. CALL TControl.CreateChildWindows
  26499. CMP [EBX].TControl.fTransparent, 0
  26500. JNE @@exit
  26501. PUSH OPAQUE
  26502. PUSH EDI
  26503. CALL SetBkMode
  26504. MOV EAX, [EBX].TControl.fColor
  26505. CALL Color2RGB
  26506. PUSH EAX
  26507. PUSH EDI
  26508. CALL SetBkColor
  26509. XOR EAX, EAX
  26510. PUSH EAX
  26511. PUSH EAX
  26512. PUSH EAX
  26513. PUSH EDI
  26514. CALL SetBrushOrgEx
  26515. SUB ESP, 16
  26516. PUSH ESP
  26517. PUSH [EBX].TControl.fHandle
  26518. CALL GetClientRect
  26519. MOV EAX, EBX
  26520. CALL dword ptr[Global_GetCtlBrushHandle]
  26521. MOV EDX, ESP
  26522. PUSH EAX
  26523. PUSH EDX
  26524. PUSH EDI
  26525. CALL Windows.FillRect
  26526. ADD ESP, 16
  26527. @@exit: POP EDI
  26528. POP EBX
  26529. @@ret_false:
  26530. XOR EAX, EAX
  26531. end;
  26532. {$ELSE ASM_VERSION PAS_VERSION}
  26533. function WndProcDoEraseBkgnd( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26534. var DC: HDC;
  26535. R: TRect;
  26536. begin
  26537. Result := FALSE;
  26538. if Msg.message = WM_ERASEBKGND then
  26539. begin
  26540. Self_.CreateChildWindows;
  26541. if Self_.Transparent then Exit;
  26542. DC := Msg.wParam;
  26543. SetBkMode( DC, OPAQUE );
  26544. SetBkColor( DC, Color2RGB( Self_.fColor ) );
  26545. SetBrushOrgEx( DC, 0, 0, nil );
  26546. GetClientRect( Self_.fHandle, R );
  26547. Windows.FillRect( DC, R, Global_GetCtlBrushHandle( Self_ ) );
  26548. Rslt := 1;
  26549. end;
  26550. end;
  26551. {$ENDIF ASM_VERSION}
  26552. //[END WndProcDoEraseBkgnd]
  26553. //[function WndProcImageShow]
  26554. function WndProcImageShow( Sender: PControl; var Msg: TMsg;
  26555. var Rslt: Integer ): Boolean;
  26556. var PaintStruct: TPaintStruct;
  26557. IL: PImageList;
  26558. OldPaintDC: HDC;
  26559. begin
  26560. Result := FALSE;
  26561. if (Msg.message = WM_PAINT) or (Msg.message = WM_PRINT) then
  26562. begin
  26563. OldPaintDC := Sender.fPaintDC;
  26564. Sender.fPaintDC := Msg.wParam;
  26565. if Sender.fPaintDC = 0 then
  26566. Sender.fPaintDC := BeginPaint( Sender.fHandle, PaintStruct );
  26567. //fOnPaint( Self_, fPaintDC );
  26568. IL := Sender.ImageListNormal;
  26569. if IL <> nil then
  26570. begin
  26571. IL.Draw( Sender.fCurIndex, Sender.fPaintDC, 0, 0 );
  26572. Result := TRUE;
  26573. end;
  26574. if Msg.wParam = 0 then
  26575. EndPaint( Sender.fHandle, PaintStruct );
  26576. Sender.fPaintDC := OldPaintDC;
  26577. Rslt := 0;
  26578. //Result := True;
  26579. Exit;
  26580. end;
  26581. end;
  26582. //[function NewImageShow]
  26583. function NewImageShow( AParent: PControl; AImgList: PImageList;
  26584. ImgIdx: Integer ): PControl;
  26585. var W, H: Integer;
  26586. begin
  26587. Result := NewLabel( AParent, '' );
  26588. Result.ImageListNormal := AImgList;
  26589. Result.AttachProc( WndProcImageShow );
  26590. Result.AttachProc( WndProcDoEraseBkgnd );
  26591. W := 32; H := 32;
  26592. if AImgList <> nil then
  26593. begin
  26594. W := AImgList.ImgWidth;
  26595. H := AImgList.ImgHeight;
  26596. end;
  26597. with Result.fBoundsRect do
  26598. begin
  26599. Right := Left + W;
  26600. Bottom := Top + H;
  26601. end;
  26602. end;
  26603. //[END NewImageShow]
  26604. //===================== Scrollbar ========================//
  26605. const
  26606. KSB_INITIALIZE = WM_USER + 10000;
  26607. KSB_KEY = $3232;
  26608. //[function WndProcScrollBar]
  26609. function WndProcScrollBar( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26610. begin
  26611. Result := False;
  26612. case Msg.message of
  26613. WM_CREATE:
  26614. PostMessage(Sender.Handle, KSB_INITIALIZE, KSB_KEY, KSB_KEY);
  26615. KSB_INITIALIZE:
  26616. if (Msg.wParam = Msg.lParam) and (Msg.wParam = KSB_KEY) then
  26617. begin
  26618. Sender.SBPageSize := Sender.fSBPageSize;
  26619. Sender.SBMinMax := Sender.fSBMinMax;
  26620. Sender.SBPosition := Sender.fSBPosition;
  26621. end;
  26622. end;
  26623. end;
  26624. //[END WndProcScrollBar]
  26625. //[function WndProcScrollBarParent]
  26626. function WndProcScrollBarParent( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
  26627. var
  26628. Bar: PControl;
  26629. SI: TScrollInfo;
  26630. NewPos: Integer;
  26631. AllowChange: Boolean;
  26632. Cmd: Word;
  26633. begin
  26634. Result := False;
  26635. case Msg.message of
  26636. WM_HSCROLL, WM_VSCROLL:
  26637. if (Msg.lParam <> 0) then begin
  26638. Bar := Pointer(GetProp(Msg.lParam, ID_SELF));
  26639. if (Bar <> nil) then begin
  26640. FillChar(SI, SizeOf(SI), 0);
  26641. SI.cbSize := SizeOf(SI);
  26642. SI.fMask := SIF_RANGE or SIF_POS or SIF_TRACKPOS or SIF_PAGE;
  26643. Bar.SBGetScrollInfo(SI);
  26644. Cmd := Msg.wParam and $0000FFFF;
  26645. case Cmd of
  26646. SB_BOTTOM: NewPos := SI.nMax;
  26647. SB_TOP: NewPos := SI.nMin;
  26648. SB_LINEDOWN: NewPos := SI.nPos + 1;
  26649. SB_LINEUP: NewPos := SI.nPos - 1;
  26650. SB_PAGEDOWN: NewPos := SI.nPos + Integer(SI.nPage);
  26651. SB_PAGEUP: NewPos := SI.nPos - Integer(SI.nPage);
  26652. SB_THUMBTRACK: NewPos := SI.nTrackPos;
  26653. else
  26654. Exit;
  26655. end;
  26656. if (NewPos > SI.nMax - Integer(SI.nPage) + 1) then
  26657. NewPos := SI.nMax - Integer(SI.nPage) + 1;
  26658. if (NewPos < SI.nMin) then
  26659. NewPos := SI.nMin;
  26660. AllowChange := True;
  26661. if Assigned(Bar.OnSBBeforeScroll) then
  26662. Bar.OnSBBeforeScroll(Bar, SI.nPos, NewPos, Cmd, AllowChange);
  26663. if AllowChange then
  26664. SI.nPos := NewPos
  26665. else
  26666. SI.nTrackPos := SI.nPos;
  26667. Bar.fSBPosition := SI.nPos;
  26668. Bar.fSBPosition := Bar.SBSetScrollInfo(SI);
  26669. if AllowChange and Assigned(Bar.OnSBScroll) then
  26670. Bar.OnSBScroll(Bar, Cmd);
  26671. end;
  26672. end;
  26673. end;
  26674. end;
  26675. //[END WndProcScrollBarParent]
  26676. //[function NewScrollBar]
  26677. function NewScrollBar( AParent: PControl; BarSide: TScrollerBar ): PControl;
  26678. const SBS_Directions: array[ TScrollerBar ] of DWORD = ( SBS_HORZ or SBS_BOTTOMALIGN,
  26679. SBS_VERT or SBS_RIGHTALIGN );
  26680. begin
  26681. Result := _NewCommonControl(
  26682. AParent,
  26683. 'SCROLLBAR',
  26684. WS_VISIBLE or WS_CHILD or SBS_Directions[ BarSide ],
  26685. False,
  26686. nil
  26687. );
  26688. Result.DetachProc(WndProcCtrl);
  26689. Result.fLookTabKeys := [tkTab];
  26690. Result.AttachProc(WndProcScrollBar);
  26691. AParent.AttachProc(WndProcScrollBarParent);
  26692. end;
  26693. //[END NewScrollBa