Em có ví dụ nhỏ, nhờ mọi người xem có thể cho hiện chữ trên thanh tiêu đề của Form không?
Declare Function DefWindowProc Lib "user32.dll" Alias "DefWindowProcW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Sub SetUnicodeCaption(ByVal frm As UserForm, ByVal UnicodeString As String)
Dim hWnd&
hWnd = FindWindow("ThunderDFrame", frm.Caption)
DefWindowProc hWnd, 12, 0, StrPtr(UnicodeString)
End Sub
Private Sub UserForm_Initialize()
SetUnicodeCaption Me, Label1.Caption
End Sub
Hiển thị tiếng Việt Unicode trên thanh tiêu đề UserForm chẳng dễ ăn đâu nhaEm có ví dụ nhỏ, nhờ mọi người xem có thể cho hiện chữ trên thanh tiêu đề của Form không?
Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetWindowDC Lib "user32.dll" (ByVal hWnd As Long) As Long
Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long
Declare Function SetBkMode Lib "gdi32.dll" (ByVal hdc As Long, ByVal nBkMode As Long) As Long
Declare Function SetTextColor Lib "gdi32.dll" (ByVal hdc As Long, ByVal crColor As Long) As Long
Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String) As Long
Declare Function TextOut Lib "gdi32.dll" Alias "TextOutW" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpString As Any, ByVal nCount As Long) As Long
Declare Function CreateFontIndirect Lib "gdi32.dll" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Public hFont As Long, Old_hFont As Long, ProcOld As Long, hWnd As Long
Public 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(32) As Byte
End Type
Public Type Unicode
H As Byte
L As Byte
End Type
Private Sub SetUnicodeTitlebar(Text As String)
Dim NC_hDC As Long, Result As Long, Lf As LOGFONT, NewCaption() As Unicode
Dim FontFace As String, NewFontFace() As Byte, Seed As Integer
NC_hDC = GetWindowDC(hWnd)
Lf.lfWeight = 700
FontFace = "Tahoma"
NewFontFace = StrConv(FontFace, vbFromUnicode)
For Seed = 1 To Len(FontFace)
Lf.lfFaceName(Seed - 1) = NewFontFace(Seed - 1)
Next Seed
hFont = CreateFontIndirect(Lf)
Old_hFont = SelectObject(NC_hDC, hFont)
Result = SetTextColor(NC_hDC, &HFFFFFF): Result = SetBkMode(NC_hDC, 1)
NewCaption = UniStr2BytesArray(Text)
Result = TextOut(NC_hDC, 24, 6, NewCaption(0), UBound(NewCaption))
Result = SelectObject(NC_hDC, Old_hFont): Result = DeleteObject(hFont): Result = ReleaseDC(hWnd, NC_hDC)
End Sub
Public Function WindowProc(ByVal hWnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
WindowProc = CallWindowProc(ProcOld, hWnd, iMsg, wParam, lParam)
SetUnicodeTitlebar Evaluate("frmCap")
End Function
Function UniStr2BytesArray(SrcStr As String) As Unicode()
Dim SrcStrLength As Long, Seed As Long, TmpUnicode() As Unicode
SrcStrLength = LenB(SrcStr)
ReDim TmpUnicode(SrcStrLength / 2)
Do Until Seed >= SrcStrLength / 2
TmpUnicode(Seed).H = CByte(AscB(MidB(SrcStr, Seed * 2 + 1, 1)))
TmpUnicode(Seed).L = CByte(AscB(MidB(SrcStr, Seed * 2 + 2, 1)))
Seed = Seed + 1
Loop
UniStr2BytesArray = TmpUnicode
End Function
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Sub UserForm_Initialize()
hWnd = FindWindow("ThunderDFrame", Me.Caption)
SetWindowText hWnd, ""
ProcOld = SetWindowLong(hWnd, -4, AddressOf WindowProc)
End Sub
Private Sub UserForm_Terminate()
SetWindowLong hWnd, -4, ProcOld
End Sub
Hiển thị tiếng Việt Unicode trên thanh tiêu đề UserForm chẳng dễ ăn đâu nha
...
Nói không có bằng chứng, đưa file lên đây tôi mới tinHỏng biết có cao siêu quá không chứ như bài của em (cũng là học hỏi từ diễn đàn) lại đơn giản với 2 dòng API thôi mà Thầy!
Vào Module thủ tục sau:
Mã:Declare Function DefWindowProc Lib "user32.dll" Alias "DefWindowProcW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Sub SetUnicodeCaption(ByVal frm As UserForm, ByVal UnicodeString As String) Dim hWnd& hWnd = FindWindow("ThunderDFrame", frm.Caption) DefWindowProc hWnd, 12, 0, StrPtr(UnicodeString) End Sub
Chép tiếp code trong Form như sau:
PHP:Private Sub UserForm_Initialize() SetUnicodeCaption Me, Label1.Caption End Sub
Nên thoát Form bằng thủ tục Unload Me thay cho End, bởi nếu bạn chắc chắn không chạy bất cứ code gì thì sử dụng End.
Nói không có bằng chứng, đưa file lên đây tôi mới tin
(Dễ ăn vậy sao???)
Em dùng Win XP, Excel 2003 mà vần bình thường màTôi thì có cái này
View attachment 70197
E rằng cái này bạn chạy trên Win7 + Excel 2007 hoặc đã chỉnh lại font hệ thống hay sao chứ làm gì có cái cửa đơn giản như vậy
Tôi thì có cái này
View attachment 70197
E rằng cái này bạn chạy trên Win7 + Excel 2007 hoặc đã chỉnh lại font hệ thống hay sao chứ làm gì có cái cửa đơn giản như vậy
Hiển thị tiếng Việt Unicode trên thanh tiêu đề UserForm chẳng dễ ăn đâu nha
Đầu tiên bạn đặt chuổi tiếng Việt Unicode vào trong 1 Define name rồi dùng code dưới đây
Dám cá rằng font hệ thống đã bị thay đổi (do cài chương trình nào đó hoặc đổi bằng tay)Đây là Excel 2003 và WinXP
Có thể mặc định máy cài sẳn là Tohama trên thanh tiêu đề.
Dám cá rằng font hệ thống đã bị thay đổi (do cài chương trình nào đó hoặc đổi bằng tay)
- Click phải trên Desktop, chọn Properties
- Chuyển sang tab Appearance, bấm nút Advanced
- Bấm mũi tên xổ xuống của mục Item, chọn Active Title Bar
- Xem khung dưới đang là font gì? Mặc định là font Trebuchet MS
Nếu nó là font Tahoma thì chứng tỏ các bạn đã chỉnh lại font rồi và code đó không phải là cách tổng quát để hiển thị tiếng Việt trên thanh Title
Verdana là Unicode rồi còn gìVới WinXP (máy thử) thì Font là Verdana (có thể trước đó ai đã đặt lại), còn mặc định của Win7 có thể là Verdana vì em chưa biết nó nằm ở đâu nữa để cài đặt trên chính máy tính của em.
Vì vậy đâu là tổng quát thì chưa biết, vì máy em không hiển thị tiêu đề của Form ở File của Thầy, ngược lại máy Thầy nếu không thay đổi Font mặc định cho tiêu đề window thì lại bị lỗi font.
Không hiểu Active Title Bar của em Font gì nữa, không biết giải thích sao đây?Verdana là Unicode rồi còn gì
Code của tôi không chỉnh font hệ thống, chỉ tạm thời chỉnh tiêu đề của Active Window thành Tahoma, thoát form lại trả mọi thứ về như cũ
Đương nhiên, nếu font hệ thống là Unicode rồi thì rất dễ, chỉ vài ba đoạn code là xong!
Tôi nghĩ code của tôi mới là tổng quát nhất, vì nó không quan tâm font hệ thống là gì... không hiểu sao bạn lại chạy không được... Nhờ các bạn khác test giúp nhé
Nói thêm: Cái vụ Unicode trên Title bar đã từng bàn rất nhiều, và nó là thứ khó nhai nhất (mà tôi biết) chứ không đơn giản như bạn đã nghĩ đâu
Mình thích nguyên tắc này. Nếu dungf nhiều phần mềm tiếng Việt, mà anh nào cũng chỉnh font hệ thống mới đọc được tiêu đề, mỗi anh mỗi loại font, khi thoát chương trình lại không chịu trả về như cũ, nếu đưa chương trình cho người khác dùng, đâu phải ai cũng biết chỉnh.Vậy thà chấp nhận tiêu đề không dấu còn hơn chỉnh font hệ thống (mất rin)...Verdana là Unicode rồi còn gì
Code của tôi không chỉnh font hệ thống, chỉ tạm thời chỉnh tiêu đề của Active Window thành Tahoma, thoát form lại trả mọi thứ về như cũ
Đương nhiên, nếu font hệ thống là Unicode rồi thì rất dễ, chỉ vài ba đoạn code là xong!
Tôi nghĩ code của tôi mới là tổng quát nhất, vì nó không quan tâm font hệ thống là gì... không hiểu sao bạn lại chạy không được... Nhờ các bạn khác test giúp nhé
Nói thêm: Cái vụ Unicode trên Title bar đã từng bàn rất nhiều, và nó là thứ khó nhai nhất (mà tôi biết) chứ không đơn giản như bạn đã nghĩ đâu
Theo mình đây chắc là lỗi do bản Ghost đa cấu hình?Không hiểu Active Title Bar của em Font gì nữa, không biết giải thích sao đây?
View attachment 70200
Bạn chuyển sang tab Theme, bấm mũi tên xổ xuống, chọn Windows XP xem thế nàoKhông hiểu Active Title Bar của em Font gì nữa, không biết giải thích sao đây?
Tiếp tục test trên máy khác xem!Đây là test trên máy em đây! Các Thầy xem rồi cho biết tại sao nhé!
Bạn chuyển sang tab Theme, bấm mũi tên xổ xuống, chọn Windows XP xem thế nào
---------------------------
Tiếp tục test trên máy khác xem!
Mình thích nguyên tắc này. Nếu dungf nhiều phần mềm tiếng Việt, mà anh nào cũng chỉnh font hệ thống mới đọc được tiêu đề, mỗi anh mỗi loại font, khi thoát chương trình lại không chịu trả về như cũ, nếu đưa chương trình cho người khác dùng, đâu phải ai cũng biết chỉnh.Vậy thà chấp nhận tiêu đề không dấu còn hơn chỉnh font hệ thống (mất rin)...
Public Function WindowProc(ByVal hWnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
WindowProc = CallWindowProc(ProcOld, hWnd, iMsg, wParam, lParam)
[COLOR=#ff0000][B]SetUnicodeTitlebar Evaluate("frmCap")[/B][/COLOR]
End Function
Vài người test file trên Win7 đều không ra kết quả, trong khi code của tôi hoàn toàn chẳng liên quan gì đến HĐH, chỉ yêu cầu duy nhất: Máy có font Tahoma
Quả thật tôi cảm thấy không phục, sáng nay tôi nhờ thằng bạn mang cái laptop dùng Win7 của nó vào đây để Test... Ẹc... Ẹc... tất cả bình thường
Chỉ khác 1 cái duy nhất so với khi test trên Windows XP là MÀU SẮC
Em test lại rồi. Kết luận : Nguyên nhân là do Themes của Win7
1. Basic anh High Constract Themes
View attachment 70292
2. Aero Themes
View attachment 70293
Hiển thị tiếng Việt Unicode trên thanh tiêu đề UserForm chẳng dễ ăn đâu nha
Đầu tiên bạn đặt chuổi tiếng Việt Unicode vào trong 1 Define name rồi dùng code dưới đây
1> Trong module
PHP:Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Declare Function GetWindowDC Lib "user32.dll" (ByVal hWnd As Long) As Long Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hdc As Long) As Long Declare Function SetBkMode Lib "gdi32.dll" (ByVal hdc As Long, ByVal nBkMode As Long) As Long Declare Function SetTextColor Lib "gdi32.dll" (ByVal hdc As Long, ByVal crColor As Long) As Long Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String) As Long Declare Function TextOut Lib "gdi32.dll" Alias "TextOutW" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpString As Any, ByVal nCount As Long) As Long Declare Function CreateFontIndirect Lib "gdi32.dll" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
PHP:Public hFont As Long, Old_hFont As Long, ProcOld As Long, hWnd As Long Public 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(32) As Byte End Type Public Type Unicode H As Byte L As Byte End Type
PHP:Private Sub SetUnicodeTitlebar(Text As String) Dim NC_hDC As Long, Result As Long, Lf As LOGFONT, NewCaption() As Unicode Dim FontFace As String, NewFontFace() As Byte, Seed As Integer NC_hDC = GetWindowDC(hWnd) Lf.lfWeight = 700 FontFace = "Tahoma" NewFontFace = StrConv(FontFace, vbFromUnicode) For Seed = 1 To Len(FontFace) Lf.lfFaceName(Seed - 1) = NewFontFace(Seed - 1) Next Seed hFont = CreateFontIndirect(Lf) Old_hFont = SelectObject(NC_hDC, hFont) Result = SetTextColor(NC_hDC, &HFFFFFF): Result = SetBkMode(NC_hDC, 1) NewCaption = UniStr2BytesArray(Text) Result = TextOut(NC_hDC, 24, 6, NewCaption(0), UBound(NewCaption)) Result = SelectObject(NC_hDC, Old_hFont): Result = DeleteObject(hFont): Result = ReleaseDC(hWnd, NC_hDC) End Sub
PHP:Public Function WindowProc(ByVal hWnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long WindowProc = CallWindowProc(ProcOld, hWnd, iMsg, wParam, lParam) SetUnicodeTitlebar Evaluate("frmCap") End Function
2> Trong UserFormPHP:Function UniStr2BytesArray(SrcStr As String) As Unicode() Dim SrcStrLength As Long, Seed As Long, TmpUnicode() As Unicode SrcStrLength = LenB(SrcStr) ReDim TmpUnicode(SrcStrLength / 2) Do Until Seed >= SrcStrLength / 2 TmpUnicode(Seed).H = CByte(AscB(MidB(SrcStr, Seed * 2 + 1, 1))) TmpUnicode(Seed).L = CByte(AscB(MidB(SrcStr, Seed * 2 + 2, 1))) Seed = Seed + 1 Loop UniStr2BytesArray = TmpUnicode End Function
PHP:Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
PHP:Private Sub UserForm_Initialize() hWnd = FindWindow("ThunderDFrame", Me.Caption) SetWindowText hWnd, "" ProcOld = SetWindowLong(hWnd, -4, AddressOf WindowProc) End Sub
Kết quả được như vầy:PHP:Private Sub UserForm_Terminate() SetWindowLong hWnd, -4, ProcOld End Sub
View attachment 70190
Vì khi bạn thoát Form nhưng chưa tắt Excel, thế thôi (xem Task Manager sẽ thấy)Sư phụ em làm theo cách của sư phụ thì OK rùi. Nhưng có một lỗi nhỏ xảy ra: Khi file này em làm xong vào đóng lại thì khi mở lại click chuột trực tiếp vào nó thì không mở. Và em phải mở chương trình Excel trước thì mở qua đây mới đuợc ah. Tại sao lại như vậy? Xin sư phụ chỉ giáo thêm cho em nhé!
Download
Tên: 010020
Mật khẩu: 010020
Vì khi bạn thoát Form nhưng chưa tắt Excel, thế thôi (xem Task Manager sẽ thấy)
Nếu bạn thích ẩn ứng dụng khi load Form thì phải tính cho kỹ ---> Thoát form thì nên làm điều gì? Hoặc mở hiện lại ứng dụng, hoặc là thoát luôn ứng dụng... tất cả hãy tính toán cho kỹ rồi ghi code vào trong sự kiện UserForm_Terminate nhé
Nếu bạn chỉ thoát form mà không nói gì thì đồng nghĩa là ứng dụng vẫn còn đang bị "treo" (vì bị ẩn trước đó chứ chưa tắt hẳn)
Application.Quit
Nếu muốn hiển thị Caption của Form bằng tiếng Việt, em vào đây:
http://www.caulacbovb.com/forum/viewtopic.php?f=15&t=16865
Click trực tiếp vào file không mở được là vì khi đóng file làm sai quy trình. Để vào nhà phải mở cửa nhà, vào trong nhà rồi mới mở cửa phòng, đúng không? Còn khi trở ra phải làm ngược lại: đóng cửa phòng rồi mới đóng cửa nhà, đúng không?Thầy ơi, em muốn hỏi tại sao file của em khi thoát nó vẫn chưa thoát hết hẳn? Thầy xem mục #29 nhé!
#29:
Khi file này em làm xong vào đóng lại thì khi mở lại click chuột trực tiếp vào nó thì không mở.
#31:
Nhưng em đã dùng:
rùi mà?PHP:Application.Quit
Click trực tiếp vào file không mở được là vì làm sai quy trình. Để vào nhà phải mở cửa cổng, vào trong cổng rồi mở mới cửa nhà, đúng không?
Nghĩa là:
Khi mở ứng dụng:
- Mở Excel
- Dấu sheet để chỉ hiện form
Khi tắt ứng dụng:
- Không cho hiện sheet lên lại
- Tắt Excel
Có nghĩa là khi đi ra chỉ đóng cửa cổng mà không đóng cửa nhà.
Việc này tôi và các cao thủ khác đã nói rất nhiều:
1. Khi đã can thiệp vào mặc định thì khi thoát ra phải trả về như cũ. Dấu sheet thì phải cho hiện sheet ra lại. Chỉnh Window title của Excel bằng tên mình thì sau đó phải trả lại mặc định.
2. Không bao giờ dùng Quit Application vì có chắc là không có file Excel nào đang mở? Quit là đóng lại hết của người ta sao? Chỉ nên dùng Workbook. Close.
Chính vì lẽ này mà không bao giờ tôi mở file của NHDK từ dạo đó đến giờ. Chưa nói đến file có pass.
With Application
If .Workbooks.Count > 1 Then
.ThisWorkbook.Close False
Else
.DisplayAlerts = False
.Quit
End If
End With
Khi tắt ứng dụng:
- Không cho hiện sheet lên lại
- Tắt Excel
Có nghĩa là khi đi ra chỉ đóng cửa cổng mà không đóng cửa nhà.
Ừ thì giấu, không phải dấu.Với cái này, nếu giấu sheet thì đương nhiên khi Close nếu không Save thì cũng chẳng sao. Nhưng nếu giấu Application thì cho dù có Save hay không Save thì sau khi thoát, mở file excel khác nó vẫn hiển thị bình thường như chưa có vấn đề gì xảy ra.
(giấu chứ nhỉ)
Tức là nói ngắn gọn thế này: Lúc trước đã làm gì thì khi "đi" hãy trả mọi thứ về như cũ, đừng có "phủi đít" như khi ngồi ghế đá công viên là được rồiỪ thì giấu, không phải dấu.
Với lại ý tôi nói giấu sheet = không hiển thị sheet tức là giấu Application
Xem cái chữ đỏ.
Mở file excel khác, tức là nói đến căn nhà khác. Nhà đó khi đi ra đã đóng đúng quy trình rồi. Vậy khi đi vào bình thường không có vấn đề nhà cửa toang hoang.
Còn NHDK mở lại file cũ, mà cái nhà đó khi đi ra đã để ngỏ cửa.
Public Sub ShowForm()
Application.Visible = False ' Mở cửa phòng (sau khi đã mở cửa nhà)
Application.DisplayAlerts = False ' Tắt chuông báo động
UserForm1.Show
End Sub
Private Sub CommandButton1_Click()
Unload Me
Application.Quit ' Đóng cửa nhà mà không khóa phòng + không bật lại chuông báo
End Sub
Private Sub UserForm_Terminate()
SetWindowLong hWnd, -4, ProcOld
End Sub