Tiếng Việt cho menu trong VB 6.0

Việc tạo menu tiếng Việt phụ thuộc vào mã tiếng Việt nào được sử dụng:

 a. Nếu bạn dùng mã tiếng Việt nào khác, không phải là mã Unicode tiếng Việt, thì việc tạo menu tiếng Việt cho 1 form VB 6.0 khá đơn giản. Trong trường hợp này, qui trình tạo menu tiếng Việt cho Form VB 6.0 gồm 2 bước chính: 

 – Thiết lập lại font chữ mà Windows sẽ dùng cho menu tương thích với mã tiếng Việt mà bạn dùng trong form. Việc thiết lập sơ đồ font chữ cho Windows có thể được thực hiện thủ công bằng cách vào Control Panel.Display.Appearance.Advanced. Bạn cũng có thể thiết lập động font chữ cho Windows dùng hiển thị menu bằng cách lập trình, chúng tôi đã trình bày đoạn code VB (và C++) thiết lập sơ đồ font hệ thống trong các số báo trước.
 – Sau khi đã thiết lập font chữ để hiển thị menu, bạn chạy VB 6.0, tạo (mở lại) Project, tạo (mở lại) form ứng dụng, rồi dùng chức năng Tools.Menu Editor để thiết kế trực quan menu cho Form. Sau khi thiết kế xong menu, bạn sẽ thấy menu trong form hiển thị đúng tiếng Việt.

 b. Trong trường hợp bạn dùng mã tiếng Việt Unicode thì qui trình tạo menu tiếng Việt sẽ khó khăn hơn nhiều, tốt nhất là dùng môi trường VB .Net thay vì VB 6.0 vì VB .Net hỗ trợ rất tốt mã Unicode. Trong trường hợp vẫn muốn dùng VB 6.0 thì bạn hãy theo qui trình tạo menu chứa chuỗi Unicode tiếng Việt như sau:

 1. Giả sử bạn cần tạo menu cho Form gồm 2 menu pop-up tên là “Tệp” và “Soạn thảo”. Menu “Tệp” có 4 option: Tạo mới, Mở, Lưu, Dừng chương trình. Menu “Soạn thảo” có 3 option: Cắt, Sao chép, Dán.
 2. Trong đoạn code tạo động menu tiếng Việt Unicode của chúng tôi dưới đây có gọi 2 hàm API Windows tên là MultiByteToWideChar() và ModifyMenuW(), nếu dùng phát biểu Declare của VB để khai báo các hàm API có tham số là chuỗi Unicode này thì khi gọi chúng hoạt động không đúng chức năng. Để có thể dùng đúng các hàm trên, ta phải xây dựng 1 thư viện kiểu (type library) chứa chúng để dùng trong ứng dụng. Bước 2 này sẽ miêu tả qui trình xây dựng thư viện kiểu cần 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() và ModifyMenuW() 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(“WIDE32 Windows API Type Library”)
 ]
 library WideWin32API
 {
 [dllname(“kernel32.dll”)]
 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);
 };
 [dllname(“user32.dll”)]
 module User32API
 { [
 helpstring(“Modify a menu item.”),
 entry(“ModifyMenuW”)
 ]
 long _stdcall ModifyMenuW(
 [in] long hMenu,
 [in] long uPosition,
 [in] long uFlags,
 [in] long uIDItem,
 [in] BSTR lpWideCharStr);
 };
 };

 3. Dịch file ODL ở trên thành file thư viện kiểu uniutil.tlb bằng tiện ích midl.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 FilesMicrosoft Visual Studio”. Nếu vậy để dịch file uniutil.odl ở trên, bạn hãy tạo 1 cửa sổ Command 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~1micros~2vc98binvcvars32.bat
 midl 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. Sau khi tiện ích midl.exe chạy xong, nó tạo ra file thư viện tên là uniutil.tlb, file thư viện này sẽ chứa 2 hàm API tên là MultiByteToWideChar() và ModifyMenuW() mà chúng ta sẽ dùng trong ứng dụng VB 6.0 dưới đây.

 4. Bạn chạy VB 6.0, tạo (hay mở lại) Project quản lý ứng dụng, tạo (hay mở) Form giao diện cần menu, chọn chức năng Tools.Menu Editor để thiết kế trực quan menu cho Form. Vì tiện ích Menu Editor của VB 6.0 không hỗ trợ tiếng Việt Unicode, nên bạn sẽ nhập vào các chuỗi không dấu.

 5. Dùng NotePad (hay trình soạn thảo văn bản có khả năng tương ứng) nhập các chuỗi tiếng Việt Unicode cần cho menu như Tệp, Tạo mới, Mở, Lưu, Dừng chương trình, Soạn thảo, Cắt, Sao chép, Dán… rồi lưu kết quả lên file theo cách mã hóa UTF8 (vì chỉ có cách này mới có thể dùng các chuỗi Unicode trong file mã nguồn VB 6.0).

 6. Quay lại cửa sổ VB 6.0 để tiếp tục viết ứng dụng. 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 3 để thêm nó vào Project.

 7. Chọn menu View.Code để hiển thị cửa sổ soạn code cho form rồi nhập đoạn chương trình sau:

 Option Explicit
 ‘khai báo các hàm API Windows cần dùng
 Private Declare Function GetMenu Lib “user32” (ByVal hwnd As Long) As Long
 Private Declare Function GetSubMenu Lib “user32” (ByVal hMenu As Long, ByVal nPos As Long) As Long
 
 ‘khai báo các hằng cần dùng
 Const MF_BYPOSITION = &H400&
 Const MF_STRING = &H0
 Const CP_UTF8 = 65001
 ‘Viết thêm code cho hàm Form_Load
 Private Sub Form_Load()
 Dim hMenu As Long
 Dim hSubMenu As Long
 hMenu = GetMenu(Me.hwnd)
 ‘hiệu chỉnh caption cho menu Tệp
 ModifyItem hMenu, 0, 0, “T»‡p”
 ‘hiệu chỉnh caption cho menu Soạn thảo
 ModifyItem hMenu, 1, 0, “Sóº¡n thº£o”
 hSubMenu = GetSubMenu(hMenu, 0)
 ‘hiệu chỉnh caption cho các option của menu Tệp
 ModifyItem hSubMenu, 0, 0, “Tº¡o m»›i”
 ModifyItem hSubMenu, 1, 0, “M»Ÿ”
 ModifyItem hSubMenu, 2, 0, “L°u”
 ModifyItem hSubMenu, 4, 0, “D»«ng ch°¡ng tr¬nh”
 hSubMenu = GetSubMenu(hMenu, 1)
 ‘hiệu chỉnh caption cho các option của menu Soạn thảo
 ModifyItem hSubMenu, 0, 0, “Cº¯t”
 ModifyItem hSubMenu, 1, 0, “Sao ch©p”
 ModifyItem hSubMenu, 2, 0, “D¡n”
 ‘đoạn code thực hiện các chức năng còn lại của form
 End Sub
 ‘thủ tục thay đổi caption của 1 option menu
 Sub ModifyItem(hMenu As Long, pos As Integer, hItem As Long, caption As String)
 Dim ret As Long
 Dim x() As Byte
 Dim ustr As String
 ‘chuyển chuỗi caption từ 2 byte về dạng 1 byte
 x = StrConv(caption, vbFromUnicode)
 ‘phân phối vùng nhớ chứa chuỗi caption theo dạng UCS-2
 ret = MultiByteToWideChar(CP_UTF8, 0, x, -1, ustr, 0)
 ustr = Space(ret)
 ‘chuyển chuỗi caption về dạng Unicode UCS-2
 ret = MultiByteToWideChar(CP_UTF8, 0, x, -1, ustr, ret)
 ‘hiệu chỉnh caption của menu option tương ứng
 ModifyMenuW hMenu, pos, MF_BYPOSITION Or MF_STRING, hItem, ustr
 End Sub
 
 Khi chạy form hiển thị như sau (các chuỗi Unicode đều hiển thị đúng):
 Xin hỏi ngôn ngữ lập trình nào tạo file *.exe.

 Các ngôn ngữ lập trình mà con người dùng để miêu tả chương trình thường là ngôn ngữ cấp cao, thí dụ như Java, VB, C++, C#,… Các ngôn ngữ cấp cao này khá thân thiện với người, tuy nhiên CPU của máy tính không hiểu và thực thi được các chương trình viết bằng ngôn ngữ cấp cao này. Để khắc phục nhược điểm này, người ta xây dựng các chương trình dịch, nhiệm vụ của chương trình dịch là dịch chương trình từ ngôn ngữ cấp cao (mã nguồn) sang chương trình có chức năng tương đương nhưng được viết bằng ngôn ngữ máy để máy có thể hiểu và thực thi được. Trên DOS và Windows, file *.exe là file chứa chương trình ngôn ngữ máy mà chương trình dịch tạo ra. Tóm lại, con người không tạo trực tiếp file *.exe, con người chỉ viết chương trình bằng ngôn ngữ cấp cao, rồi nhờ chương trình dịch dịch ra file *.exe để chạy.