2009-02-12 14 views
6

Mam kilku klientów, którzy chcą używać naszego oprogramowania do terapii mowy w języku hebrajskim.Jaki jest najlepszy sposób wyświetlania tekstu w Unicode (hebrajski itp.) W VB6

Programy są w VB6. Najlepszą opcją, o której mi wiadomo, jest:

  1. używać formantów Forms 2.0 z pakietu MS Office, ale nie można ich dystrybuować.
  2. http://www.hexagora.com/en_dw_unictrl.asp $ 899
  3. http://www.iconico.com/UniToolbox/ $ 499

Wszelkie inne opcje?

+0

W VB6 ciągi są w unicode, ale nie kontroluje. W mojej aplikacji uruchomionej w mieszanym środowisku językowym było wystarczająco jawnie ustawione zestawienie znaków dla wszystkich formantów z właściwością font (zobacz pierwszy kod w [tym przykładzie] (http://stackoverflow.com/a/25623097/2369384)). Krótki opis tła to [tutaj] (http://www.example-code.com/vb/vbUnicode1.asp). Numery stron kodowych są [tutaj] (http://msdn.microsoft.com/en-us/library/cc250412.aspx). –

Odpowiedz

7

Znalazłem ten tutorial bardzo przydatne. Tak, jest to częściowo reklama dla innej Unicode Control Suite, ale zawiera ona wiele informacji o tym, jak to zrobić samodzielnie i jakie problemy są w to zamieszane.

EDIT

Wiedziałem, że muszę na to sposób bardziej przechowywane w moich zakładek.

Przede wszystkim jest artykuł od Chilkat (inny dostawca komponentów) o tym, jak używać zestawu znaków czcionki (zakładając, że jest to czcionka Unicode) do ustawiania różnych typów czcionek (musisz ręcznie zmienić .frm, ponieważ charset isn wystawiony w gui). Następnie wszystko, co musisz zrobić, to przekonwertować z AnsiToUTF8 iz powrotem, aby obsługiwać różne języki (to właśnie kontroluje Chilkat).

Po drugie, istnieją Vesa Piittinen za darmo (Creative Commons, źródło włączone) Sterowniki VB6 do pobrania here. Obejmują one Textbox, Label, Menu, List, Dialog, CommandButton, Caption (podpis formularza)).Nie grałem z nimi zbyt wiele, ale w zasadzie on robi wszystko na Paint i fajne jest to, że wszystko odbywa się w VB i możesz spojrzeć na źródło.

+0

+1 to doskonały link – MarkJ

3

Prawdopodobnie użytkownicy nie mają wybranego hebrajskiego jako domyślnej strony kodowej systemu, w przeciwnym razie można by użyć natywnych kontrolek VB6 (pamiętając oczywiście, że hebrajski jest od prawej do lewej!).

Nie używaj Formularza 2 - spowoduje awarię programu VB6. Microsoft Knowledge Base article: "FM20.DLL ma wiele problemów podczas używania z Visual Basic i innymi produktami dla programistów, a jego użycie nie jest zalecane ani wspierane w żadnym produkcie Visual Studio."

Nie mam osobistych doświadczeń z innymi, ale twoja opcja nr 3 UniToolbox istnieje już od lat i Google rzuca trochę pozytywnych rozmów na ten temat w grupach dyskusyjnych (EDIT - na przykład guru internacjonalizacji VB6, Michael Kaplan, zalecił to w a post in 2004 i blog post in 2005).

Jedną z tych whacky jest użycie wywołań API z natywnymi kontrolkami VB6 - niektóre wskaźniki w doskonałej book Michaela Kaplana w sprawie internacjonalizacji za pomocą VB6 i niektórych przykładowy kod na his website też. Ale byłoby dużo pracy. Kup książkę mimo wszystko, ponieważ jest to złota kopalnia informacji na temat problemów międzynarodowych w VB6. Na przykład sample chapter wyjaśnia twoje problemy z hebrajskim. Szukaj go jako secondhand, ponieważ jest wyczerpany.

0

Oto wszystko powinno trzeba:

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

Charset tabelę z tego link

enter image description here

  • DBCS - Dwukrotnie Byte Character Set

DBCS jest rzeczywiście nie jest prawidłowym terminologiem y dla systemu Windows. W rzeczywistości jest to MBCS, w którym postać może mieć 1 lub 2 bajty. Aby to zilustrować, należy rozważyć następujący kod, który pobierze ciąg znaków Unicode znaków angielskich i chińskich, przekształci się w tablicę bajtów języka chińskiego MBCS, zrzuci tablicę bajtów do bezpośredniego okna i ostatecznie przekształci ją z powrotem w ciąg znaków Unicode, aby wyświetlić w postaci Pole tekstowe obsługujące Unicode. Tablica bajtów po przekonwertowaniu przy użyciu chińskiego (PRC) LCID = 2052 zawiera pojedyncze bajty dla angielskich znaków i podwójne bajty dla znaków Unicode. Dowodzi to, że jest to MBCS, a nie DBCS: