 |
|
 |
Backcolor of the readonly textbox is changed only for the textbox in the window. But i want to change the color for the readonly textbox inside the Groupbox or some other container control in the window.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
 | haha  caolvchong | 19:14 17 Dec '08 |
|
|
 |
|
 |
As another commenter already noted about two years ago...
A much better way of doing this is simply to handle the WM_CTLCOLORSTATIC message and either return the current default window background:
return GetSysColorBrush(COLOR_WINDOW);
or if for some reason you wish to enforce a specific colour, create the brush and return that instead:
HBRUSH hbrBackground = CreateSolidBrush(RGB(...));
Here's the relevant msdn entry:
http://msdn2.microsoft.com/en-us/library/bb787524.aspx
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
 |
That's all i need. Add the colorname.h (http://www.codeproject.com/gdi/colornames.asp) to your cpp's which calls the color-setter and you easily can modify your colors inside an editcontrol.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Thanks a lot for this description of the EditCtrl it works fine but: When I disable the ctrl the TextColor gets it default gray ! I found out the following:
HBRUSH CColorEditCtrl::CtlColor( CDC* pDC, UINT nCtlColor ) { pDC->SetTextColor(COLOR_EDITABLE); pDC->SetBkColor(IsWindowEnabled() ? COLOR_EDITABLE_BKGND : COLOR_DEFAULT_BKGND); return IsWindowEnabled() ? m_EnabledBrush : m_Brush; }
And I added for the multiline EditCtrl:
BOOL CColorEditCtrl::OnEraseBkgnd(CDC* pDC) { CRect rect; GetClientRect(rect); CBrush brush0( IsWindowEnabled() ? COLOR_EDITABLE_BKGND : COLOR_DEFAULT_BKGND ); pDC->FillRect(&rect,&brush0); brush0.DeleteObject(); return FALSE; } which fills the unused part opf the control with the correct Background. But I cannot change the Textcolor of a disabled EditCtrl !
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
I likewise found it easy to use this class as described in the article. Nice job. However, I ran into a problem when I tried to extend it by allowing the user to specify the font. The problem is that the text gets clipped on the right side of the box. In CReadOnlyEdit::CtlColor, I created the font and set it as follows.
LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = 14; lf.lfWeight = FW_BOLD; //lf.lfPitchAndFamily = FF_SWISS; lstrcpy(lf.lfFaceName,_T("Arial")); m_font.CreateFontIndirect(&lf);
pDC->SelectObject(&m_font);
Why doesn't it have problems with the System font but larger fonts it can't figure out? With a smaller font it still breaks the line after "read only" even though there is more room to continue with "but still". Nothing in the code seems to tell the system where to break the line. With a really big font, not only does the text get clipped on the right but also on the bottom.
Is there a way to set something in the pDC to tell it the width and height of the font being used?
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
I found this article after spending two full days getting nowhere trying to change background colors of a CEdit control. It worked right away and I rated the article 5, but I do not yet know enough to understand how the program works.
Things must happen in a thread. Since I do not know how to set up a breakpoint in a thread, I can't step through the program to discover how things are working.
My best guess is the SetBkColor and SetTextColor functions generate the WM_CTLCOLOR message somehow, which causes the CtlColor function to run, but I do not know where the return value is going--maybe ON_WM_CTLCOLOR_REFLECT()?
I would like to know; it would help me change the font of my control as well.
I noted the compiler did not let me change the names of the CReadOnlyEdit functions SetBkColor or SetTextColor
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hi How to make CReadOnlyEdit in MFC ClassWizard ? I can receive in "Add Member Variable" only 1)Category: Value Variable type: CString,int ... or 2)Category: Control Variable type: CEdit
and not CReadOnlyEdit ?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am new to this, but I believe you need to create the CReadOnlyEdit class before you do the "Add Member Variable" thing in the class wizard. With the CReadOnlyEdit having a base class of CEdit, the class wizard should then give you the option of CEdit or CReadOnlyEdit.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
 | merci  quicksoft | 20:45 15 Dec '05 |
|
|
 |
|
 |
