//***************************************************************************************** // Copyright (c) 2000 Michael Kurz // All rights reserved. // If you want to use this source in your applications conatct: // // $FileName : cIniManager.pkg // $ProjectName : General shared classes // $Author : Michael Kurz // $Created : 12-31-2000 @ 09:00 // // Contents: // Abilities to load and save values to an inifile. // This Class (cIniProperties) is not just a class it is a solution for a problem I // had for years. // // What's the idea? // Very often if you develop a class you need want it to save properties to // disk. Then you also need to build a kind of property page to edit these // Properties ans save if to disk again. // // With cIniProperties and a set of commands its possible to create a set of // properties which are save with one call into an inifile to disk. // // $Rev History // //***************************************************************************************** // // // // Stores the infos which TAPI lines should been monitored. // Class cTapiHandler_Properties is a cIniProperties // INI_Begin_Properties "FILENAME.INI" [INI_COMPUTER | INI_COMPUTER | INI_GLOBAL] // // // Normal Properties (Single Item) // INI_Property piTestInteger Public 0 // INI_Property pnTestNumber Public 0 // INI_Property psTestString Public "" // // // Multi Item Properties // INI_Property integer Line Public 0 MULTI // INI_Property.Sub string Name Public "" // INI_Property.Sub string Monitor Public "" // INI_Property.Sub string Standard Public "" // INI_End_Properties // // // Accessing Single Item Properties (as usual with set and get) // set piTestInteger to 10 // set psTestString to "" // get piTestString to sTmp // move (piTestInteger(Self)) to iTmp // // // Accessing Multi Item Properties // set Line item iNr to iWert // set Line.Name item iNr to sWert // // // Number of Items present // move (Line.Count(Self)) to iCount // // Deletes a specified Item // send Line.DeleteItem iNr // // // Deletes all Line Items. // send Line.DeleteAllItems // End_Class // Dependencies: Use Windows.Pkg // For external function use. Use DLL.Pkg // ... Use cLineParser.Pkg // Class: cLineParser, for seperating a String in its parts. Use Set.Pkg // Class: Set Use mUserAndComputerName.pkg // Functions to get the User and the ComputerName. // Possible Ini modes: Define Ini_Global For 0 // IniFilename is used as it is. -> Global Settings. Define Ini_Computer For 1 // The Computername is added at the End -> Settings for a special computer on a Networkdrive. Define Ini_User For 2 // The UserName is added at the End -> Settings for a special user on a Networkdrive. #IFDEF GET_GetFocus #ELSE External_Function GetFocus "GetFocus" user32.dll Returns Integer #ENDIF // #COMMAND: SendEx // Creates Send Commands for all procedures which exist // If you give the command a procedure name "TestProc" // it will create send Test_Proc_1 // send Test_Proc_2 // ... // send Test_Proc_X // as long as the procedures exist. #COMMAND SENDEx_Int #IFDEF MSG_!1_!K Send !1_!k !2 !3 !4 !5 !6 !7 !8 !9 SENDEx_Int !1 !2 !3 !4 !5 !6 !7 !8 !9 #ENDIF #ENDCOMMAND #COMMAND SENDEx R #PUSH !k // Save K to stack. #SET k$ 0 SENDEx_Int !1 !2 !3 !4 !5 !6 !7 !8 !9 #POP k$ // Restore K from stack #ENDCOMMAND // #COMMAND: ProcedureEx // Creates a Procedure with an addtional _X if the procedure doesnt exist. #COMMAND ProcedureEx_Int #IFDEF MSG_!1_!K ProcedureEx_Int !1 !2 !3 !4 !5 !6 !7 !8 !9 #ELSE Procedure !1_!k !2 !3 !4 !5 !6 !7 !8 !9 #ENDIF #ENDCOMMAND #COMMAND ProcedureEx #PUSH !k // Save K to stack. #SET k$ 0 ProcedureEx_Int !1 !2 !3 !4 !5 !6 !7 !8 !9 #POP k$ // Restore K from stack #ENDCOMMAND // Has the ability to read an write from and to an IniFile. // The main advantage of this class is that it stores all lines // which are not known, so that they arent lost during a save. Class cIniProperties is a Message // Sets all Tag values. Procedure onInit End_Procedure // For termination Procedure INI_AddTagValues End_Procedure // Adding properties and setting default values Procedure Construct_Object Forward Send Construct_Object Send Define_cIniProperties End_Procedure Procedure Define_cIniProperties Property String psSourceFile "cConfigManager.Ini" // Name of the inifile. Property String psSepCharacter "," // Seperating character. Property Boolean pbUseDataPath True // Data can be stored either global, user specific or // computer specific. // This is reached by adding ComputerName or UserName // to the FileName. Property Integer piLoadSaveMode Ini_Global //[ Ini_User | Ini_Computer | Ini_Global ] Object oUnusedLines is an Array // Storage for all unused (unknown) lines. End_Object Object oLineParser is a cLineParser // Seperates a String into his parts. End_Object Object oTags is a Set // Known Tags End_Object Object oTagTypes is an Array // Type of the Tags End_Object Object oTagValues is an Array // Values for the Tags. End_Object Object oTagConnectedObjects is an Array // ObjectIDs of the connected Obj. End_Object Send INI_AddTagValues Send onInit End_Procedure // Connects an Object to a tag. Procedure ConnectObjectToTag String sTag Integer hoID Integer iC Move (Uppercase(sTag)) To sTag Get Find_Element Of (oTags(Self)) sTag To iC If iC Ge 0 Begin Set Value Of (oTagConnectedObjects(Self)) Item iC To hoID End End_Procedure Procedure Set ConnectObjectValue Integer hoDest String sValue If hoDest Begin If (checkbox_item_state(hoDest,0)) Eq 0 ; Set Value Of hoDest Item 0 To sValue Else ; Set Select_State Of hoDest Item 0 To sValue End End_Procedure Function ConnectObjectValue Integer hoDest Returns String String sRet If hoDest Begin If (checkbox_item_state(hoDest,0)) Eq 0 ; Move (Value(hoDest,0)) To sRet Else ; Move (Select_State(hoDest,0)) To sRet End Function_Return sRet End_Function // Creates extended source files. Function SourceFile Integer iMode Returns String Integer iPos String sFile sExt String sPath Get psSourceFile To sFile If iMode Eq Ini_User ; Get NetzwerkBenutzer To sExt If iMode Eq Ini_Computer ; Get ComputerName To sExt If (Left(Right(sFile,2),1)) Eq "." ; Move 1 To iPos If (Left(Right(sFile,3),1)) Eq "." ; Move 2 To iPos If (Left(Right(sFile,4),1)) Eq "." ; Move 3 To iPos If iPos Gt 0 ; Move (Insert(sExt,sFile,Length(sFile)-iPos)) To sFile If (sFile<>"" and pbUseDataPath(Self)) Begin Get psDataPath Of (phoWorkspace(ghoApplication)) To sPath Get vFolderFormat sPath To sPath Move (sPath+sFile) To sFile End Function_Return sFile End_Function // Checks if a file exists. Function INI_DoesFileExist String sFile Returns Integer Integer iExist If sFile Eq "" Begin Function_Return 0 End Direct_Input sFile [Not seqeof] Move 1 To iExist Close_Input Function_Return iExist End_Function // Tries to find the best ini file. Function SourceFileForRead Returns String If (INI_DoesFileExist(Self, SourceFile(Self, piLoadSaveMode(Self)) )) Begin Function_Return (SourceFile(Self, piLoadSaveMode(Self))) End Function_Return (psSourceFile(Self)) End_Function // Delivers the file for writing. Function SourceFileForWrite Returns String Function_Return (SourceFile(Self, piLoadSaveMode(Self))) End_Function // Deletes all items of a Tag, if it is multi! Procedure DeleteAllItems String sTag Integer iC iType hoID iC2 hoTmp Get Find_Element Of (oTags(Self)) sTag To iC Get Value Of (oTagTypes(Self)) Item iC To iType Get Value Of (oTagValues(Self)) Item iC To hoID If iType If hoID Begin For iC2 From 0 To (Item_Count(hoID)-1) Get Value Of hoID Item iC2 To hoTmp If hoTmp ; Send Destroy_Object To hoTmp End Send Delete_Data To hoID End End_Procedure // Deletes one Item of a Tag if it is multi. Procedure DeleteItem String sTag Integer iNr Integer iC iType hoID hoTmp Get Find_Element Of (oTags(Self)) sTag To iC Get Value Of (oTagTypes(Self)) Item iC To iType Get Value Of (oTagValues(Self)) Item iC To hoID If iType If hoID Begin Get Value Of hoID Item iNr To hoTmp If hoTmp ; Send Destroy_Object To hoTmp Send Delete_Item To hoID iNr End End_Procedure // Deletes all values, not the defined tags (with "AddTag"). // Is sent before the data is loaded. Procedure DoInit Integer iC iType hoID iC2 hoTmp For iC From 0 To (Item_Count(oTags(Self))-1) Get Value Of (oTagTypes(Self)) Item iC To iType Get Value Of (oTagValues(Self)) Item iC To hoID If iType Begin For iC2 From 0 To (Item_Count(hoID)-1) Get Value Of hoID Item iC2 To hoTmp If hoTmp ; Send Destroy_Object To hoTmp End Send Delete_Data To hoID End Else ; Send Delete_Data To hoID End End_Procedure // Adds a iniTag. // The type can be multi of not. If it is a multi tag // there can be more than one value with the same tag. Procedure AddTag String sTag Integer iMulti Integer iC hoID Get Find_Element Of (oTags(Self)) sTag To iC If iC Lt 0 Begin Object oIniTag is an Array Move Self To hoID End_Object Get Item_Count Of (oTags(Self)) To iC Set Value Of (oTags(Self)) Item iC To sTag Set Value Of (oTagTypes(Self)) Item iC To iMulti Set Value Of (oTagValues(Self)) Item iC To hoID End End_Procedure // Sets the value of a Tag (and a SubTag) Procedure SetIniValue String sTag Integer iMultiNr Integer iSubTagNr String sValue Integer iC iType hoID hoID2 hoDest Get Find_Element Of (oTags(Self)) sTag To iC If iC Ge 0 Begin Get Value Of (oTagTypes(Self)) Item iC To iType Get Value Of (oTagValues(Self)) Item iC To hoID Get Value Of (oTagConnectedObjects(Self)) Item iC To hoDest If iType Begin If iMultiNr Lt 0 Begin Move (Item_Count(hoID)) To iMultiNr // To add new values End Get Value Of hoID Item iMultiNr To hoID2 If Not hoID2 Begin Object oSubs is an Array Move Self To hoID2 End_Object Set Value Of hoID Item iMultiNr To hoID2 End Set Value Of hoID2 Item iSubTagNr To sValue End Else Begin If hoDest Begin Set ConnectObjectValue hoDest To sValue End Set Value Of hoID Item iSubTagNr To sValue End End End_Procedure // Adds a value to a tag. If it is a mulit tag // numerous values are possible, if not only one is stored and // every call of AddTagValue for the same tag overwrites the existing // value. Procedure AddTagValue String sTag String sValue Send SetIniValue sTag -1 0 sValue End_Procedure // Runs a line and returns true if the tag was known and false if not. // This is called during the loading procedure and if it returns false // the line is stored in "oUnusedLines". // Given is the whole read line and an ObjectID of an array which contains // all parts of the line. Function DoLine String sLine Integer hoPartsID Returns Integer Integer iC iC2 iMultiItemNr hoID Get Find_Element Of (oTags(Self)) (Value(hoPartsID,0)) To iC Get Value Of (oTagValues(Self)) Item iC To hoID If hoID Begin Get Item_Count Of hoID To iMultiItemNr End If iC Ge 0 Begin For iC2 From 1 To (Item_Count(hoPartsID)-1) Send SetIniValue (Value(hoPartsID,0)) iMultiItemNr (iC2-1) (Value(hoPartsID,iC2)) End If (Item_Count(hoPartsID)) Le 1 Begin Send SetIniValue (Value(hoPartsID,0)) iMultiItemNr 1 "" End Function_Return 1 End Function_Return 0 End_Function // Reads the data out of the inifile. Procedure LoadIni String sLine String sFile Integer hoParser hoUnused Move (oUnusedLines(Self)) To hoUnused Move (oLineParser(Self)) To hoParser Send DoInit // Clears all values Send Delete_Data To hoUnused // also the unusedlines. Set psSepCharacter Of hoParser To (psSepCharacter(Self)) Get SourceFileForRead To sFile Direct_Input sFile Repeat Readln sLine [Not SeqEof] Begin Send ParseLine To hoParser sLine If (Not(DoLine(Self,sLine,hoParser))) Begin Set Value Of hoUnused Item (Item_Count(hoUnused)) To sLine End End Until [SeqEof] Close_Input End_Procedure // Saves the data to the inifile. Procedure SaveIni Integer iC iC2 iC3 hoID iType hoUnused iCount hoID2 hoDest String sTag sSep String sFileName Get psSepCharacter To sSep Get Item_Count Of (oTags(Self)) To iCount Move (oUnusedLines(Self)) To hoUnused Get SourceFileForWrite To sFileName Direct_Output sFileName For iC From 0 To (iCount-1) Get Value Of (oTags(Self)) Item iC To sTag Get Value Of (oTagTypes(Self)) Item iC To iType Get Value Of (oTagValues(Self)) Item iC To hoID Get Value Of (oTagConnectedObjects(Self)) Item iC To hoDest If iType Begin For iC2 From 0 To (Item_Count(hoID)-1) Get Value Of hoID Item iC2 To hoID2 If hoID2 Begin Write sTag For iC3 From 0 To (Item_Count(hoID2)-1) Write sSep (Value(hoID2,iC3)) End Writeln End Else Begin Writeln sTag End End End Else Begin If hoDest Begin Set Value Of hoID Item 0 To (ConnectObjectValue(Self,hoDest)) End Write sTag For iC2 From 0 To (Item_Count(hoID)-1) Write sSep (Value(hoID,iC2)) End Writeln End End For iC From 0 To (Item_Count(hoUnused)-1) Writeln (Value(hoUnused,iC)) End Close_Output End_Procedure // Delivers the value of a given tag. Function IniValueEx String sTag Integer iMultiNr Integer iSubNr Returns String Integer iC iType hoID hoDest String sRetVal Get Find_Element Of (oTags(Self)) sTag To iC Get Value Of (oTagTypes(Self)) Item iC To iType Get Value Of (oTagValues(Self)) Item iC To hoID Get Value Of (oTagConnectedObjects(Self)) Item iC To hoDest If iType Begin If iMultiNr Ge (Item_Count(hoID)) Begin Move (Item_Count(hoID)-1) To iMultiNr End If hoID ; Get Value Of hoID Item iMultiNr To hoID End Else If hoDest If hoID Begin Set Value Of hoID Item 0 To (ConnectObjectValue(Self,hoDest)) End If hoID ; Move (Value(hoID,iSubNr)) to sRetVal Else ; Move "" To sRetVal Function_Return sRetVal End_Function // Delivers the value of a given tag. Function IniValue String sTag Integer iNr Returns String Function_Return (IniValueEx(Self,sTag,iNr,0)) End_Function // Delivers the number of values of a given tag. // If it isn't a multi tag 1 is returned. Function IniValueCount String sTag Returns Integer Integer iC iType hoID iRetval Get Find_Element Of (oTags(Self)) sTag To iC Get Value Of (oTagTypes(Self)) Item iC To iType If iType Begin Get Value Of (oTagValues(Self)) Item iC To hoID Move (Item_Count(hoID)) To iRetval End Else Begin Move 1 To iRetval End Function_Return iRetval End_Function End_Class // Only for compatibility with earlier versions. // Which I only used myself. :-) Class cIniManager is a cIniProperties End_Class // Need to put this into a seperate command becouse the orginal Procedure and // Function commands require the !$ to be set to the class name of the current class // Can be used as the std commands eccexpt that the 1st argument must always be the // the name of the last global Property = !$ #COMMAND INI_Procedure R #SPOP $$ // Catch the ClassName from the STack Procedure !2 !3 !4 !5 !6 !7 !8 !9 #SPUSH !$ // Give it Back to Stack #SET $$ !1 // Set Back to the name of the Last GlobalProperty! #ENDCOMMAND #COMMAND INI_End_Procedure R #SPOP $$ // Catch the ClassName from the STack End_Procedure #SPUSH !$ // Give it Back to Stack #SET $$ !1 // Set Back to the name of the Last GlobalProperty! #ENDCOMMAND #COMMAND INI_Function R #SPOP $$ // Catch the ClassName from the STack Function !2 !3 !4 !5 !6 !7 !8 !9 #SPUSH !$ // Give it Back to Stack #SET $$ !1 // Set Back to the name of the Last GlobalProperty! #ENDCOMMAND #COMMAND INI_End_Function R #SPOP $$ // Catch the ClassName from the STack End_Function #SPUSH !$ // Give it Back to Stack #SET $$ !1 // Set Back to the name of the Last GlobalProperty! #ENDCOMMAND // The top value of the Stack is the ClassName!! // And every Stack Manipulation is done in a way that this is always the case! #COMMAND INI_Begin_Properties #IF !0>0 Procedure onInit Set psSourceFile To !1 #IF !0>1 Set piLoadSaveMode To !2 #ENDIF End_Procedure #ENDIF #PUSH !g // ... also these Vars are in doku calles as unused, perhapes #PUSH !h // ... somebody has used it somewhere else. #PUSH !i // ... #PUSH !j // ... #SPUSH !$ // Save the String compiler variable to Stack #SET g$ 101010 // To Identify that it is A begin_Properties Block! #SET h$ 0 // Used as subproperty count #SET i$ 0 // Used to check if parent property was a MULTI Item Prop. #SET j$ 0 // Used as Property count (Parents) #ENDCOMMAND #COMMAND INI_SendAddTags R #IF !j>0 #SPOP h$ // Multi/Single Item -> I use the String Stack becouse this isnt changed by the Procedure Command. #SET h$ !$ // Store it in !h #SPOP $$ // Name of the Property (TAG) Send AddTag "!$" !h #SET j$ (!j-1) INI_SendAddTags !1 #ENDIF #SET $$ !1 #ENDCOMMAND // The top value of the Stack is the ClassName!! #COMMAND INI_End_Properties #SPOP $$ // ... // ProcedureEx INI_AddTagValues Procedure INI_AddTagValues_!$ INI_SendAddTags !$ End_Procedure #POP i$ // Restores the saved compiler vars. #POP h$ // ... #POP g$ // ... #POP j$ // ... Procedure INI_AddTagValues Send INI_AddTagValues_!$ // SendEx INI_AddTagValues End_Procedure #ENDCOMMAND // Saves two values to the Stack: String TagName and Numeric: MultiLine // The 1st parameter need to be !$ becouse stack has to stay valid! #COMMAND SAVE_AddTag R R R #SPOP $$ // Catch the ClassName from the STack #SPUSH !2 // Save the argument for AddTag to Stack #SPUSH !3 // Multi/Single Item Property? #SPUSH !$ // Give it Back to Stack #SET $$ !1 // Saves the old value to !$ again. #ENDCOMMAND // Defines a MultiItem Property! #COMMAND INI_Property.Multi // 1-TYPE 2-Name 3-Public 4-IniT #SET i$ 1 // Multi Item! SAVE_AddTag !$ !2 1 INI_Procedure !$ Set !2 Integer iItemNr !1 sWert Send SetIniValue "!2" iItemNr 0 sWert INI_End_Procedure !$ INI_Function !$ !2 Integer iItemNr Returns !1 Function_Return (IniValueEx(Self,"!2",iItemNr,0)) INI_End_Function !$ INI_Function !$ !2.Count Returns Integer Function_Return (IniValueCount(Self,"!2")) INI_End_Function !$ INI_Procedure !$ !2.DeleteAllItems Send DeleteAllItems "!2" INI_End_Procedure !$ INI_Procedure !$ !2.DeleteItem Integer iNr Send DeleteItem "!2" iNr INI_End_Procedure !$ #SET $$ !2 // Saves the name of the main property! #ENDCOMMAND // Defines a Single Item Propery #COMMAND INI_Property.Single // 1-TYPE 2-Name 3-Public 4-IniT #SET i$ 0 // Single Item! SAVE_AddTag !$ !2 0 INI_Procedure !$ Set !2 !1 sWert Send SetIniValue "!2" 0 0 sWert INI_End_Procedure !$ INI_Function !$ !2 Returns !1 Function_Return (IniValueEx(Self,"!2",0,0)) INI_End_Function !$ #SET $$ !2 // Saves the name of the main property! #ENDCOMMAND // Defines a Ini Property whether MULTI Item or Single. #COMMAND INI_Property R R """PRIVATE""PUBLIC" UGO // 1-TYPE 2-Name 3-Public 4-IniT 5-MULTI #IFSAME !g 101010 #IFSAME !1 String Integer Number Date #SET j$ (!j+1) #SET h$ 0 // Used as subproperty count #IFSAME !5 MULTI INI_Property.Multi !1 !2 !3 !4 #ELSE INI_Property.Single !1 !2 !3 !4 #ENDIF #ELSE #ERROR 200 Type For ini Property Not known! !1 #ENDIF #ELSE #ERROR 200 INI_Begin_Properties Not defined! !g #ENDIF #ENDCOMMAND // Defines a sub-property for a multi item property. #COMMAND INI_Property.Sub.Multi // 1-TYPE 2-Name 3-Public 4-IniT INI_Procedure !$ Set !$.!2 Integer iItemNr !1 sWert Send SetIniValue "!$" iItemNr !H sWert INI_End_Procedure !$ INI_Function !$ !$.!2 Integer iItemNr Returns !1 Function_Return (IniValueEx(Self,"!$",iItemNr,!h)) INI_End_Function !$ #ENDCOMMAND // Defines a sub-property for a single item property. #COMMAND INI_Property.Sub.Single // 1-TYPE 2-Name 3-Public 4-IniT INI_Procedure !$ Set !$.!2 !1 sWert Send SetIniValue "!$" 0 !h sWert INI_End_Procedure !$ INI_Function !$ !$.!2 Returns !1 Function_Return (IniValueEx(Self,"!$",0,!h)) INI_End_Function !$ #ENDCOMMAND // Defines a subproprty neither to a multi or a single (parent) property. #COMMAND INI_Property.Sub R R """PRIVATE""PUBLIC" UGO . // 1-TYPE 2-Name 3-Public 4-IniT #IFSAME !1 String Integer Number Date #IFDEF GET_!$ #IF !i = 1 INI_Property.Sub.Multi !1 !2 !3 !4 #ELSE INI_Property.Sub.Single !1 !2 !3 !4 #ENDIF #ELSE #ERROR 200 parent For subproperty Not defined! !1 #ENDIF #ELSE #ERROR 200 Type For ini Property Not known! !1 #ENDIF #ENDCOMMAND // For an easier writing of the Class Import. #COMMAND INI_IMPORT_PROPERTIES Import_Class_Protocol !1 !$ ALL INHERIT #ENDCOMMAND