Как лучше всего отображать текст Unicode (иврит и т. Д.) В VB6? - PullRequest
6 голосов
/ 12 февраля 2009

У меня есть клиенты, которые хотят использовать наше логопедическое программное обеспечение на иврите.

Программы в VB6. Лучший вариант, о котором я знаю, это:

  1. используйте элементы управления Forms 2.0 из MS Office, но вы не можете их распространять.
  2. http://www.hexagora.com/en_dw_unictrl.asp $ 899
  3. http://www.iconico.com/UniToolbox/ $ 499

Есть ли другие варианты?

Ответы [ 6 ]

7 голосов
/ 12 февраля 2009

Я нашел этот учебник очень полезным. Да, это частично реклама для другого Unicode Control Suite , но в нем много информации о том, как сделать это самостоятельно и с какими проблемами это связано.

EDIT

Я знал, что у меня есть кое-что еще об этом в моих закладках.

Прежде всего, есть статья от Chilkat (другой поставщик компонентов) о том, как использовать набор символов шрифта (предполагая, что это шрифт Unicode) для установки различных типов шрифтов (вы должны вручную изменить .frm, так как кодировка не отображается в графическом интерфейсе). Затем все, что вам нужно сделать, это конвертировать из AnsiToUTF8 и обратно для поддержки разных языков (это то, что делает элемент управления Chilkat).

Во-вторых, есть бесплатные контроллеры Vesa Piittinen (Creative Commons, включая источник) VB6 для загрузки здесь . Они включают в себя текстовое поле, метку, меню, список, диалог, CommandButton, заголовок (заголовок формы)). Я не много с ними играл, но в основном он делает все на OnPaint, и приятно то, что все сделано в VB, и вы можете посмотреть на источник.

3 голосов
/ 12 февраля 2009

Предположительно, ваши пользователи не выбрали иврит в качестве кодовой страницы системы по умолчанию, в противном случае вы можете просто использовать встроенные элементы управления VB6 (учитывая, что иврит, очевидно, справа налево!).

Не используйте Forms 2 - это приведет к краху вашей программы VB6. Статья базы знаний Майкрософт : «Известно, что FM20.DLL имеет много проблем при использовании с Visual Basic и другими продуктами разработчика. Его использование не рекомендуется и не поддерживается ни в одном продукте Visual Studio."

У меня нет личного опыта других, но ваш вариант №3 UniToolbox существует уже много лет, и Google подбрасывает некоторые позитивные разговоры об этом в группы новостей (EDIT - например, гуру интернационализации VB6) Майкл Каплан рекомендовал его в сообщении в 2004 году и в сообщении в блоге в 2005 году ).

Один из вариантов - использовать вызовы API с нативными элементами управления VB6 - некоторые указатели в превосходной книге Майкла Каплана по интернационализации с VB6 и некоторые примеры кода на его веб-сайте . Но это было бы много работы. Купите книгу в любом случае, так как это золотой рудник информации о международных проблемах в VB6. Например, пример главы объясняет ваши проблемы с ивритом. Ищите его из вторых рук , так как он распечатан

0 голосов
/ 15 марта 2018

Вот некоторые комментарии по поводу отображения символов Юникода в формах Microsoft Visual Basic с использованием файлов ресурсов (.RES):

Когда я вставлял русские или японские символы в редактор ресурсов Microsoft Visual Basic 6 при создании файла ресурса (.RES), символы отображались в виде вопросительных знаков (?) Как в редакторе ресурсов MSVB6, так и в формах MSVB6, отображаемых на компьютере. с русским или японским языком, соответственно, с использованием библиотеки ресурсов, которую я создал из файла RES через MSVB6.

Однако, если я добавлю символы в файл ресурсов, вставив их в Resource Hacker http://www.angusj.com/resourcehacker,, эти символы по-прежнему будут отображаться в виде вопросительных знаков в редакторе ресурсов MSVB6, но будут отображаться правильно на компьютере с соответствующим языковым стандартом после Я создал библиотеки ресурсов через MSVB6.

Можно создать библиотеки ресурсов для каждого из нескольких языков и использовать Microsoft GetUserDefaultLCID или GetUserDefaultLocaleName, чтобы решить, какой из них загрузить.

0 голосов
/ 05 сентября 2014

Таблица символов из этой ссылки

enter image description here

  • DBCS - двухбайтовый набор символов

