Results 1 to 6 of 6

Thread: A question that only a Guru can answer!!

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jan 2000
    Posts
    95

    Talking

    How do I change the backcolor and textcolor of a MessageBox? I KNOW I have to create a App-wide Hook (SetWindowHookEx) and I KNOW I have to subclass the WM_CREATE and WM_CTLCOLOR...

    Can someone show me the code?

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    A while ago, there was a thread on changing the position of a message box. I have since cleaned this up and moved it into a C++ DLL. The previous one was here: http://www.parksie.uklinux.net/customwin.zip and full source is in it. Actually, though, the C++ is so similar to the VB (I did a line by line conversion for most of it), that anyone should be able to tweak it slightly. I'll have a go at putting a few more features in.

    I'll edit in a bit and put the other thread in.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    You didn't KNOW those things, I told them to you!
    Here's some code that I just whipped up!
    Put it in a module:
    Code:
    Option Explicit
    
    Type CWPSTRUCT
        lParam As Long
        wParam As Long
        uMsg As Long
        hWnd As Long
    End Type
    
    Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hMod As Long, ByVal dwThreadId As Long) As Long
    Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
    Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) 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 CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
    Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Declare Function OleTranslateColor Lib "olepro32" (ByVal oColor As OLE_COLOR, ByVal hPal As Long, pColorRef As Long) As Long
    Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
    Declare Function SetBkColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
    
    Public Const CLR_INVALID = &HFFFF
    
    Public Const GWL_WNDPROC = (-4)
    
    Public Const WH_CALLWNDPROC = 4
    
    Public Const WM_CREATE = &H1
    Public Const WM_DESTROY = &H2
    Public Const WM_CTLCOLORDLG = &H136
    Public Const WM_CTLCOLORSTATIC = &H138
    
    Dim lPrevWndProc As Long, hHook As Long, hBrush As Long
    Dim lBackColor As Long, lForeColor As Long
    
    Function TranslateColor(ByVal oColor As OLE_COLOR) As Long
        If OleTranslateColor(oColor, 0, TranslateColor) = CLR_INVALID Then TranslateColor = -1
    End Function
    
    Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If (uMsg = WM_CTLCOLORDLG) Or (uMsg = WM_CTLCOLORSTATIC) Then
            Call DeleteObject(hBrush)
            hBrush = CreateSolidBrush(lBackColor)
            WindowProc = hBrush
            Call SetTextColor(wParam, lForeColor)
            Call SetBkColor(wParam, lBackColor)
            Exit Function
        End If
        
        WindowProc = CallWindowProc(lPrevWndProc, hWnd, uMsg, wParam, lParam)
    End Function
    
    Function CallWndProc(ByVal nCode As Long, ByVal wParam As Long, lParam As CWPSTRUCT) As Long
        Static hWndMsgBox As Long
        
        If (lParam.uMsg = WM_CREATE) And (hWndMsgBox = 0) Then
            hWndMsgBox = lParam.hWnd
            lPrevWndProc = SetWindowLong(hWndMsgBox, GWL_WNDPROC, AddressOf WindowProc)
        End If
        If (lParam.uMsg = WM_DESTROY) And (lParam.hWnd = hWndMsgBox) Then
            Call SetWindowLong(hWndMsgBox, GWL_WNDPROC, lPrevWndProc)
            hWndMsgBox = 0
            Call DeleteObject(hBrush)
            Call UnhookWindowsHookEx(hHook)
        End If
        
        CallWndProc = CallNextHookEx(hHook, nCode, wParam, lParam)
    End Function
    
    Function CustomMsgBox(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title, Optional ByVal BackColor As OLE_COLOR = vbButtonFace, Optional ByVal ForeColor As OLE_COLOR = vbButtonText) As VbMsgBoxResult
        lBackColor = TranslateColor(BackColor)
        If lBackColor = -1 Then lBackColor = TranslateColor(vbButtonFace)
        lForeColor = TranslateColor(ForeColor)
        If lForeColor = -1 Then lForeColor = TranslateColor(vbButtonText)
        
        hHook = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf CallWndProc, App.hInstance, App.ThreadID)
        CustomMsgBox = MsgBox(Prompt, Buttons, Title)
    End Function
    Then use the CustomMsgBox function instead of the MsgBox function.
    It will support colors, and will generally work the same - except for help-button support. But then again, whoever uses that.

  4. #4
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Cool code Yonatan...do you mind if I hijack this and put it into my DLL? (I already have code to make it a different position) The more I have, the more customised it can be.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  5. #5
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892
    Sure, go ahead...
    That's barely even my code, the original idea of hooking and capturing the WM_CTLCOLOR**** messages belongs to Aaron Young, I think.
    (Even though I spent the previous 15 minutes rewriting it )

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Jan 2000
    Posts
    95
    Yeah, you pretty much did do the whole thing LOL.

    Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width