Thừa kế Textbox để đánh chữ Việt Unicode
Lập trình dùng thừa kế
Hết rồi giai đoạn bực mình với VB6 thì sự giới hạn về lập trình theo hướng đối
tượng (Object Oriented), .NET cho phép ta tha hồ thừa kế. Do đó, một trong
những dự án nho nhỏ đầu tiên của chúng ta là thừa kế từ Textbox bình thường
để tạo một Textbox, tạm gọi là vnTextbox, hỗ trợ đánh chữ Việt Unicode theo lối
VNI hay VIQR. Dĩ nhiên, ta vẫn tiếp tục giữ các programs bỏ dấu chuyên nghiệp
ưng ý của mình như VietKey, UniKey, VPSKey, .v.v.., nhưng có thể sau nầy sẽ có
trường hợp ta cung cấp cho khách hàng một chương trình áp dụng tiếng Việt để
họ dùng cho nhu cầu chuyên môn mà không cần phải dùng thêm một program
bỏ dấu hỗ trợ.
Để tạo một Control thừa kế từ Textbox bạn khởi động một Project mới loại
Windows Control Library như sau: Kế đó, khi mở code ra thay thế hai hàng:
Public Class UserControl1
Inherits System.Windows.Forms.UserControl
bằng hai hàng sau:
Public Class vnTextbox
Inherits System.Windows.Forms.TextBox
Đánh dấu theo lối VNI
Ðể đánh dấu cho các nguyên âm chữ Việt, trong vnTextbox 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.
Các con số 1..6 theo sau chữ a chẳng hạn, sẽ cho ta các chữ á à ả ã ạ â; số 7
theo sau chữ u sẽ cho ta ư; số 8 theo sau chữ a sẽ cho ta ă; số 9 theo sau chữ
d sẽ cho ta đ. Để bỏ hai dấu thì ta dùng hai con số, thí dụ a36 thì sẽ đuợc hiển
ChList(10) = "ăắằẳẵặẩ-ẳ"
ChList(11) = "ăắằẳẵặẫ-ẵ"
ChList(12) = "ăắằẳẵặậ-ặ"
ChList(13) = "aấầẩẫậ^-ă"
ChList(14) = "âấầẩẫậấ-ắ"
ChList(15) = "âấầẩẫậầ-ằ"
ChList(16) = "âấầẩẫậẩ-ẳ"
ChList(17) = "âấầẩẫậẫ-ẵ"
ChList(18) = "âấầẩẫậậ-ặ"
ChList(19) = "eéèẻẽẹê"
ChList(20) = "e^èẻẽẹế"
ChList(21) = "eé^ẻẽẹề"
ChList(22) = "eéè^ẽẹể"
ChList(23) = "eéèẻ^ẹễ"
ChList(24) = "eéèẻẽ^ệ"
ChList(25) = "eếềểễệ^"
ChList(26) = "êếềểễệế"
ChList(27) = "êếềểễệề"
ChList(28) = "êếềểễệể"
ChList(29) = "êếềểễệễ"
ChList(30) = "êếềểễệệ"
. . .
ChList(0) chứa toàn bộ các nguyên âm. Tương ứng với mỗi nguyên âm (LastCh)
trong ChList(0) là một hàng chứa tất cả mọi chữ có thể đuợc dùng để thay thế
LastCh khi user đánh vào một con số 1..9 hay Backspace.
Thí dụ nếu LastCh là
à
, ta sẽ dùng ChList(3), nó chứa các chữ:
aá^ảãạầ-ằ
, 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ế LastCh là select (highlight) LastCh rồi Paste
nguyên âm mới.
Dưới đây là Listing của Function GetToneCharPos() để trả về một giá trị từ 1
đến 9 tượng trưng cho dấu:
Private Function GetToneCharPos( ByVal KeyChar As Integer) As Integer
' If Typing stype is VNI, see if user enters "1".."9" or "d"
' If so return 1..9 and also 9 for "d". Otherwise return -1
'
' If Typing stype is VIQR, return 1..9 for characters '`?~.^+(d .
Otherwise return -1
' We also allow for * and - to be same as + and d successively.
' i.e. u+ or u* and dd or d- are OK.
GetToneCharPos = -1
If mTypingStyle = "VNI" Then
If (KeyChar = 68) Or (KeyChar = 100) Then ' ie. "d" for dd or DD
GetToneCharPos = 9
ElseIf (KeyChar >= &H31) And (KeyChar <= &H39) Then
' it's a digit. KeyChar of "1" is &H31
GetToneCharPos = KeyChar - &H30
End If
ElseIf mTypingStyle = "VIQR" Then
Console.WriteLine("KeyChar:{0}", KeyChar)
m.Msg là cho KeyDown hay KeyPress thì ta làm ngơ và cho ProcessKeyMessage
return False để KeyDown hay KeyPress events xẩy ra như bình thường.
Protected Overrides Function ProcessKeyMessage( ByRef m As
System.Windows.Forms.Message) As Boolean
' Get out if this is not a KeyUp message
If m.Msg <> 258 Then Return False
Const Delay As Integer = 100
' Obtain the Keystroke character
Dim KeyChar As Integer = m.WParam.ToInt32
' Process a keystroke
Dim Pos, ToneCharPos, Offset As Integer
Dim NewCh As String
If KeyChar = 8 Then ' It's a backspace character
If Me.SelectionStart = 0 Then Return True
' Obtain the position of the line containing all possible modified
characters
Pos = GetLastCharMapPos()
' Select the character just on the left of the cursor
Me.SelectionStart -= 1
Me.SelectionLength = 1
If Pos > 0 Then
If LastCh <> ChList(Pos).Substring(0, 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
Clipboard.SetDataObject(ChList(Pos).Substring(0, 1))
' Paste it to replace the character on the left
Me.Paste()
ConcatCharacterIfFailed(ChList(Pos).Substring(0, 1))
' If Pos = 0 then simply display the character, ie. leave