Có cách nào tô màu nền và màu chữ cho Msgbox không

Liên hệ QC

thuyyeu99

Trùm Nhiều Chuyện
Tham gia
6/6/08
Bài viết
1,729
Được thích
875
Nhờ các anh chị trên diễn đàn hướng dẫn em cách tô màu nền và màu chữ cho Msgbox.
 
Upvote 0
Em thử giả lập rồi nhưng thấy nút command nó xấu quá không giống như nút command msgbox zin
 
Upvote 0
Em thử giả lập rồi nhưng thấy nút command nó xấu quá không giống như nút command msgbox zin
Các form có sẳn của Windows, nếu để ý kỹ sẽ thấy các Object trong đó dường như có dạng giống như object thuộc thanh Forms, đúng không?
Vậy để thỏa mãn yêu cầu của bạn, chỉ có thể dùng Dialog Sheet (như bài số 2) ---> Vì các nút và Object của nó toàn thuộc thanh Forms... đẹp hơn ActiveX rất nhiều
 
Upvote 0
Có lẽ dùng API là được, cái này anh Tuân khá thạo.
 
Upvote 0
Dùng API có chăng là SetSysColors và GetSysColors ---> Tức chỉnh lại màu hệ thống ---> Điều này hoàn toàn KHÔNG NÊN LÀM

Dùng hàm API hoàn toàn làm được việc này. Tất nhiên không được làm thay đổi màu hệ thống.
MsgBox.jpg


Cái MsgBox trên em viết hoàn toàn bằng API tác động vào MessageBox/MsgBox của Windows đấy.

Để viết được cái này tương đối phức tạp, nếu không ần thiết thì bỏ qua dùng giải pháp khác đi.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Dùng hàm API hoàn toàn làm được việc này. Tấc nhiên không được làm thay đổi màu hệ thống.
MsgBox.jpg


Cái MsgBox trên em viết hoàn toàn bằng API tác động vào MessageBox/MsgBox của Windows đấy.

Để viết được cái này tương đối phức tạp, nếu không ần thiết thì bỏ qua dùng giải pháp khác đi.
Đồ chơi của TuanVNUNI là món tổng hợp nhiều thứ! Chỉ dành cho người thật sự có nhu cầu
Nếu chỉ cần tô màu nền và chữ thì Dialog Sheet thừa sức làm được rồi còn gì
 
Upvote 0
Đồ chơi của TuanVNUNI là món tổng hợp nhiều thứ! Chỉ dành cho người thật sự có nhu cầu
Nếu chỉ cần tô màu nền và chữ thì Dialog Sheet thừa sức làm được rồi còn gì

Thì em đã khuyên chủ topic rồi mà

...
... nếu không ần thiết thì bỏ qua dùng giải pháp khác đi.

Làm cái MsgBox đơn giản theo ý mình thì dùng luôn cái Userform, cho màu chữ và nền là xong. Cũng chẳng cần Dialog Sheet làm gì, chỉ vì mấy cái nút bóng bẩy.

Nếu đã làm bắt trước kiểu MsgBox tác giả nhớ là làm đúng kiểu hàm nhé
MyMgsBox(Prompt, [Buttons As VbMsgBoxStyle = vbOKOnly], [Title]) As As VbMsgBoxResult

Nếu chủ topic thích cầu kỳ tôi sẽ viết tặng cái MsgBox có thuộc tính đổi màu chữ và màu nền, tấc nhiên vãn dùng hàm MsgBox của VBA.
 
Upvote 0
Upvote 0
MsgBoxClr - Tô màu nền và chữ cho MsgBox

Gửi bạn mã nguồn về hàm MsgBoxClr. Hàm này cách sử dụng như hàm MsgBox, nhưng nó có thêm 2 đối số ở cuối là BackColor và ForeColor để tô màu nền và màu chữ cho MsgBox.
Hàm MsgBox vẫn sử dụng hàm gốc của VBA là MsgBox. Trước khi gọi hàm MsgBox(), tôi dùng thủ thuật hook của sổ, cấy vào nó một thủ tục "MsgBoxProc" để xử lý các thông điệp của Windows vẽ cửa sổ.

