Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do you read and write to an ini file? 3

Status
Not open for further replies.

buckout

MIS
Aug 23, 1998
1
US
I want to write to a couple of ini files that are not standard windows ini files. Thanks in advance.
 
You can use the getprivateprofile... functions in kernel32.dll

i.e. GetPrivateProfileStringW, GetPrivateProfileIntW etc.



Probably even better to use the registry though?
 
Couple of good reasons _not_ to use the registry. One, you stand the chance of corrupting it even though your access calls are perfect (system lockup, crash, etc.) The second is stronger though. If you build an application that is .ini-driven, then you simply modify the .ini file and redistribute it instead of re-compiling the entire app (assuming, of course, some pre-planning here). As an example, my department was recently moved from one LAN server to another, and all group and public shares were repointed to new drive letters. I've about 15 or 20 database apps in use by various groups within my department and by other departments. Since I was using .ini files to point to database locations rather than hard-coding them, all it took was a simple edit of the .ini file to keep the utilities working. Otherwise I'd have had to recompile each program - and that would have been bad, since at least one of them is in v2.0, and I don't have the source anymore!



I also use .ini files to let users of a grouip product set their own color choices so that when they log on, textboxes, labels, lists, etc., are set to their choice instead of the design defaults. (It's amazing the amount of praise that one little bit has generated!)
 
I agree with databarn, INI files are clean and simple. Use the GetPrivateProfile and WritePrivateProfile API calls. You might want to consider creating a ActiveX DLL as a wrapper to these functions, this way you can reuse the routines in future projects and it is portable to other platforms such as Visual Test.
 
Ok, hi all! :)



I am new to this board and have a few questions (like no one else does).



First, let me start off by saying "I am attempting to teach myself VB5" :) I am not looking for praise, just letting everyone know where i am coming from.



Second, i have a program that I would LOVE to have an INI file for, but cannot figure out HOW to set it up. On my form, I have a text box called "Progname" which would be changed by the user. How/where would I code for an INI file to load and save the entry in this textbox? Alos, if someone could give me a sample piece of code, it would be GREATLY appreciated. :)
 
Folk,<br>

<br>

Sorry, thought I posted this last time, but apparently got confused after a system crash (cherry-picker took out a power line &lt;grin!&gt;).<br>

<br>

'Declares for INI read/write<br>

'16-Declare Function GetPPI% Lib "Kernel" Alias "GetPrivateProfileInt" (ByVal lpAppName$, ByVal lpKeyName As Any, ByVal nDefault%, ByVal lpFileName$)<br>

Declare Function GetPPI& Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpAppName$, ByVal lpKeyName As Any, ByVal nDefault&, ByVal lpFileName$)<br>

'16-Declare Function GetPPS% Lib "Kernel" Alias "GetPrivateProfileString" (ByVal lpAppName$, ByVal lpKeyName$, ByVal lpDefault$, ByVal lpReturnedString$, ByVal nSize%, ByVal lpFileName$)<br>

Declare Function GetPPS& Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpAppName$, ByVal lpKeyName$, ByVal lpDefault$, ByVal lpReturnedString$, ByVal nSize&, ByVal lpFileName$)<br>

Declare Function GetKeyNames& Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpAppName$, ByVal lpKeyName As Any, ByVal lpDefault$, ByVal lpReturnedString$, ByVal nSize&, ByVal lpFileName$)<br>

'16-Declare Function WritePPS% Lib "Kernel" Alias "WritePrivateProfileString" (ByVal lpApplicationName$, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName$)<br>

Declare Function WritePPS& Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpAppName$, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName$)<br>

<br>

The above are the declarations that allow reading/writing .ini files, both the 16-bit - commented out - and the 32-bit. As you may note, I've abbreviated the declaration name, but you can see it in the 'Alias' element of each declare.<br>

<br>

If you happen to note duplicate declarations with different names, that will be because of allow use of 0& as a Null value (type declared As Any). Reason for this is that if I declare a Section or a KeyName As Any, I could accidentally delete that Section or KeyName if my code ended up sending a Null. However, if the Section or KeyName is declared As String, a Null entry will simply cause the call to fail. So, the only time I want to delete a Section or KeyName, I use the alternate declaration - no possibility of confusion, as I only use that declare for deletions.

<br>

Now, before I get into usage, since I don't know what the limits are here for a post - must have overlooked it in the how-to - let me say that I have a functioning .ini editor just converted from VB 3.0 to 5.0. I have the Enterprise edition, but I don't think anything is being used that won't run in the lesser versions. I'll have to pull out references to a print-preview unit, since that uses the VSView OCX(s), but otherwise, I'd be more than happy to mail it to you privately. Only problem might be the Common Controls, as I'm using that for a status bar, but that won't be a show stopper.

<br>

OK, now let's look at usage. I normally declare these variable as Global (or Public) in Utiliy.bas, a module of generic routines that I plug into all my applications (user-color routines, MRU file lists, control focus color changes, etc.). The variables are gIniFile$ (the $ sign is a string type declaration character that I got into the habit of using a long time ago - started VB with v.1.0), gSection$ (or gApplication$ in older apps), gKeyName$, and gKey$. <br>

I usually put the .ini file in the application directory, so gIniFile$ can be popoulated using App.Path and .ExeName, adding a '\' as necessary.<br>

gSection$ is the part of the .ini file that shows as [Section] in the actual file. This is the Application or Section to which the folowing KeyName/Key pairs apply.<br>

gKeyName$ is the left side of the '=', and<br>

gKey$ is the right side of the '='.<br>

<br>

For instance,<br>

[Microsoft Word]<br>

Initial = jqp<br>

<br>

might be an entry for some version of Word, and the Initial=jqp pair would hold the initials of the Word user for summary purposes.<br>

<br>

So, gSection$ would be "Microsoft Word" (spaces ok, and Windows adds the '[ . . . ]'),<br>

gKeyName$ would be 'Initial', and<br>

gKey$ would be 'jqp', for John Q. Public. Ok, with me so far?<br>

<br>

Now, to write this data to the .ini file code would be something like this.<br>

<br>

gSection$ = txtSection<br>

gKeyName$ = txtKeyName<br>

gKey$ = txtKey<br>

gIniFile$ = Me.Caption<br>

Debug.Print gSection$, gKeyName$, gKey$, gFilename$<br>

res% = WritePPS(gSection$, gKeyName$, gKey$, gFilename$)<br>

Debug.Print res%<br>

<br>

res% provides the return value which indicates whether the write was successful. Note that if the Section or KeyName do not exist, they will be created, so a successful write does not necessarily mean a successful edit. A type could cause the addition of a new key instead of changing the value of an existing one.<br>

<br>

OK, but what about reading the .ini file?<br>

<br>

This,<br>

Private Sub cboSection_click()<br>

txtSection = cboSection.Text '(cboSection.ListIndex)<br>

lstKeyName.Clear<br>

gSection$ = txtSection<br>

txtKeyName = ""<br>

txtKey = ""<br>

gFilename$ = Me.Caption<br>

Debug.Print "Section Name: " & gSection$, "FileName: " & gFilename$<br>

ReDim GetKeyName$(1000)<br>

Dim res%, ind%<br>

res% = GetAppKeyNames%(gSection$, GetKeyName$(), gFilename$)<br>

ReDim Preserve GetKeyName$(res%)<br>

For ind% = 0 To res%<br>

lstKeyName.AddItem GetKeyName$(ind%)<br>

Next ind%<br>

lstKeyName.ListIndex = 0<br>

End Sub<br>

is a subroutine that readsall the KeyNames in a Section and populates a listbox with them - we've gotten into a special case already! - but that can wait for a bit. What we really want is this next one,<br>

Private Sub lstKeyName_click()<br>

'txtSection = "[" & cboSection.Text & "] " & lstKeyName.Text<br>

txtKeyName = lstKeyName.Text '(lstKeyname.ListIndex)<br>

gFilename$ = Me.Caption<br>

txtKey = GetPKeyString$(txtSection, txtKeyName, "no value", 2048, gFilename$)<br>

End Sub<br>

