Logo of Vovisoft

Một Editor đơn giản cho Unicode

Bài nầy đi theo chung với bài Dùng VB6 để hoán chuyển Unicode để chỉ thêm cách dùng VB6 với Unicode qua việc lập trình một Editor đơn giản cho Unicode. Program nầy rất đơn sơ nhưng biểu diển cho thấy một khi ta đã đọc đuợc chữ Việt Unicode từ XML Text file vào một VB6 Text String rồi thì ta có thể sửa đổi nó không khác gì đang làm việc với ANSI Text String thông thường.

Ðó 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.

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.0. 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:



Sau khi khởi động program, bạn bấm nút Browse để chọn XML file có chứa sẵn bài thơ của Thôi Hộ, đời Ðường. Click LoadFile để program đọc XML file và tạo ra một DOM bên trong. Text của Root Node của DOM, tức là bài thơ, đuợc hiển thị trong một multilined Textbox TB của Microsoft Forms 2.0.


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 
Private mXMLPath As String 
Public Function ReadUnicode(TXMLPath) 
   Dim objTextFileRoot As IXMLDOMElement 
   Set mDOMTextFile = New DOMDocument 
   mXMLPath = TXMLPath 
   mDOMTextFile.Load mXMLPath 
   'start at the root element of the XML
   Set objTextFileRoot = mDOMTextFile.documentElement 
   ReadUnicode = objTextFileRoot.nodeTypedValue 
End Function 
Public Sub WriteUnicode(OutText, Optional TXMLPath) Dim tDOMNode As IXMLDOMElement ' Temporary Node for DOM If IsMissing(TXMLPath) Then ' Save the information on the screen by creating a new element and add its children to the DOM object mDOMTextFile.documentElement.Text = OutText ' Update the XML file mDOMTextFile.save mXMLPath Else Set mDOMTextFile = New DOMDocument ' Create a Node called "Text" in DOM Set tDOMNode = mDOMTextFile.createElement("Text") ' Make it the Root Node mDOMTextFile.appendChild tDOMNode ' Assign Output Text to Root Node mDOMTextFile.documentElement.Text = OutText ' Update the 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 instantiates một DOM rồi tạo một Root Node tên Text. Cách làm nầy hơi khác với trong bài Dùng VB6 để hoán chuyển Unicode. Ở đó Sub WriteUnicode đọc một Dummy.xml file để có sẵn một DOM với Root Node tên Text.

Ðể bỏ dấu cho các nguyên âm chữ Việt, trong program nầy ta tạm dùng phương pháp VNI. Tức là ta đánh nguyên âm trước, kế đó ta đánh một con số từ 1 đến 9 để bỏ dấu.

Thí dụ a36 thì sẽ đuợc hiển thị thành , còn u27 thì sẽ được hiển thị thành . Ðể đánh các chữ đÐ ta dùng d9D9. Chắc chắn bạn sẽ thấy program nầy đơn sơ quá, nhưng nó sẽ dễ hiểu, và sau đó, nếu thích bạn có thể thêm thắc các features.

Ðặc biệt program nầy dùng gần như hoàn toàn look-up table để tính ra các nguyên âm có dấu. Trước hết, mỗi khi User đánh một con số từ 1 đến 9, thì program nhìn xem character phía trước cursor (gọi là LastCharacter) là chữ gì. Kế đó nó tìm đến hàng chữ chứa toàn bộ những nguyên âm có thể thay thế Lastcharacter, tùy theo con số mà User vừa đánh vào. Ở đây kể cả trường hợp User vừa đánh một BackSpace.

Cái bản chứa những hàng chữ ấy đuợc loaded từ file V1.xml vào một invisible Listbox (của MS Form 2.0, để có thể hiển thị chữ Việt Unicode) tên LV như dưới đây:


Hàng đầu tiên trong Listbox LV chứa toàn bộ các nguyên âm. Tương ứng với mỗi nguyên âm trong hàng ấy (LastCharacter) là một hàng chứa tất cả mọi nguyên âm có thể đuợc dùng để thay thế LastCharacter khi User đánh vào một con số 1..9 hay BackSpace.
Thí dụ nếu LastCharacter là à, ta sẽ dùng hàng thứ tư ( LV.ListIndex= 3) của Listbox LV.
Nó chứa các chữ: aáàảãạầ-ằ
Kế đó nếu User đánh số 3 ta sẽ có chữ , tức là program sẽ thay thế chữ à bằng chữ . Còn nếu thay vì đánh số 3, User đánh số 8, thì ta sẽ có chữ , tức là thêm dấu ă cho chữ à.
Còn nếu User đánh Backspace, thay vì một con số, ta sẽ dùng nguyên âm nằm ở đầu dòng, tức là chữ a. Như thế nếu LastCharacter là , thì sau một BackSpace ta có , sau thêm một BackSpace kế tiếp ta sẽ còn lại a.

Kỹ thuật Program dùng để thay thế LastCharacter là select (highlight) LastCharacter rồi Paste nguyên âm mới. TextBox của MS Form 2.0 có hổ trợ hai Functions Copy và Paste rất hữu dụng.

Dưới đây là Listing của Function GetLastCharMapPos() :

Function GetLastCharMapPos() As Integer 
   ' Return the character on the left of the cursor in the Textbox
   If TB.SelStart > 0 Then 
      ' Position SelStart one character to the left
      TB.SelStart = TB.SelStart - 1 
      TB.SelLength = 1  ' SelLength is just one character
      TB.Copy  ' Copy the character to the clipboard
      ' Put the cursor back to where it was before
      TB.SelStart = TB.SelStart + 1 
      LastCh = ""  ' Clear the Textbox LastCh
      LastCh.Paste  ' Paste into TextBox LastCh the character from clipboard
      ' Return the position of the LastCh character in the complete Vowel list
      GetLastCharMapPos = InStr(LV.List(0), LastCh) 
   Else 
      ' Cursor is at the leftmost position in the Textbox
      GetLastCharMapPos = 0 
   End If 
End Function 


Cái lõi của cả program là Sub TB_KeyDown để xử lý keystroke của Textbox TB. Ta dùng Event KeyDown, thay vì Event KeyPress để có thể bắt đuợc BackSpace.

Private Sub TB_KeyDown(KeyCode As MSForms.ReturnInteger, Shift As Integer) 
   ' Process a keystroke
   Dim Pos, NewCh, Offset 
   If KeyCode = 8 Then  ' It's a backspace character
      ' Obtain the position of the line containing all possible modified characters
      Pos = GetLastCharMapPos 
      If Pos > 0 Then 
         ' Select the character just on the left of the cursor
         TB.SelStart = TB.SelStart - 1 
         TB.SelLength = 1 
         If InStr(LV.List(Pos), LastCh) > 1 Then 
            ' Get here if backspace means removing ^ or ', ` etc..
            ' Copy the new (modified) character to clipboard, it's the leftmost
            ' character on the line
            ToClipboard Left(LV.List(Pos), 1) 
            ' Paste it to replace the character on the left
            TB.Paste 
         Else 
            ' get here if it's a genuine backspace
            TB.Cut 
         End If 
         ' Swallow the actual keystroke
         KeyCode = 0 
      End If 
   ElseIf KeyCode = 220 Then  ' it's a back slash \ which is the Escape character
      If Not EscapeFlag Then 
         EscapeFlag = True  ' Set the Escape flag
         KeyCode = 0  ' Swallow the actual keystroke
         Exit Sub  ' get out
      End If 
   ElseIf (KeyCode >= &H31) And (KeyCode <= &H39) Then 
      ' Get here if a digit in range 1..9 has been entered
      ' Ignore the digit if Escape Flag is set
      If Not EscapeFlag Then 
         ' Obtain the position of the line containing all possible modified characters
         Pos = GetLastCharMapPos 
         ' If Pos = 0 then simply display the character, ie. leave the keystroke alone
         If Pos > 0 Then 
            ' Work out the offset of the new character on the line
            Offset = KeyCode - &H30 + 1 
            If Offset <= Len(LV.List(Pos)) Then 
               ' Extract the new character
               NewCh = Mid(LV.List(Pos), Offset, 1) 
               ' Forget it if the new character is "-", let the keystroke displayed
               If NewCh <> "-" Then 
                  ' Select the character just on the left of the cursor
                  TB.SelStart = TB.SelStart - 1 
                  TB.SelLength = 1 
                  ' Copy the new (modified) character to clipboard
                  ToClipboard NewCh 
                  ' Paste it to replace the character on the left
                  TB.Paste 
                  KeyCode = 0  ' Swallow the actual keystroke
               End If 
            End If 
         End If 
      End If 
   End If 
   EscapeFlag = False  ' Reset the Escape Flag
End Sub 


Program có hổ trợ Escape character \. Con số theo sau Escape character \ sẽ không bị dùng vào việc bỏ dấu cho nguyên âm ngay trước đó.

Xin lưu ý: Ðể program nầy chạy bỏ dấu đuợc bạn phải tạm thời ngưng các programs như VPSKEYS hay VietKey, UniKey .v.v.. Lý do là các programs kia sẽ giựt trước các keystrokes của những con số 1 đến 9, sau khi kiểm tra rồi không chịu buông ra cho program nầy thấy.

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

  Học Microsoft Visual Basic 6.0