为了方便用户使用和使系统具有灵活性,大多数Win-dows应用程序将用户所做的选择以及各种变化的系统信息记录在初始化(INI)文件中。因 此,当系统的环境发生变化时,可以直接修改INI文件,而无需修改程序。由此可见,INI文件对系统功能是至关重要的。本文将介绍采用 VisualBasicforWindows(下称VB)开发Windows应用程序时如何读写INI文件。
INI文件是文本文件,由若干部分(section)组成,在每个带括号的标题下面,是若干个以单个单词开头的关键词(keyword)和一个等号,每个关键词会控制应用程序某个功能的工作方式,等号右边的值(value)指定关键词的操作方式。其一般形式如下:
[Section1]
KeyWord1=Valuel
KeyWord2=Value2
……
[Section2]
KeyWord1=Value1
KeyWord2=Value2
……
其中,如果等号右边无任何内容(即Value为空),那就表示Windows应用程序已为该关键词指定了缺省值,如果在整个文件中找不到某个关 键词(或整个一部分),那同样表示为它们指定了缺省值。各个部分所出现的顺序是无关紧要的,在每一个部分里,各个关键词的顺序同样也无关紧要。
读写INI文件通常有两种方式:一是在Windows中用“记事本”(Notepad)对其进行编辑,比较简单,无需赘述;二是由Windows应用程序读写INI文件,通常是应用程序运行时读取INI文件中的信息,退出应用程序时保存用户对运行环境的某些修改。
关键词的值的类型多为字符串或整数型,应分两种情况读写。为了使程序具有可维护性和可移植性,最好把对INI文件的读写封装在一个模块 (RWINI.BAS)中,在RWI-NI.BAS中构造GetIniS和GetIniN函数以及SetIniS和Se-tIniN过程,在这些函数和过 程中需要使用WindowsAPI的“GetPrivateprofileString”、“GetPrivateProfileInt”和 “WritePrivateProfileString”函数。
RWINI.BAS模块的程序代码如下:
在General-Declearation部分中声明使用到的WindowsAPI函数:
Public Declare Function GetprivateprofileString Lib“Kernel”(ByVal lpAppName As String,ByVal lpKeyName As _
String,ByVal lpDefault As String,ByVal lpRetrm-String As String,ByVal cbReturnString As Integer, _
ByVal Filename As String)As Integer
Public Declare Function GetPrivatePfileInt Lib“Kernel”(ByVal lpAppName As String,ByVal lpKeyName As String, _
ByVal lpDefault As Integer,ByVal Filename As String)As Integer
Public Declare Funciton WritePrivateprofileString Lib“Kernel”(ByVal lpApplicationName As String, _
ByVal lpKeyName As String,ByVal lpString As String,ByVal lplFileName As String)As Integer
Public Function GetIniS(ByVal SectionName As String,ByValKeyWord As String,ByVal DefString As String)As String
Dim ResultString As String*144,Temp As Integer
Dim s As String,i As Integer
Temp%=GetPrivateProfileString(SectionName,KeyWord,"",ResultString,144,AppProfileName())
’检索关键词的值
If Temp%>0 Then ’关键词的值不为空
s=""
For i=1 To 144
If Asc(Mid$(ResultString,I,1))=0 Then
ExitFor
Else
s=s & Mid$(ResultString,I,1)
End If
Next
Else
Temp%=WritePrivateProfilesString(sectionname,KeyWord,DefString,ppProfileName())
’将缺省值写入INI文件
s=DefString
End If
GetIniS=s
End Function
Public Function GetIniN(ByVal SectionName As String,ByVal KeyWord As String,ByVal DefValue As Ineger)As Integer
Dim d As Long,s As String
d=DefValue
GetIniN=GetPrivateProfileInt(SectionName,
KeyWord,DefValue,ppProfileName())
If d<>DefValue Then
s=""
d=WritePrivateProfileString(SectionName,
KeyWord,s,AppProfileName())
End If
End Function
Public Sub SetIniS(ByVal SectionName As String,BtVal KeyWord As String,ByVal ValStr As String)
Dim res%
res%=WritePrivateprofileString(SectionName,KeyWord,ValStr,AppProfileName())
End Sub
Public Sub SetIniN(ByVal SectionName As String,ByVal KeyWord As String,ByVal ValInt As Integer)
Dim res%,s$
s$=Str$(ValInt)
res%=WriteprivateProfileString(SectionName,KeyWord,s$,AppProfileName())
End Sub
SectionName为每一部分的标题,KeyWord为关键词,GetIniS和GetIniN中的DefValue为关键词的缺省 值,SetIniS和SetIniN的ValStr和ValInt为要写入INI文件的关键词的值。为了能更好地说明如何使用以上函数和过程,下面举两个 实例。
实例1:
开发应用程序通常要使用数据库和其它一些文件,这些文件的目录(包括路径和文件名)不应在程序中固定,而是保存在INI文件中,程序运行时由INI文件中读入。读入数据库文件的代码如下:
Dim Databasename As String
Databasename=GetIniS(“数据库”,“职工”,"")
If DatabaseName="" Then DatabaseName=InputBox(“请输入数据库《职工》的目录”),App.Title)
’也可通过“文件对话框”进行选择
On Error Resume Next
Set db=OpenDatabas(DatabaseName)
If Err<>0 Then
MsgBox“打开数据库失败!”,MB-ICONSTOP,App.Title:GotoErrorProcessing
Else
Set IniS“数据库”,“职工”,DatabaseName
End If
On Error GoTo 0
……
实例2:
为了方便用户操作,有时需要保存用户界面的某些信息,例如窗口的高度和宽度等。装载窗体时,从INI文件中读入窗体高度和宽度,卸载窗体时将窗体当前高度和宽度存入INI文件,代码如下:
Private Sub Form1_Load()
……
Forml.Height=GetIniN(“窗体1”,“高度”,6000)
Form1.Width=GetIniN(“窗体1”,“高度”,4500)
EndSub
……
Private Sub Form1_Unload()
……
SetIniN“窗体1”,“高度”,Me.Height
SetIniN“窗体1,”宽度“,Me.Width
……
End Sub
INI文件操作经常用到的一些API函数:
- Option Explicit
- 'win.ini
- Declare Function GetProfileInt Lib "kernel32" Alias "GetProfileIntA" _
- (ByVal lpAppName As String, _
- ByVal lpKeyName As String, _
- ByVal nDefault As Long) As Long
- Declare Function GetProfileSection Lib "kernel32" Alias "GetProfileSectionA" _
- (ByVal lpAppName As String, _
- ByVal lpReturnedString As String, _
- ByVal nSize As Long) As Long
- Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA" _
- (ByVal lpAppName As String, _
- ByVal lpKeyName As String, _
- ByVal lpDefault As String, _
- ByVal lpReturnedString As String, _
- ByVal nSize As Long) As Long
- Declare Function WriteProfileSection Lib "kernel32" Alias "WriteProfileSectionA" _
- (ByVal lpAppName As String, _
- ByVal lpString As String) As Long
- Declare Function WriteProfileString Lib "kernel32" Alias "WriteProfileStringA" _
- (ByVal lpszSection As String, _
- ByVal lpszKeyName As String, _
- ByVal lpszString As String) As Long
- '*.ini
- 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
- Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" _
- (ByVal lpAppName As String, _
- ByVal lpReturnedString As String, _
- ByVal nSize As Long, _
- ByVal lpFileName As String) As Long
- 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
- Declare Function WritePrivateProfileSection Lib "kernel32" Alias "WritePrivateProfileSectionA" _
- (ByVal lpAppName As String, _
- ByVal lpString As String, _
- ByVal lpFileName As String) As Long
- 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
- Option Explicit
- 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
- Public 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
- 'FileName:Ini文件
- 'PathName:小节名
- 'KeyName:值名
- 'WriteValue:值
- Public Function WriteIni(FileName As String, _
- PathName As String, _
- KeyName As String, _
- WriteValue As String) As Long
- Dim Rc As Long
- Rc = WritePrivateProfileString(PathName, KeyName, WriteValue, FileName)
- WriteIni = Rc
- End Function
- 'FileName:Ini文件
- 'PathName:小节名
- 'KeyName:值名
- 'BackValue:返回值
- 'Default:默认字符
- Public Function ReadIni(FileName As String, _
- PathName As String, _
- KeyName As String, _
- BackValue As String, _
- Optional Default As String = "缺省") As Long
- Dim Rc As Long
- Dim TempNum As String
- Dim TempStr As String
- TempStr = String$(255, Chr$(0))
- TempNum = 255
- Rc = GetPrivateProfileString(PathName, KeyName, Default, TempStr, TempNum, FileName)
- If Rc <> 0 Then
- BackValue = Left$(TempStr, TempNum)
- End If
- ReadIni = Rc
- End Function
- Public File As String
- 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 Integer, ByVal lpFileName As String) As Integer
- Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal Appname As String, ByVal KeyName As Any, ByVal NewString As Any, ByVal Filename As String) As Integer
- Sub DeleteSection(ByVal Section As String)
- Dim retval As Integer
- retval = WritePrivateProfileString(Section, 0&, "", File)
- End Sub
- Public Function SaveSetting(ByVal Section$, ByVal Key$, ByVal Value$)
- Dim retval As Integer
- SaveSetting = WritePrivateProfileString(Section$, Key$, Value$, File)
- End Function
- Public Function GetSetting(ByVal Section As String, ByVal KeyName As String) As String
- Dim retval As Integer
- Dim t As String * 255
- ' Get the value
- retval = GetPrivateProfileString(Section, KeyName, "unknown value", t, Len(t), File)
- ' If there is one, return it
- If retval > 0 Then
- GetSetting = Left$(t, retval)
- Else
- GetSetting = "Unknown section or key"
- End If
- End Function
- //这个可以枚举所有项
- Public Function GetSection(ByVal Section As String, KeyArray() As String) As Integer
- Dim retval As Integer
- ' Allocate space for return value
- Dim t As String * 2500
- Dim lastpointer As Integer
- Dim nullpointer As Integer
- Dim ArrayCount As Integer
- Dim keystring As String
- ReDim KeyArray(0)
- ' Get the value
- retval = GetPrivateProfileString(Section, 0&, "", t, Len(t), File)
- ' If there is one, return it
- If retval > 0 Then
- '
- ' Separate the keys and store them in the array
- nullpointer = InStr(t, Chr$(0))
- lastpointer = 1
- Do While (nullpointer <> 0 And nullpointer > lastpointer + 1)
- '
- ' Extract key string
- keystring = Mid$(t, lastpointer, nullpointer - lastpointer)
- '
- ' Now add to array
- ArrayCount = ArrayCount + 1
- ReDim Preserve KeyArray(ArrayCount)
- KeyArray(ArrayCount) = keystring
- '
- ' Find next null
- lastpointer = nullpointer + 1
- nullpointer = InStr(nullpointer + 1, t, Chr$(0))
- Loop
- End If
- '
- ' Return the number of array elements
- GetSection = ArrayCount
- End Function