为 了 方 便 用 户 使 用 和 使 系 统 具 有 灵 活 性, 大 多 数 Win-dows 应 用 程 序 将 用 户 所 做 的 选 择 以 及 各 种 变 化 的 系 统 信 息 记 录 在 初 始 化 (INI) 文 件 中。 因 此, 当 系 统 的 环 境 发 生 变 化 时, 可 以 直 接 修 改 INI 文 件, 而 无 需 修 改 程 序。 由 此 可 见, INI 文 件 对 系 统 功 能 是 至 关 重 要 的。 本 文 将 介 绍 采 用 Visual Basic for Windows(下 称 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 部 分 中 声 明 使 用 到 的 Windows API 函 数 :
Declare Function GetprivateprofileString Lib “Ker-nel” (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpRetrm-StringAs String, ByVal cbReturnString As Integer, ByVal Filename As String) As Integer Declare Function GetPrivatePfileInt Lib “Kernel” (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As Integer, ByVal Filename As String) As Integer Declare Funciton WritePrivateprofileString Lib “Kernel” (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpString As String, ByVal lplFileName As String) As Integer Function GetIniS(ByVal SectionName As String, ByVal KeyWord As String, ByValDefString 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 Exit For 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 Function GetIniN(ByVal SectionName As String, ByVal KeyWord As String, ByValDefValue As Ineger) As Integer Dim d As Long, s As String d=DefValue GetIniN=GetPrivate ProfileInt(SectionName, KeyWord, DefValue, ppProfileName()) If d <> DefValue Then s=“” &d d=WritePrivateProfileString(SectionName, KeyWord, s, AppProfileName()) End If End Function Sub SetIniS(ByVal SectionName As String, BtVa KeyWord As String, ByVal ValStr As String) Dim res% res%=WritePrivateprofileString(SectionName, KeyWord, ValStr, AppProfileName()) End Sub 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:Goto ErrorProcessing Else SetIniS“数 据 库”, “职 工”, DatabaseName End If On Error GoTo 0 … …
实 例 2:
为 了 方 便 用 户 操 作, 有 时 需 要 保 存 用 户 界 面 的 某 些 信 息, 例 如 窗 口 的 高 度 和 宽 度 等。 装 载 窗 体 时, 从 INI 文 件 中 读 入 窗 体 高 度 和 宽 度, 卸 载 窗 体 时 将 窗 体 当 前 高 度 和 宽 度 存 入 INI 文 件, 代 码 如 下 :
Sub Form1_Load() … … Forml.Height=GetIniN(“窗 体 1”, “高 度”, 6000) Form1.Width=GetIniN(“窗 体 1”, “高 度”, 4500) End Sub … … Sub Form1_Unload() … … SetIniN“窗 体 1”, “高 度”, Me.Height SetIniN“窗 体 1,” 宽 度 “, Me.Width … … End Sub
|