resource.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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. if LowMemory then
  414. begin
  415. if (Constant <> nil) then
  416. Dispose(Constant,Done);
  417. LoadStrings := 8; { out of memory }
  418. Exit;
  419. end;
  420. Insert(Constant);
  421. end;
  422. end;
  423. end;
  424. {****************************************************************************}
  425. { TMemStringList.NewConstant }
  426. {****************************************************************************}
  427. function TMemStringList.NewConstant (Value: Word; S: string): PConstant;
  428. begin
  429. NewConstant := New(PConstant,Init(Value,S));
  430. end;
  431. {****************************************************************************}
  432. { TMemStringList.Put }
  433. {****************************************************************************}
  434. procedure TMemStringList.Put (Key: Word; S: string);
  435. begin
  436. Insert(New(PConstant,Init(Key,S)));
  437. end;
  438. {****************************************************************************}
  439. { TMemStringList.Store }
  440. {****************************************************************************}
  441. procedure TMemStringList.Store (var S: TStream);
  442. var
  443. StrList: PStrListMaker;
  444. Size: Word;
  445. procedure Total (Constant: PConstant);{$ifndef FPC}far;{$endif}
  446. begin
  447. with Constant^ do
  448. Inc(Size,Succ(Length(Text)));
  449. end;
  450. procedure AddString (Constant: PConstant);{$ifndef FPC}far;{$endif}
  451. const
  452. Numbers = ['0'..'9'];
  453. var
  454. i, j: Byte;
  455. N: Byte;
  456. ErrorCode: Integer;
  457. S: string;
  458. begin
  459. with Constant^ do
  460. begin
  461. { convert formatting characters }
  462. S := Text;
  463. while (Pos('#',S) <> 0) do
  464. begin
  465. i := Succ(Pos('#',S));
  466. j := i;
  467. if (Length(S) > j) then
  468. Inc(j,Byte(S[Succ(j)] in Numbers));
  469. Val(Copy(S,i,j-i+1),N,ErrorCode);
  470. System.Delete(S,Pred(i),j-i+2);
  471. System.Insert(Char(N),S,Pred(i));
  472. end;
  473. StrList^.Put(Value,Text)
  474. end;
  475. end;
  476. begin
  477. Size := 0;
  478. ForEach(@Total);
  479. StrList := New(PStrListMaker,Init(Size,Count * 6));
  480. if (StrList = nil) then
  481. begin
  482. S.Status := 8; { DOS error not enough memory }
  483. Exit;
  484. end;
  485. ForEach(@AddString);
  486. StrList^.Store(S);
  487. Dispose(StrList,Done);
  488. end;
  489. {****************************************************************************}
  490. { Public Procedures and Functions }
  491. {****************************************************************************}
  492. {****************************************************************************}
  493. { Done }
  494. {****************************************************************************}
  495. procedure DoneResource;
  496. begin
  497. if (RezFile <> nil) then
  498. begin
  499. Dispose(RezFile,Done);
  500. RezFile:=nil;
  501. end;
  502. if (Strings <> nil) then
  503. begin
  504. Dispose(Strings,Done);
  505. Strings:=nil;
  506. end;
  507. if (Hints <> nil) then
  508. begin
  509. Dispose(Hints,Done);
  510. Hints:=nil;
  511. end;
  512. if (Labels <> nil) then
  513. begin
  514. Dispose(Labels,Done);
  515. Labels:=nil;
  516. end;
  517. end;
  518. {****************************************************************************}
  519. { Init }
  520. {****************************************************************************}
  521. {$ifndef cdResource}
  522. {$I strtxt.inc}
  523. { strtxt.inc contains the real strings and procedures InitRes... which
  524. is converted from str.inc }
  525. function InitResource: Boolean;
  526. begin
  527. InitResource := False;
  528. Hints := New(PMemStringList,Init);
  529. if (Hints = nil) then
  530. begin
  531. PrintStr('Fatal error. Could not create Hints list.');
  532. Exit;
  533. end;
  534. Strings := New(PMemStringList,Init);
  535. if (Strings = nil) then
  536. begin
  537. DoneResource;
  538. Exit;
  539. end;
  540. Labels := New(PMemStringList,Init);
  541. if (Labels = nil) then
  542. begin
  543. DoneResource;
  544. Exit;
  545. end;
  546. { now load the defaults }
  547. InitResLabels;
  548. InitResStrings;
  549. InitResource := True;
  550. end;
  551. {$endif cdResource}
  552. {****************************************************************************}
  553. { InitRezFile }
  554. {****************************************************************************}
  555. {$ifdef cdResource}
  556. function InitRezFile (AFile: FNameStr; Mode: Word;
  557. var AResFile: PResourceFile): Sw_Integer;
  558. var
  559. Stream: PBufStream;
  560. Result: Sw_Integer;
  561. begin
  562. Stream := New(PBufStream,Init(AFile,Mode,RezBufferSize));
  563. if (Stream = nil) then
  564. Result := 2 { file not found; could also be out of memory }
  565. else begin
  566. AResFile := New(PResourceFile,Init(Stream));
  567. if (AResFile = nil) then
  568. begin
  569. Dispose(Stream,Done);
  570. Result := 11;
  571. end
  572. else Result := 0;
  573. end;
  574. InitRezFile := Result;
  575. end;
  576. {$endif cdResource}
  577. {****************************************************************************}
  578. { Load }
  579. {****************************************************************************}
  580. {$ifdef cdResource}
  581. function LoadResource (AFile: FNameStr): Boolean;
  582. var
  583. Stream: PBufStream;
  584. begin
  585. Load := False;
  586. Stream := New(PBufStream,Init(AFile,stOpenRead,RezBufferSize));
  587. if (Stream = nil) or (Stream^.Status <> 0) then
  588. begin
  589. Done;
  590. PrintStr('Fatal error. Could not open resource file: ' + AFile);
  591. Exit;
  592. end;
  593. RezFile := New(PResourceFile,Init(Stream));
  594. if (RezFile = nil) then
  595. begin
  596. Dispose(Stream,Done);
  597. Done;
  598. PrintStr('Fatal error. Could not initialize resource file.');
  599. Exit;
  600. end;
  601. Hints := PStringList(RezFile^.Get(reHints));
  602. if (Hints = nil) then
  603. begin
  604. Done;
  605. PrintStr('Fatal error. Could not load Hints string list.');
  606. Exit;
  607. end;
  608. Strings := PStringList(RezFile^.Get(reStrings));
  609. if (Strings = nil) then
  610. begin
  611. Done;
  612. PrintStr('Fatal error. Could not load Strings string list.');
  613. Exit;
  614. end;
  615. Load := True;
  616. end;
  617. {$endif cdResource}
  618. {****************************************************************************}
  619. { MergeLists }
  620. {****************************************************************************}
  621. function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
  622. var
  623. Result: Sw_Integer;
  624. procedure MoveItem (Constant: PConstant);{$ifndef FPC}far;{$endif}
  625. var
  626. j: Sw_Integer;
  627. begin
  628. if (Result = 0) and (not Dest^.Search(Dest^.KeyOf(Constant),j)) then
  629. begin
  630. j := Dest^.Count;
  631. Dest^.Insert(Constant);
  632. if (j = Dest^.Count) then
  633. Result := 8
  634. else Source^.Delete(Constant);
  635. end;
  636. end;
  637. begin
  638. if (Source = nil) or (Dest = nil) then
  639. begin
  640. MergeLists := 6;
  641. Exit;
  642. end;
  643. Result := 0;
  644. Source^.ForEach(@MoveItem);
  645. MergeLists := Result;
  646. end;
  647. {****************************************************************************}
  648. { Unit Initialization }
  649. {****************************************************************************}
  650. begin
  651. RezFile := nil;
  652. Hints := nil;
  653. Strings := nil;
  654. Labels := nil;
  655. end.