(代碼為藍色,紅色為背景知識)
呵,第一次在這裡發貼,我這兩天整理了下如何儲存文本框中的資訊,寫出來和大家交流下,也不知道我說得清楚不清楚,(從小到大我國文就不好)。這些資訊都是從網上找來的,并加入了我的一些了解,有不對的地方希望大家可以指出,在後面我付上一個VB程式和 Excel例子,希望對大家有用吧。其它 控件類似,如checkbox,隻要儲存checkbox.value就行了
在程式中經常要用到設定或者其他少量 資料的存盤,以便程式在下一次執行的時候可以使用,比如說儲存本次程式執行時視窗的位置、大小、一些使用者設定的資料,文本框内容等等,在 Dos 下程式設計的時候,我們一般自己産生一個檔案,由自己把這些資料寫到檔案中,然後在下一次執行的時候再讀出來使用。在 Win32 程式設計中當然你也可以這樣幹,但 Windows 已經為我們提供了兩種友善的辦法,那就是使用系統資料庫或者 ini 檔案(Profile)來儲存少量資料,下面講解如何使用 INI 檔案來儲存和讀取内容。假設目前有 Text1、Text2、Text3三個文本框的内容需要儲存,INI檔案名為 ABC.INI。 (預設路徑為c:/Windows)
先來說一下INI檔案,
ini 檔案是文本檔案,中間的資料格式一般為(打開一個INI檔案就可以看到了):
[Section1 Name]
KeyName1=value1
KeyName2=value2
...
[Section2 Name]
KeyName1=value1
KeyName2=value2
ini 檔案可以分為幾個 Section,每個 Section 的名稱用 [] 括起來,在一個 Section 中,可以有很多的 Key,每一個 Key 可以有一個值并占用一行,格式是 Key=value,Win32 對 ini 檔案操作的 api 中,有一部分是對 win.ini 操作的,有一部分是對使用者自定義的 ini 檔案操作的。Win.in 和 system.ini 是Windows的兩個非常重要的初始化檔案,Windows将使用者所作的選擇以及各種變化的系統資訊記錄在這兩個檔案中。System.ini 描述了系統硬體的目前狀态,Win.ini 檔案則包含了Windows 系統運作環境的目前配置。可以用API 函數來對INI檔案進行讀寫,下面根據這個例子來具體講一下吧。
首先建立一個Module,然後,在此Module中聲明 API 函數:
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
這裡是聲明一個公共API函數。
聲明的文法是:
Private Declare Function ...
Private Declare Sub.....
采用Private聲明,則這個API函數隻能被一個窗體内的程式所調用。
如果我們的程式有多個窗體構成,而且我們需要在多個窗體中使用同一個API函數,就需要在子產品中聲明了。
然後采用如下文法聲明:
Public Declare Function....
Public Declare Sub....
Public聲明的含義是把API函數作為一個公共函數或過程,在一個工程中的任何位置(包括所有的窗體和子產品)都能直接調用它。 聲明完畢我們就能在程式中使用此API函數了。
WritePrivateProfileString就是API函數名了,具體用法如下:
WritePrivateProfileString - 将一個 Key 值寫入 ini 檔案的指定 Section 中,它的原形是:
WritePrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名稱的字元串位址
LPCTSTR lpKeyName, // 指向包含 Key 名稱的字元串位址
LPCTSTR lpString // 要寫的字元串位址
LPCTSTR lpFileName // ini 檔案的檔案名
);
如果 ini 中沒有指定的 Section,API 會建立 Section,如果沒有指定的 Key 則建立一個 Key 并寫入資料,如果已經存在,則用字元串代替原來的值。當指定的 ini 也不存在的時候,API 會自動建立一個新的檔案,是以使用 ini 的好處是我們不必為了儲存少量的資料涉及到檔案操作,就連查找檔案是否存在的操作都不必要。
聲明中的Lib 和 Alias 是怎麼回事
一般情況下WIN32API函數總是包含在WINDOWS系統自帶的或是其它公司提供的動态連接配接庫DLL中,而Declare語句中的Lib關鍵字就用來指定DLL(動态連接配接庫)檔案的路徑,這樣VB才能找到這個DLL檔案,然後才能使用其中的API函數。如果我們隻是列出DLL檔案名而不指出其完整的路徑的話,VB會自動到.EXE檔案所在目錄、目前工作目錄、WINDOWS/SYSTEM目錄、WINDOWS目錄下搜尋這個DLL檔案。是以如果所要使用DLL檔案不在上述幾個目錄下的話,我們應該指明其完整路徑。 這裡的kernel32,代表的就是kernel32.dll—處理低級任務(比如記憶體和任務管理)的API
Alias用于指定API函數的别名,如果我們調用的API函數要使用字元串(參數中包含String型)的話,Alias關鍵字是必須的。這是因為在ANSI和Unicode字元集中同一API函數的名稱可能是不一樣的,為了保證不出現聲明錯誤,我們使用Alias關鍵字指出API函數的别名,一般來說在WIN9X平台下我們把API函數名後加一個大寫A作為别名即可。
聲明中的ByVal是作什麼用的
這跟VB的參數傳遞方式有關,在預設情況下VB是通過位址傳遞方式傳遞函數的參數、而有些API函數要求必須采用傳值方式來傳遞函數參數(這兩種參數傳遞方式是不同的,前者傳遞的是一個指針,而後者要求是參數真實的值)。這樣就會發生錯誤,解決的辦法是在API函數參數聲明的前面加上ByVal關鍵字,這樣VB就采用傳值方式傳遞參數了。是以這裡采用ByVal就是說是傳遞的是參數真實值。
使用要點:
在我們實際使用的時候,用的最多的是 GetPrivateProfileString 和 WritePrivateProfileString,但在對自定義 ini 檔案操作的時候要注意的是,如果 lpFileName 指定的檔案沒有路徑的話,Api 會去 Windows 的安裝目錄(預設路徑為c:/Windows)去找而不會在目前目錄找,但是每次用到 ini 函數要擷取目前路徑顯然太麻煩了,這裡有一個變通的辦法,你隻要在 ini 檔案名前面加上 ./ 就可以了,比如說要對本目錄下的 user.ini 操作,那麼檔案名就是 './user.ini' 這樣顯然比較友善。另外,當你要把一個 Key 清除的時候,可以使用把 lpString 指向一個空的字元串然後使用 WritePrivateProfileString。當你要把一個 section 的全部内容清空的時候,也不必把 key 一個個的清除,可以使用把 lpString 指向一個空的字元串然後使用 WritePrivateProfileSection。
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
是以這一段,我想大家根據上面應該也就都知道了,下面給隻給出GetPrivateProfileString的用法:
GetPrivateProfileString - 從 ini 檔案的某個 Section 取得一個 key 的字元串,它的原形是:
GetPrivateProfileString(
LPCTSTR lpAppName, // 指向包含 Section 名稱的字元串位址
LPCTSTR lpKeyName, // 指向包含 Key 名稱的字元串位址
LPCTSTR lpDefault, // 如果 Key 值沒有找到,則傳回預設的字元串的位址
LPTSTR lpReturnedString, // 傳回字元串的即傳回值的位址
DWORD nSize // 緩沖區的長度
LPCTSTR lpFileName // ini 檔案的檔案名
);
為了簡化工作,最好定義好幾個函數,給程式提供更簡單的操作,首先定義一個用于輸入的函數WriteOneString:
Private Function WriteOneString(ByVal Section As String, ByVal Key As String, ByVal value As String) As Boolean
Dim x As Long, buff As String * 128, I As Integer
buff = value + Chr(0)
x = WritePrivateProfileString(Section, Key, buff, ″ABC.INI″)
WriteOneString = x
End Function
可以看出,這個函數有三個參數要傳遞,第一個是Section名稱字元串,第二個是Key名稱字元串,第三個是要儲存内容Value的字元串。然後定義x為長整形,定義buff為可存128個字元的字元串,定義I為整型。給buff指派,為傳來的字元串Value,這裡Chr(0)是換行符号。令x為函數WritePrivateProfileString的傳回值,傳回值為長整型,非零表示成功,零表示失敗。而這個就是函數WriteOneString的傳回值。
然後定義一個用于輸出的函數 ReadOneString :
Private Function ReadOneString(ByVal Section As String, ByVal Key As String) As String
Dim x As Long, buff As String * 128, I As Integer
x = GetPrivateProfileString(Section, Key, ″″, buff, 128, ″ABC.INI″)
I = InStr(buff, Chr(0))
ReadOneString = Trim(Left(buff, I - 1))
End Function
這裡和上面定義的函數類似,隻說一下這裡不同的地方,在GetPrivateProfileString(Section, Key, ″″, buff, 128, ″ABC.INI″)中,buff,是要取得buff的位址,應該就是前面你賦給buff字元串的位址,而InStr(buff,Chr(0))是代表的在buff這個字元串中,得到換行符号的位置,并将其賦與I。ReadOneString = Trim(Left(buff, I - 1))中,Trim(Left(buff, I - 1))其實就是從buff這個字元串最左邊,一直選到換行符号的前一個字元,即要選中要在文本框裡顯示的字元串,而這個字元串,就是函數ReadOneString的傳回值。
InStr([start, ]string1, string2[, compare])
傳回指定一字元串在另一字元串中最先出現的位置。在字元串string1中,從start開始找string2,省略start時從string1頭開始找。找不到時,函數值為0。
Left(string, length)
從字元串左邊選擇長度為length的字元串,string 字元串表達式,其最左邊的字元被傳回。如果 string 參數中包含 Null,則傳回 Null。 length 數值表達式,指明要傳回的字元數目。如果是 0,傳回零長度字元串 ("");如果大于或等于 string 參數中的字元總數,則傳回整個字元串。
這時,你就可以在 Form 的 Load 和 UnLoad 事件裡分别進行儲存和讀取操作。
Private Sub Form_Load()
Text1 = ReadOneString(″Option″,″Text1″)
Text2 = ReadOneString(″Option″,″Text2″)
Text3 = ReadOneString(″Option″,″Text3″)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Text1 = WriteOneString(″Option″,″Text1″,Text1)
Text2 = WriteOneString(″Option″,″Text2″,Text2)
Text3 = WriteOneString(″Option″,″Text3″,Text3)
End Sub http://club.excelhome.net/thread-467428-1-1.html