123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- asjgfsdkjsfld
- { Resource Unit
- Programmer: Brad Williams
- BitSoft Development, L.L.C.
- Copyright (c) 1996
- Version 1.1
- Revision History
- 1.1 (12/26/97)
- - updated to add cdResource directive so that can use standard TStringList
- resources created by TVRW and TVDT
- 1.0
- - original implementation }
- unit Resource;
- interface
- {
- The Resource unit provides global variables which are used to build and
- access resource files. InitRez must always be called before accessing any
- variables in the Resource unit. The programmer should also always call
- Done to free all file handles allocated to the program.
- }
- {$i platform.inc}
- {$ifdef PPC_FPC}
- {$H-}
- {$else}
- {$F+,O+,E+,N+}
- {$endif}
- {$X+,R-,I-,Q-,V-}
- {$ifndef OS_UNIX}
- {$S-}
- {$endif}
- uses
- FVConsts, Objects, Dos;
- const
- RezExt: ExtStr = '.RES';
- { The file extension used on all resource files. }
- RezBufferSize: Word = 4096;
- { RezBufferSize is the number of bytes to use for the resource file's
- stream's buffer. RezBufferSize is passed to TBufStream.Init. }
- { reXXXX constants are used with resource files to retrieve the standard
- Free Vision dialogs. The constant is followed by the Unit in which it
- is used and the resource which is stored separated by a period. }
- reChDirDialog = 'ChDirDialog'; { StdDlg.TChDirDialog }
- reEditChDirDialog = 'EditChDirDialog'; { StdDlg.TEditChDirDialog }
- reFindTextDlg = 'FindTextDlg'; { Editors.CreateFindDialog }
- reHints = 'Hints'; { Resource.Hints }
- reJumpLineDlg = 'JumpLineDlg'; { Editors.MakeJumpLineDlg }
- reLabels = 'Labels'; { Resource.Labels }
- reMenuBar = 'MenuBar'; { App.MenuBar }
- reOpenDlg = 'OpenDlg'; { StdDlg.TFileDialog - Open }
- reReformDocDlg = 'ReformDocDlg'; { Editors.MakeReformDocDlg }
- reReplaceDlg = 'ReplaceDlg'; { Editors.CreateReplaceDialog }
- reRightMarginDlg = 'RightMarginDlg'; { Editors.MakeRightMarginDlg }
- reStatusLine = 'StatusLine'; { App.StatusLine }
- reStrings = 'Strings'; { Resource.Strings }
- reSaveAsDlg = 'SaveAsDlg'; { StdDlg.TFileDialog - Save As }
- reTabStopDlg = 'TabStopDlg'; { Editors.MakeTabStopDlg }
- reWindowListDlg = 'WindowListDlg'; { Editors.MakeWindowListDlg }
- reAboutDlg = 'About'; { App unit about dialog }
- {$I str.inc}
- { STR.INC declares all the string list constants used in the standard
- Free Vision library units. They are placed in a separate file as a
- template for use by the resource file generator, MakeRez.
- Applications which use resource files and need to add strings of their
- own should use STR.INC as the start for the resource file.
- See MakeRez.PAS for more information about generating resource files.}
- type
- PConstant = ^TConstant;
- TConstant = object(TObject)
- Value: Word;
- { The value assigned to the constant. }
- constructor Init (AValue: Word; AText: string);
- { Init assigns AValue to Value to AText to Text. AText may be an empty
- string.
- If an error occurs Init fails. }
- destructor Done; virtual;
- { Done disposes of Text then calls the inherited destructor. }
- procedure SetText (AText: string);
- { SetText changes FText to the word equivalent of AText. }
- procedure SetValue (AValue: string);
- { SetValue changes Value to the word equivalent of AValue. }
- function Text: string;
- { Text returns a string equivalent to FText. If FText is nil, an
- empty string is returned. }
- function ValueAsString: string;
- { ValueAsString returns the string equivalent of Value. }
- private
- FText: PString;
- { The text to display for the constant. }
- end; { of TConstant }
- PMemStringList = ^TMemStringList;
- TMemStringList = object(TSortedCollection)
- { A TMemStringList combines the functions of a TStrListMaker and a
- TStringList into one object, allowing generation and use of string
- lists in the same application. TMemStringList is fully compatible
- with string lists created using TStrListMaker, so legacy applications
- will work without problems.
- When using a string list in the same program as it is created, a
- resource file is not required. This allows language independant coding
- of units without the need for conditional defines and recompiling. }
- constructor Init;
- { Creates an empty, in-memory string list that is not associated with a
- resource file. }
- constructor Load (var S: TStream);
- { Load creates a TStringList from which it gets its strings upon a call
- to Get. The strings on the resource file may be loaded into memory
- for editing by calling LoadList.
- If initialized with Load, the stream must remain valid for the life
- of this object. }
- destructor Done; virtual;
- { Done deallocates the memory allocated to the string list. }
- function Compare (Key1, Key2: Pointer): Sw_Integer; virtual;
- { Compare assumes Key1 and Key2 are Word values and returns:
- -1 if Key1 < Key2
- 0 if Key1 = Key2
- 1 if Key1 > Key2 }
- function Get (Key: Word): String; virtual;
- { GetKey searches for a string with a key matching Key and returns it.
- An empty string is returned if a string with a matching Key is not
- found.
- If Count > 0, the in memory collection is searched. If List^.Count
- is 0, the inherited Get method is called. }
- procedure Insert (Item: Pointer); virtual;
- { If Item is not nil, Insert attempts to insert the item into the
- collection. If a collection expansion error occurs Insert disposes
- of Item by calling FreeItem.
- Item must be a pointer to a TConstant or its descendant. }
- function KeyOf (Item: Pointer): Pointer; virtual;
- { KeyOf returns a pointer to TConstant.Value. }
- function LoadStrings: Sw_Integer;
- { LoadStrings reads all strings the associated resource file into
- memory, places them in the collection, and returns 0.
- If an error occurs LoadStrings returns the stream status error code
- or a DOS error code. Possible DOS error codes include:
- 2: no associated resource file
- 8: out of memory }
- function NewConstant (Value: Word; S: string): PConstant; virtual;
- { NewConstant is called by LoadStrings. }
- procedure Put (Key: Word; S: String); virtual;
- { Put creates a new PConstant containing Key and Word then calls
- Insert to place it in the collection. }
- procedure Store (var S: TStream);
- { Store creates a TStrListMaker, fills it with the items in List,
- writes the TStrListMaker to the stream by calling
- TStrListMaker.Store, then disposes of the TStrListMaker. }
- private
- StringList: PStringList;
- end; { of TMemStringList) }
- var
- {$ifdef cdResource}
- Hints: PStringList;
- {$else}
- Hints: PMemStringList;
- {$endif cdResource}
- { Hints is a string list for use within the application to provide
- context sensitive help on the command line. Hints is always used in
- the application. }
- {$ifdef cdResource}
- Strings: PStringList;
- {$else}
- Strings: PMemStringList;
- {$endif cdResource}
- { Strings holds messages such as errors and general information that are
- displayed at run-time, normally with MessageBox. Strings is always
- used in the application. }
- {$ifdef cdResource}
- Labels: PStringList;
- {$else}
- Labels: PMemStringList;
- {$endif cdResource}
- { Labels is a string list for use within the application when a
- resource file is not used, or when creating a resource file. Labels
- contains all text used in dialog titles, labels, buttons, menus,
- statuslines, etc., used in the application which can be burned into
- language specific resources. It does not contain any messages
- displayed at run-time using MessageBox or the status line hints.
- Using the Labels variable when creating views allows language
- independant coding of views such as the MessageBox, StdDlg and Editors
- units. }
- RezFile: PResourceFile;
- { RezFile is a global variable used when the Free Vision library
- is compiled using the cdResource conditional define, or when creating
- resource files.
- All standard Free Vision application resources are accessed from the
- resource file using the reXXXX constants. Modify the STR.INC under a
- new file name to create new language specific resource files. See the
- MakeRez program file for more information. }
- procedure DoneResource;
- { Done destructs all objects initialized in this unit and frees all
- allocated heap. }
- {$ifndef cdResource}
- function InitResource: Boolean;
- {$endif cdResource}
- { Init initializes the Hints and Strings for use with in memory strings
- lists. Init should be used in applications which do not use a resource
- file, or when creating resource files. }
- {$ifdef cdResource}
- function InitRezFile (AFile: FNameStr; Mode: Word;
- var AResFile: PResourceFile): Sw_Integer;
- {$endif cdResource}
- { InitRezFile initializes a new PResourceFile using the name passed in
- AFile and the stream mode passed in Mode and returns 0.
- If an error occurs InitRezFile returns the DOS error and AResFile is
- invalid. Possible DOS error values include:
- 2: file not found or other stream initialization error
- 11: invalid format - not a valid resource file }
- {$ifdef cdResource}
- function LoadResource (AFile: FNameStr): Boolean;
- {$endif cdResource}
- { Load is used to open a resource file for use in the application.
- For Load to return True, the resource file must be properly opened and
- assigned to RezFile and the Hints string list must be successfully loaded
- from the stream. If an error occurs, Load displays an English error
- message using PrintStr and returns False. }
- function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
- { MergeLists moves all key/string pairs from Source to destination,
- deleting them from Source. Duplicate strings are ignored. }
- const
- RMemStringList: TStreamRec = (
- ObjType: idMemStringList;
- VmtLink: Ofs(TypeOf(TMemStringList)^);
- Load: @TMemStringList.Load;
- Store: @TMemStringList.Store);
- implementation
- {****************************************************************************}
- { Private Declarations }
- {****************************************************************************}
- uses
- {Memory, }Drivers;
- {****************************************************************************}
- { TConstant object }
- {****************************************************************************}
- {****************************************************************************}
- { TConstant.Init }
- {****************************************************************************}
- constructor TConstant.Init (AValue: Word; AText: string);
- begin
- if not inherited Init then
- Fail;
- Value := AValue;
- FText := NewStr(AText);
- if (FText = nil) and (AText <> '') then
- begin
- inherited Done;
- Fail;
- end;
- end;
- {****************************************************************************}
- { TConstant.Done }
- {****************************************************************************}
- destructor TConstant.Done;
- begin
- DisposeStr(FText);
- inherited Done;
- end;
- {****************************************************************************}
- { TConstant.SetText }
- {****************************************************************************}
- procedure TConstant.SetText (AText: string);
- begin
- DisposeStr(FText);
- FText := NewStr(AText);
- end;
- {****************************************************************************}
- { TConstant.SetValue }
- {****************************************************************************}
- procedure TConstant.SetValue (AValue: string);
- var
- N: Word;
- ErrorCode: Integer;
- begin
- Val(AValue,N,ErrorCode);
- if ErrorCode = 0 then
- Value := N;
- end;
- {****************************************************************************}
- { TConstant.Text }
- {****************************************************************************}
- function TConstant.Text: string;
- begin
- if (FText = nil) then
- Text := ''
- else Text := FText^;
- end;
- {****************************************************************************}
- { TConstant.ValueAsString }
- {****************************************************************************}
- function TConstant.ValueAsString: string;
- var
- S: string[5];
- begin
- Str(Value,S);
- ValueAsString := S;
- end;
- {****************************************************************************}
- { TMemStringList Object }
- {****************************************************************************}
- {****************************************************************************}
- { TMemStringList.Init }
- {****************************************************************************}
- constructor TMemStringList.Init;
- begin
- if not inherited Init(10,10) then
- Fail;
- StringList := nil;
- end;
- {****************************************************************************}
- { TMemStringList.Load }
- {****************************************************************************}
- constructor TMemStringList.Load (var S: TStream);
- begin
- if not inherited Init(10,10) then
- Fail;
- StringList := New(PStringList,Load(S));
- end;
- {****************************************************************************}
- { TMemStringList.Done }
- {****************************************************************************}
- destructor TMemStringList.Done;
- begin
- if (StringList <> nil) then
- Dispose(StringList,Done);
- inherited Done;
- end;
- {****************************************************************************}
- { TMemStringList.Compare }
- {****************************************************************************}
- function TMemStringList.Compare (Key1, Key2: Pointer): Sw_Integer;
- begin
- if Word(Key1^) < Word(Key2^) then
- Compare := -1
- else Compare := Byte(Word(Key1^) > Word(Key2^));
- end;
- {****************************************************************************}
- { TMemStringList.Get }
- {****************************************************************************}
- function TMemStringList.Get (Key: Word): string;
- var
- i: Sw_Integer;
- S: string;
- begin
- if (StringList = nil) then
- begin { started with Init, use in memory string list }
- if Search(@Key,i) then
- Get := PConstant(At(i))^.Text
- else Get := '';
- end
- else begin
- S := StringList^.Get(Key);
- Get := S;
- end;
- end;
- {****************************************************************************}
- { TMemStringList.Insert }
- {****************************************************************************}
- procedure TMemStringList.Insert (Item: Pointer);
- var
- i: Sw_Integer;
- begin
- if (Item <> nil) then
- begin
- i := Count;
- inherited Insert(Item);
- if (i = Count) then { collection expansion failed }
- Dispose(PConstant(Item),Done);
- end;
- end;
- {****************************************************************************}
- { TMemStringList.KeyOf }
- {****************************************************************************}
- function TMemStringList.KeyOf (Item: Pointer): Pointer;
- begin
- KeyOf := @(PConstant(Item)^.Value);
- end;
- {****************************************************************************}
- { TMemStringList.LoadStrings }
- {****************************************************************************}
- function TMemStringList.LoadStrings: Sw_Integer;
- procedure MakeEditableString (var Str: string);
- const
- SpecialChars: array[1..3] of Char = #3#10#13;
- var
- i, j: Byte;
- begin
- for i := 1 to 3 do
- while (Pos(SpecialChars[i],Str) <> 0) do
- begin
- j := Pos(SpecialChars[i],Str);
- System.Delete(Str,j,1);
- case i of
- 1: System.Insert('#3',Str,j);
- 2: System.Insert('#10',Str,j);
- 3: System.Insert('#13',Str,j);
- end;
- end;
- end;
- var
- Constant: PConstant;
- i: Word;
- S: string;
- begin
- LoadStrings := 0;
- if (StringList = nil) then
- begin
- LoadStrings := 2;
- Exit;
- end;
- for i := 0 to 65535 do
- begin
- S := StringList^.Get(i);
- if (S <> '') then
- begin
- MakeEditableString(S);
- Constant := NewConstant(i,S);
- (*
- if LowMemory then
- begin
- if (Constant <> nil) then
- Dispose(Constant,Done);
- LoadStrings := 8; { out of memory }
- Exit;
- end;
- *)
- Insert(Constant);
- end;
- end;
- end;
- {****************************************************************************}
- { TMemStringList.NewConstant }
- {****************************************************************************}
- function TMemStringList.NewConstant (Value: Word; S: string): PConstant;
- begin
- NewConstant := New(PConstant,Init(Value,S));
- end;
- {****************************************************************************}
- { TMemStringList.Put }
- {****************************************************************************}
- procedure TMemStringList.Put (Key: Word; S: string);
- begin
- Insert(New(PConstant,Init(Key,S)));
- end;
- {****************************************************************************}
- { TMemStringList.Store }
- {****************************************************************************}
- procedure TMemStringList.Store (var S: TStream);
- var
- StrList: PStrListMaker;
- Size: Word;
- procedure Total (Constant: PConstant);{$ifndef FPC}far;{$endif}
- begin
- with Constant^ do
- Inc(Size,Succ(Length(Text)));
- end;
- procedure AddString (Constant: PConstant);{$ifndef FPC}far;{$endif}
- const
- Numbers = ['0'..'9'];
- var
- i, j: Byte;
- N: Byte;
- ErrorCode: Integer;
- S: string;
- begin
- with Constant^ do
- begin
- { convert formatting characters }
- S := Text;
- while (Pos('#',S) <> 0) do
- begin
- i := Succ(Pos('#',S));
- j := i;
- if (Length(S) > j) then
- Inc(j,Byte(S[Succ(j)] in Numbers));
- Val(Copy(S,i,j-i+1),N,ErrorCode);
- System.Delete(S,Pred(i),j-i+2);
- System.Insert(Char(N),S,Pred(i));
- end;
- StrList^.Put(Value,Text)
- end;
- end;
- begin
- Size := 0;
- ForEach(@Total);
- StrList := New(PStrListMaker,Init(Size,Count * 6));
- if (StrList = nil) then
- begin
- S.Status := 8; { DOS error not enough memory }
- Exit;
- end;
- ForEach(@AddString);
- StrList^.Store(S);
- Dispose(StrList,Done);
- end;
- {****************************************************************************}
- { Public Procedures and Functions }
- {****************************************************************************}
- {****************************************************************************}
- { Done }
- {****************************************************************************}
- procedure DoneResource;
- begin
- if (RezFile <> nil) then
- begin
- Dispose(RezFile,Done);
- RezFile:=nil;
- end;
- if (Strings <> nil) then
- begin
- Dispose(Strings,Done);
- Strings:=nil;
- end;
- if (Hints <> nil) then
- begin
- Dispose(Hints,Done);
- Hints:=nil;
- end;
- if (Labels <> nil) then
- begin
- Dispose(Labels,Done);
- Labels:=nil;
- end;
- end;
- {****************************************************************************}
- { Init }
- {****************************************************************************}
- {$ifndef cdResource}
- {$I strtxt.inc}
- { strtxt.inc contains the real strings and procedures InitRes... which
- is converted from str.inc }
- function InitResource: Boolean;
- begin
- InitResource := False;
- Hints := New(PMemStringList,Init);
- if (Hints = nil) then
- begin
- PrintStr('Fatal error. Could not create Hints list.');
- Exit;
- end;
- Strings := New(PMemStringList,Init);
- if (Strings = nil) then
- begin
- DoneResource;
- Exit;
- end;
- Labels := New(PMemStringList,Init);
- if (Labels = nil) then
- begin
- DoneResource;
- Exit;
- end;
- { now load the defaults }
- InitResLabels;
- InitResStrings;
- InitResource := True;
- end;
- {$endif cdResource}
- {****************************************************************************}
- { InitRezFile }
- {****************************************************************************}
- {$ifdef cdResource}
- function InitRezFile (AFile: FNameStr; Mode: Word;
- var AResFile: PResourceFile): Sw_Integer;
- var
- Stream: PBufStream;
- Result: Sw_Integer;
- begin
- Stream := New(PBufStream,Init(AFile,Mode,RezBufferSize));
- if (Stream = nil) then
- Result := 2 { file not found; could also be out of memory }
- else begin
- AResFile := New(PResourceFile,Init(Stream));
- if (AResFile = nil) then
- begin
- Dispose(Stream,Done);
- Result := 11;
- end
- else Result := 0;
- end;
- InitRezFile := Result;
- end;
- {$endif cdResource}
- {****************************************************************************}
- { Load }
- {****************************************************************************}
- {$ifdef cdResource}
- function LoadResource (AFile: FNameStr): Boolean;
- var
- Stream: PBufStream;
- begin
- Load := False;
- Stream := New(PBufStream,Init(AFile,stOpenRead,RezBufferSize));
- if (Stream = nil) or (Stream^.Status <> 0) then
- begin
- Done;
- PrintStr('Fatal error. Could not open resource file: ' + AFile);
- Exit;
- end;
- RezFile := New(PResourceFile,Init(Stream));
- if (RezFile = nil) then
- begin
- Dispose(Stream,Done);
- Done;
- PrintStr('Fatal error. Could not initialize resource file.');
- Exit;
- end;
- Hints := PStringList(RezFile^.Get(reHints));
- if (Hints = nil) then
- begin
- Done;
- PrintStr('Fatal error. Could not load Hints string list.');
- Exit;
- end;
- Strings := PStringList(RezFile^.Get(reStrings));
- if (Strings = nil) then
- begin
- Done;
- PrintStr('Fatal error. Could not load Strings string list.');
- Exit;
- end;
- Load := True;
- end;
- {$endif cdResource}
- {****************************************************************************}
- { MergeLists }
- {****************************************************************************}
- function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
- var
- Result: Sw_Integer;
- procedure MoveItem (Constant: PConstant);{$ifndef FPC}far;{$endif}
- var
- j: Sw_Integer;
- begin
- if (Result = 0) and (not Dest^.Search(Dest^.KeyOf(Constant),j)) then
- begin
- j := Dest^.Count;
- Dest^.Insert(Constant);
- if (j = Dest^.Count) then
- Result := 8
- else Source^.Delete(Constant);
- end;
- end;
- begin
- if (Source = nil) or (Dest = nil) then
- begin
- MergeLists := 6;
- Exit;
- end;
- Result := 0;
- Source^.ForEach(@MoveItem);
- MergeLists := Result;
- end;
- {****************************************************************************}
- { Unit Initialization }
- {****************************************************************************}
- begin
- RezFile := nil;
- Hints := nil;
- Strings := nil;
- Labels := nil;
- end.
|