DBCS на самом деле не является правильной терминологией для того, что использует Windows. Это на самом деле MBCS, где символ может быть 1 или 2 байта. Чтобы проиллюстрировать это, рассмотрим следующий код, который будет принимать строку Unicode из английских и китайских символов, преобразовывать в байтовый массив китайских MBCS, сбрасывать массив байтов в непосредственное окно и, наконец, преобразовывать его обратно в строку Unicode для отображения в Текстовое поле с поддержкой Юникода. Массив байтов при преобразовании с использованием китайского языка (PRC) LCID = 2052 содержит одиночные байты для английских символов и двойные байты для символов Юникода. Это доказывает, что это MBCS, а не DBCS:

0 голосов
/ 23 июня 2014

Вот все, что вам нужно:

Option Explicit
'
Private Type GETTEXTEX
    cb As Long
    flags As Long
    codepage As Long
    lpDefaultChar As Long
    lpUsedDefChar As Long
End Type
'
Private Type GETTEXTLENGTHEX
    flags As Long
    codepage As Long
End Type
'
Private Type SETTEXTEX
    flags As Long
    codepage As Long
End Type
'
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 Sub PutMem4 Lib "msvbvm60" (Destination As Any, Value As Any)
Private Declare Function SysAllocStringLen Lib "oleaut32" (ByVal OleStr As Long, ByVal bLen As Long) As Long
Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hWnd As Long) As Long
Private Declare Function EmptyClipboard Lib "user32.dll" () As Long
Private Declare Function CloseClipboard Lib "user32.dll" () As Long
Private Declare Function IsClipboardFormatAvailable Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function GetClipboardData Lib "user32.dll" (ByVal wFormat As Long) As Long
Private Declare Function SetClipboardData Lib "user32.dll" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyW" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
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
'
' The following is from MSDN help:
'
' UNICODE: International Standards Organization (ISO) character standard.
' Unicode uses a 16-bit (2-byte) coding scheme that allows for 65,536 distinct character spaces.
' Unicode includes representations for punctuation marks, mathematical symbols, and dingbats,
' with substantial room for future expansion.
'
' vbUnicode constant:     Converts the string toUnicode using the default code page of the system.
' vbFromUnicode constant: Converts the string from Unicode to the default code page of the system.
'
' LCID: The LocaleID, if different than the system LocaleID. (The system LocaleID is the default.)
'

Public Property Let UniCaption(ctrl As Object, sUniCaption As String)
    Const WM_SETTEXT As Long = &HC
    ' 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
    Const WM_GETTEXT As Long = &HD
    Const WM_GETTEXTLENGTH As Long = &HE
    ' 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

Public Property Let UniClipboard(sUniText As String)
    ' Puts a VB string in the clipboard without converting it to ASCII.
    Dim iStrPtr As Long
    Dim iLen As Long
    Dim iLock As Long
    Const GMEM_MOVEABLE As Long = &H2
    Const GMEM_ZEROINIT As Long = &H40
    Const CF_UNICODETEXT As Long = &HD
    '
    OpenClipboard 0&
    EmptyClipboard
    iLen = LenB(sUniText) + 2&
    iStrPtr = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, iLen)
    iLock = GlobalLock(iStrPtr)
    lstrcpy iLock, StrPtr(sUniText)
    GlobalUnlock iStrPtr
    SetClipboardData CF_UNICODETEXT, iStrPtr
    CloseClipboard
End Property

Public Property Get UniClipboard() As String
    ' Gets a UNICODE string from the clipboard and puts it in a standard VB string (which is UNICODE).
    Dim iStrPtr As Long
    Dim iLen As Long
    Dim iLock As Long
    Dim sUniText As String
    Const CF_UNICODETEXT As Long = 13&
    '
    OpenClipboard 0&
    If IsClipboardFormatAvailable(CF_UNICODETEXT) Then
        iStrPtr = GetClipboardData(CF_UNICODETEXT)
        If iStrPtr Then
            iLock = GlobalLock(iStrPtr)
            iLen = GlobalSize(iStrPtr)
            sUniText = String$(iLen \ 2& - 1&, vbNullChar)
            lstrcpy StrPtr(sUniText), iLock
            GlobalUnlock iStrPtr
        End If
        UniClipboard = sUniText
    End If
    CloseClipboard
End Property

