resource.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. asjgfsdkjsfld
  2. { Resource Unit
  3. Programmer: Brad Williams
  4. BitSoft Development, L.L.C.
  5. Copyright (c) 1996
  6. Version 1.1
  7. Revision History
  8. 1.1 (12/26/97)
  9. - updated to add cdResource directive so that can use standard TStringList
  10. resources created by TVRW and TVDT
  11. 1.0
  12. - original implementation }
  13. unit Resource;
  14. interface
  15. {
  16. The Resource unit provides global variables which are used to build and
  17. access resource files. InitRez must always be called before accessing any
  18. variables in the Resource unit. The programmer should also always call
  19. Done to free all file handles allocated to the program.
  20. }
  21. {$i platform.inc}
  22. {$ifdef PPC_FPC}
  23. {$H-}
  24. {$else}
  25. {$F+,O+,E+,N+}
  26. {$endif}
  27. {$X+,R-,I-,Q-,V-}
  28. {$ifndef OS_UNIX}
  29. {$S-}
  30. {$endif}
  31. uses
  32. FVConsts, Objects, Dos;
  33. const
  34. RezExt: ExtStr = '.RES';
  35. { The file extension used on all resource files. }
  36. RezBufferSize: Word = 4096;
  37. { RezBufferSize is the number of bytes to use for the resource file's
  38. stream's buffer. RezBufferSize is passed to TBufStream.Init. }
  39. { reXXXX constants are used with resource files to retrieve the standard
  40. Free Vision dialogs. The constant is followed by the Unit in which it
  41. is used and the resource which is stored separated by a period. }
  42. reChDirDialog = 'ChDirDialog'; { StdDlg.TChDirDialog }
  43. reEditChDirDialog = 'EditChDirDialog'; { StdDlg.TEditChDirDialog }
  44. reFindTextDlg = 'FindTextDlg'; { Editors.CreateFindDialog }
  45. reHints = 'Hints'; { Resource.Hints }
  46. reJumpLineDlg = 'JumpLineDlg'; { Editors.MakeJumpLineDlg }
  47. reLabels = 'Labels'; { Resource.Labels }
  48. reMenuBar = 'MenuBar'; { App.MenuBar }
  49. reOpenDlg = 'OpenDlg'; { StdDlg.TFileDialog - Open }
  50. reReformDocDlg = 'ReformDocDlg'; { Editors.MakeReformDocDlg }
  51. reReplaceDlg = 'ReplaceDlg'; { Editors.CreateReplaceDialog }
  52. reRightMarginDlg = 'RightMarginDlg'; { Editors.MakeRightMarginDlg }
  53. reStatusLine = 'StatusLine'; { App.StatusLine }
  54. reStrings = 'Strings'; { Resource.Strings }
  55. reSaveAsDlg = 'SaveAsDlg'; { StdDlg.TFileDialog - Save As }
  56. reTabStopDlg = 'TabStopDlg'; { Editors.MakeTabStopDlg }
  57. reWindowListDlg = 'WindowListDlg'; { Editors.MakeWindowListDlg }
  58. reAboutDlg = 'About'; { App unit about dialog }
  59. {$I str.inc}
  60. { STR.INC declares all the string list constants used in the standard
  61. Free Vision library units. They are placed in a separate file as a
  62. template for use by the resource file generator, MakeRez.
  63. Applications which use resource files and need to add strings of their
  64. own should use STR.INC as the start for the resource file.
  65. See MakeRez.PAS for more information about generating resource files.}
  66. type
  67. PConstant = ^TConstant;
  68. TConstant = object(TObject)
  69. Value: Word;
  70. { The value assigned to the constant. }
  71. constructor Init (AValue: Word; AText: string);
  72. { Init assigns AValue to Value to AText to Text. AText may be an empty
  73. string.
  74. If an error occurs Init fails. }
  75. destructor Done; virtual;
  76. { Done disposes of Text then calls the inherited destructor. }
  77. procedure SetText (AText: string);
  78. { SetText changes FText to the word equivalent of AText. }
  79. procedure SetValue (AValue: string);
  80. { SetValue changes Value to the word equivalent of AValue. }
  81. function Text: string;
  82. { Text returns a string equivalent to FText. If FText is nil, an
  83. empty string is returned. }
  84. function ValueAsString: string;
  85. { ValueAsString returns the string equivalent of Value. }
  86. private
  87. FText: PString;
  88. { The text to display for the constant. }
  89. end; { of TConstant }
  90. PMemStringList = ^TMemStringList;
  91. TMemStringList = object(TSortedCollection)
  92. { A TMemStringList combines the functions of a TStrListMaker and a
  93. TStringList into one object, allowing generation and use of string
  94. lists in the same application. TMemStringList is fully compatible
  95. with string lists created using TStrListMaker, so legacy applications
  96. will work without problems.
  97. When using a string list in the same program as it is created, a
  98. resource file is not required. This allows language independant coding
  99. of units without the need for conditional defines and recompiling. }
  100. constructor Init;
  101. { Creates an empty, in-memory string list that is not associated with a
  102. resource file. }
  103. constructor Load (var S: TStream);
  104. { Load creates a TStringList from which it gets its strings upon a call
  105. to Get. The strings on the resource file may be loaded into memory
  106. for editing by calling LoadList.
  107. If initialized with Load, the stream must remain valid for the life
  108. of this object. }
  109. destructor Done; virtual;
  110. { Done deallocates the memory allocated to the string list. }
  111. function Compare (Key1, Key2: Pointer): Sw_Integer; virtual;
  112. { Compare assumes Key1 and Key2 are Word values and returns:
  113. -1 if Key1 < Key2
  114. 0 if Key1 = Key2
  115. 1 if Key1 > Key2 }
  116. function Get (Key: Word): String; virtual;
  117. { GetKey searches for a string with a key matching Key and returns it.
  118. An empty string is returned if a string with a matching Key is not
  119. found.
  120. If Count > 0, the in memory collection is searched. If List^.Count
  121. is 0, the inherited Get method is called. }
  122. procedure Insert (Item: Pointer); virtual;
  123. { If Item is not nil, Insert attempts to insert the item into the
  124. collection. If a collection expansion error occurs Insert disposes
  125. of Item by calling FreeItem.
  126. Item must be a pointer to a TConstant or its descendant. }
  127. function KeyOf (Item: Pointer): Pointer; virtual;
  128. { KeyOf returns a pointer to TConstant.Value. }
  129. function LoadStrings: Sw_Integer;
  130. { LoadStrings reads all strings the associated resource file into
  131. memory, places them in the collection, and returns 0.
  132. If an error occurs LoadStrings returns the stream status error code
  133. or a DOS error code. Possible DOS error codes include:
  134. 2: no associated resource file
  135. 8: out of memory }
  136. function NewConstant (Value: Word; S: string): PConstant; virtual;
  137. { NewConstant is called by LoadStrings. }
  138. procedure Put (Key: Word; S: String); virtual;
  139. { Put creates a new PConstant containing Key and Word then calls
  140. Insert to place it in the collection. }
  141. procedure Store (var S: TStream);
  142. { Store creates a TStrListMaker, fills it with the items in List,
  143. writes the TStrListMaker to the stream by calling
  144. TStrListMaker.Store, then disposes of the TStrListMaker. }
  145. private
  146. StringList: PStringList;
  147. end; { of TMemStringList) }
  148. var
  149. {$ifdef cdResource}
  150. Hints: PStringList;
  151. {$else}
  152. Hints: PMemStringList;
  153. {$endif cdResource}
  154. { Hints is a string list for use within the application to provide
  155. context sensitive help on the command line. Hints is always used in
  156. the application. }
  157. {$ifdef cdResource}
  158. Strings: PStringList;
  159. {$else}
  160. Strings: PMemStringList;
  161. {$endif cdResource}
  162. { Strings holds messages such as errors and general information that are
  163. displayed at run-time, normally with MessageBox. Strings is always
  164. used in the application. }
  165. {$ifdef cdResource}
  166. Labels: PStringList;
  167. {$else}
  168. Labels: PMemStringList;
  169. {$endif cdResource}
  170. { Labels is a string list for use within the application when a
  171. resource file is not used, or when creating a resource file. Labels
  172. contains all text used in dialog titles, labels, buttons, menus,
  173. statuslines, etc., used in the application which can be burned into
  174. language specific resources. It does not contain any messages
  175. displayed at run-time using MessageBox or the status line hints.
  176. Using the Labels variable when creating views allows language
  177. independant coding of views such as the MessageBox, StdDlg and Editors
  178. units. }
  179. RezFile: PResourceFile;
  180. { RezFile is a global variable used when the Free Vision library
  181. is compiled using the cdResource conditional define, or when creating
  182. resource files.
  183. All standard Free Vision application resources are accessed from the
  184. resource file using the reXXXX constants. Modify the STR.INC under a
  185. new file name to create new language specific resource files. See the
  186. MakeRez program file for more information. }
  187. procedure DoneResource;
  188. { Done destructs all objects initialized in this unit and frees all
  189. allocated heap. }
  190. {$ifndef cdResource}
  191. function InitResource: Boolean;
  192. {$endif cdResource}
  193. { Init initializes the Hints and Strings for use with in memory strings
  194. lists. Init should be used in applications which do not use a resource
  195. file, or when creating resource files. }
  196. {$ifdef cdResource}
  197. function InitRezFile (AFile: FNameStr; Mode: Word;
  198. var AResFile: PResourceFile): Sw_Integer;
  199. {$endif cdResource}
  200. { InitRezFile initializes a new PResourceFile using the name passed in
  201. AFile and the stream mode passed in Mode and returns 0.
  202. If an error occurs InitRezFile returns the DOS error and AResFile is
  203. invalid. Possible DOS error values include:
  204. 2: file not found or other stream initialization error
  205. 11: invalid format - not a valid resource file }
  206. {$ifdef cdResource}
  207. function LoadResource (AFile: FNameStr): Boolean;
  208. {$endif cdResource}
  209. { Load is used to open a resource file for use in the application.
  210. For Load to return True, the resource file must be properly opened and
  211. assigned to RezFile and the Hints string list must be successfully loaded
  212. from the stream. If an error occurs, Load displays an English error
  213. message using PrintStr and returns False. }
  214. function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
  215. { MergeLists moves all key/string pairs from Source to destination,
  216. deleting them from Source. Duplicate strings are ignored. }
  217. const
  218. RMemStringList: TStreamRec = (
  219. ObjType: idMemStringList;
  220. VmtLink: Ofs(TypeOf(TMemStringList)^);
  221. Load: @TMemStringList.Load;
  222. Store: @TMemStringList.Store);
  223. implementation
  224. {****************************************************************************}
  225. { Private Declarations }
  226. {****************************************************************************}
  227. uses
  228. {Memory, }Drivers;
  229. {****************************************************************************}
  230. { TConstant object }
  231. {****************************************************************************}
  232. {****************************************************************************}
  233. { TConstant.Init }
  234. {****************************************************************************}
  235. constructor TConstant.Init (AValue: Word; AText: string);
  236. begin
  237. if not inherited Init then
  238. Fail;
  239. Value := AValue;
  240. FText := NewStr(AText);
  241. if (FText = nil) and (AText <> '') then
  242. begin
  243. inherited Done;
  244. Fail;
  245. end;
  246. end;
  247. {****************************************************************************}
  248. { TConstant.Done }
  249. {****************************************************************************}
  250. destructor TConstant.Done;
  251. begin
  252. DisposeStr(FText);
  253. inherited Done;
  254. end;
  255. {****************************************************************************}
  256. { TConstant.SetText }
  257. {****************************************************************************}
  258. procedure TConstant.SetText (AText: string);
  259. begin
  260. DisposeStr(FText);
  261. FText := NewStr(AText);
  262. end;
  263. {****************************************************************************}
  264. { TConstant.SetValue }
  265. {****************************************************************************}
  266. procedure TConstant.SetValue (AValue: string);
  267. var
  268. N: Word;
  269. ErrorCode: Integer;
  270. begin
  271. Val(AValue,N,ErrorCode);
  272. if ErrorCode = 0 then
  273. Value := N;
  274. end;
  275. {****************************************************************************}
  276. { TConstant.Text }
  277. {****************************************************************************}
  278. function TConstant.Text: string;
  279. begin
  280. if (FText = nil) then
  281. Text := ''
  282. else Text := FText^;
  283. end;
  284. {****************************************************************************}
  285. { TConstant.ValueAsString }
  286. {****************************************************************************}
  287. function TConstant.ValueAsString: string;
  288. var
  289. S: string[5];
  290. begin
  291. Str(Value,S);
  292. ValueAsString := S;
  293. end;
  294. {****************************************************************************}
  295. { TMemStringList Object }
  296. {****************************************************************************}
  297. {****************************************************************************}
  298. { TMemStringList.Init }
  299. {****************************************************************************}
  300. constructor TMemStringList.Init;
  301. begin
  302. if not inherited Init(10,10) then
  303. Fail;
  304. StringList := nil;
  305. end;
  306. {****************************************************************************}
  307. { TMemStringList.Load }
  308. {****************************************************************************}
  309. constructor TMemStringList.Load (var S: TStream);
  310. begin
  311. if not inherited Init(10,10) then
  312. Fail;
  313. StringList := New(PStringList,Load(S));
  314. end;
  315. {****************************************************************************}
  316. { TMemStringList.Done }
  317. {****************************************************************************}
  318. destructor TMemStringList.Done;
  319. begin
  320. if (StringList <> nil) then
  321. Dispose(StringList,Done);
  322. inherited Done;
  323. end;
  324. {****************************************************************************}
  325. { TMemStringList.Compare }
  326. {****************************************************************************}
  327. function TMemStringList.Compare (Key1, Key2: Pointer): Sw_Integer;
  328. begin
  329. if Word(Key1^) < Word(Key2^) then
  330. Compare := -1
  331. else Compare := Byte(Word(Key1^) > Word(Key2^));
  332. end;
  333. {****************************************************************************}
  334. { TMemStringList.Get }
  335. {****************************************************************************}
  336. function TMemStringList.Get (Key: Word): string;
  337. var
  338. i: Sw_Integer;
  339. S: string;
  340. begin
  341. if (StringList = nil) then
  342. begin { started with Init, use in memory string list }
  343. if Search(@Key,i) then
  344. Get := PConstant(At(i))^.Text
  345. else Get := '';
  346. end
  347. else begin
  348. S := StringList^.Get(Key);
  349. Get := S;
  350. end;
  351. end;
  352. {****************************************************************************}
  353. { TMemStringList.Insert }
  354. {****************************************************************************}
  355. procedure TMemStringList.Insert (Item: Pointer);
  356. var
  357. i: Sw_Integer;
  358. begin
  359. if (Item <> nil) then
  360. begin
  361. i := Count;
  362. inherited Insert(Item);
  363. if (i = Count) then { collection expansion failed }
  364. Dispose(PConstant(Item),Done);
  365. end;
  366. end;
  367. {****************************************************************************}
  368. { TMemStringList.KeyOf }
  369. {****************************************************************************}
  370. function TMemStringList.KeyOf (Item: Pointer): Pointer;
  371. begin
  372. KeyOf := @(PConstant(Item)^.Value);
  373. end;
  374. {****************************************************************************}
  375. { TMemStringList.LoadStrings }
  376. {****************************************************************************}
  377. function TMemStringList.LoadStrings: Sw_Integer;
  378. procedure MakeEditableString (var Str: string);
  379. const
  380. SpecialChars: array[1..3] of Char = #3#10#13;
  381. var
  382. i, j: Byte;
  383. begin
  384. for i := 1 to 3 do
  385. while (Pos(SpecialChars[i],Str) <> 0) do
  386. begin
  387. j := Pos(SpecialChars[i],Str);
  388. System.Delete(Str,j,1);
  389. case i of
  390. 1: System.Insert('#3',Str,j);
  391. 2: System.Insert('#10',Str,j);
  392. 3: System.Insert('#13',Str,j);
  393. end;
  394. end;
  395. end;
  396. var
  397. Constant: PConstant;
  398. i: Word;
  399. S: string;
  400. begin
  401. LoadStrings := 0;
  402. if (StringList = nil) then
  403. begin
  404. LoadStrings := 2;
  405. Exit;
  406. end;
  407. for i := 0 to 65535 do
  408. begin
  409. S := StringList^.Get(i);
  410. if (S <> '') then
  411. begin
  412. MakeEditableString(S);
  413. Constant := NewConstant(i,S);
  414. (*
  415. if LowMemory then
  416. begin
  417. if (Constant <> nil) then
  418. Dispose(Constant,Done);
  419. LoadStrings := 8; { out of memory }
  420. Exit;
  421. end;
  422. *)
  423. Insert(Constant);
  424. end;
  425. end;
  426. end;
  427. {****************************************************************************}
  428. { TMemStringList.NewConstant }
  429. {****************************************************************************}
  430. function TMemStringList.NewConstant (Value: Word; S: string): PConstant;
  431. begin
  432. NewConstant := New(PConstant,Init(Value,S));
  433. end;
  434. {****************************************************************************}
  435. { TMemStringList.Put }
  436. {****************************************************************************}
  437. procedure TMemStringList.Put (Key: Word; S: string);
  438. begin
  439. Insert(New(PConstant,Init(Key,S)));
  440. end;
  441. {****************************************************************************}
  442. { TMemStringList.Store }
  443. {****************************************************************************}
  444. procedure TMemStringList.Store (var S: TStream);
  445. var
  446. StrList: PStrListMaker;
  447. Size: Word;
  448. procedure Total (Constant: PConstant);{$ifndef FPC}far;{$endif}
  449. begin
  450. with Constant^ do
  451. Inc(Size,Succ(Length(Text)));
  452. end;
  453. procedure AddString (Constant: PConstant);{$ifndef FPC}far;{$endif}
  454. const
  455. Numbers = ['0'..'9'];
  456. var
  457. i, j: Byte;
  458. N: Byte;
  459. ErrorCode: Integer;
  460. S: string;
  461. begin
  462. with Constant^ do
  463. begin
  464. { convert formatting characters }
  465. S := Text;
  466. while (Pos('#',S) <> 0) do
  467. begin
  468. i := Succ(Pos('#',S));
  469. j := i;
  470. if (Length(S) > j) then
  471. Inc(j,Byte(S[Succ(j)] in Numbers));
  472. Val(Copy(S,i,j-i+1),N,ErrorCode);
  473. System.Delete(S,Pred(i),j-i+2);
  474. System.Insert(Char(N),S,Pred(i));
  475. end;
  476. StrList^.Put(Value,Text)
  477. end;
  478. end;
  479. begin
  480. Size := 0;
  481. ForEach(@Total);
  482. StrList := New(PStrListMaker,Init(Size,Count * 6));
  483. if (StrList = nil) then
  484. begin
  485. S.Status := 8; { DOS error not enough memory }
  486. Exit;
  487. end;
  488. ForEach(@AddString);
  489. StrList^.Store(S);
  490. Dispose(StrList,Done);
  491. end;
  492. {****************************************************************************}
  493. { Public Procedures and Functions }
  494. {****************************************************************************}
  495. {****************************************************************************}
  496. { Done }
  497. {****************************************************************************}
  498. procedure DoneResource;
  499. begin
  500. if (RezFile <> nil) then
  501. begin
  502. Dispose(RezFile,Done);
  503. RezFile:=nil;
  504. end;
  505. if (Strings <> nil) then
  506. begin
  507. Dispose(Strings,Done);
  508. Strings:=nil;
  509. end;
  510. if (Hints <> nil) then
  511. begin
  512. Dispose(Hints,Done);
  513. Hints:=nil;
  514. end;
  515. if (Labels <> nil) then
  516. begin
  517. Dispose(Labels,Done);
  518. Labels:=nil;
  519. end;
  520. end;
  521. {****************************************************************************}
  522. { Init }
  523. {****************************************************************************}
  524. {$ifndef cdResource}
  525. {$I strtxt.inc}
  526. { strtxt.inc contains the real strings and procedures InitRes... which
  527. is converted from str.inc }
  528. function InitResource: Boolean;
  529. begin
  530. InitResource := False;
  531. Hints := New(PMemStringList,Init);
  532. if (Hints = nil) then
  533. begin
  534. PrintStr('Fatal error. Could not create Hints list.');
  535. Exit;
  536. end;
  537. Strings := New(PMemStringList,Init);
  538. if (Strings = nil) then
  539. begin
  540. DoneResource;
  541. Exit;
  542. end;
  543. Labels := New(PMemStringList,Init);
  544. if (Labels = nil) then
  545. begin
  546. DoneResource;
  547. Exit;
  548. end;
  549. { now load the defaults }
  550. InitResLabels;
  551. InitResStrings;
  552. InitResource := True;
  553. end;
  554. {$endif cdResource}
  555. {****************************************************************************}
  556. { InitRezFile }
  557. {****************************************************************************}
  558. {$ifdef cdResource}
  559. function InitRezFile (AFile: FNameStr; Mode: Word;
  560. var AResFile: PResourceFile): Sw_Integer;
  561. var
  562. Stream: PBufStream;
  563. Result: Sw_Integer;
  564. begin
  565. Stream := New(PBufStream,Init(AFile,Mode,RezBufferSize));
  566. if (Stream = nil) then
  567. Result := 2 { file not found; could also be out of memory }
  568. else begin
  569. AResFile := New(PResourceFile,Init(Stream));
  570. if (AResFile = nil) then
  571. begin
  572. Dispose(Stream,Done);
  573. Result := 11;
  574. end
  575. else Result := 0;
  576. end;
  577. InitRezFile := Result;
  578. end;
  579. {$endif cdResource}
  580. {****************************************************************************}
  581. { Load }
  582. {****************************************************************************}
  583. {$ifdef cdResource}
  584. function LoadResource (AFile: FNameStr): Boolean;
  585. var
  586. Stream: PBufStream;
  587. begin
  588. Load := False;
  589. Stream := New(PBufStream,Init(AFile,stOpenRead,RezBufferSize));
  590. if (Stream = nil) or (Stream^.Status <> 0) then
  591. begin
  592. Done;
  593. PrintStr('Fatal error. Could not open resource file: ' + AFile);
  594. Exit;
  595. end;
  596. RezFile := New(PResourceFile,Init(Stream));
  597. if (RezFile = nil) then
  598. begin
  599. Dispose(Stream,Done);
  600. Done;
  601. PrintStr('Fatal error. Could not initialize resource file.');
  602. Exit;
  603. end;
  604. Hints := PStringList(RezFile^.Get(reHints));
  605. if (Hints = nil) then
  606. begin
  607. Done;
  608. PrintStr('Fatal error. Could not load Hints string list.');
  609. Exit;
  610. end;
  611. Strings := PStringList(RezFile^.Get(reStrings));
  612. if (Strings = nil) then
  613. begin
  614. Done;
  615. PrintStr('Fatal error. Could not load Strings string list.');
  616. Exit;
  617. end;
  618. Load := True;
  619. end;
  620. {$endif cdResource}
  621. {****************************************************************************}
  622. { MergeLists }
  623. {****************************************************************************}
  624. function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
  625. var
  626. Result: Sw_Integer;
  627. procedure MoveItem (Constant: PConstant);{$ifndef FPC}far;{$endif}
  628. var
  629. j: Sw_Integer;
  630. begin
  631. if (Result = 0) and (not Dest^.Search(Dest^.KeyOf(Constant),j)) then
  632. begin
  633. j := Dest^.Count;
  634. Dest^.Insert(Constant);
  635. if (j = Dest^.Count) then
  636. Result := 8
  637. else Source^.Delete(Constant);
  638. end;
  639. end;
  640. begin
  641. if (Source = nil) or (Dest = nil) then
  642. begin
  643. MergeLists := 6;
  644. Exit;
  645. end;
  646. Result := 0;
  647. Source^.ForEach(@MoveItem);
  648. MergeLists := Result;
  649. end;
  650. {****************************************************************************}
  651. { Unit Initialization }
  652. {****************************************************************************}
  653. begin
  654. RezFile := nil;
  655. Hints := nil;
  656. Strings := nil;
  657. Labels := nil;
  658. end.