genebuckle Posted September 8, 2011 Report Posted September 8, 2011 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.
Pete Dowson Posted September 8, 2011 Report Posted September 8, 2011 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
genebuckle Posted September 8, 2011 Author Report Posted September 8, 2011 (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 September 8, 2011 by genebuckle
Pete Dowson Posted September 8, 2011 Report Posted September 8, 2011 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
genebuckle Posted September 9, 2011 Author Report Posted September 9, 2011 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.
Pete Dowson Posted September 9, 2011 Report Posted September 9, 2011 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
genebuckle Posted September 9, 2011 Author Report Posted September 9, 2011 That works for me. Thanks Pete. g.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now