Is there any way to change the background color of a messagebox?
Here is what I did,
Code:
oldHook = ::SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProc, NULL, ::GetCurrentThreadId());
MessageBox(...);
UnhookWindowsHookEx(oldHook);
Then within the callback function CallWndRetProc, I tried to change the background color of the dialog,
Code:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(msg->hwnd, &ps);
::SetBkColor(hdc, RGB(255, 0, 0));
EndPaint(msg->hwnd, &ps);
But it doesn't change the background color of the dialog. I wonder what is the right way to do that? Thanks.
Re: Is there any way to change the background color of a messagebox?
Is this your process or are you hooking into another process?
Re: Is there any way to change the background color of a messagebox?
Does the SetWindowsHookEx() function succeed or fail as I don't see any code to check the returned value.
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
Arjay
Is this your process or are you hooking into another process?
The call to SetWindowHookEx and the call to the callback function CallWndRetProc are in the same process.
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
2kaud
Does the SetWindowsHookEx() function succeed or fail as I don't see any code to check the returned value.
Yes, it succeeds. Actually I can make use of the callback function CallWndRetProc to change the position of the dialog but I can't change the color of the dialog within the same callback function CallWndRetProc.
Re: Is there any way to change the background color of a messagebox?
See SetBkColor function
From the docs you'll see a link to Using Menus which shows SetBkColor done in OnDrawItem. Not sure if that helps you.
Re: Is there any way to change the background color of a messagebox?
For what message are you testing in your CallWndRetProc() when you execute a BeginPaint()/EndPaint() sequence?
As a message box is a dialog box, have you tried hooking the WM_CTLCOLORDLG message? See http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Re: Is there any way to change the background color of a messagebox?
Re: Is there any way to change the background color of a messagebox?
BeginPaint/EndPaint should ONLY be called in the handler for WM_PAINT using them at any other time can have weird results and sideeffects.
WM_CTLCOLORDLG is for controls on a dialog,
you probably want the WM_ERASEBKGND
though you will probably ALSO need to do some work in WM_CTLCOLORDLG to have the controls on the dialog patch with the dialog.
what you're asking for is highly "abnormal" and things will behave differently on different flavours of windows. You'll probably have an easier time to simply not use MessageBox() at all, but rather, create your own dialog with a custom background that displays the desired message.
The above may or may not work in combination with windows themes which have a different way of doing things, and your color changes may not fit into the theme at all. It may also have an assortment of issues when used with remote desktop.
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
OReubens
BeginPaint/EndPaint should ONLY be called in the handler for WM_PAINT using them at any other time can have weird results and sideeffects.
WM_CTLCOLORDLG is for controls on a dialog,
you probably want the WM_ERASEBKGND
though you will probably ALSO need to do some work in WM_CTLCOLORDLG to have the controls on the dialog patch with the dialog.
what you're asking for is highly "abnormal" and things will behave differently on different flavours of windows. You'll probably have an easier time to simply not use MessageBox() at all, but rather, create your own dialog with a custom background that displays the desired message.
The above may or may not work in combination with windows themes which have a different way of doing things, and your color changes may not fit into the theme at all. It may also have an assortment of issues when used with remote desktop.
Now I created my own custom window and then within window procedure I tried to process the window message WM_ERASEBKGND, here is the code,
Code:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_ERASEBKGND:
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
::SetBkColor(hdc, RGB(255, 0, 0));
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
But it doesn't work. Anything wrong? Thanks.
Re: Is there any way to change the background color of a messagebox?
Quote:
BeginPaint/EndPaint should ONLY be called in the handler for WM_PAINT using them at any other time can have weird results and sideeffects.
So why are you calling BeginPaint() for the WM_ERASEBKGND message??
If you want a dc when not processing a WM_PAINT message, use GetDC() and ReleaseDC().
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
2kaud
SO I changed the code,
Code:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_ERASEBKGND:
hdc = GetDC(hwnd);
::SetBkColor(hdc, RGB(255, 0, 0));
ReleaseDC(hwnd, hdc);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
But it still doesn't work. Thanks.
Re: Is there any way to change the background color of a messagebox?
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
2kaud
Even I return TRUE in processing WM_ERASEBKGND, it still doesn't work. The window looks transparent but I expect it to be red. What went wrong? Thanks.
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
LarryChen
SO I changed the code,
Code:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_ERASEBKGND:
hdc = GetDC(hwnd);
::SetBkColor(hdc, RGB(255, 0, 0));
ReleaseDC(hwnd, hdc);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
But it still doesn't work. Thanks.
Note then WM_ERASEBKND is sent with wParam set to the device context. So you don't need to GetDC/ReleaseDC.
BTW, did you try to handle WM_CTLCOLORDLG?
Re: Is there any way to change the background color of a messagebox?
For WM_ERASEBKGND, wParam is the required dc. See http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Why do you think that calling SetBkColor() for WM_ERASEBKGND message is going to change the colour of the background? Have you read the article to which I provided a link in post #13?
Re: Is there any way to change the background color of a messagebox?
To change the background colour of a message box as per your original question, try something like this
Code:
#include <iostream>
#include <Windows.h>
using namespace std;
LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PCWPRETSTRUCT prs = (PCWPRETSTRUCT)lParam;
HWND md = FindWindow(NULL, "Caption");
if ((md != NULL) && (prs->hwnd == md) && (prs->message == WM_ERASEBKGND)) {
HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
RECT rect;
GetClientRect(prs->hwnd, &rect);
FillRect((HDC)prs->wParam, &rect, brush);
DeleteObject(brush);
return TRUE;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
HHOOK oldHook = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProc, NULL, GetCurrentThreadId());
MessageBox(NULL, "Text", "Caption", MB_OK);
UnhookWindowsHookEx(oldHook);
}
Re: Is there any way to change the background color of a messagebox?
I can't help but notice that the code would be far more maintainable if the OP would simply create his own MessageBox or at least use the system colors/themes.
Re: Is there any way to change the background color of a messagebox?
Quote:
Originally Posted by
Arjay
I can't help but notice that the code would be far more maintainable if the OP would simply create his own MessageBox or at least use the system colors/themes.
True.
Re: Is there any way to change the background color of a messagebox?
Try this (not tested)
Code:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_ERASEBKGND:
{
HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
RECT rect;
GetClientRect(hwnd, &rect);
FillRect((HDC)wParam, &rect, brush);
DeleteObject(brush);
return TRUE;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Re: Is there any way to change the background color of a messagebox?
First note that WM_CTLCOLORMSGBOX message is discontinued and actually has no use.
However, we can customize a dialog box shown with MessageBox or related functions as follows:
- Before calling MessageBox create a CBT hook.
- In the hook procedure, catch message box window creation and subclass it (assign an app-defined window procedure).
- In the app-defined window procedure associated with the message box, handle WM_CTLCOLORDLG (and other messages if needed).
- Remove the hook procedure when MessageBox exits.
If using MFC, we can override CWinApp::DoMessageBox in order to create a custom message box (based on above steps) when call AfxMessageBox.
See implementation details and demo projects in the following articles: