[英]Is it possible to change the background color of a read only edit control
I've been trying to find a simple solution to change the color of an edit control that has the ES_READONLY flag. 我一直在尝试找到一个简单的解决方案来更改具有ES_READONLY标志的编辑控件的颜色。 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. 如果我在我的其他编辑控件上取出ES_READONLY,它确实可以正常工作。 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. 然后返回此画笔,而不是在代码段中return 0
。 Once brush is no longer needed you must delete it. 一旦不再需要刷子,您必须删除它。 This is usually done in response to WM_DESTROY
message. 这通常是为了响应WM_DESTROY
消息而完成的。
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: 在只读模式下,编辑控件响应WM_CTLCOLORSTATIC
而不是WM_CTLCOLOREDIT
,因此您必须正确处理此消息:
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: 在绘制编辑/静态控件时,您有3个可用于绘画的部分:
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 ). 为了将整个控件绘制成所需的颜色,必须返回所需颜色的画笔( return (LRESULT)someBrush
用于窗口过程,或return (INT_PTR)someBrush
用于对话框)。
Your call to SetBkColor
sets the color of text background, which is different from control's background color. 你调用SetBkColor
设置文本背景,这是从控制的背景颜色不同的颜色。 That is why we call SetBkMode
with TRANSPARENT
parameter, to "say" that we want text background to match control's background. 这就是为什么我们使用TRANSPARENT
参数调用SetBkMode
来“说”我们希望文本背景与控件的背景匹配。
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. 在窗口/对话框过程中创建全局HBRUSH
变量或static HBRUSH
变量。 WM_CREATE
if in window procedure. 如果在窗口过程中,则初始化此变量以响应WM_CREATE
。 If in dialog procedure initialize the brush in WM_INITDIALOG
. 如果在对话框过程中初始化WM_INITDIALOG
的画笔。 Something like someBrush = CreateSolidBrush( RGB( 255, 0, 255 ) );
像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 ). 返回这个画笔,就像我在上面的例子中给你看的那样( return (LRESULT)someBrush
用于窗口过程,或者return (INT_PTR)someBrush
用于对话框)。 WM_DESTROY
with DeleteObject(someBrush);
这通常使用DeleteObject(someBrush);
在WM_DESTROY
完成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 ). 我强烈建议您删除以响应WM_DESTROY
而不是WM_CLOSE
因为这是您的窗口将始终收到的消息,而有时可以跳过WM_CLOSE
(搜索Internet以查找此方案的示例)。
Hope this helps, if you have further questions leave a comment and I will try to help. 希望这有帮助,如果你有进一步的问题留下评论,我会尽力帮助。 Best regards. 最好的祝福。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.