• Thứ Hai, 19/03/2007 13:46 (GMT+7)

    Cách hiển thị tiếng Việt cho menu trong chương trình VB 6.0.

    Câu hỏi :
    Xin hướng dẫn cách hiển thị tiếng Việt cho menu trong chương trình VB 6.0. 


    Trả lời :
    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 Files\Microsoft 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~1\micros~2\vc98\bin\vcvars32.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
     
     
    Chuyên mục: Lập trình