Qua ví dụ này các bạn thấy, có những thứ tưởng như rất khó nhưng với chút hiểu biết về lập trình Windows API chúng ta sẽ làm được!

Ta có thể đưa Progress, tô màu, unicode cho MsgBox, InputBox.
MsgBoxTimer.jpg


InputBoxPass.jpg
Mã:
Function MsgBoxClr(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title As String = vbNullString, Optional HelpFile As String = vbNullString, Optional ByVal Context As Long, Optional ByVal BackColor As Long = -1, Optional ByVal ForeColor As Long = -1) As VbMsgBoxResult
    Dim inst&
    inst = GetWindowLong(GetActiveWindow, GWL_HINSTANCE)
    With MSG
        .BackColor = BackColor
        .ForeColor = ForeColor
       [COLOR="SeaGreen"] 'This is where you need to Hook the MsgBox[/COLOR]
        .HOOK = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf HookMsgBox, inst, GetCurrentThreadId)
        MsgBoxClr = MsgBox(Prompt, Buttons, Title, HelpFile, Context)
        [COLOR="SeaGreen"]'Remove the Hook[/COLOR]
        Call UnhookWindowsHookEx(.HOOK)
        .PrevProc = 0
    End With
End Function

Private Function MsgBoxProc(ByVal hwnd As Long, ByVal uMSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim tLB As LOGBRUSH
    Select Case uMSG
        Case WM_CTLCOLORDLG, WM_CTLCOLORSTATIC
            If MSG.ForeColor <> -1 Then Call SetTextColor(wParam, MSG.ForeColor)
            If MSG.ForeColor <> -1 Then Call SetBkColor(wParam, MSG.BackColor)                            
            [COLOR="SeaGreen"]'Create a Solid Brush using that Color[/COLOR]
            If MSG.BackColor <> -1 Then
                tLB.lbColor = MSG.BackColor
               [COLOR="SeaGreen"] 'Return the Handle to the Brush to Paint the MsgBox[/COLOR]
                MsgBoxProc = CreateBrushIndirect(tLB)
                Exit Function
            End If            
        Case WM_DESTROY
           [COLOR="SeaGreen"] 'Remove the MsgBox Subclassing[/COLOR]
            Call SetWindowLong(hwnd, GWL_WNDPROC, MSG.PrevProc)
    End Select    
    MsgBoxProc = CallWindowProc(MSG.PrevProc, hwnd, uMSG, wParam, ByVal lParam)    
End Function

[COLOR="SeaGreen"]'Test------------------------------------------------------------------------------------------------[/COLOR]
Sub TestMsgBox1()
    MsgBoxClr "Created by: Nguyen Duy Tuan - www.bluesofts.net", , "MsgBox with color", , , vbYellow, vbRed
End Sub

Các bạn có thể download file về xem mã nguồn.
 

File đính kèm

  • MsgBoxClr.rar
    16.2 KB · Đọc: 232
Upvote 0
Xin lỗi các bạn. Có một dòng code bị nhầm BackColorForeColor trong thủ tục MsgBoxProc.
Mã:
Private Function MsgBoxProc(ByVal hwnd As Long, ByVal uMSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim tLB As LOGBRUSH
    Select Case uMSG
        Case WM_CTLCOLORDLG, WM_CTLCOLORSTATIC
            If MSG.ForeColor <> -1 Then Call SetTextColor(wParam, MSG.ForeColor)
            [COLOR="Red"]If MSG.ForeColor <> -1 Then Call SetBkColor(wParam, MSG.BackColor)[/COLOR]
           [COLOR="SeaGreen"] 'Create a Solid Brush using that Color[/COLOR]
            If MSG.BackColor <> -1 Then
                tLB.lbColor = MSG.BackColor
               [COLOR="SeaGreen"] 'Return the Handle to the Brush to Paint the MsgBox[/COLOR]
                MsgBoxProc = CreateBrushIndirect(tLB)
                Exit Function
            End If
        Case WM_DESTROY
           [COLOR="SeaGreen"] 'Remove the MsgBox Subclassing[/COLOR]
            Call SetWindowLong(hwnd, GWL_WNDPROC, MSG.PrevProc)
    End Select
    MsgBoxProc = CallWindowProc(MSG.PrevProc, hwnd, uMSG, wParam, ByVal lParam)
End Function

Thay thành

Mã:
Private Function MsgBoxProc(ByVal hwnd As Long, ByVal uMSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim tLB As LOGBRUSH
    Select Case uMSG
        Case WM_CTLCOLORDLG, WM_CTLCOLORSTATIC
            If MSG.ForeColor <> -1 Then Call SetTextColor(wParam, MSG.ForeColor)
           [COLOR="Red"] If MSG.BackColor <> -1 Then Call SetBkColor(wParam, MSG.BackColor)[/COLOR]
            [COLOR="SeaGreen"]'Create a Solid Brush using that Color[/COLOR]
            If MSG.BackColor <> -1 Then
                tLB.lbColor = MSG.BackColor
                [COLOR="SeaGreen"]'Return the Handle to the Brush to Paint the MsgBox[/COLOR]
                MsgBoxProc = CreateBrushIndirect(tLB)
                Exit Function
            End If
        Case WM_DESTROY
           [COLOR="SeaGreen"] 'Remove the MsgBox Subclassing[/COLOR]
            Call SetWindowLong(hwnd, GWL_WNDPROC, MSG.PrevProc)
    End Select
    MsgBoxProc = CallWindowProc(MSG.PrevProc, hwnd, uMSG, wParam, ByVal lParam)
End Function
 
Upvote 0
Tuyệt vời quá (nhưng Sao nút command nó cũng vuông vức vậy anh có cách nào làm cho nó bo tròn giống cái MSgbox của anh đưa không)
 
Upvote 0
Tuyệt vời quá (nhưng Sao nút command nó cũng vuông vức vậy anh có cách nào làm cho nó bo tròn giống cái MSgbox của anh đưa không)

Hình thù của nó tùy vào HĐH bạn đang chạy. MsgBox là hàm chuẩn MessageBox của Windows nên HĐH thay đổi nó cũng thay đổi theo. Hình anh chụp là trên Windows Vista.
 
Upvote 0
Như vậy trên XP mình có thể làm cho nút command bo tròn cạnh được không anh
 
Upvote 0
Upvote 0
Các nút của MsgBox chuẩn trên Windows XP cũng là dạng bo tròn mà Tuấn
Nó đây:

View attachment 48504

Nếu cái MsgBox trong VBA mà bo tròn thì cái MsgBoxClr cũng là vậy vì nó dùng MsgBox trong VBA mà.

Việc các nút bấm cũng như các controls óng mượt trên Windows XP/Vista/7 là do theme của nó. Các ứng dụng lập trình chạy độc lập hiện lên được theme cùng Windows là phải cấy file manifest vào, hoặc tạo file kiểu "application.exe.manifest" rồi đặt chúng nằm chung trong cùng thư mục của ứng dụng.
Ví dụ đặt file "EXCEL.exe.manifest" trong thư mục chứa file Excel.exe thì các điều khiển dùng trong VBA sẽ nhận được theme theo Windows. Để tạo file application.exe.manifest như thế nào các bác tìm trên google nhé.
"application" là tên file chạy ứng dụng.

Nói về Excel. Dù không cần EXCEL.exe.manifest thì Excel vẫn lên được theme, nhưng chỉ là theme riêng nó quản lý. Với Office từ 2007 trở đi nếu không có EXCEL.exe.manifest là ứng dụng không chạy. File manifest gốc của Office, trong VBA không lên được đúng theme của Windows.

Các bạn muốn lên được theme trong VBA như ngoài Windows với các controls, MsgBox,... (ngoại trừ các controls thuộc Userform - FM20.DLL) thì cài BSAC hoặc A-Tools hoặc A-Excel sẽ được giao diện như vậy.
Tôi đã kỳ công nghiên cứu và tạo ra file EXCEL.exe.manifest cho Excel và *** đặt cho các sản phẩm của mình. Các bạn có thể lấy file này để làm cài đặt cho ứng dụng của mình.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom