配置文件.ini在VB5中的应用
在16位的Windows平台上,几乎所有的标准Windows程序都利用.in
i文件进行程序的初始化配置。到了Windows 95平台后,这一功能基本上被系统注册表所代替。但.ini文件确实有着它独特的功用和方便之处,与系统注册表比较,.ini文件具有更强的用户透明性,利用一般的文体编辑器,就可进行修改编辑。根据变量的命名及清晰的注释,用户可以很容易修改程序的运行参数,增加程序适应性,同时还可减轻一些系统的负担。
本文介绍.ini在VB 5.0中的应用情况。
.ini文件的结构
在.ini文件中,主要保存的是"变量名/对应值"对,它根据这一个关键字,可找到相对应的值,可以是字符串或数字,形式是:
Key = Value
为了能更多地保存这样的数据,在此之上又加上了一个分类层次, 或称"主题"。每一个"变量名/对应值"对都必须存在于一个主题之中,
每个主题是通过"[主题名]"这样的形式进行分段。一个完整的.ini文件大体的形式是:
[主题-1]
Key-1=Value-1
Key-2=Value-2
[主题-2]
Key-1=Value-1
Key-2=Value-2
……
.ini文件的实现
如何来实现.ini文件的类?首先是取个名字("ProFile"),然后定义要用到的API函数
Private Declare Function GetPrivateProfileInt Lib "kerne
l32" Alias "GetP rivateProfileIntA" (ByVal lpApplicationName
As String, ByVal lpKeyName AsStr ing, ByVal nDefault As Lon g,
ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileSection Lib "k
ernel32" Alias"G etPrivateProfileSectionA" (ByVal
lpAppName As String, ByVal lpReturnedString As String, ByVal nSize
As Long, ByVal lpFileName As String) As Long
Private Declare Function GetPrivateProfileString Lib "ke
rnel32" Alias "G etPrivateProfileStringA" (ByVal
lpApplicat ionName As String, ByVal lpKeyNam e As Any, ByVal lpDefault
As String, ByVal lpReturnedString As String, ByVal nSize As Long,
ByVal lpFileName As String) As Long
Private Declare Function WritePrivateProfileSection Lib "kernel32"
Alias "WritePrivateProfileSectionA" (ByVal lpApp Name
As String, ByVal lpStringAs String, ByVal lpFileName A s String)
As Long
Private Declare Function WritePrivateProfileString Lib "
kernel32" Alias "WritePrivateProfileStringA" (ByVal
lpAppli cationName As String, ByVal lpKey Name As Any, ByVal lpStrin
g As Any, ByVal lpFileName As String) As Long
注意:这里每一项定义前都加上了"Private"关键字,原因是在类模块中进行定义,"P rivate"关键字是必要的。这几个API函数的用法
,可查阅Win32 API帮助文件。
为了能从API函数中返回字符串,调用时参数一定要使用VB中的定长字符串变量。为了减少内存的分配次数,可定义一个类中的全局变量来保存数据:
Const BufSize = 10240
Dim buf As String * BufSize
buf长度定义为10K,该长度可以根据具体需要来增大或减少。
由于.ini是以文件的形式存在,故可为这个类定义一个变量来保存文件名及其路径:
Public FileName As String
注意:该定义使用了"Public"关键字,说明使用该类时可以读写该变量。另有两个变量是为下面的算法定义的,它们是:
Dim Ret As Long
Dim Start As Long
接下来为该类实现两个最基本的功能函数:
Public Sub SetValue(ByVal clsName As String, ByVal key A s String,
ByValV As String)
Ret=WritePrivateProfileString(clsName, key, V, FileName)
End Sub
Public Function GetValue(ByVal clsName As String, ByVal key
As String) As String
Ret=GetPrivateProfileString(clsName, key, "", buf,
BufSi ze, FileName)
Start = 1
GetValue = RetStr()
End Function
SetValue是根据指定的主题(clsName),增加或修改一条"变量名/ 对应值"对(Key/Va
lue)。这一过程仅仅是调用了相应的API函数,比较容易理解。GetValue函数与其互补,是根据指定的主题和变量名,提取对应的值。该函数除了调用了API函数之外,还调用了该类中的RetS
tr()函数,该函数形式如下:
Private Function RetStr() As String
Dim i As Long
i=InStr(Start, buf, Chr(0))
If i > Start Then
RetStr=Mid(buf, Start, i - Start)
End If
Start = i + 1
End Function
RetStr函数的一个功能是返回一个正确长度的字符串。因为buf 被定义为固定长度,而实际的数据应该小于这一长度,所以要根据C字符串的零结尾符(‘\0’),提取正确长度的字符串,以便为下面的两个函数提供方便。
有时候需要知道在一个主题下,有多少个"变量名/对应值"对,API 函数GetPrivatePr ofileSection就是来实现这一点的,它将指定主题下的所有"变量名/对应值"对一起返回,之间用零(‘0\’)隔开,分解时比较麻烦,但可用下面两个函数来简化这一过程:
Public Function FirstValue(ByVal clsName As String) As S tring
Ret=GetPrivateProfileSection(clsName, buf, BufSize, Fil eName)
Start = 1
FirstValue = RetStr()
End Function
Public Function NextValue() As String
NextValue = RetStr()
End Function
调用FirstValue来提取指定主题的第一个"变量名/对应值"对,形式为:
Key=Value,
然后再调用NextValue提取下一个,直到返回一个零长的字符串为止,表示提取结束。
到此,这个ProFile类就完成了。
应用实例
例1.很多Windows程序,为了和用户拉近距离,往往要保存本次窗口的状态,当下次窗口再打开时,依然是上次关闭时的形状。要做到这一点,用ProFile来完成就非常方便,主要的实现过程就是下面两个函数:
Public Sub SaveWinState(ProF As ProFile, frm As Form, Op tional
ByVal cls Name As String = "Window")
ProF.SetValue clsName, "State", frm.WindowState
ProF.SetValue clsName, "X", frm.Left
ProF.SetValue clsName, "Y", frm.Top
ProF.SetValue clsName, "W", frm.Width
ProF.SetValue clsName, "H", frm.Height
End Sub
Public Sub LoadWinState(ProF As ProFile, frm As Form, Op tional
ByVal cls Name As String = "Window")
On Error GoTo lErr
Dim w As String, h As String
Dim x As String, y As String
Dim State As String
State=GetValue(clsName, "State")
x=ProF.GetValue(clsName, "X")
y=ProF.GetValue(clsName, "Y")
h=ProF.GetValue(clsName, "H")
w=ProF.GetValue(clsName, "W")
If Len(State) > 0 Then
If State="0" Then
frm.Move x, y, w, h
End If
End If
Exit Sub
lErr:
End Sub
在窗口的Form_Unload事件中调用SaveWinState的过程是将窗口的状态信息保存到初始化文件当中,在窗口的Form_Load事件中再调用
LoadWinState过程恢复窗口原来的状态。注意:在LoadWinState过程中有一句On Error GoTo lErr,是因为在这一过程中出现错误的可能性很大,比如用户修改了初始化文件中参数的值等情况,所以对错误进行一下保护是很有必要的。
例2.实现打开文件的历史表。现在一些较有人情味的软件都自动维护一个打开文件的历史记录表,使用户重新打开老文件时有更快捷的途径。用ProFile来完成这件事,也是再合适不过了,尤其利用First
Value和NextValue两个函数来提取指定主题下的所有变量值,操作更加方便。这里就不一一表述,有兴趣的读者可亲自一试。
大众日报社(250100) 王飞