Gordon McComb
Automation

Using INI Files to Store Data

In this document:

Windows has long used text-based configuration files to store setting information for itself, as well as for applications programs you have installed on your computer. These configuration files are better known as INI files; typical examples include WIN.INI and SYSTEM.INI, used in Windows 3.1- as well as many Windows 95-based systems. The WIN.INI file, for instance, contains user-selectable functions, such as the current printer, and whether to use wallpaper or a pattern for the desktop.

Windows 95 (and Windows NT) does not rely on INI files as much as Windows 3.1 did, and instead uses something called the Registry for storing system and application setting information. Though Windows 95 does not make heavy use of INI files, the operating system still supports them. Windows (3.1, 95, and NT) provides a handful of special built-in functions for writing and retrieving information in INI files.

The INI file function are designed for use by Windows programmers, but can be accessed by a WordPerfect macro. This is handy because WordPerfect for Windows lacks its own macro commands for manipulating INI files. You might want to use an INI function to read the data stored in an existing INI file, or to use an INI file to store scraps of information for later use. For example, an INI file could contain the next file number to use in an automatically incrementing file naming system you've developed.

Windows provides a series of INI file functions, but the two most commonly used are GetPrivateProfileString and WritePrivateProfileString. These functions are available to a WPWin macro using the DLLCall statement. This statement is used whenever you wish to access a function built into the Windows application programming interface (API).

GetPrivateProfileString

The GetPrivateProfileString function retrieves a string value from a private initialization (INI) file. Your macro can write and read information from these INI files. You can also use INI files to store pieces of information you want to use later.

Note that WPWin 6.1 doesn't use many INI files itself; (rather, it stores configuration data in its proprietary binary initialization file (BIF). Further, WPWin 7 and 8 don't use INI files at all, preferring to store their information into the Windows Registry.

The 6.1 syntax for the GetPrivateProfileString function is"

  DLLLoad (Kernel; "KERNEL")
  DLLCall (Kernel; "GetPrivateProfileString"; wProfileResult: WORD;{
     lpAppName;
     lpKeyName;
     Loword (nDefault);
     Address (lpReturnString);
     lpFileName})
  DLLFree (Kernel)

The syntax for WPWin 7 and 8 is almost identical, except that the Loword keyword is omitted:

The 6.1 syntax for the GetPrivateProfileString function is:

  DLLLoad (Kernel; "KERNEL")
  DLLCall (Kernel; "GetPrivateProfileString"; wProfileResult: WORD;{
     lpAppName;
     lpKeyName;
     nDefault;
     Address (lpReturnString);
     lpFileName})
  DLLFree (Kernel)

In both cases, The function returns the length of the string copied to the lpReturnString variable. The lpAppName, lpKeyname, and lpFileName parameters are not case dependent. Before using GetPrivateProfileString, you must declare the lpReturnString variable. This is done by assigning a "buffer" variable.

For more info on the construction of an INI file see WritePrivateProfileString, below.

Example of GetPrivateProfileString:

  // Retrieve and print current setting of "Value" keyword under
  // the [Text] section, in file JUNK.INI

  restoring=""
  DLLLoad (Kernel; "KERNEL")
  DLLCall (Kernel; "GetPrivateProfileString"; wGetProf:WORD;{
     "Test";
     "Value";
     "Ick";
     Address (retString);
     Loword (128);  	// drop Loword in WPWin 7/8
     "junk.ini"})
  DLLFree (Kernel)

WritePrivateProfileString

The WritePrivateProfileString is used to write a value in an INI file. You can write to INI files that below to another application, or you can create your own INI files for use with your macros.

The syntax of the function (6.1, 7, or 8) is:

  DLLLoad (Kernel; "KERNEL")
  DLLCall (Kernel; "WritePrivateProfileString"; bPrivateProf:BOOL;{
     lpAppName;
     lpKeyName;
     lpString;
     lpFileName})
  DLLFree (Kernel)

The function returns a True if the function was successful; otherwise the return value is False.

You can better visualize how the WritePrivateProfileString function works by visualizing the way data is stored in an INI file. INI files are composed of sections, identified by a name in brackets. Under each section is a list of one or more keynames and values. For example,

  [Section Name]
  keyname = value or string
  ...
  • lpAppName is the section name you want to write. If it already exists, WritePrivateProfileString will use the existing section, and not add another.
  • lpKeyName is the keyname you want to add or change.
  • lpString is the value or string you want to attach to the lpKeyName entry.
  • lpFileName is the name (and optional path) of the private initialization file. The INI file extension is optional; you can use any file extension you wish.

If the file specified in lpFileName already exists, then WritePrivateProfileString alters the existing file. If the file doesn't exist, the function creates a new file. If you omit the path in lpFileName, WritePrivateProfileString searches the Windows directory.

WritePrivateProfileString makes no change if lpString is the same as the value already found in the file (Windows ignores the case of the string). If the keyname doesn't already exist, the function adds it under the appropriate section.

Example of WritePrivateProfileString:

  // Write string to private INI file

  DLLLoad (User; "KERNEL")
  DLLCall (User; "WritePrivateProfileString"; bProfile:BOOL;{
     "application name";      // [application name] section
     "keyname";          // keyword
     "newstring";        // new string for keyword
     "junking"})         // Name of private INI file
  DLLFree (Kernel)

