• Thứ Năm, 08/01/2004 10:32 (GMT+7)

    Tiếng Việt trên title bar và menu bar

    PC World VN số 01/2002 có giới thiệu 2 bài viết về vấn đề tiếng Việt trong lập trình Windows. Tôi cũng xin đưa ra cách giải quyết của mình để trao đổi cùng bạn đọc.
    Cách làm này liên quan đến một cấu trúc có tên là NONCLIENTMETRICS. Cấu trúc này chứa các thuộc tính “NonClient Area” của một window: Border, Menu Bar, Title Bar, và Scroll Bar. Để hiển thị tiếng Việt trên Title Bar và Menu Bar, bạn chỉ cần thay đổi thuộc tính của font mặc định thành font tiếng Việt mong muốn. Chúng ta sẽ dùng hàm Windows API: SystemParametersInfo với hai  tác vụ: SPI_GETNONCLIENTMETRICS và SPI_SETNONCLIENTMETRICS.
    Tuy nhiên, cách làm này có nhược điểm là sau khi được thay đổi, ngoài các form của chương trình, các ứng dụng khác đang chạy cũng bị đổi font. Cách giải quyết là mỗi khi chương trình của bạn bị Deactive thì bạn nạp font cũ, và khi nó được Activate thì bạn lại nạp font tiếng Việt. Cách của tôi là nạp font tiếng Việt có kiểu dáng gần giống font “MS Sans Serif” của Windows, người dùng sẽ không nhận thấy sự thay đổi font, mà chương trình cũng đỡ rắc rối và ổn định hơn.
    Trong bài này tôi chọn font “VNI-Times”, một font rất phổ biến để làm thí dụ. Trước hết bạn khai báo các kiểu, hàm API. Các kiểu, hàm này bạn nên sao chép từ trình APIViewer.

     

    Private Const LF_FaceSize = 32

    Private Type LOGFONT

            lfHeight As Long

            lfWidth As Long

            lfEscapement As Long

            lfOrientation As Long

            lfWeight As Long

            lfItalic As Byte

            lfUnderline As Byte

            lfStrikeOut As Byte

            lfCharSet As Byte

            lfOutPrecision As Byte

            lfClipPrecision As Byte

            lfQuality As Byte

            lfPitchAndFamily As Byte

            lfFaceName(1 To LF_FaceSize) As Byte

    End Type

    Private Type NONCLIENTMETRICS

            cbSize As Long

            iBorderWidth As Long

            iScrollWidth As Long

            iScrollHeight As Long

            iCaptionWidth As Long

            iCaptionHeight As Long

            lfCaptionFont As LOGFONT

            iSMCaptionWidth As Long

            iSMCaptionHeight As Long

            lfSMCaptionFont As LOGFONT

            iMenuWidth As Long

            iMenuHeight As Long

            lfMenuFont As LOGFONT

            lfStatusFont As LOGFONT

            lfMessageFont As LOGFONT

    End Type

    Private Const SPI_SetNonClientMetrics = 42

    Private Const SPI_GetNonClientMetrics = 41

    Private Declare Function SystemParametersInfo Lib “user32” Alias “SystemParametersInfoA” (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long

     

    Sau đó là các hàm của chương trình:

     

    Private Const REG_StructureSize = 340 ‘Size of NONCLIENTMETRICS

    Private Const VNI_FontHeight = -13

    Private Const VNI_FontWeight = 700

    Private Const VNI_FontName = “VNI-Times”

    Private Const VNI_FontLen = 9 ‘Len(VNI_FontName)

     

    FontHeight=-13 tương đương với Size=10 và –11 là Size=8, FontWeight= 700 tương đương kiểu Bold, 400 là kiểu Normal,  bạn có thể thay đổi tùy thích, và có thể tùy biến kiểu Italic, Underline hay StrikeOut bằng cách thay đổi thuộc tính lfItalic, lfUnderline, lfStrikeOut … Tiếp theo là các biến:

     

    Private FontMetric As NONCLIENTMETRICS

    Private OldFontMetric As NONCLIENTMETRICS

     Và 2 thủ tục: ChangeFont làm công việc lưu font mặc định vào biến OldFontMetric thay đổi font thành font mới; RestoreFont nạp font mặc định từ OldFontMetric.

    Private Sub ChangeFont()

        Dim I As Integer

        Dim VarGT As Long

        Dim VarHeight As Long

        Dim VarWeight As Long

        Dim VarStr As String

        FontMetric.cbSize = REG_StructureSize

    VarGT=SystemParametersInfo (SPI_GetNonClientMetrics,REG_ StructureSize,FontMetric, 0)

        OldFontMetric = FontMetric

        FontMetric.lfCaptionFont.lfHeight = VNI_FontHeight

        FontMetric.lfCaptionFont.lfWeight = VNI_FontWeight

        FontMetric.lfMenuFont.lfHeight = VNI_FontHeight

        FontMetric.lfMenuFont.lfWeight = VNI_FontWeight

        VarStr = VNI_FontName

        For I = 1 To LF_FaceSize

            If I <= VNI_FontLen Then

                 FontMetric.lfCaptionFont.lfFaceName(I) = CByte(Asc(Mid(VarStr, I, 1)))

                 FontMetric.lfMenuFont.lfFaceName(I) = CByte(Asc(Mid(VarStr, I, 1)))

            Else

                 FontMetric.lfCaptionFont.lfFaceName(I) = 0

                 FontMetric.lfMenuFont.lfFaceName(I) = 0

            End If

        Next I

    VarGT=SystemParametersInfo (SPI_SetNonClientMetrics,REG_ StructureSize,FontMetric, 0)

    End Sub

     

    Private Sub RestoreFont()

        Dim VarGT As Long

         VarGT=SystemParametersInfo (SPI_SetNonClientMetrics,REG_ StructureSize,OldFontMetric,0)

    End Sub

     

    Chèn các đoạn mã trên vào phần General/Decration, rồi thêm đoạn mã sau:

     

    Private Sub Form_Load()

        ChangeFont

    End Sub

     

    Private Sub Form_Unload(Cancel As Integer)

        RestoreFont

        End

    End Sub

    Chúc bạn thành công.

    Hồng Linh
    E-mail: ngay23@yahoo.com

     

     

    ID: A0202_78