Monday, October 26, 2009

Dùng VB6 để hoán chuyển Unicode

Dùng VB6 để hoán chuyển Unicode

VB6 không đuợc thiết kế để hổ trợ Unicode. Do đó khi dùng VB6 làm ngôn ngữ lập trình để làm việc với Unicode ta chạm phải những trở ngại vì giới hạn của nó.
VB6 gần như không đá động gì đến Unicode. Người ta nói bên trong data type loại String của VB6 thì nó có khả năng chứa Unicode characters, nhưng thế thôi.
Có một số nhu cầu ta cần phải giải quyết nếu ta muốn dùng VB6 cho Unicode. Ðó là:

  1. Làm sao hiển thị chữ Việt trong Textbox, Listbox .v.v..
  2. Làm sao đọc và viết Text file chứa Unicode chữ Việt
  3. Làm sao xử lý Text String chứa Unicode chữ Việt
  4. Trong giai đoạn giao thời khi các kiểu chữ VNI, VPS, VISCII, TCVN ..v.v. còn thịnh hành, làm sao ta hoán chuyển các encodings ấy ra Unicode.

Trong bài nầy ta sẽ tìm hiểu cách đáp ứng các nhu cầu trên qua việc viết một program bằng VB6 để hoán chuyển các Text files có kiểu chữ VNI, VPS, VISCII, TCVN ..v.v. ra Unicode và ngược lại, nhân đó biểu diển cách giải quyết tất cả 4 nhu cầu nói trên.

Trước hết muốn hiển thị Unicode cho chữ Việt ta cần phải dùng Menu command của VB6 IDE để Project | Components Microsoft Forms 2.0 Object Library. Cái ActiveX nầy cho ta những Label, TextBox, Listbox và ComboBox cần thiết để hiển thị chữ Việt trong Unicode.
Kế đó, để đọc và viết chữ Việt dưới dạng UTF-8 Unicode, ta chứa Unicode text file trong một XML file giữa một cặp tags tên Text (đó cũng là root node) , rồi dùng Microsoft Document Object Model (DOM) để đọc và viết chữ Việt. Bạn nhớ Project | References Microsoft XML, v3.0Microsoft Scripting Runtime. Nguyên phần Text là nodeTypedValue của root node của DOM.
Làm như thế ta tránh phải đọc từng byte rồi tìm cách chuyển data ấy qua Unicode String. Ở đây phải nhấn mạnh là bạn phải vui lòng dùng MSWindowsNT hay MSWindows2000 mới được. Bạn có thể dùng Notepad trong WindowsNTđể edit XML file chứa chữ Việt và lưu trử dưới format UTF-8 như trong hình dưới đây:



Việc đọc và viết Việt Unicode text file được làm cho dễ dàng ra bằng cách dùng một VB6 Class tên clsUnicodeText như sau:

Dim MyUnicodeText As clsUnicodeText
Set MyUnicodeText = New clsUnicodeText
' Read Unicode Text from file txtFileName and display in TextBox1(0)
TextBox1(0).Text = MyUnicodeText.ReadUnicode(txtFileName)

Listing của Class clsUnicodeText như sau:

Option Explicit
Private mDOMTextFile As DOMDocument ' Document Object Model
Private mXMLPath As String ' XML filename
Public Function ReadUnicode(TXMLPath)
' Read Unicode text from XML file
Dim objTextFileRoot As IXMLDOMElement
Set mDOMTextFile = New DOMDocument
' Remember the XML file name to update later
mXMLPath = TXMLPath
' Read the XML file and create a DOM
mDOMTextFile.Load mXMLPath
'start at the root element of the XML
Set objTextFileRoot = mDOMTextFile.documentElement
' Return the root node's text
ReadUnicode = objTextFileRoot.nodeTypedValue
End Function

Public Sub WriteUnicode(OutText, Optional TXMLPath)
' Update Unicode Text of same XML file or write to another XML file
If IsMissing(TXMLPath) Then
' Assign the Text to write out to the Root node of DOM
mDOMTextFile.documentElement.Text = OutText
' Update the XML file
mDOMTextFile.save mXMLPath
Else
' Read a dummy file to create a DOM
ReadUnicode GetLocalDirectory & "Dummy.xml"
' Assign the Text to write out to the Root node of DOM
mDOMTextFile.documentElement.Text = OutText
' Write the Text to the given XML file
mDOMTextFile.save TXMLPath
End If
End Sub