Do not use white brush unless you absolutely want white background for your read only control.
What happens if the user changes the desktop color scheme and the text background color is now yellow. Your white background will be out of sync with the windows color scheme.
To use the standard windows color and to make things easy use the following code in the you CtlColor notification handler.
return GetSysColorBrush(COLOR_WINDOW);
Thats it. So the entire functions looks like
HBRUSH CSomeWindow::CtlColor(CDC* pDC, UINT nCtlColor) { return GetSysColorBrush(COLOR_WINDOW); }
Peace...
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
You actually need a bit more than a one-liner. If you want an arbitrary color for the background, create a CBrush of the appropriate color, and a color for your text. Here's code for a derived dialog with a CEdit control called m_edtMyEdit:
HBRUSH CMyDlg::OnCtlColor( CDC *pDC, CWnd *pWnd, UINT nCtlColor ) { HWND hWnd = pWnd->GetSafeHwnd(); if ( hWnd == m_edtMyEdit.GetSafeHwnd() ) { pDC->SetBkColor( m_clrBackground ); pDC->SetTextColor( m_clrText ); return (HBRUSH)m_brBackground; } else return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
what a fight!!!!!!!
to get the colors activated without using the controlvariable, just using it as a winform control: i had to rearrange the "DoPropExchange"..
void CCS_TBoxCtrl::DoPropExchange(CPropExchange* pPX) { PX_Color( pPX, _T("BackColor"), m_crBackGrnd );//Force permanent storing PX_Color( pPX, _T("ForeColor"), m_crForeColor ); OnBackColorChanged();// kick it in ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); } void CCS_TBoxCtrl::OnBackColorChanged(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); SetBackColor(m_crBackGrnd); //the Demo "SetBackColor" routine
SetModif iedFlag(); InvalidateControl(); }
thanks a lot for that codepiece!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Instead of setting the text backgound colour to match the brush using SetBkColor() why not just set the text backgound mode to transparent using SetBkMode( TRANSPARENT ), that way you don't need to store the text background colour and you can even use brush types other than solid.
I have tried this with your demo project and even changed the brush to a hatched type and it works fine. You should even be able to create a bitmap brush if you like, that way you can have any kind of pattern as the background.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
This might work for the control when it's style is read only and single line but this will cause residual droppings of text if you decide to use this control in the general sense and extend it's color capabilities such as when it's focused and when it's disabled.
If it's multiline, and you type some text and place the caret midstream in the text and start typing you will see what I mean. I would recommend using the authors technique of storing the brush and current color and ensuring the background is opaque.
SetBkMode(OPAQUE);
To be fair, I tried the Transparent solution a couple of years back but I quickly found during informal debugging that the potential for refresh issues exists when the control is used outside of the intended context.
|
| Sign In·View Thread·PermaLink | 3.50/5 |
|
|
|
 |
|
 |
Thank you for posting this article. Anyone who is willing to share handy classes & techniques should be applauded, and so I voted 5 for this article.
I encourage you to get in the habit of reading your code - and other's code - to try to learn and improve. I would like to offer the following suggestions for things to think about for your next update:
- With GDI objects, get in the habit of freeing them. In the dtor, you could write
CReadOnlyEdit::~CReadOnlyEdit() { if (m_brBackGnd.GetSafeHandle()) m_brBackGnd.DeleteObject(); }
- After creating a class like this, ask yourself, What is first thing someone will want to change? Well, to me, first thing I wanted to know was, how to change background color? You could easily implement a
SetBackgroundColor(COLORREF rgb) function, which might look like:
CReadOnlyEdit::SetBackgroundColor(COLORREF rgb) { if (m_brBackGnd.GetSafeHandle()) m_brBackGnd.DeleteObject(); m_brBackGnd.CreateSolidBrush(rgb); }
- The m_brBackGnd member variable should probably be protected.
Best wishes, Hans
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|
 |
|
 |
Good question. Unfortunately there ist (at least to my knowledge) no such thing like message reflection in the .NET Framework. So, the only place to handle WM_CTLCOLOR (or better WM_CTLCOLOREDIT) seems to be the parent form.
Do something like this:
"C#"> const int WM_CTLCOLOREDIT = 0x0133; const int WM_CTLCOLORSTATIC = 0x0138;
[DllImport("gdi32.dll")] internal static extern IntPtr CreateSolidBrush(int color); [DllImport("gdi32.dll")] internal static extern int SetBkColor(IntPtr hdc, int color);
protected override void WndProc(ref Message m) { base.WndProc (ref m);
if (m.Msg == WM_CTLCOLOREDIT) { SetBkColor(m.WParam, 0x8080FF); IntPtr brush = CreateSolidBrush(0x8080FF); m.Result = brush; }
if (m.Msg == WM_CTLCOLORSTATIC) { SetBkColor(m.WParam, 0x80FFFF); IntPtr brush = CreateSolidBrush(0x80FFFF); m.Result = brush; } }
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|
 |