locked
How to change the text color of a checkbox using Common Controls 6.0 RRS feed

  • Question

  • Prior to using Common Controls 6.0 in our Visual Studio 2003 build environment we were able to set the text color of a checkbox by using SetTextColor.  With Common Controls 6.0 we cannot.  This is documented in Article ID 944311.  In this article a workaround is given where the controls text is removed and a static control is used and the text color changed via the WM_CTLCOLORSTATIC handling.  Does anybody have a C/C++ example of how this is implemented?
    Friday, August 3, 2012 3:52 PM

Answers

  • Try this:

    BEGIN_MESSAGE_MAP(MyDialog, CDialog)
    	ON_NOTIFY(NM_CUSTOMDRAW, IDC_CHECK1, &MyDialog::OnNMCustomdraw)
    END_MESSAGE_MAP()
    void MyDialog::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMCUSTOMDRAW custDraw  = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
    	
    	if (custDraw->dwDrawStage == CDDS_PREPAINT)
    	{
    		const int textLength = ::GetWindowTextLength(custDraw->hdr.hwndFrom);
    		if (textLength > 0)
    		{
    			TCHAR* buttonText = new TCHAR[textLength+1];
    			SIZE   dimensions = {0};
    			::GetWindowText(custDraw->hdr.hwndFrom, buttonText, textLength+1);
    			::GetTextExtentPoint32(custDraw->hdc, buttonText, textLength, &dimensions);
    			const int xPos = (custDraw->rc.right - dimensions.cx) / 2;
    			const int yPos = (custDraw->rc.bottom - dimensions.cy) / 2;
    			::SetBkMode(custDraw->hdc, TRANSPARENT);
    			::SetTextColor(custDraw->hdc, RGB(24, 27, 255));
    			::TextOut(custDraw->hdc, xPos, yPos, buttonText, textLength);
    			delete [] buttonText;
    			*pResult = CDRF_SKIPDEFAULT;
    			return;
    		}
    	}
    	*pResult = CDRF_DODEFAULT;
    }

    -Seetharam

    • Proposed as answer by Jesse Jiang Monday, August 6, 2012 3:11 AM
    • Marked as answer by Donald Criley Monday, August 6, 2012 9:09 PM
    • Unmarked as answer by Donald Criley Thursday, August 9, 2012 6:09 PM
    • Unproposed as answer by Jesse Jiang Friday, August 10, 2012 2:46 AM
    • Proposed as answer by Jesse Jiang Monday, August 13, 2012 3:16 AM
    • Marked as answer by Jesse Jiang Tuesday, August 14, 2012 1:33 AM
    Saturday, August 4, 2012 1:39 PM
  • Just one more question. The statement is:

    const int xPos = (custDraw->rc.right - dimensions.cx) / 2;

    Why do we divide by 2?

    Thanks,

    Don

    • Marked as answer by Donald Criley Monday, August 13, 2012 6:03 PM
    Thursday, August 9, 2012 6:12 PM
  • I think it used to center align.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Donald Criley Monday, August 13, 2012 6:04 PM
    Friday, August 10, 2012 2:46 AM

