Results 1 to 11 of 11

Thread: Classic VB - Does Visual Basic 6 support Unicode?

  1. #1

    Thread Starter
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Classic VB - Does Visual Basic 6 support Unicode?

    Yes and no. For yes, VB strings can hold 16-bit characters and is thus Unicode compatible. The problems come from several directions:
    • Strings passed to API are converted to ANSI and vice versa

    • Reading a file to a string is done by automatically converting ANSI to Unicode

    • The same applies when saving: string is converted to ANSI

    • Visual Basic controls are not Unicode aware

    Luckily we have byte arrays to help us with the reading and writing business: they are easy to convert to strings and string contents can be copied to byte arrays easily with native VB code. Thus when working with Unicode, a byte array is your best bet.


    Where are the controls?

    The worst news is that VB6 controls use ANSI. The VB propertybags can't hold Unicode data and VB runtime also passes the data to the controls after ANSI conversion. Thus none of the default controls can be used for Unicode. The only free choice left is to code the controls by yourself or to seek for controls done by others on the internet. The easy solution costs money: people are selling Unicode aware controls and there is no free version available for many. Personally, I've made a UniLabel and a UniCommand and both are available for free (link).


    Switching codepages

    This code is still a work in progress: it is a simple module that allows to switch between codepages. This includes UTF-8 conversions, which might be handy. The functions take in and return a byte array. This far I haven't found an error with the current code. Use GetACP to find out the default codepage the system has in use (this codepage is used when a file is loaded by VB into a string).

    VB Code:
    1. Option Explicit
    2.  
    3. Public Enum KnownCodePage
    4.     CP_UNKNOWN = -1
    5.     CP_ACP = 0
    6.     CP_OEMCP = 1
    7.     CP_MACCP = 2
    8.     CP_THREAD_ACP = 3
    9.     CP_SYMBOL = 42
    10. '   ARABIC
    11.     CP_AWIN = 101   ' Bidi Windows codepage
    12.     CP_709 = 102    ' MS-DOS Arabic Support CP 709
    13.     CP_720 = 103    ' MS-DOS Arabic Support CP 720
    14.     CP_A708 = 104   ' ASMO 708
    15.     CP_A449 = 105   ' ASMO 449+
    16.     CP_TARB = 106   ' MS Transparent Arabic
    17.     CP_NAE = 107    ' Nafitha Enhanced Arabic Char Set
    18.     CP_V4 = 108     ' Nafitha v 4.0
    19.     CP_MA2 = 109    ' Mussaed Al Arabi (MA/2) CP 786
    20.     CP_I864 = 110   ' IBM Arabic Supplement CP 864
    21.     CP_A437 = 111   ' Ansi 437 codepage
    22.     CP_AMAC = 112   ' Macintosh Code Page
    23. '   HEBREW
    24.     CP_HWIN = 201   ' Bidi Windows codepage
    25.     CP_862I = 202   ' IBM Hebrew Supplement CP 862
    26.     CP_7BIT = 203   ' IBM Hebrew Supplement CP 862 Folded
    27.     CP_ISO = 204    ' ISO Hebrew 8859-8 Character Set
    28.     CP_H437 = 205   ' Ansi 437 codepage
    29.     CP_HMAC = 206   ' Macintosh Code Page
    30. '   CODE PAGES
    31.     CP_OEM_437 = 437
    32.     CP_ARABICDOS = 708
    33.     CP_DOS720 = 720
    34.     CP_DOS737 = 737
    35.     CP_DOS775 = 775
    36.     CP_IBM850 = 850
    37.     CP_IBM852 = 852
    38.     CP_DOS861 = 861
    39.     CP_DOS862 = 862
    40.     CP_IBM866 = 866
    41.     CP_DOS869 = 869
    42.     CP_THAI = 874
    43.     CP_EBCDIC = 875
    44.     CP_JAPAN = 932
    45.     CP_CHINA = 936
    46.     CP_KOREA = 949
    47.     CP_TAIWAN = 950
    48. '   UNICODE
    49.     CP_UNICODELITTLE = 1200
    50.     CP_UNICODEBIG = 1201
    51. '   CODE PAGES
    52.     CP_EASTEUROPE = 1250
    53.     CP_RUSSIAN = 1251
    54.     CP_WESTEUROPE = 1252
    55.     CP_GREEK = 1253
    56.     CP_TURKISH = 1254
    57.     CP_HEBREW = 1255
    58.     CP_ARABIC = 1256
    59.     CP_BALTIC = 1257
    60.     CP_VIETNAMESE = 1258
    61. '   KOREAN
    62.     CP_JOHAB = 1361
    63. '   MAC
    64.     CP_MAC_ROMAN = 10000
    65.     CP_MAC_JAPAN = 10001
    66.     CP_MAC_ARABIC = 10004
    67.     CP_MAC_GREEK = 10006
    68.     CP_MAC_CYRILLIC = 10007
    69.     CP_MAC_LATIN2 = 10029
    70.     CP_MAC_TURKISH = 10081
    71. '   CODE PAGES
    72.     CP_CHINESECNS = 20000
    73.     CP_CHINESEETEN = 20002
    74.     CP_IA5WEST = 20105
    75.     CP_IA5GERMAN = 20106
    76.     CP_IA5SWEDISH = 20107
    77.     CP_IA5NORWEGIAN = 20108
    78.     CP_ASCII = 20127
    79.     CP_RUSSIANKOI8R = 20866
    80.     CP_RUSSIANKOI8U = 21866
    81.     CP_ISOLATIN1 = 28591
    82.     CP_ISOEASTEUROPE = 28592
    83.     CP_ISOTURKISH = 28593
    84.     CP_ISOBALTIC = 28594
    85.     CP_ISORUSSIAN = 28595
    86.     CP_ISOARABIC = 28596
    87.     CP_ISOGREEK = 28597
    88.     CP_ISOHEBREW = 28598
    89.     CP_ISOTURKISH2 = 28599
    90.     CP_ISOLATIN9 = 28605
    91.     CP_HEBREWLOG = 38598
    92.     CP_USER = 50000
    93.     CP_AUTOALL = 50001
    94.     CP_JAPANNHK = 50220
    95.     CP_JAPANESC = 50221
    96.     CP_JAPANISO = 50222
    97.     CP_KOREAISO = 50225
    98.     CP_TAIWANISO = 50227
    99.     CP_CHINAISO = 50229
    100.     CP_AUTOJAPAN = 50932
    101.     CP_AUTOCHINA = 50936
    102.     CP_AUTOKOREA = 50949
    103.     CP_AUTOTAIWAN = 50950
    104.     CP_AUTORUSSIAN = 51251
    105.     CP_AUTOGREEK = 51253
    106.     CP_AUTOARABIC = 51256
    107.     CP_JAPANEUC = 51932
    108.     CP_CHINAEUC = 51936
    109.     CP_KOREAEUC = 51949
    110.     CP_TAIWANEUC = 51950
    111.     CP_CHINAHZ = 52936
    112.     CP_GB18030 = 54936
    113. '   UNICODE
    114.     CP_UTF7 = 65000
    115.     CP_UTF8 = 65001
    116. End Enum
    117.  
    118. ' Flags
    119. Public Const MB_PRECOMPOSED = &H1
    120. Public Const MB_COMPOSITE = &H2
    121. Public Const MB_USEGLYPHCHARS = &H4
    122. Public Const MB_ERR_INVALID_CHARS = &H8
    123.  
    124. Public Const WC_DEFAULTCHECK = &H100                ' check for default char
    125. Public Const WC_COMPOSITECHECK = &H200              ' convert composite to precomposed
    126. Public Const WC_DISCARDNS = &H10                    ' discard non-spacing chars
    127. Public Const WC_SEPCHARS = &H20                     ' generate separate chars
    128. Public Const WC_DEFAULTCHAR = &H40                  ' replace with default char
    129.  
    130. Public Declare Function GetACP Lib "kernel32" () As Long
    131. Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, _
    132. ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, _
    133. ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
    134. Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, _
    135. ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, _
    136. ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, _
    137. lpUsedDefaultChar As Long) As Long
    138. Public Function ANSItoUTF16(ByRef Text() As Byte, Optional ByVal cPage As KnownCodePage = CP_UNKNOWN, _
    139.                             Optional lFlags As Long) As Byte()
    140.     Static tmpArr() As Byte, textStr As String
    141.     Dim tmpLen As Long, textLen As Long, A As Long
    142.     If (Not Text) = True Then Exit Function
    143.     ' set code page to a valid one
    144.     If cPage = CP_UNKNOWN Then cPage = GetACP
    145.     If cPage = CP_ACP Or cPage = CP_WESTEUROPE Then
    146.         textLen = UBound(Text)
    147.         tmpLen = textLen + textLen + 1
    148.         If (Not tmpArr) = True Then ReDim Preserve tmpArr(tmpLen)
    149.         If UBound(tmpArr) <> tmpLen Then ReDim Preserve tmpArr(tmpLen)
    150.         For A = 0 To UBound(Text)
    151.             tmpArr(A + A) = Text(A)
    152.         Next A
    153.     Else
    154.         textStr = CStr(Text) & "|"
    155.         textLen = LenB(textStr)
    156.         tmpLen = textLen + textLen
    157.         ReDim Preserve tmpArr(tmpLen + 1)
    158.         ' get the new string to tmpArr
    159.         tmpLen = MultiByteToWideChar(CLng(cPage), lFlags, ByVal StrPtr(textStr), -1, _
    160.                                      ByVal VarPtr(tmpArr(0)), tmpLen)
    161.         If tmpLen = 0 Then Exit Function
    162.         tmpLen = tmpLen + tmpLen - 5
    163.         'If tmpArr(tmpLen - 1) = 0 And tmpArr(tmpLen) = 0 Then tmpLen = tmpLen - 2
    164.         If UBound(tmpArr) <> tmpLen Then ReDim Preserve tmpArr(tmpLen)
    165.     End If
    166.     ' return the result
    167.     ANSItoUTF16 = tmpArr
    168. End Function
    169. Public Function UTF16toANSI(ByRef Text() As Byte, Optional ByVal cPage As KnownCodePage = CP_UNKNOWN, _
    170.                             Optional lFlags As Long) As Byte()
    171.     Static tmpArr() As Byte
    172.     Dim tmpLen As Long, textLen As Long, A As Long
    173.     If (Not Text) = True Then Exit Function
    174.     ' set code page to a valid one
    175.     If cPage = CP_UNKNOWN Then cPage = GetACP
    176.     If cPage = CP_ACP Or cPage = CP_WESTEUROPE Then
    177.         textLen = UBound(Text)
    178.         tmpLen = (textLen + 1) \ 2 - 1
    179.         If (Not tmpArr) = True Then ReDim Preserve tmpArr(tmpLen)
    180.         If UBound(tmpArr) <> tmpLen Then ReDim Preserve tmpArr(tmpLen)
    181.         For A = 0 To tmpLen
    182.             tmpArr(A) = Text(A + A)
    183.         Next A
    184.     Else
    185.         textLen = (UBound(Text) + 1) \ 2
    186.         ' at maximum ANSI can be four bytes per character in new Chinese encoding GB18030–2000
    187.         tmpLen = textLen + textLen + textLen + textLen + 1
    188.         ReDim Preserve tmpArr(tmpLen - 1)
    189.         ' get the new string to tmpArr
    190.         tmpLen = WideCharToMultiByte(CLng(cPage), lFlags, ByVal VarPtr(Text(0)), textLen, ByVal VarPtr(tmpArr(0)), _
    191.                                      tmpLen, ByVal 0&, ByVal 0&)
    192.         If tmpLen = 0 Then Exit Function
    193.         ' a hopeless try to correct a weird error?
    194.         ReDim Preserve tmpArr(tmpLen - 1)
    195.     End If
    196.     ' return the result
    197.     UTF16toANSI = tmpArr
    198. End Function
    Last edited by si_the_geek; Jun 17th, 2008 at 07:23 AM. Reason: updated link to controls

  2. #2
    New Member
    Join Date
    Mar 2006
    Posts
    3

    Arrow Re: Classic VB - Does Visual Basic 6 support Unicode?

    Let me provide an alternative. You can use Office 2000 activeX controls, otherwise known as the Forms 2.0 (FM20.dll) I use in all the senerios (at least I think I have) that you mentioned.

    But you say "But I have to purchase Office 2000 in order to use it. My clients will have to purchase Office 2000 to use it." Nope, luckily you and they don't have to. Microsoft provided a legal free version of using the control, but you have to download and install a program to do so...

    READ HERE -> INFO: Usage and Redistribution of FM20.DLL
    Download -> MS ActiveX Control Pad

  3. #3
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    Quote Originally Posted by Merri View Post
    ... The worst news is that VB6 controls use ANSI. The VB propertybags can't hold Unicode data
    Though that is a true statement, there is a relatively easy workaround for storing unicode in a propertybag, i.e., usercontrols. VB can store 1 dimensional byte arrays in propertybags.

    Let's say that a string variable m_Text contains unicode data. To store and read the data via a userconrol's propertybag, one can do this:
    vb Code:
    1. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
    2.  
    3. Dim m_Text As String
    4.  
    5. Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    6.     Dim bData() As Byte, tLen As Long
    7.     If m_Text <> vbNullString Then
    8.         tLen = LenB(m_Text)
    9.         ReDim bData(0 To tLen - 1)
    10.         CopyMemory bData(0), ByVal StrPtr(m_Text), tLen
    11.         PropBag.WriteProperty "Text", bData()
    12.     End If
    13. End Sub
    14.  
    15. Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    16.     Dim bData() As Byte, tLen As Long
    17.     bData() = PropBag.ReadProperty("Text", vbNullString)
    18.     tLen = UBound(bData) + 1
    19.     If tLen = 0 Then
    20.        m_Text = vbNullString
    21.     Else
    22.        m_Text = String$(tLen \ 2, vbNullChar)
    23.        CopyMemory ByVal StrPtr(m_Text), bData(0), tLen
    24.     End If
    25. End Sub
    Last edited by LaVolpe; Dec 7th, 2009 at 09:52 AM. Reason: clarify content
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    Codepages aren't the way to do it. It depends on what you want to do but VB6 will get UNICODE done fairly easily. For captions, here's some code:
    Code:
    Option Explicit
    Private Const WM_GETTEXT As Long = &HD
    Private Const WM_GETTEXTLENGTH As Long = &HE
    Private Const WM_SETTEXT As Long = &HC
    Private Declare Function DefWindowProcW Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function SysAllocStringLen Lib "oleaut32" (ByVal OleStr As Long, ByVal bLen As Long) As Long
    Private Declare Sub PutMem4 Lib "msvbvm60" (Destination As Any, Value As Any)
    
    Public Property Let UniCaption(ctrl As Object, sUniCaption As String)
        ' USAGE: UniCaption(SomeControl) = s
        '
        ' This is known to work on Form, MDIForm, Checkbox, CommandButton, Frame, & OptionButton.
        ' Other controls are not known.
        '
        ' As a tip, build your Unicode caption using ChrW.
        ' Also note the careful way we pass the string to the unicode API call to circumvent VB6's auto-ASCII-conversion.
        DefWindowProcW ctrl.hWnd, WM_SETTEXT, 0, ByVal StrPtr(sUniCaption)
    End Property
    
    Public Property Get UniCaption(ctrl As Object) As String
        ' USAGE: s = UniCaption(SomeControl)
        '
        ' This is known to work on Form, MDIForm, Checkbox, CommandButton, Frame, & OptionButton.
        ' Other controls are not known.
        Dim lLen As Long
        Dim lPtr As Long
        '
        lLen = DefWindowProcW(ctrl.hWnd, WM_GETTEXTLENGTH, 0, ByVal 0) ' Get length of caption.
        If lLen Then ' Must have length.
            lPtr = SysAllocStringLen(0, lLen) ' Create a BSTR of that length.
            PutMem4 ByVal VarPtr(UniCaption), ByVal lPtr ' Make the property return the BSTR.
            DefWindowProcW ctrl.hWnd, WM_GETTEXT, lLen + 1, ByVal lPtr ' Call the default Unicode window procedure to fill the BSTR.
        End If
    End Property
    The problem isn't in strings or in the captions. It's in the fact that Unicode wasn't implemented in the PropertyBag. Therefore, you just have to go around the PropertyBag to set control properties.

    Also, the standard textbox doesn't support Unicode in the .Text property either, but the RTF control does. I'll make another post with some code for that.
    Last edited by si_the_geek; Jun 22nd, 2014 at 09:17 AM.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    Here's some nice code for using the rtf control (don't forget to add to project) with Unicode.
    Code:
    Option Explicit
    Private Const WM_USER As Long = &H400
    Private Const EM_SETTEXTMODE As Long = WM_USER + 89
    Private Const EM_SETTEXTEX As Long = WM_USER + 97
    Private Const EM_GETTEXTEX As Long = WM_USER + 94
    Private Const EM_GETTEXTLENGTHEX As Long = WM_USER + 95
    Private Const TM_PLAINTEXT As Long = 1
    Private Const CP_UNICODE = 1200&
    Private Const GT_USECRLF = 1&
    Private Const GTL_USECRLF = 1&
    Private Const GTL_PRECISE = 2&
    Private Const GTL_NUMCHARS = 8&
    Private Enum RTBC_FLAGS ' CharFormat (SCF_) flags for EM_SETCHARFORMAT message.
        RTBC_DEFAULT = 0
        RTBC_SELECTION = 1
        RTBC_WORD = 2 'Combine with RTBC_SELECTION!
        RTBC_ALL = 4
    End Enum
    Public Enum RTBW_FLAGS ' Flags for the SETEXTEX data structure.
        RTBW_DEFAULT = 0   ' Deletes undo stack, discards RTF formatting, replaces all text.
        RTBW_KEEPUNDO = 1  ' Keeps undo stack.
        RTBW_SELECTION = 2 ' Replaces selection and keeps RTF formatting.
    End Enum
    Private Type SETTEXTEX
        flags As RTBW_FLAGS
        codepage As Long
    End Type
    Private Type GETTEXTLENGTHEX
        flags As Long
        codepage As Long
    End Type
    Private Type GETTEXTEX
        cb As Long
        flags As Long
        codepage As Long
        lpDefaultChar As Long
        lpUsedDefChar As Long
    End Type
    Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
    Private Declare Function SendMessageWLng Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    
    Public Sub SetupRichTextboxForUnicode(rtb As RichTextBox)
        SendMessage rtb.hWnd, EM_SETTEXTMODE, TM_PLAINTEXT, 0 ' Set the control to use "plain text" mode so RTF isn't interpreted.
    End Sub
    
    Public Property Let RichTextboxUniText(rtb As RichTextBox, sUniText As String)
        Dim stUnicode As SETTEXTEX
        '
        stUnicode.flags = RTBC_DEFAULT ' This could be otherwise.
        stUnicode.codepage = CP_UNICODE
        SendMessageWLng rtb.hWnd, EM_SETTEXTEX, VarPtr(stUnicode), StrPtr(sUniText)
    End Property
    
    Public Property Get RichTextboxUniText(rtb As RichTextBox) As String
        Dim gtlUnicode As GETTEXTLENGTHEX
        Dim gtUnicode As GETTEXTEX
        Dim iChars As Long
        '
        gtlUnicode.flags = GTL_USECRLF Or GTL_PRECISE Or GTL_NUMCHARS
        gtlUnicode.codepage = CP_UNICODE
        iChars = SendMessageWLng(rtb.hWnd, EM_GETTEXTLENGTHEX, VarPtr(gtlUnicode), 0)
        '
        gtUnicode.cb = (iChars + 1) * 2
        gtUnicode.flags = GT_USECRLF
        gtUnicode.codepage = CP_UNICODE
        RichTextboxUniText = String$(iChars, 0)
        SendMessageWLng rtb.hWnd, EM_GETTEXTEX, VarPtr(gtUnicode), StrPtr(RichTextboxUniText)
    End Property
    Again, we've got to go around the PropertyBag to get it done.

    There's also some nice code for using Unicode with the clipboard and also to write Unicode files that Windows Notepad can read (which also supports Unicode).
    Last edited by si_the_geek; Jun 22nd, 2014 at 09:18 AM. Reason: added Code tags

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    I feel compelled to say it again: The VB6 controls are mostly ready to go for Unicode. It's that VB6 PropertyBag (the Properties window on the screen) that's stuck in ANSI/ASCII mode. The one exception to this is the .Text property of the textbox, but that's easily circumvented with the RTF control. Also, if you need to make API calls with Unicode, you just have to know to declare the string variable as LONG, and then use StrPtr(TheString) when you make the call.
    Last edited by si_the_geek; Jun 20th, 2014 at 06:06 PM. Reason: this is not the place for off-topic discussions

  7. #7
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    I have made two controls, a listbox and a textbox for unicode support.
    My approach is to use only user control and standard controls like a scroll bar. You can load file and save in UTF16 format.
    About code page
    Because vb standard forms are for ANSI, you need to set the codepage so the right conversion from utf16 can be done. For my controls there is no need to specify codepage because no conversion happen. If you have to display Chinese characters then you have to assign a font unicode with those characters, otherwise you see ?.
    I use Greek Letters.
    Print Asc("Á")
    193
    Print AscW("Á")
    913
    What this means? That in VB6 the real number for Alfa is 913 (Unicode UTF16), and when you ask the number using the codepage then you get 193 (ANSI). If you print CHRW$(20506) a chinnese char then youget ? because the print Function cannot find that UTF16 code in the ANSI of the system.
    So where you can display that UTF16? Only where you can DRAWTEXT in a DC, through HDC founded from a hWnd. And for clipboard you can use api calls. For files is very easy...to save or load a unicode text, if you fill a byte array and put it in a binary file. If you place &HFEFF as the 2 bytes in position 1 and 2 in the file then you can open it from Word.
    You can pass a string in iDE as a CHRW$(913), only. So is better to place it in a file.

    In the exampes you can find how to use a picturebox as a label for unicode displaying, how to use the listbox as listbox and as combobox, and you can see the textbox how you can use it as multiline or not, with or without transparency, with colorized text.

  8. #8
    Frenzied Member
    Join Date
    May 2014
    Location
    Kallithea Attikis, Greece
    Posts
    1,289

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    Here are some examples for using unicode in vb6.
    Vb6 uses string as utf16 and in a picture box with a drawtext function we can display that code. In other cases vb6 check if each utf16 code in the string has a equivalent in ANSI user charset and if not fount the replace the char with a question mark. This is done with any print command. So print command is forbidden. For files there are byte arrays that can perform the job right. Its very simple to write and read these files. Also these files can opened from Word.
    So the difficult part is about the controls for user input in unicode. These controls, that I provide are free and open source. The gEditbox is an advance gListbox. I made that for an ide to colorize code. So yer there isn't a wrapping function. Any paragraph (terminated with Cr or CrLf) is in one line. You can move lines with tab (or ctrl-tab if tab is using to change control), in the same way you can done in the VB IDE. There is no horizonal scroll bar, but there are events to utilize an external one. (I have an example for it). The purpose for this is to setup a split editor with two views of the same file to edit, and any change to one control copied to the other without notice any delay.
    That's all..
    Attached Files Attached Files

  9. #9
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    Here, full unicode support in both design mode and during runtime for VB6.
    OptionButton
    Checkbox
    Label
    COmmandButton
    File I/O
    Clipboard I/O
    Other routines for putting Unicode into the caption of any VB control with a hWnd.

    Just download http://motionlabresources.org/Unicod...0for%20VB6.zip

    Your Welcome.

  10. #10
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,817

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    People are all stressed about the PropertyBag not supporting Unicode, but that's not a problem. There is a problem with the actual properties window. That does NOT support Unicode, but if you're willing to build your own properties window (which can be done in VB6), you can circumvent that problem too. However, back to the PropertyBag. The problem is that .FRM files are written out in ANSI (which can't do Unicode), and the PropertyBag must be written out to these .FRM files. But there's also the .FRX files. Any binary stuff or non-ANSI stuff (including Unicode) is written into these .FRX files. Therefore, any Unicode fields we have in our custom controls must be coerced into these .FRX files and not the ANSI .FRM file. Here are two procedures for assisting with that. Just use them to go back and forth before writing your strings into the PropertyBag and everything will work. When you hit "save" that field of the PropertyBag will be written into the .FRX rather than the .FRM. Here you go:
    Code:
    Private Function UniToVar(sText As String) As Variant ' For keeping Unicode in the PropertyBag and the .FRX file.
        Dim bb() As Byte
        If Len(sText) = 0 Then
            UniToVar = Null
        Else
            bb = sText
            UniToVar = bb
        End If
    End Function
    
    Private Function VarToUni(vVar As Variant) As String ' For keeping Unicode in the PropertyBag and the .FRX file.
        Dim bb() As Byte
        If IsNull(vVar) Then Exit Function ' Just return empty string.
        bb = vVar
        VarToUni = bb
    End Function
    Last edited by si_the_geek; Jul 15th, 2014 at 02:22 AM. Reason: added Code tags

  11. #11
    Member
    Join Date
    Oct 2007
    Posts
    52

    Re: Classic VB - Does Visual Basic 6 support Unicode?

    Quote Originally Posted by Elroy View Post
    Codepages aren't the way to do it. It depends on what you want to do but VB6 will get UNICODE done fairly easily. For captions, here's some code:
    Code:
    Option Explicit
    Private Const WM_GETTEXT As Long = &HD
    Private Const WM_GETTEXTLENGTH As Long = &HE
    Private Const WM_SETTEXT As Long = &HC
    Private Declare Function DefWindowProcW Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function SysAllocStringLen Lib "oleaut32" (ByVal OleStr As Long, ByVal bLen As Long) As Long
    Private Declare Sub PutMem4 Lib "msvbvm60" (Destination As Any, Value As Any)
    
    Public Property Let UniCaption(ctrl As Object, sUniCaption As String)
        ' USAGE: UniCaption(SomeControl) = s
        '
        ' This is known to work on Form, MDIForm, Checkbox, CommandButton, Frame, & OptionButton.
        ' Other controls are not known.
        '
        ' As a tip, build your Unicode caption using ChrW.
        ' Also note the careful way we pass the string to the unicode API call to circumvent VB6's auto-ASCII-conversion.
        DefWindowProcW ctrl.hWnd, WM_SETTEXT, 0, ByVal StrPtr(sUniCaption)
    End Property
    
    Public Property Get UniCaption(ctrl As Object) As String
        ' USAGE: s = UniCaption(SomeControl)
        '
        ' This is known to work on Form, MDIForm, Checkbox, CommandButton, Frame, & OptionButton.
        ' Other controls are not known.
        Dim lLen As Long
        Dim lPtr As Long
        '
        lLen = DefWindowProcW(ctrl.hWnd, WM_GETTEXTLENGTH, 0, ByVal 0) ' Get length of caption.
        If lLen Then ' Must have length.
            lPtr = SysAllocStringLen(0, lLen) ' Create a BSTR of that length.
            PutMem4 ByVal VarPtr(UniCaption), ByVal lPtr ' Make the property return the BSTR.
            DefWindowProcW ctrl.hWnd, WM_GETTEXT, lLen + 1, ByVal lPtr ' Call the default Unicode window procedure to fill the BSTR.
        End If
    End Property
    Just a note that the code Elroy posted does seem to work and obviously is a real easy way to get Unicode to display. But the catch is that as soon as you theme your compiled EXE to Common Controls 6.0, which many people in the last 10-15 years have been doing for their apps, it no longer works. If anyone knows any way around this, please share. Thanks!

    EDIT: I found reference on MSDN to a CCM_SETUNICODEFORMAT message you can send a control (i.e. a command button) to make it Unicode. I first verified with a CCM_GETUNICODEFORMAT message (sent via SendMessage API) that the format was indeed 0 (ANSI), and then I sent the CCM_SETUNICODEFORMAT message with a 1 (true) param and verified that it took with another CCM_GETUNICODEFORMAT message. The sending and receiving of the messages worked and the Unicode flag was set. But the button still would not show Unicode text like it did in the IDE (which is using Common Controls 5.0 rather than the 6.0 specified in the manifest in order to use themed controls). So I feel like I'm CLOSE, but am missing something. Anyone have any thoughts?
    Last edited by chrislong2; Sep 7th, 2016 at 10:33 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width