CPaneDialog control backgroung (text control) - c++

In my application I have CPaneDialog with controls (e.g. Text control). I try to set background color for this CPanelDialog. For this purpose, I overwrited OnEraseBkgnd
BOOL CBgPaneDialog::OnEraseBkgnd(CDC* pDC)
{
CBrush backBrush(RGB(255, 128, 128));
CBrush* pOldBrush = pDC->SelectObject(&backBrush);
CRect rect;
pDC->GetClipBox(&rect); // Erase the area needed
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY);
pDC->SelectObject(pOldBrush);
return TRUE;
}
Unfortunately, controls on this CPaneDialog have other background.
http://fotoo.pl//out.php?t=964580_text.png
I overwrot next method: OnCtlColor to set caontrol's backgorund.
HBRUSH CBgPaneDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CBrush br;
br.CreateSolidBrush(RGB(255,255,255));
HBRUSH hbr = (HBRUSH)br;
CWnd *pCheckBox = GetDlgItem(IDC_STATIC); // put ID of your checkbox here.
int a;
if (*pCheckBox == *pWnd)
{
br.DeleteObject();
br.CreateSolidBrush(a=pDC->SetBkColor(RGB(255, 128, 128)));
hbr = (HBRUSH)br;
}
else
hbr = CPaneDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
The control's background have changed, but not completely. Please see in the picture:
http://fotoo.pl//out.php?i=964579_textcontrol.jpg
How can I change background completely for the text control?

Don't return temporary brush. Your code is okay for OnEraseBkgnd() because it's using the brush, not returning it, but for OnCtlColor use this instead:
class CMyDialog ...
{
COLORREF BkColor;
CBrush BkBrush;
//...
};
CMyDialog::CMyDialog...
{
BkColor = RGB(0, 255, 255);
BkBrush.CreateSolidBrush(BkColor);
}
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
//add conditions...
pDC->SetBkColor(BkColor);
return BkBrush;
}
By the way, you can add mfc tag to your question to get faster answer in future.

Related

MFC CEdit - Painting the Background at a Portion of Length

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.

Do I need to select HBRUSH when replacing background in the edit control?

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.

Change color of scrollbar of CListCtrl

I have a class derived from CListCtrl, named CListCtrlExt, which I need to change the color of scrollbars ... how can I achieve that ?
I made an trial, like that:
HBRUSH CListCtrlExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CListCtrl::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if(CTLCOLOR_SCROLLBAR == nCtlColor)
{
pDC->SetBkColor(RGB(0, 0, 0));
HBRUSH b = CreateSolidBrush(RGB(233,233,220));
return b;
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
nor even pass by here ... another trial:
HBRUSH CTestDlg2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if(pWnd == GetDlgItem(IDC_LIST1) && CTLCOLOR_SCROLLBAR == nCtlColor)
{
pDC->SetBkColor(RGB(0, 0, 0));
HBRUSH b = CreateSolidBrush(RGB(0, 0, 0));
return b;
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
not working either ...
I also have a CScrollbarEx (from here), but I don't know how to attach it on my CListCtrlExt ... can you help me, please ?

Creating a custom dialog in mfc

I need to create a custom dialog in mfc which has a different appearance than the usual MFC dialogs.For example the color should be blue, the style etc. Is it possible? How can I do this?
I googled the background color:
See
here
//CMyDlg.h
//Add a CBrush object
class CMyDlg : public CDialog
{
// Construction
public:
CTest2Dlg(CWnd* pParent = NULL); // standard constructor
CBrush m_brush;
// Dialog Data
//initialize the brush with the desired color in the OnInitDialog() methodl
BOOL CMyDlg::OnInitDialog()
{
m_brush.CreateSolidBrush(RGB(255,0,0));
CDialog::OnInitDialog();
}
//Return the brush like this:
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Return a different brush if the default is not desired
return m_brush;
}'

Stop OnCtlColor() changing combobox's (edit control)'s "text color"

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