CIniFile: Difference between revisions

From DataFlex Wiki
Jump to navigationJump to search
m (doh! - fixed cat tutorial)
m (added structure)
Line 1: Line 1:
An object of the cIniFile class can be used for reading information avaiable from an INI file.
An object of the '''cIniFile''' class can be used for reading information avaiable from an INI file.


INI files are often used to store user preferences or setup options for applications.
INI files are often used to store user preferences or setup options for applications.


==INI files==
In [[Visual DataFlex]] you can freely use as many INI files as you require, however the two-level structure of INI files (sections and keys) means that there is often no need to use more than one.  Here, for example, is a boot.ini file (usually found in the root directory of the system drive of Windows operating systems):
In [[Visual DataFlex]] you can freely use as many INI files as you require, however the two-level structure of INI files (sections and keys) means that there is often no need to use more than one.  Here, for example, is a boot.ini file (usually found in the root directory of the system drive of Windows operating systems):


Line 14: Line 15:
As you can see, it defines two sections - [boot loader] and [operating systems] - each with different settings within them.
As you can see, it defines two sections - [boot loader] and [operating systems] - each with different settings within them.


==Visual DataFlex Workspace files==
Another example are the workspace configuration files used by [[Visual DataFlex]] itself (by default named "Config.ws", showing that they don't have to use the .ini extension - see the artice in "See Also" below), which must exist in the same directory the program is run from (usually the "Programs" subdirectory of the workspace).  Here is an example:
Another example are the workspace configuration files used by [[Visual DataFlex]] itself (by default named "Config.ws", showing that they don't have to use the .ini extension - see the artice in "See Also" below), which must exist in the same directory the program is run from (usually the "Programs" subdirectory of the workspace).  Here is an example:


Line 33: Line 35:
Note that section names (the ones in the square brackets), key names ("Home", "AppSrcPath", etc.) and key values can all contain spaces (although for my own part I prefer not to use those and depend on [http://en.wikipedia.org/wiki/Camelcase camelCase] to supply readability).
Note that section names (the ones in the square brackets), key names ("Home", "AppSrcPath", etc.) and key values can all contain spaces (although for my own part I prefer not to use those and depend on [http://en.wikipedia.org/wiki/Camelcase camelCase] to supply readability).


==INI file advantages==
The advantage of the INI file approach is that it can make programs configurable for different environments or uses without them having to be recompiled with different settings each time: the program can be made with a set of default values which can then be overridden at run-time by the settings in an INI file.  It has the advantage over Registry settings, which perform very much the same function, in that you don't need any special rights on the machine to set it up and make changes to it: you are just working with text files, so security policy issues about who has rights to the [http://en.wikipedia.org/wiki/Windows_Registry Windows Registry], or who can run RegEdit or RegEdit32 do not apply - if you can run Notepad and modify files you can configure your application.
The advantage of the INI file approach is that it can make programs configurable for different environments or uses without them having to be recompiled with different settings each time: the program can be made with a set of default values which can then be overridden at run-time by the settings in an INI file.  It has the advantage over Registry settings, which perform very much the same function, in that you don't need any special rights on the machine to set it up and make changes to it: you are just working with text files, so security policy issues about who has rights to the [http://en.wikipedia.org/wiki/Windows_Registry Windows Registry], or who can run RegEdit or RegEdit32 do not apply - if you can run Notepad and modify files you can configure your application.


Line 59: Line 62:
Combining these factors - the fact that there is probably no need to have more than one INI file, and the fact that [[Visual DataFlex]] requres one anyway - means that for most purposes you can just add what you need to the existing workspace configuration file.
Combining these factors - the fact that there is probably no need to have more than one INI file, and the fact that [[Visual DataFlex]] requres one anyway - means that for most purposes you can just add what you need to the existing workspace configuration file.


==Accessing INI files==
So how do you access that information in your program?
So how do you access that information in your program?


Line 124: Line 128:
But some might consider that a bridge too far!
But some might consider that a bridge too far!


==Summary==
The cIniFile has other methods as well: it can write as well as read (WriteString, DeleteKey and DeleteSection) and can dynamically determine the contents of the file (ReadSections, ReadSection, SectionExists and KeyExists) - see the VDF Help for full information - but the ReadString method is the one you will need in most circumstances.
The cIniFile has other methods as well: it can write as well as read (WriteString, DeleteKey and DeleteSection) and can dynamically determine the contents of the file (ReadSections, ReadSection, SectionExists and KeyExists) - see the VDF Help for full information - but the ReadString method is the one you will need in most circumstances.



Revision as of 14:44, 8 April 2008

An object of the cIniFile class can be used for reading information avaiable from an INI file.

INI files are often used to store user preferences or setup options for applications.

INI files

In Visual DataFlex you can freely use as many INI files as you require, however the two-level structure of INI files (sections and keys) means that there is often no need to use more than one. Here, for example, is a boot.ini file (usually found in the root directory of the system drive of Windows operating systems):

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS

[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Microsoft Windows XP Professional" /fastdetect /NoExecute=OptIn

As you can see, it defines two sections - [boot loader] and [operating systems] - each with different settings within them.

Visual DataFlex Workspace files

Another example are the workspace configuration files used by Visual DataFlex itself (by default named "Config.ws", showing that they don't have to use the .ini extension - see the artice in "See Also" below), which must exist in the same directory the program is run from (usually the "Programs" subdirectory of the workspace). Here is an example:

[Workspace]
Home=..\
AppSrcPath=.\AppSrc
AppHTMLPath=.\AppHtml
BitmapPath=.\Bitmaps
IdeSrcPath=.\IdeSrc
DataPath=.\Data
DDSrcPath=.\DdSrc
HelpPath=.\Help
ProgramPath=.\Programs
FileList=.\Data\Filelist.cfg
Description=MyFirstProject

Here only a single section - [Workspace] - is defined, however the fact that an INI file can have as many sections as it needs means that you can use this very file to set up options for how you want your program to behave.

Note that section names (the ones in the square brackets), key names ("Home", "AppSrcPath", etc.) and key values can all contain spaces (although for my own part I prefer not to use those and depend on camelCase to supply readability).

INI file advantages

The advantage of the INI file approach is that it can make programs configurable for different environments or uses without them having to be recompiled with different settings each time: the program can be made with a set of default values which can then be overridden at run-time by the settings in an INI file. It has the advantage over Registry settings, which perform very much the same function, in that you don't need any special rights on the machine to set it up and make changes to it: you are just working with text files, so security policy issues about who has rights to the Windows Registry, or who can run RegEdit or RegEdit32 do not apply - if you can run Notepad and modify files you can configure your application.

Here is an example where an additional section allowing the configuration of a database location and login has been added:

[Workspace]
Home=..\
AppSrcPath=.\AppSrc
AppHTMLPath=.\AppHtml
BitmapPath=.\Bitmaps
IdeSrcPath=.\IdeSrc
DataPath=.\Data
DDSrcPath=.\DdSrc
HelpPath=.\Help
ProgramPath=.\Programs
FileList=.\Data\Filelist.cfg
Description=MyFirstProject

[Database Login]
Server=big-iron.database-servers.local
Login=itsme
Password=letmein
Database=Accounting
Driver=MSSQLDRV

Combining these factors - the fact that there is probably no need to have more than one INI file, and the fact that Visual DataFlex requres one anyway - means that for most purposes you can just add what you need to the existing workspace configuration file.

Accessing INI files

So how do you access that information in your program?

For most purposes the information in an INI file will only be read at program start-up. This means that (a) the oApplication object is a good place to do such things (see the article in "See Also" below for some guidance on sub-classing the cApplicatiion class) and (b) the cIniFile object need not be retained after it has been used. (Of course you might have different requirements, but here we will assume these are true.)

So... in your oApplication object (perhaps in the "OnCreate" procedure, perhaps elsewhere, such as in "Construct_Object" or "End_Construct_Object") what you need to do is dynamically create a cIniFile object, use it to get the information you want, then destroy it again. You also want to be able to access the workspace configuration file for the application, perhaps without knowing ahead of time what that is actually called.

Here is one way of doing it (note - this code is assumed to be in the oApplication object or a sub-class of the cApplication class; the only place this matters is in the "Set psFileName ..." line, where "Self" will refer to the oApplication object, and where the various properties are held):

  String  sServer sLogin sPW sDrv sDB
  Boolean bLogin
  Handle  hoIni

  // Retrieve your application defaults into local variables
  Get psServer   to sServer
  Get psLogin    to sLogin
  Get psPassword to sPW
  Get psDriver   to sDrv
  Get psDatabase to sDB
  Get pbDoLogin  to bDB

  Get Create U_cIniFile to hoIni    // Create INI file object

  // Make it use the workspace configuration file
  Set psFileName of hoIni to (psWorkspaceWSFile(phoWorkspace(Self)))

  // Read the information
  Move (ReadString(hoIni, "Database Login", "Server",   sServer)) to sServer
  Move (ReadString(hoIni, "Database Login", "Login",    sLogin))  to sLogin
  Move (ReadString(hoIni, "Database Login", "Password", sPW))     to sPW
  Move (ReadString(hoIni, "Database Login", "Driver",   sDrv))    to sDrv
  Move (ReadString(hoIni, "Database Login", "Database", sDB))     to sDB
  Move (ReadString(hoIni, "Database Login", "DoLogin",  bLogin))  to bLogin
     
  Send Destroy of hoIni             // And Destroy it again

  // Set the properties to make the information persistent
  Get psServer   to sServer
  Get psLogin    to sLogin
  Get psPassword to sPW
  Get psDriver   to sDrv
  Get psDatabase to sDB
  Get pbDoLogin  to bDB

The above code will retrieve the values set in the second workspace file example above. Note that in that example, the "DoLogin" value is not present - the "ReadString" method of the cIniFile class lets you supply a default value to use if the setting is not present, and here we have used the bLogin variable, which was set from the pbDoLogin property, and which is then used to set that property again... so the fact that the setting is absent (not "missing" - it is deliberate!) means that the default property remains unchanged.

You could save some code by not retrieving the properties into local variables first, but using the properties as defaults directly:

  Move (ReadString(hoIni, "Database Login", "Server",   psServer(Self)))   to sServer
  Move (ReadString(hoIni, "Database Login", "Login",    psLogin(Self)))    to sLogin
  Move (ReadString(hoIni, "Database Login", "Password", psPassword(Self))) to sPW
  Move (ReadString(hoIni, "Database Login", "Driver",   psDriver(Self)))   to sDrv
  Move (ReadString(hoIni, "Database Login", "Database", psDatabase(Self))) to sDB
  Move (ReadString(hoIni, "Database Login", "DoLogin",  pbDoLogin(Self)))  to bLogin

Or even dispense with the local variables completely:

  Set psServer   to (ReadString(hoIni, "Database Login", "Server",   psServer(Self)))
  Set psLogin    to (ReadString(hoIni, "Database Login", "Login",    psLogin(Self)))
  Set psPassword to (ReadString(hoIni, "Database Login", "Password", psPassword(Self)))
  Set psDriver   to (ReadString(hoIni, "Database Login", "Driver",   psDriver(Self)))
  Set psDatabase to (ReadString(hoIni, "Database Login", "Database", psDatabase(Self)))
  Set pbDoLogin  to (ReadString(hoIni, "Database Login", "DoLogin",  pbDoLogin(Self)))

But some might consider that a bridge too far!

Summary

The cIniFile has other methods as well: it can write as well as read (WriteString, DeleteKey and DeleteSection) and can dynamically determine the contents of the file (ReadSections, ReadSection, SectionExists and KeyExists) - see the VDF Help for full information - but the ReadString method is the one you will need in most circumstances.

See Also

Passing the workspace as a parameter

External references