I want to make edit control's background transparent and change text's color to white. I can do both of them with this function, the only problem is that when you type on edit control, text keeps overlapping, follow the link for an example. I believe the problem is NULL_BRUSH, which makes background transparent, because if I change only the text color it works fine, unfortunately I need both.
How can I do this?
HBRUSH CDlg::OnCtlColor(CDC* pDc, CWnd* pWnd, UINT nCtlColor){
HBRUSH hbr = NULL;
switch (nCtlColor) {
case CTLCOLOR_EDIT:
if (pWnd->GetDlgCtrlID() == editControl){
pDc->SetBkMode(TRANSPARENT);
pDc->SetBkColor(TRANSPARENT);
pDc->SetTextColor(RGB(255, 255, 255));
hbr = (HBRUSH)GetStockObject(NULL_BRUSH);
}
break;
default:
hbr = CDialogEx::OnCtlColor(pDc, pWnd, nCtlColor);
}
return hbr;
}
Related
I'm trying to find a way to change background color of checkbox inside CListCtrl, please help me to find a working solution. Maybe there is some way to work with CListCtrl subitems inside the OnCtlColor function? I can change the text color and backcolor of CListCtrl, but can't find a way how to change the checkboxes background color...
HBRUSH CZilchDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if ( nCtlColor== CTLCOLOR_LISTBOX)
{
pDC->SetTextColor(RGB(255, 0, 0));
pDC->SetBkMode(TRANSPARENT);
pDC->SetBkColor(RGB(0,255,0));
hbr = m_brush;
}
return hbr;
}
I would like to have a CEdit control, background-painted half-length or in any other portion of its length.
I have implemented the following code
HBRUSH CMyView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_EDIT)
{
if (pWnd->GetDlgCtrlID() == IDC_MY_NORMAL_PERCENT_BOX)
{
// Set the text color to red
pDC->SetTextColor(RGB(255, 0, 0));
CRect rc;
// Get the client area of the edit control
m_CTV_Normal_Percent_Box_Ctrl.GetClientRect(&rc);
m_CTV_Normal_Percent_Box_Ctrl.ScreenToClient(&rc);
// Apply the device context to the client area of the edit control
pDC->Rectangle(0, 0, rc.Width()/2, rc.Height());
// Set the background mode for text to transparent
// so background will show thru.
pDC->SetBkMode(TRANSPARENT);
// Return handle to our CBrush object
hbr = m_brush;
}
}
return hbr;
}
but this could not be achieved. Could anyone possibly assist?
This is what I would like to get
and this is what I get
Thanks in advance.
My goal is to replace a background for the common-control's edit control. My current code does this:
HBITMAP hBmp = ::LoadBitmap(hInstance, MAKEINTRESOURCE(BKGND_ID));
HBRUSH hBkgndBrush = ::CreatePatternBrush(hBmp);
::DeleteObject(hBmp);
HBRUSH CDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if(pWnd->GetDlgCtrlID() == MY_CTRL_ID && hBkgndBrush)
{
hbr = hBkgndBrush;
//Do I need to select it?
//pDC->SelectObject(hbr); //This line?
pDC->SetBkMode(TRANSPARENT);
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
The question is, do I need to select hbr before returning it? (See commented out line above.) I seem to see it done both ways in different examples online.
EDIT: Also forgot to mention, I override WM_ERASEBKGND as such:
HDC hDc = ::GetDC(hWnd);
if(hDc)
{
RECT rc = {0};
::GetClientRect(hWnd, &rc);
::FillRect(hDc, &rc, hBkgndBrush);
::ReleaseDC(hWnd, hDc);
}
EDIT2: I made a small sample MFC project to illustrate the issue. Basically, when I move the app quickly off the screen and then back, it creates this visual "glitch" but only if control doesn't have ES_MULTILINE style:
When background brush is created from bitmap using CreatePatternBrush, some "repeating artifacts" may occur during dialog resizing or moving.
To remove these artifacts, force the child controls to repaint in response to ON_WM_WINDOWPOSCHANGED message:
void CMyDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
CDialog::OnWindowPosChanged(wndpos);
CWnd *wnd = GetWindow(GW_CHILD);
while (wnd)
{
wnd->Invalidate(TRUE);
wnd = wnd->GetWindow(GW_HWNDNEXT);
}
}
or
void CMyDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
CDialog::OnWindowPosChanged(wndpos);
edit1.Invalidate(FALSE);
edit2.Invalidate(FALSE);
...
}
OnCtlColor override will be as follows:
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_DLG)
return CDialogEx::OnCtlColor(pDC, wnd, nCtlColor);
pDC->SetBkMode(TRANSPARENT);
return hBkgndBrush;
}
You can add other conditions based on wnd or nCtlColor to change the background of edit control only.
How to change the background color of a edit box if user modifies its content in MFC.
How to change it in ON_EN_CHANGE MSg of a Edit control.
basically your solution is
HBRUSH CEditDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
switch (nCtlColor) {
case CTLCOLOR_EDIT:
case CTLCOLOR_MSGBOX:
// Set color to green on black and return the background
brush.
pDC->SetTextColor(RGB(0, 255, 0));
if(ChangeColor == TRUE)
{
pDC->SetBkColor(RGB(0, 0, 0));
ChangeColor = FALSE;
}
return (HBRUSH)(m_pEditBkBrush->GetSafeHandle());
default:
return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}
}
Now you want textbox color change on text change then,
::OnEnchange()
{
ChangeColor = TRUE; //Its global flag maintain in any global position may be in your .H file.
}
The MFC combobox is really a wierd design.
I use "drop list" type combo box.
HBRUSH CValueInputDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hBrush = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_STATIC || nCtlColor == CTLCOLOR_EDIT)
{
pDC->SetTextColor(RGB(255, 255, 255));
pDC->SetBkMode(TRANSPARENT);
hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
}
return hBrush;
}
what I do is having all my CStatic and CEdit color WHITE.
but i discover that I also change the combobox's edit to white.
that is what I don't want.
that is what I don't want. and I can't stop it from
pWnd->GetDlgCtrlID() == IDC_COMBO
it is so unfriendly. this combo box.
The Edit box is a child of the combo box. Try this:
pWnd->GetParent()->GetDlgCtrlID() == IDC_COMBO