.INI Files - Preserving Unit Variables Between Macro Uses In DCAL macros any variables declared at the unit file level were both globally accessible and preserved between uses of the macro. While Delphi unit variables are also globally accessible in the macro, their values are not preserved between calls to the macro. This means that any settings made by the user during the use of a macro must be reset in the next call. To compensate it is necessary to store the values in a file at the end of each macro use and reload them at the start of the next use. One of the simplest means for doing so is to use an '<name>.ini' file to hold the relevant information. This is how Datacad stores a number of settings that are independent of a single drawing file.
To do so, it is necessary to use one of Delphi's class types
tIniFile. This primer does not go into detail requirements of using Delphi classes, however the following code snippet provides an example of the class in use.
Code: Select allunit <name>_u;
interface
uses
System.SysUtils, System.Classes, {1}
inifiles, {1}
UConstants, //contants declarations
Uvariables, //all variables available in DCAl
URecords, //all record structures available in DCAL
UInterfaces, //DCAL for Delphi methods used for interfacing directly with user
UinterfacesRecords; //Record structures for various interface functions.
const
cfilename = '<name>.ini';
var
iniFl: tIniFile; {2}
//persistent variables
int : integer;
fl : afloat;
str : string;
bool : boolean;
implementation
procedure InitVariables;
begin
int := 1;
fl := 2.3;
str := 'My string';
bool := true;
end;
Procedure <unitName>StartUp; {3}
//Load settings from 'ini' file
var
fname, path : str255;
begin
getpath (path, pathsup); //places the ini file in the Support directory of Datacad. use pthmcr for macro directory.
fname := path + filename; //change the name for custom ini file.
if fileexists(fName) then begin //change the name to match Datacad settings
try
iniFl := TIniFile.Create(fname); //create the class object
//insert your variables
{ iniFl.readinteger ('Section 1', 'the Integer', int);
iniFl.readFloat ('Section 1', 'the Float', fl);
iniFl.readString ('Section 1', 'the Float', str);
iniFl.readBool ('Section 1', 'the Boolean', bool);
}
finally
IniFl.free; //close the class object
end;
end
else
initVariables;
end;
end; //<unitName>StartUp
Procedure <unitName>ShutDown; {4}
//Save settings to 'ini' file
var
fname, path : str255;
begin
getpath (path, pathsup); //places the ini file in the Support directory of Datacad. use pthmcr for macro directory.
fname := fname + cfilename; //change the name for custom ini file.
try
iniFl := TIniFile.Create(fname); //create the class object
//insert your variables
( iniFl.writeInteger ('Section 1', 'the Integer', int);
iniFl.writeFloat ('Section 1', 'the Float', fl);
iniFl.writeString ('Section 1', 'the String', str);
iniFl.writeBool ('Section 1', 'the Boolean', bool);
}
finally
IniFl.free; //close the class object
end;
end; //<unitName>ShutDown
initialization
<unitName>StartUp; {5}
finalization
<unitName>Shutdown: {5}
{1} Add the Delphi 'inifiles' unit for use in this file.
{2} Define a tiniFile object variable for use in the unit.
{3} Define a
<unitName>startup initialization procedure to load the settings from an 'ini' file. The procedure begins by getting the path where Datacad stores support files. 'Pathsup' is a constant defined in uconstants.pas. As an alternative directory you might also consider 'pathmcr' which is the directory used to store macros. After getting the path, provide a specific
<name>.ini file name. The code then tests to see if the file already exists. If it does, the values are loaded to your variables. If not, the procedure
InitVariables is called to load default values.Use the Delphi
try/finally statement to create the Tinifile object and write the specific variables to the file. The format for all
iniFl.write and
iniFl.read procedure arguments is
(Section, Identifier, Value) which reads in the '.ini' file as:
[Section]
Identifier=ValueThese values can be inspected and edited outside of the macro by the user with any text editor. Also note that the last step in the
try/finally statement frees the object releasing its memory allocation, a necessary step for all Delphi class objects.
{4} Similar to
<unitName>startup the
<unitName>shutdown procedure writes the current variable values from the file and loads them into your macro unit's global variables.
{5} Place calls for the
startup and
shutdown procedures in the initialization and finalization sections. These procedures will then be called when the macro is loaded and closed. Note that 'initialization' and 'finalization' sections cannot be used in the actual 'dll' library file. They must be placed in a '<name>unit' file to be called by the macro. (see the 'Initialization & Finalization' section in this post.
You must include procedures in each unit of your macro to read and write the global variables it contains. Each unit should assign a different 'section' argument in the 'iniFl.read...' or 'iniFl.write...' procedure calls.