概述
在程序中經(jīng)常要用到設(shè)置或者其他少量數(shù)據(jù)的存盤(pán),以便程序在下一次執(zhí)行的時(shí)候可以使用,比如說(shuō)保存本次程序執(zhí)行時(shí)窗口的位置、大小、一些用戶(hù)設(shè)置的數(shù)據(jù)等等,在 Dos 下編程的時(shí)候,我們一般自己產(chǎn)生一個(gè)文件,由自己把這些數(shù)據(jù)寫(xiě)到文件中,然后在下一次執(zhí)行的時(shí)候再讀出來(lái)使用。在 Win32 編程中當(dāng)然你也可以這樣干,但 Windows 已經(jīng)為我們提供了兩種方便的辦法,那就是使用注冊(cè)表或者 ini 文件(Profile)來(lái)保存少量數(shù)據(jù)。本文中先介紹一下 .ini 文件的使用。
ini 文件是文本文件,中間的數(shù)據(jù)格式一般為:
[Section1 Name]
KeyName1=value1
KeyName2=value2
...
[Section2 Name]
KeyName1=value1
KeyName2=value2
ini 文件可以分為幾個(gè) Section,每個(gè) Section 的名稱(chēng)用 [] 括起來(lái),在一個(gè) Section 中,可以有很多的 Key,每一個(gè) Key 可以有一個(gè)值并占用一行,格式是 Key=value,Win32 對(duì) ini 文件操作的 api 中,有一部分是對(duì) win.ini 操作的,有一部分是對(duì)用戶(hù)自定義的 ini 文件操作的。Win.in 和 system.ini 是Windows的兩個(gè)非常重要的初始化文件,Windows將用戶(hù)所作的選擇以及各種變化的系統(tǒng)信息記錄在這兩個(gè)文件中。System.ini 描述了系統(tǒng)硬件的當(dāng)前狀態(tài),Win.ini 文件則包含了Windows 系統(tǒng)運(yùn)行環(huán)境的當(dāng)前配置。由于 Win.ini 文件的重要性和常用性,Win32 中有專(zhuān)門(mén)對(duì) Win.ini 進(jìn)行操作的 api,它們是:
GetProfileInt - 從 Win.ini 文件的某個(gè) Section 取得一個(gè) key 的整數(shù)值,它的原形是:
GetProfileInt(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名稱(chēng)的字符串地址
INT nDefault // 如果 Key 值沒(méi)有找到,則返回缺省的值是多少
);
如果 Key 值沒(méi)有找到的話(huà),返回值是 nDefault 指定的缺省值,如果 Key 中的值是負(fù)數(shù),則返回 0,如果 Key 指定的是數(shù)字和字符串的混合,則返回?cái)?shù)字部分的值,比如說(shuō) x=1234abcd,則返回 1234
GetProfileString - 從 Win.ini 文件的某個(gè) Section 取得一個(gè) key 的字符串,它的原形是:
GetProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名稱(chēng)的字符串地址
LPCTSTR lpDefault, // 如果 Key 值沒(méi)有找到,則返回缺省的字符串的地址
LPTSTR lpReturnedString, // 返回字符串的緩沖區(qū)地址
DWORD nSize // 緩沖區(qū)的長(zhǎng)度
);
返回的字符串在緩沖區(qū)內(nèi),返回的 eax 值是返回的字符串的長(zhǎng)度(不包括尾部的0)
GetProfileSection - 從 Win.ini 文件中讀出整個(gè) Section 的內(nèi)容,它的原形是:
GetProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPTSTR lpReturnedString, // 返回?cái)?shù)據(jù)的緩沖區(qū)地址
DWORD nSize // 返回?cái)?shù)據(jù)的緩沖區(qū)長(zhǎng)度
);
WriteProfileSection - 將一個(gè)整個(gè) Section 的值 寫(xiě)入 Win.ini 文件的指定 Section 中,它的原形是:
WriteProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpString // 要寫(xiě)入的數(shù)據(jù)的地址
);
如果 Win.ini 沒(méi)有指定的 Section,API 會(huì)新建立一個(gè)并寫(xiě)入數(shù)據(jù),如果已經(jīng)存在,則先刪除原來(lái) Seciton 中所有的 Key 值然后寫(xiě)入新的。
WriteProfileString - 將一個(gè) Key 值寫(xiě)入 Win.ini 文件的指定 Section 中,它的原形是:
WriteProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名稱(chēng)的字符串地址
LPCTSTR lpString // 要寫(xiě)的字符串地址
);
如果 Win.ini 沒(méi)有指定的 Section,API 會(huì)新建 Section,如果沒(méi)有指定的 Key 則新建一個(gè) Key 并寫(xiě)入數(shù)據(jù),如果已經(jīng)存在,則用字符串代替原來(lái)的值。
以上的 Api 是對(duì) Win.ini 操作的,當(dāng)然對(duì)于我們來(lái)說(shuō),用的更多的是在程序運(yùn)行的目錄中建立自己的 ini 文件,如果需要對(duì)自己的 ini 文件操作,就要用到另一組 Api,這一組 api 和上面的很象,只要把上面一組的 Profile 換成 PrivateProfile(私有的)就可以了,參數(shù)中也相應(yīng)的多了一個(gè) ini 文件名的參數(shù)。例如 GetPrivateProfileInt、GetPrivateProfileSection、WritePrivateProfileString 等等, 下面分別介紹:
GetPrivateProfileInt - 從 ini 文件的某個(gè) Section 取得一個(gè) key 的整數(shù)值,它的原形是:
GetPrivateProfileInt(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名稱(chēng)的字符串地址
INT nDefault // 如果 Key 值沒(méi)有找到,則返回缺省的值是多少
LPCTSTR lpFileName // ini 文件的文件名
);
中間參數(shù)和返回值的定義和 GetProfileInt 是一樣的。
GetPrivateProfileString - 從 ini 文件的某個(gè) Section 取得一個(gè) key 的字符串,它的原形是:
GetPrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名稱(chēng)的字符串地址
LPCTSTR lpDefault, // 如果 Key 值沒(méi)有找到,則返回缺省的字符串的地址
LPTSTR lpReturnedString, // 返回字符串的緩沖區(qū)地址
DWORD nSize // 緩沖區(qū)的長(zhǎng)度
LPCTSTR lpFileName // ini 文件的文件名
);
GetPrivateProfileSection - 從 ini 文件中讀出整個(gè) Section 的內(nèi)容,它的原形是:
GetPrivateProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPTSTR lpReturnedString, // 返回?cái)?shù)據(jù)的緩沖區(qū)地址
DWORD nSize // 返回?cái)?shù)據(jù)的緩沖區(qū)長(zhǎng)度
LPCTSTR lpFileName // ini 文件的文件名
);
這個(gè) api 可以讀出整個(gè) section 的內(nèi)容,當(dāng)你不知道 section 中有哪些 key 的時(shí)候,可以使用這個(gè) api 將整個(gè) section 讀出后再處理。
GetPrivateProfileSectionNames - 從 ini 文件中獲得 Section 的名稱(chēng),它的原形是:
GetPrivateProfileSectionNames(
LPTSTR lpszReturnBuffer, // 返回?cái)?shù)據(jù)的緩沖區(qū)地址
DWORD nSize // 返回?cái)?shù)據(jù)的緩沖區(qū)長(zhǎng)度
LPCTSTR lpFileName // ini 文件的文件名
);
如果 ini 中有兩個(gè) Section: [sec1] 和 [sec2],則返回的是 'sec1',0,'sec2',0,0 ,當(dāng)你不知道 ini 中有哪些 section 的時(shí)候可以用這個(gè) api 來(lái)獲取名稱(chēng)
WritePrivateProfileSection - 將一個(gè)整個(gè) Section 的內(nèi)容入 ini 文件的指定 Section 中,它的原形是:
WritePrivateProfileSection(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpString // 要寫(xiě)入的數(shù)據(jù)的地址
LPCTSTR lpFileName // ini 文件的文件名
);
WritePrivateProfileString - 將一個(gè) Key 值寫(xiě)入 ini 文件的指定 Section 中,它的原形是:
WritePrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名稱(chēng)的字符串地址
LPCTSTR lpKeyName, // 指向包含 Key 名稱(chēng)的字符串地址
LPCTSTR lpString // 要寫(xiě)的字符串地址
LPCTSTR lpFileName // ini 文件的文件名
);
如果 ini 中沒(méi)有指定的 Section,API 會(huì)新建 Section,如果沒(méi)有指定的 Key 則新建一個(gè) Key 并寫(xiě)入數(shù)據(jù),如果已經(jīng)存在,則用字符串代替原來(lái)的值。當(dāng)指定的 ini 也不存在的時(shí)候,API 會(huì)自動(dòng)建立一個(gè)新的文件,所以使用 ini 的好處是我們不必為了保存少量的數(shù)據(jù)涉及到文件操作,就連查找文件是否存在的操作都不必要。
使用要點(diǎn):
在我們實(shí)際使用的時(shí)候,用的最多的是 GetPrivateProfileString 和 WritePrivateProfileString,但在對(duì)自定義 ini 文件操作的時(shí)候要注意的是,如果 lpFileName 指定的文件沒(méi)有路徑的話(huà),Api 會(huì)去 Windows 的安裝目錄去找而不會(huì)在當(dāng)前目錄找,但是每次用到 ini 函數(shù)要獲取當(dāng)前路徑顯然太麻煩了,這里有一個(gè)變通的辦法,你只要在 ini 文件名前面加上 .\ 就可以了,比如說(shuō)要對(duì)本目錄下的 user.ini 操作,那么文件名就是 '.\user.ini' 這樣顯然比較方便。另外,當(dāng)你要把一個(gè) Key 清除的時(shí)候,可以使用把 lpString 指向一個(gè)空的字符串然后使用 WritePrivateProfileString。當(dāng)你要把一個(gè) section 的全部?jī)?nèi)容清空的時(shí)候,也不必把 key 一個(gè)個(gè)的清除,可以使用把 lpString 指向一個(gè)空的字符串然后使用 WritePrivateProfileSection。