|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic File Routines WritePrivateProfileString: INI Files - The Basics |
||
Posted: | Friday August 13, 1999 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6, and VB3, VB4-16 with appropriate declarations | |
Developed with: | VB6, Windows NT4 | |
OS restrictions: | None | |
Author: | VBnet - Randy Birch | |
Related: |
WritePrivateProfileString: INI Files - Saving Entire Sections | |
Prerequisites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
None. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
All
VB programmers need to persist application settings and data between sessions. Prior to Windows 95 the most popular ways were to save the
data as a VB Type, or to write the data out line by line to a text file. The magic of the Windows 3x INI files eluded most until the
Get/WriteProfileString and Get/WritePrivateProfileString APIs were discovered.
Since releasing Windows 95, Microsoft has switched tactics and has consistently encouraged developers to save their application-persistent data to the registry. To make that even easier to adopt, they provided the VB Get/SaveSetting methods. But as the registry grows larger, and systems fail because of poorly-designed apps, the question being asked has become "Is the registry always the right place to store data?" Even MS says no; while they encourage application designers to use the registry for small data sets (i.e. window position, recent files), they agree that larger application-specific data should not be stored there (i.e. list content). While the registry via API continues to offer more flexibility in the type of data that can be saved, the INI file still has its place in the developer's arsenal, especially as users - and especially developers - grow increasingly concerned over an application's interference with the system registry, a critical and at times sensitive (aka temperamental) part of the operating system. It is actually becoming common place for users to refuse to use software from third-parties that directly write to the registry. And the INI file continues to hold the top place as the mechanism of choice with developers sincerely concerned with their users wishes and their systems. Windows actually provides a number of "Profile" APIs available to the developer:
References to "user.ini" indicate that the API is for use with application-specific files. The file can have any name, but it remains the custom is to name it the same as the application to facilitate easier locating should it need editing or removal. And historically, in Win3x days, Microsoft had encouraged saving application-specific ini files in the system's Windows directory. Common practice nowadays is to use the application's folder. Despite the number of possible APIs available, most applications get away with using only two - GetPrivateProfileString and WritePrivateProfileString. Regardless, all the APIs share a commonality in the declaration of the APIs and the method of passing/receiving data using any given one. This demo starts out by covering the basics - using GetPrivateProfileString and WritePrivateProfileString to read/write data to a private ini file. And long with saving and reading, we'll also cover deleting specific items as well as entire sections. In VBnet fashion, there is more commenting than code; you'll be pleasantly surprised how little code is really necessary to add this functionality to your apps. Subsequent demos will build on the same BAS module, providing enhanced functionality. And while there now exists APIs to handle entire sections at a time (something introduced with Win9x), as a learning process those will be skipped in favour of using just the same two APIs to do everything we need. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BAS Module Code | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
None. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Form Code | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
On a form, add four command buttons (Command1 through Command4), and four text boxes (Text1 through Text4). Labels are optional; the code will title the buttons. Add the following code to the form: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private sIniFile As String Private Declare Function GetPrivateProfileString _ Lib "kernel32" Alias "GetPrivateProfileStringA" _ (ByVal lpSectionName As String, _ ByVal lpKeyName As Any, _ ByVal lpDefault As String, _ ByVal lpbuffurnedString As String, _ ByVal nBuffSize As Long, _ ByVal lpFileName As String) As Long Private Declare Function WritePrivateProfileString _ Lib "kernel32" Alias "WritePrivateProfileStringA" _ (ByVal lpSectionName As String, _ ByVal lpKeyName As Any, _ ByVal lpString As Any, _ ByVal lpFileName As String) As Long Private Sub Form_Load() 'setup Text1.Text = "VBnet Demo" Text2.Text = "URL1" Text3.Text = "http://vbnet.mvps.org/" 'Text4 is used only to display the 'contents of the raw file. Editing 'the contents of this text box will 'have no effect on the demo and will. 'Ensure Text4 is set to Multiline. Text4.Text = "" With Command1 .Caption = "Save Key and Value under Section" .Width = 2700 End With With Command2 .Caption = "Save Value of Key under Section" .Width = 2700 End With With Command3 .Caption = "Delete Key and Value from INI" .Width = 2700 End With With Command4 .Caption = "Delete Entire Section from INI" .Width = 2700 End With 'this will be our test file sIniFile = App.Path & "\test.ini" 'show the file contents (empty at first) Call LoadIniFile End Sub Private Sub Command1_Click() 'save the the value entered under 'the key in the specified section Dim sSection As String Dim sKeyName As String Dim sValue As String sSection = Text1.Text sKeyName = Text2.Text sValue = Text3.Text Call ProfileSaveItem(sSection, sKeyName, sValue, sIniFile) 'refresh the raw file contents LoadIniFile End Sub Private Sub Command2_Click() 'load the value of the specified key 'located in sSection Dim sSection As String Dim sKeyName As String Dim sResult As String sSection = Text1.Text sKeyName = Text2.Text Text3.Text = "" sResult = ProfileGetItem(sSection, _ sKeyName, _ "oops...data not in file!", _ sIniFile) Text3.Text = sResult LoadIniFile End Sub Private Sub Command3_Click() 'delete the specified key (and its value) 'from the specified section Dim sSection As String Dim sKeyName As String sSection = Text1.Text sKeyName = Text2.Text Call ProfileDeleteItem(sSection, sKeyName, sIniFile) LoadIniFile End Sub Private Sub Command4_Click() 'delete the entire section specified Dim sSection As String sSection = Text1.Text Call ProfileDeleteSection(sSection, sIniFile) LoadIniFile End Sub Private Function ProfileGetItem(sSection As String, _ sKeyName As String, _ sDefValue As String, _ sIniFile As String) As String 'retrieves a value from an ini file 'corresponding to the section and 'key name passed. Dim dwSize As Long Dim nBuffSize As Long Dim buff As String 'Call the API with the parameters passed. 'nBuffSize is the length of the string 'in buff, including the terminating null. 'If a default value was passed, and the 'section or key name are not in the file, 'that value is returned. If no default 'value was passed (""), then dwSize 'will = 0 if not found. ' 'pad a string large enough to hold the data buff = Space$(2048) nBuffSize = Len(buff) dwSize = GetPrivateProfileString(sSection, _ sKeyName, _ sDefValue, _ buff, _ nBuffSize, _ sIniFile) If dwSize > 0 Then ProfileGetItem = Left$(buff, dwSize) End If End Function Private Sub ProfileSaveItem(sSection As String, _ sKeyName As String, _ sValue As String, _ sIniFile As String) 'This function saves the passed value to the file, 'under the section and key name specified. ' 'If the ini file does not exist, it is created. 'If the section does not exist, it is created within the file. 'If the key name does not exist, it is created under the section. 'If the key name exists, it's value is replaced. Call WritePrivateProfileString(sSection, sKeyName, sValue, sIniFile) End Sub Private Sub ProfileDeleteItem(sSection As String, sKeyName As String, sIniFile As String) 'this call will remove the keyname and its 'corresponding value from the section sepcified 'in sSection. This is accomplished by passing 'vbNullString as the sValue parameter. For example, 'assuming that an ini file had: ' [Colours] ' Colour1=Red ' Colour2=Blue ' Colour3=Green ' 'and this sub was called passing "Colour2" 'as sKeyName, the resulting ini file 'would contain: ' [Colours] ' Colour1=Red ' Colour3=Green Call WritePrivateProfileString(sSection, _ sKeyName, _ vbNullString, _ sIniFile) End Sub Private Sub ProfileDeleteSection(sSection As String, sIniFile As String) 'this call will remove the entire section 'corresponding to sSection in the file. 'This is accomplished by passing 'vbNullString as both the sKeyName and 'sValue parameters. For example, assuming 'that an ini file had: ' [Colours] ' Colour1=Red ' Colour2=Blue ' Colour3=Green ' 'and this sub was called passing "Colours" 'as sSection, the entire Colours 'section and all keys and values in 'the section would be deleted. Call WritePrivateProfileString(sSection, _ vbNullString, _ vbNullString, _ sIniFile) End Sub Private Sub LoadIniFile() Dim hFile As Integer On Local Error Resume Next 'obtain the next free file handle hFile = FreeFile 'load the file Open sIniFile For Input As #hFile Text4.Text = Input$(LOF(hFile), hFile) Close #hFile End Sub |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comments | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
The form code is pretty self-explanatory. Each command button retrieves the data from the required textbox, and writes or reads as needed. After each call, Text4 is refilled with the current file contents. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |