http://hi.baidu.com/vcknow/blog/item/b23313d59b263bc450da4b74.html 2007-02-27 17:01
1 基 礎(chǔ)知識(shí)INI文件 (Initialization file ,又稱(chēng)為初始化文件)是用來(lái)保存應(yīng)用程序設(shè)置和選項(xiàng)的一種特殊的ASCII文件,以“.ini”作為文件擴(kuò)展 名,也被稱(chēng)做配置文件或概要文件(Profile)。除了各個(gè)應(yīng)用程序可以擁有自己私有的初始化文件外,Windows系統(tǒng)還提供有一個(gè)系統(tǒng)的初始化文件 Win.ini,并由此對(duì)當(dāng)前的Windows系統(tǒng)進(jìn)行配置,同時(shí)也可以在其內(nèi)記錄系統(tǒng)內(nèi)其他應(yīng)用程序在運(yùn)行時(shí)的選項(xiàng)。 通常為應(yīng)用程序所私有的初始化文件比較小,這樣可以減少程序在初始化 時(shí)所讀取的信息量,從而提高程序的啟動(dòng)速度。而系統(tǒng)初始化文件Win.ini由于除了記錄有關(guān)系統(tǒng)的大量信息外,還存儲(chǔ)著許多其他應(yīng)用軟件的 初始化數(shù)據(jù),因此其通常比較龐大,訪問(wèn)的數(shù)據(jù)量要遠(yuǎn)比私有的配置文件大得多。如沒(méi)有必要,一般不建議對(duì)Win.ini文件進(jìn)行操作,但如果待存取的信息涉 及到Windows系統(tǒng)環(huán)境或是其他應(yīng)用程序時(shí), 就必須對(duì)Win.ini進(jìn)行讀寫(xiě)訪問(wèn),并在訪問(wèn)的同時(shí)發(fā)送WM_WININICHANGE消息給所有的 頂層窗口,通知其他進(jìn)程系統(tǒng)初始化文件已被更改。 配置文件里的信息之所以能為系統(tǒng)和眾多不同類(lèi)型的應(yīng)用程序讀取并識(shí) 別,是由于其內(nèi)部對(duì)數(shù)據(jù)的存取采用了預(yù)先約定的“項(xiàng)-值對(duì)(Entry-value pairs)”存儲(chǔ)結(jié)構(gòu), 并對(duì)待存取的數(shù)據(jù)分門(mén)別類(lèi)地 進(jìn)行存儲(chǔ)。下面是系統(tǒng)目錄下Win.ini文件的部分內(nèi)容: [windows] load= run= NullPort=None [Desktop] WallpaperStyle=2 Pattern=(無(wú))
在此,配置文件將信息分為若干“節(jié)”,節(jié)標(biāo)題放在方括號(hào)中,如“[Desktop]” 就是Desktop節(jié),在每一個(gè)節(jié)中包含了一些與之相關(guān)的“項(xiàng)”,并通過(guò)等號(hào)對(duì)其進(jìn)行賦值。一般形式如下: [SECTION] ENTRY=VALUE
在初始化文件中,VALUE值只能有兩種數(shù)據(jù)類(lèi)型:數(shù)值 和字符串。Windows分別為這兩種數(shù)據(jù)類(lèi)型提供了兩套API函數(shù)對(duì)初始化文件進(jìn)行數(shù)據(jù)讀取,在寫(xiě)入初始化文件時(shí)則只支持對(duì)字符串的寫(xiě)入,數(shù)值等類(lèi)型必 須先進(jìn)行數(shù)據(jù)類(lèi)型的轉(zhuǎn)換,然后才能寫(xiě)入到初始化文件。私有初始化文件的訪問(wèn) 對(duì)私有初始化文件的數(shù)據(jù)存取是由 GetPrivateProfileInt()、GetPrivateProfileString()和 WritePrivateProfileString()等三個(gè)API函數(shù)來(lái)完成的。其函數(shù)說(shuō)明如下: UINT GetPrivateProfileInt(LPCTSTR lpAppName, // 節(jié) 名地址 LPCTSTR lpKeyName, // 項(xiàng) 名地址 INT nDefault, // 在 項(xiàng)名沒(méi)有找到時(shí)返回的缺省值 LPCTSTR lpFileName // 初 始化文件名地址 ); DWORD GetPrivateProfileString(LPCTSTR lpAppName, // 節(jié) 名地址 LPCTSTR lpKeyName, // 項(xiàng) 名地址 LPCTSTR lpDefault, // 缺 省字符串 LPTSTR lpReturnedString, // 存 放字符串的緩沖區(qū)地址 DWORD nSize, // 緩 沖區(qū)大小 LPCTSTR lpFileName // 初 始化文件名地址 ); BOOL WritePrivateProfileString(LPCTSTR lpAppName, // 節(jié) 名地址 LPCTSTR lpKeyName, // 項(xiàng) 名地址 LPCTSTR lpString, // 要 寫(xiě)入的字符串地址 LPCTSTR lpFileName // 初 始化文件名地址 );
其中,GetPrivateProfileInt()返 回的是初始化文件lpFileName中l(wèi)pAppName節(jié)內(nèi)lpKeyName項(xiàng)的整數(shù)值,如果沒(méi)有找到該項(xiàng)則返回缺省值nDefault。如果此項(xiàng) 目存在,但值不為整數(shù),則返回0。如果某項(xiàng)目的值中含有非數(shù)字字符則只返回第一個(gè)非數(shù)字前的字符,例如對(duì)于“Value = 21century”則只返 回?cái)?shù)值21。初始化文件名lpFileName可以是全路徑也可以只是文件名,如果不指定具體路徑,Windows系統(tǒng)將在系統(tǒng)目錄對(duì)文件進(jìn)行尋找。 GetPrivateProfileString()和WritePrivateProfileString()的用法基本與之類(lèi)似,只是處理對(duì)象的數(shù)據(jù) 類(lèi)型不同。 2 知識(shí)應(yīng)用私有初始化文件主要用來(lái)保存同應(yīng)用程序當(dāng)前狀態(tài)相關(guān)的一些信息,當(dāng)程 序退出后,這些信息由于已寫(xiě)入到初始化文件而得以保留,當(dāng)程序再次運(yùn)行時(shí),可以通過(guò)對(duì)此初始化文件各項(xiàng)數(shù)據(jù)的讀取而得知此應(yīng)用程序在上次運(yùn)行期間的相關(guān)信 息。下面這段代碼即通過(guò)對(duì)私有初始化文件的訪問(wèn)而對(duì)程序的運(yùn)行次數(shù)和上一次的運(yùn)行日期進(jìn)行記錄: CString sPath,sMsg,sTime,sDate; char buffer[255]; // 獲 取當(dāng)前應(yīng)用程序全路徑 GetModuleFileName(NULL, buffer, MAX_PATH); sPath = CString(buffer); sPath = sPath.Left(sPath.ReverseFind('\\')); // 得 到初始化文件的全路徑 sPath += "\\Sample04.ini"; // 得 到程序累計(jì)運(yùn)行次數(shù) UINT Time = GetPrivateProfileInt("PROGRAM", "RUNTIME", 0, sPath); // 得 到上次運(yùn)行日期 GetPrivateProfileString("DATE", "LAST", "2002-11-1", buffer, 1000, sPath); // 顯 示從初始化文件獲取到的文件信息 sMsg.Format("本 軟件共運(yùn)行過(guò)%d次,上次運(yùn)行日期為%s", Time, CString(buffer)); AfxMessageBox(sMsg); // 累 加運(yùn)行次數(shù),并保存到 初始化文件 Time++; sTime.Format("%d", Time); WritePrivateProfileString("PROGRAM", "RUNTIME", sTime, sPath); // 獲 取當(dāng)前日期,并保存到 初始化文件 CTime tm = CTime::GetCurrentTime(); sDate.Format("%d-%d-%d", tm.GetYear(), tm.GetMonth(), tm.GetDay()); WritePrivateProfileString("DATE", "LAST", sDate, sPath);
在程序執(zhí)行后,初始化文件Sample04.ini的內(nèi) 容為: [DATE] LAST =2002-11-12 [PROGRAM] RUNTIME =1
系統(tǒng)目錄下的Win.ini是一種特殊的初始化文件,主 要為系統(tǒng)提供初始化服務(wù),在系統(tǒng)啟動(dòng)時(shí)將被系統(tǒng)所訪問(wèn),并根據(jù)其所保存的參數(shù)值對(duì)系統(tǒng)進(jìn)行配置。Windows專(zhuān)門(mén)提供了三個(gè)API函數(shù) GetProfileInt()、GetProfileString()和WriteProfileString()對(duì)Win.ini進(jìn)行讀寫(xiě)訪問(wèn),其函 數(shù)用法同訪問(wèn)私有初始化文件的那幾個(gè)函數(shù)非常類(lèi)似,只是不必再去指定初始化文件名。下面是這三個(gè)函數(shù)的原型聲明: UINT GetProfileInt(LPCTSTR lpAppName, // 節(jié) 名地址 LPCTSTR lpKeyName, // 項(xiàng) 名地址 INT nDefault // 在 項(xiàng)名沒(méi)有找到時(shí)返回的缺省值 ); DWORD GetProfileString(LPCTSTR lpAppName, // 節(jié) 名地址 LPCTSTR lpKeyName, // 項(xiàng) 名地址 LPCTSTR lpDefault, // 缺 省字符串地址 LPTSTR lpReturnedString, // 存 放字符串的緩存的地址 DWORD nSize // 緩 存的大小 ); BOOL WriteProfileString(LPCTSTR lpAppName, // 節(jié) 名地址 LPCTSTR lpKeyName, // 項(xiàng) 名地址 LPCTSTR lpString // 要 寫(xiě)入字符串的地址 );
只要對(duì)前面對(duì)私有初始化文件進(jìn)行訪問(wèn)的代碼稍加改動(dòng)即可將程序的配置 信息添加到Win.ini中,改動(dòng)后的代碼如下: CString sPath,sMsg,sTime,sDate; // 得 到程序累計(jì)運(yùn)行次數(shù) UINT Time = GetProfileInt("PROGRAM", "RUNTIME", 0); // 得 到上次運(yùn)行日期 GetProfileString("DATE", "LAST", "2002-11-1", buffer, 1000); // 顯 示從初始化文件獲取到的文件信息 sMsg.Format("本 軟件共運(yùn)行過(guò)%d次,上次運(yùn)行日期為%s", Time, CString(buffer)); AfxMessageBox(sMsg); // 累 加運(yùn)行次數(shù),并保存到 初始化文件 Time++; sTime.Format("%d", Time); WriteProfileString("PROGRAM", "RUNTIME", sTime); // 獲 取當(dāng)前日期,并保存到 初始化文件 CTime tm = CTime::GetCurrentTime(); sDate.Format("%d-%d-%d", tm.GetYear(), tm.GetMonth(), tm.GetDay()); WriteProfileString("DATE", "LAST", sDate);
由于Win.ini文件是系統(tǒng)初始化文件,在程序沒(méi)有運(yùn) 行前文件內(nèi)不含“DATE”和“PROGRAM”等自定義的節(jié)以及其下各項(xiàng),因此在程序第一次執(zhí)行后,將由WriteProfileString()函數(shù) 向Win.ini文件末尾創(chuàng)建相關(guān)節(jié)、項(xiàng),并完成數(shù)據(jù)的寫(xiě)入。 (#) |
|