All replies

  • Use the following to remove the visual styles and try WM_CTLCOLORSTATIC. You can also try below links

    SetWindowTheme(hCheckButtonHandle, L"", L"");

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/92941fec-ce5b-4061-ac5b-8fc48c60bc07/

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/cd6e7637-3550-4d1c-9b11-4f0f0965675f/


    Thanks, Renjith V R

    Friday, August 3, 2012 7:10 PM
  • That certainly works.  However without a theme the nice checkbox highlighting (orange) is also disabled.  We need the highlighting.

    Thanks.

    Friday, August 3, 2012 7:52 PM
  • 1) You first put a CComboBox  and make the caption blank.

    2) Then put a static control right to Combobox with the caption you want.

    Implement following handler

    HBRUSH CComboTextDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    {
    	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    	
    	if( CTLCOLOR_STATIC == nCtlColor  && pWnd->GetDlgCtrlID() == IDC_COMBOSTATIC )
        {			
            pDC->SetTextColor( RGB(255,0,0) );
        }
    
    	return hbr;
    }
    


    Thanks, Renjith V R

    • Proposed as answer by Jesse Jiang Monday, August 6, 2012 3:11 AM
    Saturday, August 4, 2012 8:16 AM
  • Try this:

    BEGIN_MESSAGE_MAP(MyDialog, CDialog)
    	ON_NOTIFY(NM_CUSTOMDRAW, IDC_CHECK1, &MyDialog::OnNMCustomdraw)
    END_MESSAGE_MAP()
    void MyDialog::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMCUSTOMDRAW custDraw  = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
    	
    	if (custDraw->dwDrawStage == CDDS_PREPAINT)
    	{
    		const int textLength = ::GetWindowTextLength(custDraw->hdr.hwndFrom);
    		if (textLength > 0)
    		{
    			TCHAR* buttonText = new TCHAR[textLength+1];
    			SIZE   dimensions = {0};
    			::GetWindowText(custDraw->hdr.hwndFrom, buttonText, textLength+1);
    			::GetTextExtentPoint32(custDraw->hdc, buttonText, textLength, &dimensions);
    			const int xPos = (custDraw->rc.right - dimensions.cx) / 2;
    			const int yPos = (custDraw->rc.bottom - dimensions.cy) / 2;
    			::SetBkMode(custDraw->hdc, TRANSPARENT);
    			::SetTextColor(custDraw->hdc, RGB(24, 27, 255));
    			::TextOut(custDraw->hdc, xPos, yPos, buttonText, textLength);
    			delete [] buttonText;
    			*pResult = CDRF_SKIPDEFAULT;
    			return;
    		}
    	}
    	*pResult = CDRF_DODEFAULT;
    }

    -Seetharam

    • Proposed as answer by Jesse Jiang Monday, August 6, 2012 3:11 AM
    • Marked as answer by Donald Criley Monday, August 6, 2012 9:09 PM
    • Unmarked as answer by Donald Criley Thursday, August 9, 2012 6:09 PM
    • Unproposed as answer by Jesse Jiang Friday, August 10, 2012 2:46 AM
    • Proposed as answer by Jesse Jiang Monday, August 13, 2012 3:16 AM
    • Marked as answer by Jesse Jiang Tuesday, August 14, 2012 1:33 AM
    Saturday, August 4, 2012 1:39 PM
  • Try this:

    BEGIN_MESSAGE_MAP(MyDialog, CDialog)
    	ON_NOTIFY(NM_CUSTOMDRAW, IDC_CHECK1, &MyDialog::OnNMCustomdraw)
    END_MESSAGE_MAP()
    void MyDialog::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMCUSTOMDRAW custDraw  = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
    	
    	if (custDraw->dwDrawStage == CDDS_PREPAINT)
    	{
    		const int textLength = ::GetWindowTextLength(custDraw->hdr.hwndFrom);
    		if (textLength > 0)
    		{
    			TCHAR* buttonText = new TCHAR[textLength+1];
    			SIZE   dimensions = {0};
    			::GetWindowText(custDraw->hdr.hwndFrom, buttonText, textLength+1);
    			::GetTextExtentPoint32(custDraw->hdc, buttonText, textLength, &dimensions);
    			const int xPos = (custDraw->rc.right - dimensions.cx) / 2;
    			const int yPos = (custDraw->rc.bottom - dimensions.cy) / 2;
    			::SetBkMode(custDraw->hdc, TRANSPARENT);
    			::SetTextColor(custDraw->hdc, RGB(24, 27, 255));
    			::TextOut(custDraw->hdc, xPos, yPos, buttonText, textLength);
    			delete [] buttonText;
    			*pResult = CDRF_SKIPDEFAULT;
    			return;
    		}
    	}
    	*pResult = CDRF_DODEFAULT;
    }

    -Seetharam


    That does it! Thanks - Don
    Monday, August 6, 2012 9:09 PM
  • Hi Don,

    This is just a confirmation for my knowledge.

    With Common Controls 6.0 we cannot. This is documented in Article ID 944311. In this article a workaround is given where the controls text is removed and a static control is used and the text color changed via the WM_CTLCOLORSTATIC handling

    1) You first put a CComboBox and make the caption blank.

    2) Then put a static control right to Combobox with the caption you want.

    Implement following handler

    HBRUSH CComboTextDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    {
    	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    	
    	if( CTLCOLOR_STATIC == nCtlColor  && pWnd->GetDlgCtrlID() == IDC_COMBOSTATIC )
        {			
            pDC->SetTextColor( RGB(255,0,0) );
        }
    
    	return hbr;
    }

    You asked about WM_CTLCOLORSTATIC handling. I want to know whether above solution working or not in Common Controls 6.0?


    Thanks, Renjith V R

    Wednesday, August 8, 2012 5:27 AM
  • Just one more question. The statement is:

    const int xPos = (custDraw->rc.right - dimensions.cx) / 2;

    Why do we divide by 2?

    Thanks,

    Don

    • Marked as answer by Donald Criley Monday, August 13, 2012 6:03 PM
    Thursday, August 9, 2012 6:12 PM
  • I think it used to center align.

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    • Marked as answer by Donald Criley Monday, August 13, 2012 6:04 PM
    Friday, August 10, 2012 2:46 AM