resource.pas 24 KB

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