Jump to content
The simFlight Network Forums

VB6 - Correct method for working with strings in FSUIPC


Recommended Posts

Posted

Here's a short bit of stand-alone code that illustrates the correct method of reading string data from FSUIPC.

Public Function GetAircraftTitle(ByRef AircraftTitle as String) as Boolean
     Dim dwResult As Long
     Dim workArray(256) As Byte
     Dim idx As Integer
     If FSUIPC_Read(&H3D00, 256, VarPtr(workArray(1)), dwResult) Then
         If FSUIPC_Process(dwResult) Then
             idx = 1
             While workArray(idx) <> 0
                 AircraftTitle = AircraftTitle & Chr(workArray(idx))
                 idx = idx + 1
             Wend
             GetAircraftTitle = true
         Else
             AircraftTitle = "Err:FSUIPC_Process(): " & ResultText(dwResult)
             GetAircraftTitle = false
         End If
     Else
         AircraftTitle = "Err:FSUICP_Read(): " & ResultText(dwResult)
         GetAircraftTitle = false
     End If
End Sub

This simple function will return the name of the currently selected aircraft.

To use it:

Dim ACTitle as string
if GetAircraftTitle(ACTitle) then
   ' do whatever with the result passed back in ACTitle
else
   '* display/process the error message based back in ACTitle
end if

Strings in VB are stored internally as UNICODE or "double-byte" strings. This means that you can't use them to interchange data with code that either doesn't support UNICODE or relies solely on single-byte character arrays for strings. In the case of FSUIPC, strings are treated as simple arrays of 8 bit bytes that are terminated with a literal 0. (think CHR(0))

The FSUIPC_Read() call requests 256 bytes of data starting at the hex offset 0x3D00 - it places the result of that read at the address pointed to (VarPtr()) by the first element of workingArray. (Note that by default, VB6 counts array elements from 1, not 0 as do most other languages. If you want to start from 0, make sure you've got "OPTION BASE 0" at the top of your source file or in the global project configuration.) Always make sure that you never request more data than the destination can hold. You run the risk of crashing your program or making it do really, really strange things. (This is known as a "buffer overflow" and is a Bad Thing)

The aircraft name is then built by iterating through the byte array until we hit a NULL character - as noted above, the NULL indicates the end of a string.

By making the AircraftTitle parameter "ByRef", it allows an additional path to return data to the calling routine - the ByRef keyword tells the compiler to pass a reference to the variable (its address) instead of the value itself (ByVal). The result of this is that when the calling parameter is modified in the function, the "original" is modified.

This code should work in VB.Net as well - just change the instances of "GetAircraftTitle =" to "Return".

g.

Posted

In the case of FSUIPC, strings are treated as simple arrays of 8 bit bytes that are terminated with a literal 0. (think CHR(0))

Thanks for your contribution. Just a clarification here. It is FS which uses strings in this format. Remember that FSUIPC is simply acting as an interface to FS.

Regards

Pete

Posted (edited)

Thanks for your contribution. Just a clarification here. It is FS which uses strings in this format. Remember that FSUIPC is simply acting as an interface to FS.

Regards

Pete

That's correct. I wonder if FS is doing any internal conversion to work with DBCS localization issues. Can someone try that code snippet on a Chinese localized version of FSX? :) The 256 byte buffer would result in a max "string" length of 128 characters/symbols if they're storing the localized DBCS data.

Pete, you might want to add that code snippet to the readme file for the VB sample code.

For those that want to _write_ data out, this might work:

dim destArray(256) as byte
dim origString as string
dim x as integer

origString = "\\I am a UNC\path\name\"

for x = 1 to len(origString)
  destArray(x) = asc(mid(origString,x,1))  ' The syntax on the mid() call might not be right'
next x
destArray(x+1) = 0  ' terminate with a null '

That code will break apart the string one character at a time and stick it into the byte array - the asc() call is used because you want the _value_ of the character in the byte array. This is simply the reverse of how I did it above.

g.

[wow, the syntax coloring code lost it's mind.... ;) ]

Edited by genebuckle
Posted

That's correct. I wonder if FS is doing any internal conversion to work with DBCS localization issues.

I think all the strings it uses internally relate to CFG files which I suspect are not localised. Some others in FSUIPC are folder paths -- I think they have to be workable in 8-bit characters otherwise 90% of software designed to access files won't work.

Pete, you might want to add that code snippet to the readme file for the VB sample code.

Is that old VB file relevant to today's versions? Anyway, it isn't actually my file -- all of the SDK parts other than C and ASM are from others. I can certainly have a look, but it might be better if someone who knows what he is doing does it.

Regards

Pete

Posted

Is that old VB file relevant to today's versions? Anyway, it isn't actually my file -- all of the SDK parts other than C and ASM are from others. I can certainly have a look, but it might be better if someone who knows what he is doing does it.

The UIPC_Visual_Basic example is specifically targeted at VB6, not any of the .Net languages, so it would be relevant.

g.

Posted

The UIPC_Visual_Basic example is specifically targeted at VB6, not any of the .Net languages, so it would be relevant.

Okay. Rather than edit the existing ReadMe I'm adding your examples and supporting text as a separate TXT file entitled as per this thread.

Thanks!

Pete

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.