How can I change background/text color of CComboBox ?
-
How can I change background / text color of an CComboBox , but that have CBS_DROPDOWNLIST style ? Thank you .
You need to handle OnCtlColor()[^] in your parent window to check (nCtlColor == CTLCOLOR_EDIT) condition for normal state. You need to subclass CComboBox and handle OnCtlColor() to check (nCtlColor == CTLCOLOR_LISTBOX) condition for dropped down state, that is, while the list box is visible. In this case a child LB is created on the fly. In OnCtlColor() members:
pDC->SetTextColor(clrTextColor));
pDC->SetBkColor(clrBkColor);
if(NULL == m_pBrush)
m_pBrush = new CBrush(clrBkColor); // this is for demonstration purposes
return (HBRUSH)*m_pBrush; // you can handle this brush more convenient wayDon't forget to return HBRUSHes in both cases.
-
You need to handle OnCtlColor()[^] in your parent window to check (nCtlColor == CTLCOLOR_EDIT) condition for normal state. You need to subclass CComboBox and handle OnCtlColor() to check (nCtlColor == CTLCOLOR_LISTBOX) condition for dropped down state, that is, while the list box is visible. In this case a child LB is created on the fly. In OnCtlColor() members:
pDC->SetTextColor(clrTextColor));
pDC->SetBkColor(clrBkColor);
if(NULL == m_pBrush)
m_pBrush = new CBrush(clrBkColor); // this is for demonstration purposes
return (HBRUSH)*m_pBrush; // you can handle this brush more convenient wayDon't forget to return HBRUSHes in both cases.
posted your solution as a question... this isn't jeopardy! ;P ...i was about to give you a 5 when i noticed all i could choose was "good question/bad question"...
-
posted your solution as a question... this isn't jeopardy! ;P ...i was about to give you a 5 when i noticed all i could choose was "good question/bad question"...
:) I don't know how it could be? Thanks. I will try to put my signature permanently. I remember, seeing you. :) Edit: It again didn't save it permanently. :^)
Time is never on our side! -- Albert Holguin
-
:) I don't know how it could be? Thanks. I will try to put my signature permanently. I remember, seeing you. :) Edit: It again didn't save it permanently. :^)
Time is never on our side! -- Albert Holguin
-
Hi, which background you are talking about whether drop down list or in combo box itself.
-
Hi, which background you are talking about whether drop down list or in combo box itself.
I mean drop down list , not edit box where I succeded :
HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else pDC->SetBkColor(COLOR\_ALERT); } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired if(m\_bAlertBkg)return m\_hBrushAlert; return m\_hBrushWhite;
}
well , I change CTLCOLOR_EDIT with CTLCOLOR_LISTBOX but with no effect ... I don't know why ...
-
I mean drop down list , not edit box where I succeded :
HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else pDC->SetBkColor(COLOR\_ALERT); } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired if(m\_bAlertBkg)return m\_hBrushAlert; return m\_hBrushWhite;
}
well , I change CTLCOLOR_EDIT with CTLCOLOR_LISTBOX but with no effect ... I don't know why ...
In above code, that is, subclassed combo box's OnCtlColor() member, you should handle CTLCOLOR_LISTBOX for dropped-down list box. May be, subclassing fails. To ensure that above code is called, put the following line on top of function.
TRACE(_T("CComboBoxExt::OnCtlColor() was called with nCtlColor: %d\n"), nCtlColor);
And watch output window to see above phrase. -
I mean drop down list , not edit box where I succeded :
HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else pDC->SetBkColor(COLOR\_ALERT); } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired if(m\_bAlertBkg)return m\_hBrushAlert; return m\_hBrushWhite;
}
well , I change CTLCOLOR_EDIT with CTLCOLOR_LISTBOX but with no effect ... I don't know why ...
I did not tried the subclassed combobox, but according to msdn, http://msdn.microsoft.com/en-us/library/0wwk06hc(v=vs.80).aspx[^] In subclassed combobox you have to handle CTLCOLOR_LISTBOX to change the color. I tried handling OnCtlColor in dialog box,with nCtrClr == (IDOFCOMBOBOX),it is working
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);if (pWnd->GetDlgCtrlID() == IDC_COMBO1)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(128,128, 128));
hbr = m_brush;
}return hbr;
} -
In above code, that is, subclassed combo box's OnCtlColor() member, you should handle CTLCOLOR_LISTBOX for dropped-down list box. May be, subclassing fails. To ensure that above code is called, put the following line on top of function.
TRACE(_T("CComboBoxExt::OnCtlColor() was called with nCtlColor: %d\n"), nCtlColor);
And watch output window to see above phrase.I think I am in dead point ... I use already OnCtlColorListBox but for other reason , and with other signature :
ON_MESSAGE(WM_CTLCOLORLISTBOX, OnCtlColorListBox)
...
...LRESULT CComboBoxExt::OnCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so...
if(m_hListBox == NULL)
{
HWND hWnd = reinterpret_cast(lParam);
if(hWnd != 0 && hWnd != m_hWnd)
{
// Save the listbox handle
m_hListBox = hWnd;
// Do the subclassing
m_pWndProc = reinterpret_cast(GetWindowLong(m_hListBox, GWL_WNDPROC));
SetWindowLong(m_hListBox, GWL_WNDPROC, reinterpret_cast(ComboBoxListBoxProc));
}
}return 1;
}
to get a handle to list box window ...
-
In above code, that is, subclassed combo box's OnCtlColor() member, you should handle CTLCOLOR_LISTBOX for dropped-down list box. May be, subclassing fails. To ensure that above code is called, put the following line on top of function.
TRACE(_T("CComboBoxExt::OnCtlColor() was called with nCtlColor: %d\n"), nCtlColor);
And watch output window to see above phrase.To make a review :
ON\_MESSAGE(WM\_CTLCOLORLISTBOX, OnCtlColorListBox) ON\_WM\_CTLCOLOR()
LRESULT CComboBoxExt::OnCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so...
if(m_hListBox == NULL)
{
HWND hWnd = reinterpret_cast(lParam);
if(hWnd != 0 && hWnd != m_hWnd)
{
// Save the listbox handle
m_hListBox = hWnd;
// Do the subclassing
m_pWndProc = reinterpret_cast(GetWindowLong(m_hListBox, GWL_WNDPROC));
SetWindowLong(m_hListBox, GWL_WNDPROC, reinterpret_cast(ComboBoxListBoxProc));
}
}return 1;
}
HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired return hbr;
}
-
I think I am in dead point ... I use already OnCtlColorListBox but for other reason , and with other signature :
ON_MESSAGE(WM_CTLCOLORLISTBOX, OnCtlColorListBox)
...
...LRESULT CComboBoxExt::OnCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so...
if(m_hListBox == NULL)
{
HWND hWnd = reinterpret_cast(lParam);
if(hWnd != 0 && hWnd != m_hWnd)
{
// Save the listbox handle
m_hListBox = hWnd;
// Do the subclassing
m_pWndProc = reinterpret_cast(GetWindowLong(m_hListBox, GWL_WNDPROC));
SetWindowLong(m_hListBox, GWL_WNDPROC, reinterpret_cast(ComboBoxListBoxProc));
}
}return 1;
}
to get a handle to list box window ...
Yes. This blocks OnCtlColor(CTLCOLOR_LISTBOX). OnCtlColor() (WM_CTLCOLOR) is retained from 16Bit Windows and should be managed by MFC using newer messages like WM_CTLCOLORLISTBOX. You can also use this handler to do your work, the HDC is wParam and you need to return a valid HBRUSH. But, above return value is invalid (as brush). Probably, that listbox should paint itself if this doesn't produce a problem. In this case, how could you paint again?
-
To make a review :
ON\_MESSAGE(WM\_CTLCOLORLISTBOX, OnCtlColorListBox) ON\_WM\_CTLCOLOR()
LRESULT CComboBoxExt::OnCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so...
if(m_hListBox == NULL)
{
HWND hWnd = reinterpret_cast(lParam);
if(hWnd != 0 && hWnd != m_hWnd)
{
// Save the listbox handle
m_hListBox = hWnd;
// Do the subclassing
m_pWndProc = reinterpret_cast(GetWindowLong(m_hListBox, GWL_WNDPROC));
SetWindowLong(m_hListBox, GWL_WNDPROC, reinterpret_cast(ComboBoxListBoxProc));
}
}return 1;
}
HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired return hbr;
}
Don't use both. Use 1st one.
LRESULT CComboBoxExt::OnCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so
...// CWnd \*pWnd = CWnd::FromHandle((HWND)lParam); // UINT nID = npWnd->GetDlgCtrlID(); // nCtlColor = CTLCOLOR\_LISTBOX; CDC\* pDC = CDC::FromHandle((HDC)wParam); // move your attributes here ... return hbr;
}
-
To make a review :
ON\_MESSAGE(WM\_CTLCOLORLISTBOX, OnCtlColorListBox) ON\_WM\_CTLCOLOR()
LRESULT CComboBoxExt::OnCtlColorListBox(WPARAM wParam, LPARAM lParam)
{
// If the listbox hasn't been subclassed yet, do so...
if(m_hListBox == NULL)
{
HWND hWnd = reinterpret_cast(lParam);
if(hWnd != 0 && hWnd != m_hWnd)
{
// Save the listbox handle
m_hListBox = hWnd;
// Do the subclassing
m_pWndProc = reinterpret_cast(GetWindowLong(m_hListBox, GWL_WNDPROC));
SetWindowLong(m_hListBox, GWL_WNDPROC, reinterpret_cast(ComboBoxListBoxProc));
}
}return 1;
}
HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired return hbr;
}
BTW, beware that list box is already subclassed by other reason. If it paints itself without using windows behaviour, that is, without sending WM_CTLCOLOR notifications to its parent, your attempt can be failed again.
-
I did not tried the subclassed combobox, but according to msdn, http://msdn.microsoft.com/en-us/library/0wwk06hc(v=vs.80).aspx[^] In subclassed combobox you have to handle CTLCOLOR_LISTBOX to change the color. I tried handling OnCtlColor in dialog box,with nCtrClr == (IDOFCOMBOBOX),it is working
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);if (pWnd->GetDlgCtrlID() == IDC_COMBO1)
{
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(128,128, 128));
hbr = m_brush;
}return hbr;
}I solve the problem in the follow matter :
// header
CListBox m_ListBox;// implementation
ON_WM_CTLCOLOR()HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(m\_Edit.GetSafeHwnd() == NULL) { m\_Edit.SubclassWindow(pWnd->GetSafeHwnd()); } if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } if(nCtlColor == CTLCOLOR\_LISTBOX) { if(m\_ListBox.GetSafeHwnd() == NULL) { m\_ListBox.SubclassWindow(pWnd->GetSafeHwnd()); m\_pWndProc = reinterpret\_cast<WNDPROC>(GetWindowLong(m\_ListBox, GWL\_WNDPROC)); SetWindowLong(m\_ListBox, GWL\_WNDPROC, reinterpret\_cast<long>(ComboBoxListBoxProc)); } if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired return hbr;
}
I get handle of drop down list box in OnCtlColor but I still have an question : How can I change text / background color of edit while combo box have CBS_DROPDOWNLIST style ?
-
I solve the problem in the follow matter :
// header
CListBox m_ListBox;// implementation
ON_WM_CTLCOLOR()HBRUSH CComboBoxExt::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: Change any attributes of the DC here if(nCtlColor == CTLCOLOR\_EDIT) { if(m\_Edit.GetSafeHwnd() == NULL) { m\_Edit.SubclassWindow(pWnd->GetSafeHwnd()); } if(! m\_bAlertText)pDC->SetTextColor(COLOR\_BLACK); else pDC->SetTextColor(COLOR\_RED); if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } if(nCtlColor == CTLCOLOR\_LISTBOX) { if(m\_ListBox.GetSafeHwnd() == NULL) { m\_ListBox.SubclassWindow(pWnd->GetSafeHwnd()); m\_pWndProc = reinterpret\_cast<WNDPROC>(GetWindowLong(m\_ListBox, GWL\_WNDPROC)); SetWindowLong(m\_ListBox, GWL\_WNDPROC, reinterpret\_cast<long>(ComboBoxListBoxProc)); } if(! m\_bAlertBkg)pDC->SetBkColor(COLOR\_WHITE); else { pDC->SetBkColor(COLOR\_ALERT); hbr = m\_hBrushAlert; } } pDC->SetBkMode(TRANSPARENT); // TODO: Return a different brush if the default is not desired return hbr;
}
I get handle of drop down list box in OnCtlColor but I still have an question : How can I change text / background color of edit while combo box have CBS_DROPDOWNLIST style ?
-
Finllay I solve my problem , and for that I thank you very much , for you kindness and for your patient . ! Best wishes !
I solve the problem in follow way :
class CMyComboBox : public CComboBox
{
// ...
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
// ...
};and
//...
ON_WM_CTLCOLOR_REFLECT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMyComboBox message handlersHBRUSH CMyComboBox::CtlColor(CDC* pDC, UINT nCtlColor)
{
HBRUSH hBrush = NULL;
switch(nCtlColor)
{
case CTLCOLOR_EDIT:
{
pDC->SetBkColor(RGB(255, 0, 0));
pDC->SetTextColor(RGB(255, 255, 255));
hBrush = m_brush;
}
break;
//...
}
return hBrush;
}