PageRenderTime 81ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 2ms

/KO208L.pas

http://github.com/rofl0r/KOL
Pascal | 10844 lines | 3819 code | 1050 blank | 5975 comment | 0 complexity | a81b16c76440c8b48a9fd8dcd1486d3f MD5 | raw file

Large files files are truncated, but you can click here to view the full 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. …

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