29 January 2012

Gfa_Setting() returns extra #0

Gfa_Setting is available as a statement and as a function. They are used as follows:

' Set/Create a subkey
Gfa_Setting("MySubKey") = mysetting$
' Get subkey value ($)
mysetting$ = Gfa_Setting("MySubKey")
' Delete a subkey
Gfa_Setting("MySubKey") = ""

The Gfa_Setting(subkey$) reads a value from the subkey under HKEY_CURRENT_USER\Software\GFA\Basic using the RegQueryValueEx() API function that retrieves the data for a specified value name associated with an open registry key. The advantage of using this API is that it doesn't require a data type. Even better, the function returns a code indicating the type of data stored in the specified value. The possible type codes are:

Const REG_NONE  = 0
Const REG_SZ  = 1
Const REG_EXPAND_SZ  = 2
Const REG_BINARY  = 3
Const REG_DWORD  = 4
Const REG_DWORD_LITTLE_ENDIAN  = 4
Const REG_DWORD_BIG_ENDIAN  = 5
Const REG_LINK  = 6
Const REG_MULTI_SZ  = 7
etc..

After invoking RegQueryValueEx GB32 checks the value in the type parameter and than decides how to copy the data to the GB32 variable used in the var$ = Gfa_Setting(subkey$) code. When the type value returned is REG_SZ or REG_EXPAND_SZ or REG_BINARY then GB32 uses the StrPeek(addr, size) function to create and copy the data to the string. The size of the data is also returned by RegQueryValueEx. Simple enough. But there is a catch that is overlooked:

"If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, then the data will also include the size of the terminating null character or characters."

GB32 uses the size value to invoke StrPeek and stores the terminating #0 character inside the string and sets the length of the string to the size of data + 1 for the #0 character. GB32 uses the same function for Gfa_BinSetting() and does not care for the value of the size.

Now, when you apply a string concatenation (str & str2) the second string doesn't seem to be appended to the first string. The including #0 character in the last position of the string makes the use of string functions awkward. When you pass that string to a function that expects a C-string the string data is read to the first #0 character. Internally, and externally on the API level, many functions expect a C-string and stop processing the string at first occurrence of a #0 character.  

For now, you best use ZTrim() on the return value of Gfa_Setting(). It seems not to predict how many #0 characters will be included. See underlined words in the quotation.

' Get subkey string value
mysetting$ = ZTrim(Gfa_Setting("MySubKey"))

No comments:

Post a Comment