Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I use INI files

Windows API

How do I use INI files

by  WilMead  Posted    (Edited  )
I know this subject has been beaten to death and beyond, but I have not seen a decent solution to this problem. Sure one could write a file parser to cash the file into memory using collections or what not. One could also easily write a module to re-represent the API calls needed to work with these files. There is a better way.

I created a solution for this task years ago, one that is slightly better than any I've seen even though it lacks their thuroughness. It uses a class named cIniFile to represent INI files as objects. My needs never went beyond getting numbers and strings so the class is very small, one property and four methods are all I ever needed. The [color blue]filename[/color] property provides the object with its link to the physical file. [color blue]GetString[/color] and [color blue]PutString[/color] provide the string acess. Finally [color blue]GetNumber[/color] and [color blue]PutNumber[/color] provide access to INI file number values. I thought of adding StringVal and NumberVal properties, but felt it overkill and better left to customized classes to be built later.

Using a class allows me to create other objects with the same interface to store the values in a database or even the registry without needing extensive changes in the main line code.

The basic low level design of this class make it ideal for developing classes using it to create endless possibilities. Default filenames could be assigned in the class_initialize method. Properties can be used to represent INI-file sections, the gets read from the file, the lets write. The embedded cIniFile object can be exposed, made public, assuring that all necessary access remains available...

I've put the class code last to make it easier to get. The sample program uses the same ini file and keys so watching the changes requires a debugger and single stepping.

Sample 1 Basic use of cIniFile:
-----[tt]
Sub main()
Dim oIni As cINIFile
Dim oCustIni as New cCustINI
Set oIni = New cINIFile

With oIni
.Filename = App.Path & "\Config.ini"

.PutString "System", "Type", "Sample File"
.PutNumber "System", "FirstNum", 1

Debug.Print .GetNumber("System", "FirstNum", -1)
Debug.Print .GetString("System", "Type")
End With
With oCustIni
.mSystem("Type") = "Customized Sample"
.mSystem("FirstNum") = 2
Debug.Print .mSystem("FirstNum")
Debug.Print .mSystem("Type")
End With
With oCustIni.oIni
.PutString "System", "Type", "Customized Sample File2"
.PutNumber "System", "FirstNum", 5

Debug.Print .GetNumber("System", "FirstNum", -1)
Debug.Print .GetString("System", "Type")
End With

Set oIni = Nothing
End Sub
[/tt]-----

Sample 2 -- Customized Class [color blue]cCustIni[/color]
-----[tt]
Option Explicit
Public oINI as cIniFile

Private Sub Class_Initialize
oINI = New cIniFile
oINI.Filename = App.Path & "\Config.ini"
End Sub

Private Sub Class_Terminate
oINI = Nothing
End Sub

Public Property Get mSystem(sKey as String)
Dim ls0 as String
With oINI
If LCase$(Mid$(sKey, 2, 1)) = "i" then
mSystem = .GetNumber("System", sKey)
ElseIf LCase$(Mid$(sKey, 2, 1)) = "b" then
ls0 = .GetString("System", sKey)
mSystem = lcase(ls0) = "true"
Else
mSystem = .GetString("System", sKey)
End If
End With
End Property

Public Property Let mSystem(sKey as String, v)
Dim ls0 as String
If "String" <> TypeName(v) then
ls0 = cStr(v)
Else
ls0 = v
End If

oINI.PutString "System", sKey, ls0
End Property
[/tt]-----


[color blue]cIniFile[/color] CLASS CODE Copy and past into a class module. For the example above to work, make sure the class is named cIniFile.

[tt]
Option Explicit
Private Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long

Private sFile As String

Public Property Let Filename(ByVal vNewValue As Variant)
sFile = vNewValue
End Property

Public Function GetString(sSection As String, sKey As String, Optional sDefault As String = "None") As String
Dim ls0 As String
ls0 = Space(1024)

GetPrivateProfileString sSection, sKey, sDefault, ls0, 1024, sFile
If InStr(ls0, Chr(0)) Then
ls0 = Left$(ls0, InStr(ls0, Chr(0)) - 1)
End If
GetString = ls0
End Function

Public Function GetNumber(sSection As String, sKey As String, Optional lDefault As Long = 0) As Long
Dim ln0 As Long
ln0 = GetPrivateProfileInt(sSection, sKey, lDefault, sFile)
GetNumber = ln0
End Function

Public Function PutString(sSection As String, sKey As String, sValue As String)
WritePrivateProfileString sSection, sKey, sValue, sFile
End Function

Public Function PutNumber(sSection As String, sKey As String, lValue As Long)
Dim ls0 As String
ls0 = Str(lValue)
ls0 = Trim$(ls0)
WritePrivateProfileString sSection, sKey, ls0, sFile
End Function
[/tt]
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top