Public Sub SetupRichTextboxForUnicode(rtb As RichTextBox)
    ' Call this so that the rtb doesn't try to do any RTF interpretation.  We will just be using it for Unicode display.
    ' Once this is called, the following two procedures will work with the rtb.
    Const TM_PLAINTEXT As Long = 1&
    Const EM_SETTEXTMODE As Long = &H459
    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)
    ' Usage: Just assign any VB6 string to the rtb.
    '        If the string contains Unicode (which VB6 strings are capable of), it will be correctly handled.
    Dim stUnicode As SETTEXTEX
    Const EM_SETTEXTEX As Long = &H461
    Const RTBC_DEFAULT As Long = 0&
    Const CP_UNICODE As Long = 1200&
    '
    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 uGTL As GETTEXTLENGTHEX
    Dim uGT As GETTEXTEX
    Dim iChars As Long
    Const EM_GETTEXTEX As Long = &H45E
    Const EM_GETTEXTLENGTHEX As Long = &H45F
    Const CP_UNICODE As Long = 1200&
    Const GTL_USECRLF As Long = 1&
    Const GTL_PRECISE As Long = 2&
    Const GTL_NUMCHARS As Long = 8&
    Const GT_USECRLF As Long = 1&
    '
    uGTL.flags = GTL_USECRLF Or GTL_PRECISE Or GTL_NUMCHARS
    uGTL.codepage = CP_UNICODE
    iChars = SendMessageWLng(rtb.hWnd, EM_GETTEXTLENGTHEX, VarPtr(uGTL), 0&)
    '
    uGT.cb = (iChars + 1) * 2
    uGT.flags = GT_USECRLF
    uGT.codepage = CP_UNICODE
    RichTextboxUniText = String$(iChars, 0&)
    SendMessageWLng rtb.hWnd, EM_GETTEXTEX, VarPtr(uGT), StrPtr(RichTextboxUniText)
End Property

Public Sub SaveStringToUnicodeFile(sData As String, sFileSpec As String)
    ' These are typically .TXT files.  They can be read with notepad.
    Dim iFle As Long
    '
    iFle = FreeFile
    Open sFileSpec For Binary As iFle
    Put iFle, , &HFEFF ' This is the Unicode header to a text file.  First byte = FF, second byte = FE.
    Put iFle, , UnicodeByteArrayFromString(sData)
    Close iFle
End Sub

Public Function LoadStringFromUnicodeFile(sFileSpec As String) As String
    ' These are typically .TXT files.  They can be read with notepad.
    Dim iFle As Long
    Dim bb() As Byte
    Dim i As Integer
    '
    iFle = FreeFile
    Open sFileSpec For Binary As iFle
    Get iFle, , i
    If i <> &HFEFF Then ' Unicode file header.  First byte = FF, second byte = FE.
        Close iFle
        Exit Function ' It's not a valid Unicode file.
    End If
    ReDim bb(1 To LOF(iFle) - 2&)
    Get iFle, , bb
    Close iFle
    LoadStringFromUnicodeFile = bb ' This directly copies the byte array to the Unicode string (no conversion).
    ' Note: If you try to directly read the file as a string, VB6 will attempt to convert the string from ASCII to Unicode.
End Function

Public Function AsciiByteArrayFromString(s As String) As Byte()
   ' This converts the "s" string to an ASCII string before placing in the byte array.
   AsciiByteArrayFromString = StrConv(s, vbFromUnicode)
End Function

Public Function StringFromAsciiByteArray(bb() As Byte) As String
    ' This assumes that the "bb" array uses only one byte per character and expands it to UNICODE before placing in string.
    StringFromAsciiByteArray = StrConv(bb, vbUnicode)
End Function

Public Function UnicodeByteArrayFromString(s As String) As Byte()
    ' This directly copies the Unicode string into the byte array, using two bytes per character (i.e., Unicode).
    UnicodeByteArrayFromString = s
End Function

Public Function StringFromUnicodeByteArray(bb() As Byte) As String
    ' This directly copies the byte array into the Unicode string, using two bytes per character.
    '
    ' Interestingly, you can assign an odd number of bytes to a string.
    ' The Len(s) function will not count the last (odd) byte, but the LenB(s) function will correctly report it.
    ' However, it is advisable to keep the byte array an even number of bytes.
    StringFromUnicodeByteArray = bb
End Function
0 голосов
/ 12 февраля 2009

Согласно KB224305 («ИНФОРМАЦИЯ: Использование и распространение FM20.DLL»), вы можете установить бесплатную « Microsoft ActiveX Control Pad », которая, в свою очередь, устанавливает формы 2.0 библиотека.

Может быть, это вариант для вас.

...