Khi dùng Sub WriteUnicode ta có thể cho nó tên một XML file nếu ta muốn lưu trử Text trong một file khác với input XML file. Trong trường hợp đó, Sub WriteUnicode đọc một XML file trống tên Dummy.xml để tạo một DOM.

Các nguyên âm có dấu của các encodings VPS, VNI, VISCII, TCVN .v.v được chứa trong các ANSI text file như VPSVowles.txt, VNIVowels.txt, VISCIIVowels.txt, TCVNVowels.txt, .v.v..
Trong khi đó các nguyên âm có dấu của Unicode chữ Việt đuợc chứa trong một XML file và đuợc đọc vào cùng một cách như mọi XML Unicode text files khác. Nó giống như dưới đây:

Một khi Unicode text đã đuợc đọc vào trong VB6 Text String rồi, nó đuợc dùng y hệt như cho ANSI characters. Ðó là vì bên trong VB6 Unicode characters đuợc chứa đàng hoàng, không cần biết mỗi character cần bao nhiêu bytes. Nói như thế có nghĩa là các Functions Left, Mid, InStr đều có thể đuợc dùng cho Unicode Text String như một ANSI String bình thường.
Do đó khi hoán chuyển một nguyên âm từ encoding VPS hay VISCII ra Unicode, và ngược lại, ta có thể dùng mối liên hệ từng nguyên âm một (one-to-one correspondence). Hãy xem cái Function StringToString dùng trong công việc hoán chuyển nầy.

Function StringToString(Vowel1, Vowel2) As String
' Direct one-to-one character mapping from one encoding to another
Dim letter As String
Dim Text1 As String
Dim Text2 As String
Dim i, Pos
' Use Text1 to execute a litle faster than TextBox1(0)
Text1 = TextBox1(0).Text
' Iterate through each character of the from Text string
For i = 1 To Len(Text1)
letter = Mid(Text1, i, 1)
' Leave Carriage Return and Line Feed characters as is
If (letter = vbCr) Then
Text2 = Text2 & vbCr
ElseIf (letter = vbLf) Then
Text2 = Text2 & vbLf
Else
' Find position of character in the vowel list
Pos = InStr(Vowel1, letter)
If Pos <= 0 Then
' Not found - so do not map
Text2 = Text2 & letter
Else
' Found - so pick the corresponding character in the other vowel list
Text2 = Text2 & Mid(Vowel2, Pos, 1)
End If
End If
Next
StringToString = Text2
End Function

Program nầy chỉ hoán chuyển từ các encodings ra Unicode và ngược lại, chớ không có hoán chuyển giữa các encodings không phải là Unicode. Nếu bạn thích thì có thể thêm cho program feature đó. Hay nếu làm biếng thì cứ để program y nguyên rồi hoán chuyển hai lần qua trung gian Unicode.
Các encodings như VNI và VIQR thì dùng 2 hay 3 characters cho một nguyên âm có dấu. Việc hoán chuyển từ Unicode ra VNI hay VIQR thì đơn giản vì ta có thể look-up trực tiếp. Nhưng từ VNI hay VIQR ra Unicode thì ta thực hiện bằng 2 bước. Bước thứ nhất là thay thế tất cả nguyên âm có dấu bằng dòng chữ như |016 cho a^~ của VIQR lấy từ file VIQRVowelMap.txt. Bước thứ hai là lấy ra Vowel thứ 16, tức là trong danh sách các Unicode Vowels trong file UnicodeVowels.xml như trình bày phía trên.

Khi hoán chuyển text files có nhiều lúc bạn sẽ thấy một số chữ trong các encodings không đuợc hiển thị đúng, thí dụ như không display chữ ư của TCVN. Ðó là các trục trặc của MSWindows. Bạn cứ kiểm lại kỷ từ kết quả trong ANSI text file, nó không sai đâu. Unicode text thì luôn luôn hiển thị đúng.



Bạn có thể download source code của program mẫu nầy kể cả class clsUnicodeText

No comments:

Post a Comment