Lessons XIX : Toàn tập các vấn đề về Unicode trong VB6

Toàn tập các vấn đề về Unicode trong VB6

Chủ nhật, 24 Tháng 8 2008 06:24 Nhiều tác giả Hướng dẫn lập trình Visual Basic-VB.NET
Email In

Tổng hợp các bài viết về tiếng Việt unicode của các tác giả Việt Nam


 

Bạn có bao giờ gặp trục trặc với tiếng Việt Unicode trong các ứng dụng Access của mình chưa? Một vấn đề mà nhiều bạn đọc gặp phải trong Access 2000 (chạy trên Win98), khi thực hiện function chuyển số sang chữ (ví dụ: “123” thành “một trăm hai mươi ba”)dùng chữ Việt Unicode khi gởi ra form thì không hiển thị được chữ Việt.

Trước khi giải quyết vấn đề chúng ta cần làm rõ một số điểm. Thường Office 2000 dùng ngôn ngữ VBA version 6.0 để viết code. Trên Win9x hay WinMe, có hai trở ngại khi dùng Unicode trong lập trình hiển thị chuỗi Unicode lên các phần tử giao diện, đó là:

1. Môi trường soạn thảo code VBA không cho phép bạn nhập đúng các chuỗi Unicode.

2. Các đối tượng giao diện chuẩn của VBA, version 6.0 không hiển thị được chuỗi Unicode.

Để khắc phục 2 trở ngại trên, bạn nên:

1. Nhập chuỗi Unicode trong cửa sổ thiết kế giao diện và cửa sổ soạn code theo định dạng UTF-8 vì định dạng này tương thích với mã ASCII truyền thống. Dĩ nhiên, trước
khi sử dụng thật chuỗi UTF-8, bạn cần chuyển nó về định dạng USC-2 thông qua việc gọi hàm API Windows có tên là MultibyteToWideChar().

2. Thay vì dùng các đối tượng giao diện có sẵn của môi trường thiết kế VBA, bạn phải dùng các đối tượng Form2 tương ứng. “Microsoft Form 2.0 Object Library” là một thư viện các đối tượng giao diện mà Microsoft mới viết sau này để hỗ trợ đúng mã Unicode.
Chúng tôi có viết một form đơn giản, có 1 textbox để nhập giá trị số, 1 textbox để hiển thị chuỗi chữ tương ứng (ở dạng đơn giản nhất, cốt yếu để minh họa việc xử lý chuỗi Unicode), 1 button cho phép chuyển số thành chuỗi. Các đối tượng được dùng đều có trong thư viện “Form 2.0”. Qui trình xây dựng ứng dụng này gồm các bước cụ thể sau:

1. Vì phát biểu Declare của VB không khai báo đúng các hàm API có tham số là chuỗi Unicode nên trước tiên bạn phải xây dựng một thư viện kiểu (type library) chứa hàm MultiByteToWideChar() để dùng trong ứng dụng. Hãy dùng một trình soạn thảo văn bản soạn nội dung đặc tả thư viện TypeLib chứa hàm MultiByteToWideChar() bằng ngôn ngữ ODL như sau (cất nội dung lên file uniutil.odl):

[
 uuid(13C9AF40-856A-101B-B9C2-04021C007002),
 helpstring("WIDE Windows API Type Library")
]
library WideWin32API
{
 [
   helpstring("KERNEL API Calls"),
   dllname("KERNEL32")
 ]
module KernelAPI
{
 [
   helpstring("Convert a UTF8 string to a UCS-2 string."),
   entry("MultiByteToWideChar")
 ]
long _stdcall MultiByteToWideChar
(
  [in] long CodePage,
  [in] long dwFlags,
  [in] BSTR lpMultiByteStr,
  [in] long cchMultiByte,
  [in] BSTR lpWideCharStr,
  [in] long cchWideChar
);
};
};

2. Dịch file ODL trên thành file thư viện kiểu uniutil.tlb bằng tiện ích mktyplib.exe. Để có tiện ích này, bạn có thể cài bộ Visual Studio 6.0, nếu cài ở chế độ Typical, bộ VS sẽ được cài vào thư mục “c:\Program Files\Microsoft Visual Studio”. Nếu vậy, để dịch file uniutil.odl ở trên, bạn hãy tạo một cửa sổ DOS Prompt, dùng lệnh cd để chuyển về thư mục chứa file uniutil.odl, rồi nhập tuần tự 2 lệnh sau để dịch nó:

c:\progra~1\micros~3\vc98\bin\vcvars32.bat
mktyplib /I c:\progra~1\micros~3\vc98\include /win32 /tlb uniutil.tlb uniutil.odl

Giả sử tên ngắn của thư mục “Program Files” là progra~1, của thư mục “Microsoft Visual Studio” là micros~3.

3. Chạy VB, tạo 1 project “Standard Exe” để quản lý ứng dụng.

