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?
Printable View
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?
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.
You didn't KNOW those things, I told them to you! ;)
Here's some code that I just whipped up! :rolleyes:
Put it in a module:
Then use the CustomMsgBox function instead of the MsgBox function.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
It will support colors, and will generally work the same - except for help-button support. But then again, whoever uses that. :rolleyes:
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.
Sure, go ahead... :rolleyes:
That's barely even my code, the original idea of hooking and capturing the WM_CTLCOLOR**** messages belongs to Aaron Young, I think. :eek:
(Even though I spent the previous 15 minutes rewriting it ;))
Yeah, you pretty much did do the whole thing LOL. :D
Thanks!