which reads a discrete KeyName from a Section in the .ini file. The '2048' in GetPKeyString sets a large buffer length. If the buffer is set too small, say 10, a Key value that is greater than 10 characters long will be truncated to 10 characters.<br>

<br>

So, now you need to see the GetPKeyString function.<br>

Function GetPKeyString$(ByVal AppName$, ByVal KeyName$, Default$, Size&, Filename$)<br>

'this function retrieves string from private INI & manages string handling tasks<br>

ReturnString$ = Space$(Size&)<br>

ValidLength& = GetPPS(AppName$, KeyName$, Default$, ReturnString$, Size&, Filename$)<br>

GetPKeyString$ = Left$(ReturnString$, ValidLength&)<br>

End Function<br>

<br>

The GetPPS (GetPrivateProfileString) function returns the length of the string stored in ReturnString$. This allows use of Left$ to get rid of any garbage, such as ASCIIZ or Nulls after the returned text value. Remember, the returned buffer is still as large as it was when you set it, with only the left-most spaces having been replaced by the string value being returned.<br>

<br>

That's a quick-n'-dirty explanation, and may leave much to be desired, but I was afraid of running up against some posting limitation. If clarification is required, post here or e-mail me. Guess we need to see if there is an 'archive' space for such code snippets.<br>

<br>

Make a good day .<br> . .

. . . barn<br>
 
Folk,



I'm *_really_* sorry. Did not realize that my 'formatting', i.e., CRLFs would not hold. Apparently, all text is reformatted to wrap regardless of carriage returns. Oh, well . . .! The offer still stands to provide the code by e-mail if you like. Would really prefer to do here, but doesn't seem feasible.
 
Databarn, I fixed the formatting of your post. Thank you for sharing that code. I will work on this and let you know when we are able to automatically include carriage returns in the posts...Should be some time today.
 
I've fixed the formatting to include carriage returns in the output. Also, we do not currently have a code archive, but you should be able to find snippits like this using the key word search. We intend to make all user posting available through this feature.
 
Umm... ok, thanks for the code snippet. ( i think ).<br>
<br>
In reviewing all that code above, the only thing i can says is "WOW, have i got lots to learn".<br>
<br>
I can understand some of it, but for "my" purpose, i think the code allows for alot more items to be saved/retrieved than i need, i think.<br>
<br>
My E-mail address is Buthy@worldnet.att.net, i only need one field called "progname" to be stored, it is in a textbox. I am hoping that this will be stored and retrieved when the program starts and ends.<br>
<br>
I am not sure if this is concise enough for someone to help my with, but would greatly appreciate someone pointing me in a direction that will allow me to either find what i need to understand what has to happen, or a "quick" piece of code that would do it for me.<br>
<br>
Thanks for your help and patience :)<br>
<br>
Ken Norman
 
To: Ken Norman<br>
<br>
I don't think you need a registry or an Ini file in your problem. I think you are experimenting on how to save your data. If you don't need to save it in a database, then you can try saving it in a textfile. Read on Open, Print, Write commands. I think this is the easiest method.
 
just in case anyone stumbled here through a search (as i did) another useful post may be :^) thread705-25711. [sig]<p> Mark Saunders
 
I'm Glad Tek-Tips keeps such an extensive archive! Well done Tek-Tips!!!

Great explanation by Databurn, and thanks markSaunders for the additional thread link.

Keep up the community work!
 
I'm a bit late to the thread but if you wanted to be a bit fancy - you could try using xml instead of ini - take a look at this faq222-3454
 
Hi friends,
u can read and write by using FSO(FileSystemObject).

-=Start=-

dim fso As FileSystemObject
dim a
Set fso = New FileSystemObject
Set a = fso_OpenTextFile(&quot;c:\sample\file1.ini&quot;, ForReading, False)

'====== &quot;You can give a .txt file also &quot;=====
'== to read from file =====
MsgBox a.ReadLine

' ====to write line into file ======
a.Writeline


-=End=-


a.read(4) :- it reads 4 letters
a.skipline :- skip a line
a.skip(5) :- skip 5 letters


Hope this will help u

bye bye
SAJU
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top