4. Ấn chuột phải vào chỗ trống trong cửa sổ ToolBox, chọn mục “Components…” để hiển thị cửa sổ “Components”, ấn button Controls, duyệt đến mục “Microsoft Forms 2.0 Object Library” và chọn nó để thêm các phần tử giao diện trong thư viện này vào Toolbox của Project VB.

5. Chọn menu Project.References… để hiển thị cửa sổ References, ấn button Browse rồi duyệt hệ thống file để chọn file uniutil.tlb vừa tạo ở bước 1 để thêm nó vào Project.

6. Vẽ lần lượt từng phần tử: 1 TextBox có thuộc tính Name=txtSo; 1 Label kết hợp có thuộc tính Caption=”Hãy nhập số :”; 1 CommandButton có thuộc tính Caption=”Bắt đầu chuyển” và thuộc tính Name=cmdChuyenSo; 1 TextBox nữa có thuộc tính Name=txtChuoi; 1 Label kết hợp có thuộc tính Caption=”Chuỗi tương đương :”. Lưu ý rằng bạn phải dùng trình hỗ trợ tiếng Việt có khả năng tạo mã UTF-8 (VietKey 2000, GVSBK 2.2,…) và chọn mã này trong việc nhập các chuỗi tiếng Việt trong lúc thiết kế form và viết code. Cũng lưu ý rằng các phần tử cần vẽ là các phần tử của thư viện “Microsoft Forms 2.0 Object Library”, chứ không phải là các phần tử VB chuẩn (thường chúng nằm phía dưới cùng trong cửa sổ ToolBox). Sau khi thiết kế xong, form sẽ có dạng sau (chú ý các chuỗi UTF-8 rất khó đọc):

user posted image

7. Tạo thủ tục xử lý sự kiện Click chuột cho button cmdChuyenSo rồi vào cửa sổ viết code của form để nhập đoạn chương trình sau:

Option Explicit

'dãy chứa chuỗi UTF8 mi êu tả các ký số
'mã ký số 0 đến 9 là 48 đến 57
Dim dayUTF8(48 To 57) As String
'dãy chứa chuỗi UCS2 miêu tả các ký số
Dim dayUCS2(48 To 57) As String
' Thủ tục khởi động Form
Private Sub Form_Load()

Dim s As String
Dim x() As Byte
Dim ret As Integer
Dim i As Integer
   dayUTF8(48) = "không"
   dayUTF8(49) = "một"
   dayUTF8(50) = "hai"
   dayUTF8(51) = "ba"
   dayUTF8(52) = "bốn"
   dayUTF8(53) = "năm"
   dayUTF8(54) = "sáu"
   dayUTF8(55) = "bảy"
   dayUTF8(56) = "tám"
   dayUTF8(57) = "chín"
' Chuyển caption của button cmdChuyenSo về Unicode

x = StrConv(cmdChuyenSo.Caption, vbFromUnicode)
ret = MultiByteToWideChar(65001, 0, x, -1, s, 0)
s = Space(ret)
ret = MultiByteToWideChar(65001, 0, x, -1, s, ret)

cmdChuyenSo.Caption = s
' Chuyển caption của label lblSo về Unicode

x = StrConv(lblSo.Caption, vbFromUnicode)
ret = MultiByteToWideChar(65001, 0, x, -1, s, 0)
s = Space(ret)
ret = MultiByteToWideChar(65001, 0, x, -1, s, ret)

lblSo.Caption = s
' Chuyển caption của label lblChuoi về Unicode

x = StrConv(lblChuoi.Caption, vbFromUnicode)
ret = MultiByteToWideChar(65001, 0, x, -1, s, 0)
s = Space(ret)
ret = MultiByteToWideChar(65001, 0, x, -1, s, ret)
lblChuoi.Caption = s
' Chuyển các chuỗi UTF8 miêu tả các ký số về Unicode
For i = 48 To 57
x = StrConv(dayUTF8(i), vbFromUnicode)
ret = MultiByteToWideChar(65001, 0, x, -1, s, 0)
s = Space(ret)
ret = MultiByteToWideChar(65001, 0, x, -1, s, ret)
dayUCS2(i) = Left(s, Len(s) - 1)
Next i
End Sub
'hàm xử lý sự kiện click chuột

Private Sub cmdChuyenSo_Click()
Dim so() As Byte
Dim chuoi As String
Dim i As Integer
   chuoi = ""
   so = StrConv(txtSo.Value, vbFromUnicode)
   For i = 0 To Len(txtSo.Value) - 1
   chuoi = chuoi & dayUCS2(so(i)) & " "
   Next i
   txtChuoi.Value = chuoi
End Sub

Khi chạy, form hiển thị như sau (các chuỗi Unicode đều hiển thị đúng):
user posted image

Tác giả: Ts.Nguyễn Văn Hiệp

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: