Unicode and the byte data type

Visual Basic 3 was not Unicode or Double-Byte Character Set (DBCS)–aware. Unicode stores each character in the character set in 2 bytes instead of 1. DBCS is a mixture—if the first character is in a certain range, the following byte also forms part of that character. These systems are used for displaying character sets in regions of the world where more than 256 characters are used—in Asia, for example. Since Visual Basic 4, the language has converted strings to Unicode for internal manipulation. If you’re using Visual Basic under a version of Windows that uses DBCS, any information that is read in as a string can be translated into its equivalent Unicode string that maps to the DBCS byte pair. Because of this effect, any existing code that reads binary data (File I/O) using the string data type might need to be converted to use the byte data type. Visual Basic’s internal Unicode strings are translated to ANSI strings when you are writing to a file or passing the string to a DLL. Additionally, code written to use Visual Basic strings as a way to manipulate binary data might need to be rewritten.

For example, the following code runs fine under Visual Basic 3 and 16-bit Visual Basic 4, but it will not work properly under 32-bit Visual Basic 4 or Visual Basic 5.

Type TData
    nAge  As Integer
    sName As String * 20
End Type
Type TStringBuffer
    sString As String * 22
End Type

Sub Main ()
    Dim nFileNo     As Integer
    Dim nNoRecords  As Integer
    Dim nRecord     As Integer
    Dim sTestString As String
    Dim udtData     As TData
    Dim udtString   As TStringBuffer

    nFileNo = FreeFile
    Open "TESTFILE.TST" For Binary As #nFileNo
    nNoRecords = 2
    Put #nFileNo, , nNoRecords
    udtData.nAge = 69
    udtData.sName = "Kevin"
    Put #nFileNo, , udtData
    udtData.nAge = 25
    udtData.sName = "Clive"
    Put #nFileNo, , udtData
    Close nFileNo
    nFileNo = FreeFile
    Open "TESTFILE.TST" For Binary As #nFileNo
    sTestString = Space(LOF(nFileNo) - 2)
    Get #nFileNo, , nNoRecords
    Get #nFileNo, , sTestString
    For nRecord = 1 To nNoRecords
        udtString.sString = Mid$(sTestString, _
            ((nRecord - 1) * 22) + 1, 22)
        LSet udtData = udtString
        MsgBox Trim$(udtData.sName) & " is " _
            & CStr(udtData.nAge)
    Next
    Close nFileNo
End Sub

The code that reads the data in needs to be rewritten thus:

Type TData
    nAge      As Integer
    sName(20) As Byte
End Type
Type TStringBuffer
    sString As String * 22
End Type
Sub Main()
    Dim nFileNo     As Integer
    Dim nNoRecords  As Integer
    Dim nRecord     As Integer
    Dim sTestString As String
    Dim bytArray()  As Byte
    Dim udtData     As TData
    Dim udtString   As TStringBuffer
    nFileNo = FreeFile
    Open "TESTFILE.TST" For Binary As #nFileNo
    ReDim bytArray(0 To LOF(nFileNo) - 2)
    Get #nFileNo, , nNoRecords
    Get #nFileNo, , bytArray
    sTestString = bytArray
    For intRecord = 1 To nNoRecords
        udtString.sString = MidB(sTestString, _
            ((nRecord - 1) * 22) + 1, 22)
        LSet udtData = udtString
        MsgBox Trim$(StrConv(udtData.sName, _
            vbUnicode)) & " is " & CStr(udtData.nAge)
    Next
    Close nFileNo
End Sub

Tip Most DLLs that accept strings have two versions—one that handles Unicode and one that handles ANSI. When calling the API from Visual Basic, it is best to use the ANSI version because Visual Basic converts strings to this form when handing strings to DLL calls.

The conversion to using the Byte data type is accomplished as follows:

16-Bit Visual Basic Implementation

nFreeFile = FreeFile
Open sFileName For Binary As #nFreeFile
Dim sTemp As String * 128
Get #nFreeFile, , sTemp

32-Bit Visual Basic Implementation

nFreeFile = FreeFile
Open sFileName For Binary As #nFreeFile
Dim bTemp(0 To 127) As Byte
Get #nFreeFile, , bTemp()

To manipulate binary data using string functions, do the following:

The following functions manipulate strings of binary data:

Function What It Does
AscB Returns the value corresponding to the first byte in a string of binary data
InStrB Returns the position of the first occurrence of one byte array within a string of binary data
MidB Returns the specified number of bytes from a string of binary data
LeftB/RightB Returns the specified number of bytes from the right or left side of a string of binary data
ChrB Takes a byte and returns a binary string containing the byte