Creating User-Defined INI File Functions

You can extend the usefulness of using the Windows INI file API functions in your WPWin macros by creating your user-defined functions. A user-defined function is like a built-in macro command, except that you define what the function does, the data it accepts, and the data it returns upon completion.

Below are two user-defined INI file functions you can include in your own macros. The WriteIniString function serves as a "wrapper" for the Windows WritePrivateProfileString API function. Conversely, the GetIniString function serves as a wrapper for the GetPrivateProfileString function. Note that two versions of GetIniString are provided -- one for WPWin 6.1/7 for Windows 3.1, and another for WPWin 7/8 for Windows 95. Also note that these functions use the AnsiString statement to ensure that WPWin uses only Windows text with the functions.

  
  //============================================================== 
  // For WPWin 6.1, 7, and 8
  Function WriteIniString (AppName;Keyname;ValString;Filename) 
  DllCall (Kernel;"WritePrivateProfileString"; ret:BOOL;
     {AnsiString(AppName);AnsiString(Keyname);
     AnsiString(ValString);AnsiString(Filename)})
  Return (ret)
  EndFunc

  //============================================================== 
  // For WPWin 6.1 or 7 for Windows 3.1
  Function GetIniString (AppName;Keyname;DefaultString;Filename)
  RetString=""
  DllCall (Kernel;"GetPrivateProfileString";ret:WORD;
     {AnsiString(Appname);AnsiString(Keyname);
     AnsiString(DefaultString);AnsiString(Address(RetString));
     Loword (128);AnsiString(Filename)})
  Return (RetString)
  EndFunc

  //============================================================== 
  // For WPWin 7/8 for Windows 95
  Function GetIniString (AppName;Keyname;DefaultString;Filename)
  RetString=""
  DllCall (Kernel;"GetPrivateProfileString";ret:WORD;
     {AnsiString(Appname);AnsiString(Keyname);
     AnsiString(DefaultString);AnsiString(Address(RetString));
     128;AnsiString(Filename)})
  Return (RetString)
  EndFunc

To use either function you must first add the following near the top of your macro:

  Global (Kernel)
  DLLLoad (Kernel; "Kernel")

Note: In all instances, the maximum length of any INI text value is 128 characters.

Call the WriteIniString function with:

  Ret=WriteIniString (AppName;Keyname;ValString;Filename) 

where AppName is a section name in the INI file, Keyname is a key under that section, ValString is the string you want to write to the file, and Filename is the path and name of the INI file (note: if you leave off the path, Windows will expect the INI file to be in the main Windows directory). The Ret return variable contains a True or False, depending on whether the function worked.

Call the GetIniString function with:

  Ret=GetIniString (AppName;Keyname;DefaultString;Filename)

where AppName is a section name in the INI file, Keyname is a key under that section, DefaultString is a string to return if the INI file cannot be processed, and Filename is the path and name of the INI file (note: if you leave off the path, Windows will expect the INI file to be in the main Windows directory). The Ret return variable contains the returned string.

Examples of INI File Functions In Action

Several example of using INI file functions are available here. These examples include:

  • counter.zip -- Generic counter system for WordPerfect for Windows. It keeps track of one or more counters in documents; the counters are for automatically incrementing numbers, such as invoice numbers, order numbers, and customer numbers. Counters are configured by editing a simple text file; there is no need to alter the macro engine.
  • macmenu.zip -- Easy-to-use, generic macro-based menu system for WPWin 8. You can specify any number of menu options, and associate "actions" with each option. Supported actions include playing a macro, running a merge, and selecting a template. The menu is configured by editing a simple text file; there is no need to alter the macro engine.

INI Files Versus Windows Registry and BIF Files

A common question of those looking to store configuration data is whether to use INI files, the Windows Registry, or WPWin's proprietary BIFs (Binary Intialization Files). All three have their uses.

  • INI files are ideal when the there is relatively little data (INI files have a 64K file size limit), and when it is in text-only format. INI files can be readily shared across a network simply by placing the file on a network drive. The main disadvantage to INI files is that the text for each key entry must be under 256 bytes (the example above limit the entry to 128 characters). Another disadvantage is that the data in an INI file can contain text only, no special formatting, tabs, hard returns, or extended formatting. INI files can be edited by any text editor or word processor.
  • The Windows Registry is now a popular location for storing configuration data. WPWin 7 and 8 provide built-in macros commands for using the Registry. The Registry has no inherent size or data type limits. The main disadvantage to the Registry is that by default the data in the registry is local to each user. The Registry can be edited using the Windows Regedit.exe program.
  • BIF files were used by WPWin 6.x in place of INI files or the Windows 3.1 Registry. Though neither WPWin 7 nor 8 use BIF files for their own configuration data, macro commands are still provide for storing and retrieving information in BIFs (examples: BifRead and BifWrite). The main advantage of BIF files is that they can store binary data, including special WordPerfect formatting and extended characters. The main disadvantage to BIFs is the rather arcane and complex macro commands used for them. BIF files can be edited with the Bifed20.EXE program, which is provided with WPWin 6.0a and 6.1 (but not with WPWin 7 and 8).