I've been trying to find a simple solution to change the color of an edit control that has the ES_READONLY flag. The code I have (sort of) works when the edit control is editable, however has no effect on my edit control that has the read only flag.
case WM_CTLCOLOREDIT:
{
HDC hdc = (HDC)wParam;
//if (GetDlgItem(hwnd, IDC_EDIT_IN) == (HWND)lParam)
//{
SetTextColor(hdc, RGB(255, 255, 255)); // Set text color to white
SetBkColor(hdc, RGB(255, 255, 255)); // Set background color to black
//}
return 0;
}
break;
I have the comment there just to check if my code worked, and it does on the edit control that's not read only. If i take out ES_READONLY on my other edit control, it does work on it. I'm creating a chat program and don't want the user to be able to type in the chatbox area. And when its read only, it makes it a gray-ish color, but I want a white color. Is there another way to do this? Also The color only colors the area where text is, not the entire height of the edit control. What am I doing wrong?
You need to create a brush and keep track of it. Then you return this brush instead of return 0
in your code snippet. Once brush is no longer needed you must delete it. This is usually done in response to WM_DESTROY
message.
In your case you could dodge the bullet by using stock brush, which is what I would recommend.
When in readonly mode, edit controls respond to WM_CTLCOLORSTATIC
instead of WM_CTLCOLOREDIT
, so you must properly handle this message:
case WM_CTLCOLORSTATIC:
{
if( (HWND)lParam == GetDlgItem(hwnd, IDC_EDIT_IN) )
{
SetBkMode( (HDC)wParam, TRANSPARENT );
SetTextColor(hdc, RGB(255, 255, 255));
return (LRESULT)( (HBRUSH)GetStockObject(BLACK_BRUSH) );
// if edit control is in dialog procedure change LRESULT to INT_PTR
}
else // this is some other static control, do not touch it!!
return DefWindowProc( hwnd, message, wParam, lParam );
}
When painting edit/static control, you have 3 parts available for painting:
In order to paint entire control into desired color you must return brush with desired color ( return (LRESULT)someBrush
for window procedure, or return (INT_PTR)someBrush
for dialog box ).
Your call to SetBkColor
sets the color of text background, which is different from control's background color. That is why we call SetBkMode
with TRANSPARENT
parameter, to "say" that we want text background to match control's background.
In your case I have used stock brush, because you do not need to keep track of it, nor do you need to delete it after it is not needed anymore.
Still, there might be cases when you will want some other color. In that case here is what you will have to do:
HBRUSH
variable or static HBRUSH
variable in your window/dialog procedure.WM_CREATE
if in window procedure. If in dialog procedure initialize the brush in WM_INITDIALOG
. Something like someBrush = CreateSolidBrush( RGB( 255, 0, 255 ) );
See documentation for more info and examples.return (LRESULT)someBrush
for window procedure, or return (INT_PTR)someBrush
for dialog box ).WM_DESTROY
with DeleteObject(someBrush);
call. I strongly advise you to do the deletion in response to WM_DESTROY
instead of WM_CLOSE
because this is the message your window will always receive, while WM_CLOSE
can sometimes be skipped ( search the Internet to find examples for this scenario ).
Hope this helps, if you have further questions leave a comment and I will try to help. Best regards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With