LB Booster
Programming >> Liberty BASIC language >> struct type ptr
http://lbb.conforums.com/index.cgi?board=lblang&action=display&num=1447933632

struct type ptr
Post by joker on Nov 19th, 2015, 10:47am

It is frustrating to read the "examples" in the LB Encyclopedia for things like "struct". The authors, in the case of "struct" seem to always avoid examples of how to use "ptr". There are examples on how to WRITE, but I can't seem to find an example where the author didn't avoid a GET example.

I've tried different ways to write to an INI and then read back from the INI without success. The "number" parts of "STRUCT" work fine, but I can't see how to recover the "PTR" part of "STRUCT".

EDIT: Perhaps nothing is wrong other than my thinking. It is saving a "PTR" to the string. I guess I was mis-thinking about saving/recovering a string value. :(

For instance :D :

Code:
'code by Richard Russell
'struct config, soundon as long, fullscreen as long 
'config.soundon.struct = 1 
'config.fullscreen.struct = 0 
struct config, soundon$ as ptr, fullscreen as long
SoundOn$ = "sound is on" 
config.soundon$.struct = SoundOn$
config.fullscreen.struct = 4

' locate the ini file
'print DefaultDir$   'no trailing backslash
'print StartupDir$   'has trailing backslash
if right$(DefaultDir$,1)<>"\" then
    DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"

print inifile$
print "Initial values: [soundon$ = ";config.soundon$.struct;"]  [fullscreen = ";config.fullscreen.struct;"]"
 
size = len(config.struct) 
calldll #kernel32, "WritePrivateProfileStructA", _ 
"settings" as ptr, _  ' Section name 
"config" as ptr, _    ' Key name 
config as struct, _   ' Structure 
size as ulong, _      ' Size of structure 
inifile$ as ptr, ret as long
print "ret from write: ";ret
SoundOn$ = ""
FullScreen = 0

'code by Richard Russell
size = len(config.struct) 
calldll #kernel32, "GetPrivateProfileStructA", _ 
"settings" as ptr, _  ' Section name 
"config" as ptr, _    ' Key name 
config as struct, _   ' Structure 
size as ulong, _      ' Size of structure 
inifile$ as ptr, ret as long
print "ret from get: ";ret

'  To retrieve the information from the struct:
'
'SoundOn$ = config.soundon$.struct  
FullScreen = config.fullscreen.struct
print "SoundOn$: ";SoundOn$
print "FullScreen: ";FullScreen
 


Richard! Help! :D
Re: struct type ptr
Post by AAW on Nov 19th, 2015, 11:04am

on Nov 19th, 2015, 10:47am, pnlawrence wrote:
It is frustrating to read the "examples" in the LB Encyclopedia for things like "struct". The authors, in the case of "struct" seem to always avoid examples of how to use "ptr". There are examples on how to WRITE, but I can't seem to find an example where the author didn't avoid a GET example.


Richard! Help! cheesy


http://lbpe.wikispaces.com/ABCs+of+APIs+10

http://lbpe.wikispaces.com/ABCs+of+APIs+10


Re: struct type ptr
Post by tsh73 on Nov 19th, 2015, 11:09am

Search on LB forum (for "inifile") returns this:
Anyone having issues with GetPrivateProfileString?

Re: struct type ptr
Post by Richard Russell on Nov 19th, 2015, 11:09am

on Nov 19th, 2015, 10:47am, pnlawrence wrote:
The "number" parts of "STRUCT" work fine, but I can't see how to recover the "PTR" part of "STRUCT".

I think you're misunderstanding what the PTR type is. It's an abbreviation for 'pointer', and what it means is that the struct contains a pointer to the string, not the string itself! So when you save the structure in an INI file and later read it back, the pointer is no doubt intact but the string it originally pointed to is no longer there!

What you need in your application is not the PTR type at all but the CHAR type. With the CHAR type the string really is stored in the structure, so it can be safely saved to, and read back from, an INI file (this code is compatible with both LB and LBB):

Code:
struct config, soundon$ as char[12], fullscreen as long
SoundOn$ = "sound is on" 
config.soundon$.struct = SoundOn$
config.fullscreen.struct = 4

' locate the ini file
'print DefaultDir$   'no trailing backslash
'print StartupDir$   'has trailing backslash
if right$(DefaultDir$,1)<>"\" then
    DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"

print inifile$
print "Initial values: [soundon$ = ";config.soundon$.struct;"]  [fullscreen = ";config.fullscreen.struct;"]"
 
size = len(config.struct) 
calldll #kernel32, "WritePrivateProfileStructA", _ 
"settings" as ptr, _  ' Section name 
"config" as ptr, _    ' Key name 
config as struct, _   ' Structure 
size as ulong, _      ' Size of structure 
inifile$ as ptr, ret as long
print "ret from write: ";ret
SoundOn$ = ""
FullScreen = 0

size = len(config.struct) 
calldll #kernel32, "GetPrivateProfileStructA", _ 
"settings" as ptr, _  ' Section name 
"config" as ptr, _    ' Key name 
config as struct, _   ' Structure 
size as ulong, _      ' Size of structure 
inifile$ as ptr, ret as long
print "ret from get: ";ret

'  To retrieve the information from the struct:
'
SoundOn$ = config.soundon$.struct  
FullScreen = config.fullscreen.struct
print "SoundOn$: ";SoundOn$
print "FullScreen: ";FullScreen 

I don't think Alyce's reference to winstring() is very relevant here, because the problem is not how to access the string in memory but that the string no longer is in memory (of course in the case of your test program it will be, but not in general when you are reading the INI file in a different session).

You could use Anatoly's suggestion of WritePrivateProfileString and GetPrivateProfileString, but it's a much more complicated modification. Changing PTR to CHAR[12] (in this case) is all you need to do. Make sure you allow enough space for the longest string you want to store, so (e.g.) CHAR[20] might be safer.

Richard.

Re: struct type ptr
Post by AAW on Nov 19th, 2015, 12:20pm

on Nov 19th, 2015, 11:09am, Richard Russell wrote:
I don't think Alyce's reference to winstring() is very relevant here,
Richard.


Nor was it meant to be.I did not even look at his code. I was addressing only the part of the message I quoted, in which pnlawrence said, "always avoid examples of how to use "ptr". There are examples on how to WRITE, but I can't seem to find an example where the author didn't avoid a GET example. "

Re: struct type ptr
Post by joker on Nov 19th, 2015, 12:54pm

Two references to the same page! (I wish I had moderator privileges here so I could delete one of those references, because it is obviously frivolous. tongue )

Neither one of them has to do with an INI file, either.

on Nov 19th, 2015, 11:04am, AAW wrote:
http://lbpe.wikispaces.com/ABCs+of+APIs+10

http://lbpe.wikispaces.com/ABCs+of+APIs+10


Re: struct type ptr
Post by joker on Nov 19th, 2015, 12:56pm

Thanks, Richard. I did finally clear up with PTR (see my EDIT), but now I see a way to do the INI file. I just wanted a bit of obscurity in my INI file to help a user resist changes.

EDIT: I know why I didn't try CHAR[], here's what the LB help file lists as types:

Code:
Using types with STRUCT and CALLDLL

The STRUCT statement requires that each field be typed to specify what type of data it will contain. The CALLDLL statement also requires that each parameter passed be typed. The types are common to both STRUCT and CALLDLL. Simple data TYPES in Windows programming are often renamed versions of the types below. A program should specify the TYPE according to the chart below.

TYPES

  double(a double floating point)
  ulong(4 bytes, unsigned long integer)
  long(4 bytes, signed long integer)
  short(2 bytes, signed short integer)
  ushort, word(2 bytes, unsigned short integer)
  ptr(4 bytes, long pointer, for passing strings)
  struct(4 bytes, long pointer, for passing structs)
  void, none(a return type only, used when a function doesn't return a value)
  boolean(true/false expression)

 

Re: struct type ptr
Post by joker on Nov 19th, 2015, 1:15pm

Well, changing PTR to CHAR[12] didn't change much.

I also tried adding CHR$(0) to the end of the string without change.

Here's what's in the INI file:

Quote:
[settings]
config=736F756E64206973206F6E000400000026


I must have screwed up something different. cheesy
Re: struct type ptr
Post by AAW on Nov 19th, 2015, 1:21pm

on Nov 19th, 2015, 12:54pm, pnlawrence wrote:
Two references to the same page! (I wish I had moderator privileges here so I could delete one of those references, because it is obviously frivolous. tongue )

Neither one of them has to do with an INI file, either.



I apologize for duplicating the link. I hope it didn't cause too much confusion.

Did you read the post directly above yours? I responded to Richard.

Quote:
I did not even look at his code. I was addressing only the part of the message I quoted, in which pnlawrence said, "always avoid examples of how to use "ptr". There are examples on how to WRITE, but I can't seem to find an example where the author didn't avoid a GET example. "

Re: struct type ptr
Post by joker on Nov 19th, 2015, 1:27pm

Aww, come on AAW. I'm just messing with you. cheesy

I'm from Texas. We have a saying here, "If you mess with the bull, don't be surprised if you get the horns!" cheesy
Re: struct type ptr
Post by joker on Nov 19th, 2015, 1:28pm

I finally figured out that I had remarked-out the line where I assigned the string the value from the struct.

Works just fine now.

Thanks!

EDIT: Wow! I didn't realize the string would be tokenized in the INI file. That's even better.
EDIT2: Arrg! I forgot that my string was all lower case ASCII. Still it "looks" tokenized. :D
Code:
[settings]
config=736F756E64206973206F6E000000000000000000000000000000000000000400000026
 

Re: struct type ptr
Post by Richard Russell on Nov 19th, 2015, 2:02pm

on Nov 19th, 2015, 1:15pm, pnlawrence wrote:
Well, changing PTR to CHAR[12] didn't change much.

It does, it fixes the problem completely. I also explained in detail why the version with PTR cannot work, and why the version with CHAR does work. I listed the modified program in my post, and I tested it both in LB and LBB, and it works perfectly.

I must say I am disappointed that you should think I would take so little care as to post something which doesn't work.

Richard.

Re: struct type ptr
Post by joker on Nov 19th, 2015, 2:08pm

Chill out, Richard and read ALL of my posts. embarassed
Re: struct type ptr
Post by Richard Russell on Nov 19th, 2015, 2:39pm

on Nov 19th, 2015, 2:08pm, pnlawrence wrote:
I know why I didn't try CHAR[], here's what the LB help file lists as types

It is certainly extremely strange that CHAR isn't mentioned at all in the LB Help file (as far as I have been able to find), and stranger still that it wasn't added in the recently updated LB 4.5.0 docs. It isn't some minor 'feature' or subtlety that would benefit from being clarified, but an essential language element without which many Windows API functions couldn't readily be used.

I hope the explanation isn't that Carl knows it to be unreliable. There is one issue that I am aware of (fixed in LBB) which is that CHAR[1] is effectively unusable in LB 4.04 and 4.5.0. This code works in LBB but not in LB:

Code:
    struct test, c$ as char[1]
    test.c$.struct = "a"
    print test.c$.struct 

The reason for the failure in LB is that strings stored in a CHAR member are assumed to be NUL-terminated, and if there's space for only a single character there is no room for the termination.

LBB treats this as a special case. If the member is declared as CHAR[2] or larger then a NUL-termination is included just the same as with LB, so CHAR[12] will hold at most an 11-character string. But with CHAR[1] no NUL-termination is added, ensuring that a single-byte structure member can be used successfully.

Richard.

Re: struct type ptr
Post by joker on Nov 19th, 2015, 4:17pm

Mr. Gundel needs to hire me to be his "bumbling around and finding problems" guru. cheesy

Along with describing my problematic experience with installing LB, this discovery of the missing "CHAR[i]" type makes two bumbles.

I'd have to charge way too much per bumble to make it a commercial endeavor, though. cheesy
Re: struct type ptr
Post by Richard Russell on Nov 19th, 2015, 4:51pm

on Nov 19th, 2015, 4:17pm, pnlawrence wrote:
Mr. Gundel needs to hire me to be his "bumbling around and finding problems" guru. cheesy

Although you probably don't want a serious answer to a frivolous post, there's little evidence that Carl cares. angry

In 'updating' LB from 4.04 to 4.5.0 he has failed to address the majority of bugs recorded at the Liberty BASIC Bug Tracker Wiki. I would have expected him to go through that list and either fix every bug or explain why he is unable or unwilling to do so. I am prepared to accept that some bugs may be considered insufficiently important to warrant the time and effort it would take to fix them, and even that some are impractical to fix because of limitations in his tools, but we should be told that.

Instead, major bugs (like TIMER being unable to use a SUB handler) remain unfixed in LB 4.5.0 with no explanation.

Richard.
Re: struct type ptr
Post by joker on Nov 19th, 2015, 5:19pm

After trying to compile the previous code in LB, the compiler error message related that CHAR[12] is an illegal type.

Not a type and not even a reserved word.
Re: struct type ptr
Post by joker on Nov 19th, 2015, 5:26pm

I would like to do something like this:

Code:
function WriteINIStruct1(SectionName$,KeyName$,KeyChars$,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    size = len(KeyChars$) * 2 + 1
    struct structName, keychars$ as CHAR[size]
    structName.keychars$.struct = KeyChars$
    size = len(structName.struct) 
    calldll #kernel32, "WritePrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    WriteINIStruct = ret
end function
 


However, LBB seems to choke on this with a "struct not defined error". Either I can't define the struct within the function or it doesn't like the variable within the CHAR[ statement. I can't tell which.
Re: struct type ptr
Post by Richard Russell on Nov 19th, 2015, 5:42pm

on Nov 19th, 2015, 5:19pm, pnlawrence wrote:
After trying to compile the previous code in LB, the compiler error message related that CHAR[12] is an illegal type.

I don't get an error message from either LB 4.04 or LB 4.5.0 with the code I listed. Are you definitely using exactly the code I listed in my earlier post?

Quote:
I would like to do something like this:
Code:
struct structName, keychars$ as CHAR[size] 

You can't. LB and LBB must know the size of the STRUCT at compile time, so you can't specify something like CHAR[size] because then the size is known only at run time. This is quite normal in other languages too.

You should specify whatever the maximum required size is, so if your string has a maximum length of 255 characters specify CHAR[256] (including the terminating NUL).

Richard.

Re: struct type ptr
Post by joker on Nov 19th, 2015, 6:39pm

I probably had the CHAR[size] code in the first trial. I know where to go now.
Re: struct type ptr
Post by joker on Nov 21st, 2015, 12:43am

I can make this code operate, but I can't make the "Get" work as a FUNCTION by returning the value. I had to pass a variable BYREF. It works, but wasn't my goal.

I speculate that since I am passing the STRUCT name that the FUNCTION is working on a copy of STRUCT. Interesting.

Any ideas on returning the STRUCT value with a FUNCTION?

Also, I found out that CHAR[10] really only stores a string of 9 characters. I guess the rest is overhead? I don't understand why specifying [10] in the code doesn't save 10.

OUTPUT LOOKS LIKE THE FOLLOWING:

Code:
[settings]
config=30313233343536373839000D 


Code:
if right$(DefaultDir$,1)<>"\" then
    DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"

print inifile$

struct structName, keychars$ as CHAR[11] ' if CHAR[10] you can only write 9 characters

ret = WriteINIStruct1("settings","config","0123456789",structName,inifile$)
print "ret from write: ";ret

'structName.keychars$.struct = ""
'print "test struct clear: "+structName.keychars$.struct

ret = GetINIStruct1("settings","config",GetKeyChars$,structName,inifile$)
print "ret from get: ";ret
print "Got this: ->"+GetKeyChars$+"<- (from GetINIStruct1)"

end

function WriteINIStruct1(SectionName$,KeyName$,KeyChars$,structName,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    structName.keychars$.struct = KeyChars$
    size = len(structName.struct) 
    calldll #kernel32, "WritePrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    WriteINIStruct1 = ret
end function

function GetINIStruct1(SectionName$,KeyName$,byref GetKeyChars$,structName,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    size = len(structName.struct) 
    calldll #kernel32, "GetPrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    GetKeyChars$ = structName.keychars$.struct
    'GetINIStruct1 = structName.keychars$.struct ' this won't work. "Type mismatch" error.
    GetINIStruct1 = ret
end function
 

Re: struct type ptr
Post by Richard Russell on Nov 21st, 2015, 03:35am

on Nov 21st, 2015, 12:43am, pnlawrence wrote:
I can't make the "Get" work as a FUNCTION by returning the value.

I wonder if the problem is as simple as forgetting that a function which returns a string must itself have a name ending in a dollar. So for example the function might be called GetINIStruct1$().

Quote:
I speculate that since I am passing the STRUCT name that the FUNCTION is working on a copy of STRUCT.

STRUCTs in Liberty BASIC are always global. You cannot pass a struct as a parameter to a SUB or FUNCTION. Is that what you were hoping to be able to do?

Quote:
I don't understand why specifying [10] in the code doesn't save 10.

You berated me the other day for not reading all of your messages, now you're not reading all of mine! I wrote: "strings stored in a CHAR member are assumed to be NUL-terminated ... so CHAR[12] will hold at most an 11-character string."

Richard.

Re: struct type ptr
Post by tsh73 on Nov 21st, 2015, 03:57am

Quote:
Also, I found out that CHAR[10] really only stores a string of 9 characters. I guess the rest is overhead? I don't understand why specifying [10] in the code doesn't save 10.


ABS of API#5 says
Quote:
The GetWindowTextA function also requires an argument that specifies the length of the string buffer. We can get the length with the LEN() function, like this:

length=len(Caption$) + 1

We add 1 to the length argument because Liberty BASIC adds a null termination character to strings passed into API calls.


Also, wikipedia::Null-terminated string
Re: struct type ptr
Post by joker on Nov 21st, 2015, 08:51am

Ok, ok. At least I only make simple mistakes. rolleyes

The old "$" specification problem. The error message was telling me, but I wasn't listening.

I thought I tried struct as GLOBAL but ... Oh well, I have an eye doctor appointment coming up. embarassed

The last character at the end of the OUTPUT (in Notepad) looks like a "D" I haven't looked at it with anything else. I was thinking how did a CR get there?

PS. Richard, I don't "berate". I just gently "chide." cheesy
Re: struct type ptr
Post by joker on Nov 21st, 2015, 09:15am

I remember now.

tsh73 posted (on that "other" forum) that the API puts a CHECKSUM on the end.

The last 2 bytes are the checksum. (The least significant byte of the sum of all the ASCII values.)
Re: struct type ptr
Post by joker on Nov 21st, 2015, 09:39am

I found out that CHAR[32766] is the largest that works with the API (or is it a limit of CHAR[]?) That's plenty of room for INI stuff. I suppose there's a problem with running out of something while the program is running if the STRUCT gets too large.

Its a little clunky, because the name of the STRUCT is coded into the FUNCTION, but I envision several specific FUNCTIONs with several specific STRUCTs writing to the same INI file.

Maybe obfuscation isn't so clunky after all? :D

Code:
if right$(DefaultDir$,1)<>"\" then
    DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"

print inifile$

struct structName, keychars$ as CHAR[32766] ' fails when CHAR[32766] is exceeded

ret = WriteINIStruct1("settings","config","0123456789:",inifile$)
print "ret from write: ";ret

print "Got this: ->"+GetINIStruct1$("settings","config",inifile$)+"<- (from GetINIStruct1$)"

end

function WriteINIStruct1(SectionName$,KeyName$,KeyChars$,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    structName.keychars$.struct = KeyChars$
    size = len(structName.struct) 
    calldll #kernel32, "WritePrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    WriteINIStruct1 = ret
end function

function GetINIStruct1$(SectionName$,KeyName$,inifile$)
    ' Returns string value if nothing wrong or NULL if a problem
    'code by Richard Russell
    size = len(structName.struct) 
    calldll #kernel32, "GetPrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    if ret = 0 then GetINIStruct1$ = "" : exit function
    GetINIStruct1$ = structName.keychars$.struct
end function
 

Re: struct type ptr
Post by Richard Russell on Nov 21st, 2015, 10:00am

on Nov 21st, 2015, 09:39am, pnlawrence wrote:
I found out that CHAR[32766] is the largest that works with the API (or is it a limit of CHAR[]?)

I'm really not sure what you are trying to achieve. If you are storing a single string, especially if it is quite a long string, using a STRUCT isn't a particularly appropriate method. For example it stores more than twice as much data in the INI file as it needs to (each character of the string gets expanded to two hex characters).

If your objective is to obfuscate the string, storing it as hex will defeat only the most simplistic attempts at reading it. Many people will immediately recognise hex text, and either be able to read it 'by inspection' or simply copy-and-paste it into their favourite hex editor.

A trivial encryption technique, like XOR-ing each character of the string with a pseudo-random key, would be much more effective and not waste space in the file. STRUCTs wouldn't be involved at all.

Richard.

Re: struct type ptr
Post by joker on Nov 21st, 2015, 10:46am

Not concerned with file size. "Many people" are not part of my target audience. Some folks just think its fun to poke around and see what they can do.

Also, I like it that the "fields" of the STRUCT are not delineated in the file.

Of course one wouldn't write a 32K section to an INI file, but that is a tested limit.

I used the word "obfuscation" instead of "encryption" for a reason. Not even trying to hide it in plain site.

If the STRUCT(s) look like the following, then I think the INI file data would be obscured well with little programming effort. And there's the checksum, although that's not much of a deterrent, to contend with if one just changes a character.

Code:
STRUCT startup, keychars$ as CHAR[12], numUsers as long, posX as ulong, posY as ulong, mainDataFilename$ as CHAR[32], thumbDrivePresent as boolean, screenSizeHeight as ulong, screenSizeWidth as ulong

STRUCT currentUser, userName$ as CHAR[12], userDescription$ as CHAR[257]
 


Write these in separate sections of an INI file, and Bob's your uncle. (Bob is your uncle, isn't he? :D )



Re: struct type ptr
Post by joker on Nov 22nd, 2015, 12:21am

Posted the following to the other forum, too.

My version using FUNCTIONS. (Thanks to R.R. and tsh73 for debugging.)

Code:
'===========================================
' WritePrivateProfileStructA Demo
'===========================================
' Acknowledgements to the original authors
' Submitted by pnlawrence 11/21/2015

' This is only one example on how to perform INI file Section writing with a STRUCT. 
'   Of course, the STRUCT(s) can be rewritten and the FUNCTION(s) 
'   can be slightly rewritten to return almost any INI file data.

if right$(DefaultDir$,1)<>"\" then
    DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"

print inifile$

' STRUCT can be created however required with many different types included
'   nothing in the resulting INI file section delineates the different parts of the STRUCT
'   the resulting INI file section also includes a checksum to detect changes
'   the resulting INI file section is more than double the original total length of the values written
'       because each input character string/value is written as double-digit ASCII + nul termination + checksum
'   the STRUCT is GLOBAL

struct structName, keychars$ as CHAR[12] ' fails when CHAR[32766] is exceeded

print "Return from write: "; WriteINIStruct("settings","config","0123456789:",inifile$)

print "Return from get: ->"+GetINIStruct$("settings","config",inifile$)+"<-"

end

'===========================================
'   FUNCTIONS
'===========================================

function WriteINIStruct(SectionName$,KeyName$,KeyChars$,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    structName.keychars$.struct = KeyChars$
    size = len(structName.struct) 
    calldll #kernel32, "WritePrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    WriteINIStruct = ret
end function

function GetINIStruct$(SectionName$,KeyName$,inifile$)
    ' Returns string value if nothing wrong or NULL if a problem
    'code by Richard Russell
    size = len(structName.struct) 
    calldll #kernel32, "GetPrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    structName as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    if ret = 0 then GetINIStruct$ = "" : exit function
    GetINIStruct$ = structName.keychars$.struct
end function
 
 

Re: struct type ptr
Post by Richard Russell on Nov 22nd, 2015, 8:03pm

on Nov 22nd, 2015, 12:21am, pnlawrence wrote:
Posted the following to the other forum

I trust you explained, in 'the other place', why you are using a STRUCT to store a string. I wouldn't want anybody to be misled into thinking it was preferable to using WritePrivateProfileString / GetPrivateProfileString (in normal circumstances).

Richard.

Re: struct type ptr
Post by joker on Nov 23rd, 2015, 12:16am

They wouldn't listen anyway. They think I'm being difficult. I'll probably get banned, too. cheesy
Re: struct type ptr
Post by AAW on Nov 23rd, 2015, 10:33am

on Nov 23rd, 2015, 12:16am, pnlawrence wrote:
They wouldn't listen anyway. They think I'm being difficult. I'll probably get banned, too. cheesy


When you wrote, "Apparently, you think I'm being difficult." I responded, "I reread my messages and I do not see anything that implies that I think you are being difficult. I am trying to be helpful."

In order to help you, I updated articles on LBPE. Anatoly created a new, in-depth demo for you, and Rod and I made suggestions of other ways you could accomplish your goal. I suggested a simple Rot13 encryption to obfuscate your text in WritePrivateProfileString.

I can find no place AT ALL where anybody indicates that you are being difficult, that we don't listen to you, and certainly not that you are about to be banned. I am completely confused. We've all tried to be polite and helpful.

I am sorry were were unable to help you do exactly as you wanted, but we tried.

Re: struct type ptr
Post by SarmedNafi on Nov 23rd, 2015, 10:49am

Quote:
Anatoly created a new, in-depth demo for you



A link please Dear Madam, I will appreciate that.

Regards
Sarmed
Re: struct type ptr
Post by SarmedNafi on Nov 23rd, 2015, 10:54am

Dear pnlawrence,

I have a question if you please.
What is the benefits of using API for creating an initial file (.ini)?
Why not using a normal sequential file? as I always did?

Regards
Sarmed
Re: struct type ptr
Post by joker on Nov 23rd, 2015, 11:10am

Hey, Alyce, it was a joke. grin We're free to joke around on this forum.

Hey, Alyce, how come you can freely post on this forum for Liberty Basic Booster AKA LBB, about things that happen on the LB forum but it is "against the rules" for ANYONE to do the reverse? I'm just curious.

Wouldn't it be nice if Richard could comment on topics of interest to LBB on the LB forum? It is kind of difficult with the current arrangement.

I'm sure that Richard could have had several helpful suggestions with recent posts, but I don't think he's on the list of members with posting privileges. (Actually, he did comment, but he had to do it on this forum only. Remember that? I admit to copying text from LB to LBB forum, so there's your opportunity with the broken rule.)

I've read all the tiring posts about "promoting" etc., but I fail to see the difference between "promoting" Liberty Basic Booster and "promoting" languages like "Visual Basic" or "C" or "C++" or "Pascal" or etc. I'm purty sure those are OK to write about on that forum.

Can you explain how "promoting" those other languages are OK on the LB forum, but no one can even obliquely mention Liberty Basic Booster? (You surreptitiously deleted a forum post of mine because I obliquely mentioned Liberty Basic Booster.)

I'm just curious.

PS. Feel free to comment here, because I'm hoping to clear the air and get these BASIC programs back into a cooperative state instead of stuck in 2006.
Re: struct type ptr
Post by joker on Nov 23rd, 2015, 11:12am

Another tool in the toolbox. You can do both within the same file, too.

on Nov 23rd, 2015, 10:54am, SarmedNafi wrote:
What is the benefits of using API for creating an initial file (.ini)? Why not using a normal sequential file? as I always did?

Re: struct type ptr
Post by Richard Russell on Nov 23rd, 2015, 11:17am

on Nov 23rd, 2015, 12:16am, pnlawrence wrote:
They wouldn't listen anyway. They think I'm being difficult. I'll probably get banned, too. cheesy

Hmm, sounds like things are getting worse over there, if anything. I wonder if it stems from disappointment with LB 4.5.0; many people must have been hoping for a more comprehensive update, with many more bugs being fixed.

Has Carl released LB Pro 4.5 yet? I think it was a very unwise decision to delay it because LB Pro users represent some of his most loyal and enthusiastic customers. In his position I wouldn't have released any update until both regular and Pro versions were ready.

Richard.

Re: struct type ptr
Post by Richard Russell on Nov 23rd, 2015, 11:33am

on Nov 23rd, 2015, 10:54am, SarmedNafi wrote:
What is the benefits of using API for creating an initial file (.ini)?
Richard.

Re: struct type ptr
Post by tsh73 on Nov 23rd, 2015, 11:44am

SarmedNafi

>>A link please Dear Madam, I will appreciate that.

WritePrivateProfileStructA Demo

Re: struct type ptr
Post by Richard Russell on Nov 23rd, 2015, 11:59am

on Nov 23rd, 2015, 11:10am, pnlawrence wrote:
I'm sure that Richard could have had several helpful suggestions with recent posts, but I don't think he's on the list of members with posting privileges.

I'm not even allowed to read the LB Forum, let alone post there; I can't even see what guests, who have never joined, are allowed to see. angry

There was a time, in the distant past, when I was allowed to be a member of, and even post to, the LB Forum. I contributed a number of posts which I like to think were valuable, for example demonstrating how COM Objects could be called from LB, something which had previously been believed to be impossible without a helper DLL.

But I made the mistake of using the Private Messaging system for exactly what the rules (at the time) encouraged its use for - i.e. communicating with other members about 'sensitive' subjects not permitted in posted messages (in this case telling them about LBB when they had posted a query that LBB provided a solution for).

Apparently some recipients of those messages complained to the forum administrators about them (why they would complain about being given an answer to their queries I don't know). I wasn't told about those complaints (at the time), I was never asked not to send messages of that sort, there was never any direct communication with me at all. I was simply banned.

Richard.

Re: struct type ptr
Post by SarmedNafi on Nov 23rd, 2015, 12:06pm




Alyce, Richard, Anatoly, and Pnlawrence, thank you very much.

All the best,
Sarmed

Re: struct type ptr
Post by joker on Nov 23rd, 2015, 1:18pm

on Nov 23rd, 2015, 12:06pm, SarmedNafi wrote:
Alyce, Richard, Anatoly, and Pnlawrence, thank you very much.


Sarmed, my FUNCTION example only shows about saving a string, and as Richard says, string saving is so inefficient ... more than 2 to 1 inefficient. So, as Richard neatly posted above, there are so many other and better reasons to use this method. I am probably going to combine both API methods, because I have several types of variables in my project's INI file.
Re: struct type ptr
Post by SarmedNafi on Nov 24th, 2015, 01:53am

Yes Paul,

Thank you for the hint.
Hope I wrote a correct name.

Sarmed
Re: struct type ptr
Post by SarmedNafi on Nov 24th, 2015, 02:20am

Quote:
I'm not even allowed to read the LB Forum, let alone post there; I can't even see what guests, who have never joined, are allowed to see.


I wonder, If we suppose that one day say Anatoly used Russian language and wrote some Booster or simulator for Liberty Basic.
Is he going to be banned?
Why Richard banned? Is that because Richards TIMER was not broken, or work better than Carls TIMER?
I Just wonder?
Richard fond of LB syntax which created by Carl.
Is he make a crime because of that?
We still all of us purchase licence for LB as necessary. Richard and his booster don't prevent us from that.
Whey then??
Re: struct type ptr
Post by Richard Russell on Nov 24th, 2015, 08:30am

on Nov 24th, 2015, 02:20am, SarmedNafi wrote:
We still all of us purchase licence for LB as necessary. Richard and his booster don't prevent us from that.

There seems to be an assumption in some quarters that the existence of LBB necessarily operates against Carl's interests, for example by taking away paying customers. But that isn't always the case; I know of people who have stuck with Liberty BASIC - and therefore continue to promote and support it - solely because of LBB. If LBB had not existed they would have abandoned the language altogether because of its bugs and limitations.

Richard.

Re: struct type ptr
Post by joker on Nov 24th, 2015, 4:32pm

The following are the two functions that I ended up working with. They don't just return one key.

Your mileage may vary! :D

Code:
function WriteINIStruct(SectionName$,KeyName$,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    size = len(theStruct.struct) 
    calldll #kernel32, "WritePrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    theStruct as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    WriteINItheStruct = ret
end function

function GetINIStruct(SectionName$,KeyName$,inifile$)
    ' Returns true (1) if nothing wrong or false (0) if a problem
    'code by Richard Russell
    size = len(theStruct.struct) 
    calldll #kernel32, "GetPrivateProfileStructA", _ 
    SectionName$ as ptr, _  ' Section name 
    KeyName$ as ptr, _    ' Key name 
    theStruct as struct, _   ' Structure 
    size as ulong, _      ' Size of structure 
    inifile$ as ptr, ret as long
    GetINIStruct = ret
end function