June 16, 2024, 01:00:47 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


GetPrivateProfileString

Started by LarryMc, December 04, 2010, 09:02:41 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

I know that if I specify the key name as a null when using the command that all key names in the section will be returned to the buffer.  Each key name will be followed by a null and the last keyname will followed by an extra null.

What I don't know is the most efficient way to parse the buffer to extract each of the keynames.

Anyone got any ideas?

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

DennisL

December 04, 2010, 09:17:56 PM #1 Last Edit: December 04, 2010, 09:22:58 PM by DennisL
Hi Larry,

I may be barking up the wrong tree here (or about to state something obvious, but which doesn't apply to you), but from how you describe the structure of the returned buffer, this sounds remarkably like just a normal array of C strings.

Wouldn't the most efficient way to retrieve the key names be to just to assign the return value of the function to be such a string array, and then you'd just have each key name in each array index space?

This all assumes you're using C or C++; Not sure what language you're actually using to develop in...

Feel free to tell me I'm completely off my tree  :D  Cheers, DennisL

LarryMc

Duh, this is the IWBasic forum ;D
I  couldn't resist that.

The API function returns all the strings into a buffer as I described.

If I make my buffer a STRING variable then only one keyname would appear (the 1st) because when IWB hits the NULL character that is the end of the string.
If I make a string array in IWB each element is 255 characters so I don't think the API is going to match up.
If the keynames were separated by something else like a "|" then it would be a breeze.
If the keynameswere all the same length (they're not) I could probably use an ISTRING array of the correct length and it might work.

When Sapero gets around to it he'll whip out some simple code to do it that will make me feel like a dummy; which is pretty much becoming the norm for me. ;)

LarryMc

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

DennisL

Yep, I knew it would be something like that  :-[

Well, until Sapero come up with the correct answer, here's another idea that you may want to look at (I haven't tested this out so it probably won't work as I expect).

save the returned buffer to a ISTRING variable.
loop through this variable and extract out each STRING using the MID$ function with the start index being 0 in the first instance, and then as the length + 1 of the previous extracted STRING (as you said earlier IWB would think it's the end of each string when it encounters the NULL character).
keep looping through extracting STRINGs until you get the empty string (which means you've extracted out all of them).

sapero

Here is an example EnumPrivateProfileStrings function, it takes ini file path, and optionally section name, returns a list with section names, or key names (from the specified section):

$define WIN32_LEAN_AND_MEAN ' speedup
$include "windowssdk.inc"

' enumerate sections
pointer list = EnumPrivateProfileStrings("ODBCINST.INI")
if (list)
pointer pos = ListGetFirst(list)
while (pos)
pointer pData = ListGetData(pos)
print "[",*<string>pData,"]"
pos = ListGetNext(pos)
endwhile
ListRemoveAll(list)
print "--------"
endif

' enumerate keys in a section
list = EnumPrivateProfileStrings("ODBCINST.INI", "Microsoft Text Driver (*.txt; *.csv) (32 Bit)")
if (list)
pos = ListGetFirst(list)
while (pos)
pData = ListGetData(pos)
print "\t",*<string>pData
pos = ListGetNext(pos)
endwhile
ListRemoveAll(list)
print "--------"
endif



sub EnumPrivateProfileStrings(string iniPath, opt pointer pszSectionName=0),pointer
pointer list = 0
pointer memo = new(char,65536)

if (memo)
if (GetPrivateProfileString(pszSectionName, NULL, NULL, memo, 65536, iniPath))
pointer pos = memo

while (*<char>pos)
int cch = len(*<string>pos)
' create the list only when we need it
if (!list) then list = ListCreate()
' add *<string>pos to the list
if (list)
pointer pData = new(char,cch+1)
if (pData)
*<string>pData = *<string>pos
ListAdd(list, pData)
endif
endif
' jump to the next string
pos = *<byte>pos[cch+1]
wend
endif
delete memo
endif
return list
endsub

LarryMc

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library