11

I know it can be done with OnCtlColor(), but it changes colors when the form is being loaded and the static texts are to be drawn, I want to do it after form is loaded, with a timer maybe, I searched for a solution but I didn't find a clear one, this is what I wrote:

void CTabFive::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here
    CWnd* pWnd = this->GetDlgItem(IDC_Chromosome1);
    CDC* dc = pWnd->GetDC();
    dc->SetBkColor(RGB(200,0,0));
    pWnd->Invalidate();
    pWnd->UpdateWindow();
    Invalidate();
    UpdateWindow();
    //flag = true;
}
  • 1
    OnCtlColor should be called every time when a control is redrawn. Try to invalidate the window, and write OnCtlColor function which works depending on the current state - for example, using some variables set by WM_TIMER handler. – Alex F Aug 17 '12 at 13:23
  • @AlexFarber : Is there anyway to invalidate just one control of the form not the whole form? cause when I use invalidate it redraws the whole form and it causes a blink! – Saman Hakimzadeh Abyaneh Sep 02 '12 at 14:15
  • great, `pWnd->Invalidate(); pWnd->UpdateWindow();` solve my problem. – Zhang Jun 03 '20 at 07:42

1 Answers1

11

No timer is needed. Here I have a bool m_coloured member of the class initialized to false, and toggled in the button press. The OnCtlColor will draw in red or in the system colour depending on the value of m_coloured. Works nicely.

HBRUSH Cmfcvs2010Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

    if (nCtlColor == CTLCOLOR_STATIC && pWnd->GetDlgCtrlID() == IDC_LABEL)
    {
        DWORD d = GetSysColor(COLOR_BTNFACE);

        COLORREF normal = RGB(GetRValue(d), GetGValue(d), GetBValue(d));
        COLORREF red = RGB(255, 0, 0);

        pDC->SetBkColor(m_coloured ? red : normal);

    }
    return hbr;
}


void Cmfcvs2010Dlg::OnBnClickedButton1()
{
    m_coloured = !m_coloured;
    Invalidate();
}
acraig5075
  • 10,588
  • 3
  • 31
  • 50
  • 1
    Is there anyway to invalidate just one control of the form not the whole form? cause when I use invalidate it redraws the whole form and it causes a blink! – Saman Hakimzadeh Abyaneh Sep 02 '12 at 14:16
  • 2
    @SamanHakimzadeh Not easily because the OnCtlColor is overriden for the dialog not the control. If you want only the control to invalidate, then you must subclass the CStatic control, override only it's OnCtlColor (not the dialog's), and call only it's Invalidate instead. – acraig5075 Sep 02 '12 at 17:21
  • 1
    Using your code, it only changed background color of written text area. It doesn't draw entire background color of static text control. How can I do this? – Nipun May 01 '14 at 11:03
  • 1
    @Nipun I can color the whole background by returning `(HBRUSH)CreateSolidBrush(yourDesiredCOLORREF)` from `OnCtlColor`. However, I have not managed to also color the modal frame border (if you have one). – Gutblender Apr 10 '15 at 15:41