Introduction
This is my first article. So bear with me. I know it is a simple control, but I spent quite a lot of time figuring this out. I hope someone can read this and figure it out quicker.
The Problem
I needed a read-only text box. I created one using the CEdit
control. The problem was that it had a grey background. There is no option or function to change it directly.
The Solution
I derived a class from CEdit
called CReadOnlyEdit
. I intercepted the background ON_WM_CTLCOLOR_REFLECT()
message. This message's function looks like this:
HBRUSH CReadOnlyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
return NULL;
}
To change the background color of the EditBox
, instead of returning NULL
for the function above, I returned a brush with the color I wanted for the background. Also, if you notice in the function, above one of the parameters is a pointer to the Device Context (pDC
) of the control. I used the pDC->SetTextColor(COLORREF rgb)
function to change the text color. I then ran into a slight problem. The background changed to the correct color and the text did as well but the background of the text stayed white. This was a simple fix. I simply set the background color of the text using pDC->SetBkColor(COLORREF rgb)
function. This is my modified function:
HBRUSH CReadOnlyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
pDC->SetTextColor(m_crText);
pDC->SetBkColor(m_crBackGnd);
return m_brBackGnd;
}
As you can see, my control has three variables: COLORREF m_crText
, COLORREF m_crBackGnd
, and CBrush m_brBackGnd
. I added two functions to my control, one to change the background color (and update the brush) and one to change the text color. Those two functions look like this:
void CReadOnlyEdit::SetBackColor(COLORREF rgb)
{
m_crBackGnd = rgb;
if (m_brBackGnd.GetSafeHandle())
m_brBackGnd.DeleteObject();
m_brBackGnd.CreateSolidBrush(rgb);
Invalidate(TRUE);
}
void CReadOnlyEdit::SetTextColor(COLORREF rgb)
{
m_crText = rgb;
Invalidate(TRUE);
}
The reason I have a COLORREF
background variable is because to change the background color of the device context, I need a COLORREF
. A problem I ran into was, the entire edit control was not being colored right away, this is why I added the Invalidate(TRUE)
call to repaint the control.
That's all there was to it. By the way, my control doesn't set a background or text color by default. This can easily be done in the constructor.
Using the Code
Dialog Based
Create a CEdit
control. Control double-click it. The Add Member Variable dialog appears. Choose Control for the Category and CEdit
for the variable type. Set the variable name to something like m_wndEdit
. When modifying the control, remember m_wndEdit
is the control not a string
containing the window text. To access the text, you will have to use the proper functions for the control (ie. CEdit::SetWindowText()
).
Programmatically
The simplest way I can think of to use this is just change all the CEdit
controls you want to be read-only to CReadOnlyEdit
.
Changing the Colors
Change the background and text color of the control using the SetBack Color(COLORREF rgb)
and SetTextColor(COLORREF rgb)
functions. In the demo, I use a CColorDialog
to get a color. The following is code from my demo. It is located in the Change Back Color button's click function:
void CReadOnlyDlg::OnBack()
{
CColorDialog dlg;
if (dlg.DoModal() == IDOK)
m_wndReadOnly.SetBackColor(dlg.GetColor());
}
Where m_wndReadOnly
is the CReadOnlyEdit
control.
Note: My control doesn't set the read-only
flag, you have to do this yourself in the CReadOnlyEdit::Create
function or in the dialog control properties. Also, this can be done with the CEdit::SetReadOnly(BOOL)
function.
History
- Jan 21, 2005 - Update
- Fixed bugs
- Added
SetBackColor
and SetTextColor
functions
- Jan 18, 2005 - Posted
- Basic control, changed background color to white
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.