سؤال

I have an edit control which background color depends from validity of user input.

If input is valid edit control should keep default look, else the background color should change to light gray.

I am checking validity in EN_UPDATE handler and if it is invalid I store the HWND of the edit control into vector.

Visual Styles are enabled.

The problem comes when I change the position of the mouse pointer. Let me describe it:

  1. I click on edit control and type invalid input.

  2. I move mouse pointer elsewhere, but edit control still has focus.

  3. Now I delete invalid input by pressing backspace.

  4. As soon as input becomes valid the color changes properly, but borders become thicker/darker.

These pictures illustrate the problem:

Edit control before typing in data: enter image description here

Edit control when user pastes invalid data ( mouse pointer is in grey area ): enter image description here

The last character is r.

Now if mouse pointer is out of edit control's client area ( on dialog's client area for example ) and user deletes r here is what I get: enter image description here

Notice the thicker border.

When mouse pointer hovers above the edit control it gets repainted properly.

Here are the relevant code snippets ( if needed I can submit a small SSCCE ) :

// minimal code snippet for EN_UPDATE
case WM_COMMAND:
{
    switch( LOWORD(wParam) )
    {
    case IDC_MYEDIT:
        {
            if( HIWORD(wParam) == EN_CHANGE )
            {
                if( /* invalid input */ )
                {
                    // store HWND into vector

                } 
                // InvalidateRect(...); // tried this too...
            }
        }
        break;

// minimal code snippet for WM_CTLCOLOREDIT
case WM_CTLCOLOREDIT:
    {
        if( /* this control is stored in vector */ )
        {
            //=== then this is invalid entry->paint it grey ===//

            // Needed SetBkMode for text's background transparency 
            SetBkMode( (HDC)wParam, TRANSPARENT ); 
            // return light gray brush 
            return (INT_PTR)( (HBRUSH)GetStockObject( LTGRAY_BRUSH ) );
        }
        else
            return DefWindowProc( ... );  // default processing
    }

How can I fix this?

هل كانت مفيدة؟

المحلول

I have found a solution to my problem. I just added RedrawWindow instead of InvalidateRect and ordered frame to be redrawn as well :

// minimal code snippet for EN_UPDATE
case WM_COMMAND:
{
    switch( LOWORD(wParam) )
    {
    case IDC_MYEDIT:
        {
            if( HIWORD(wParam) == EN_CHANGE )
            {
                if( /* invalid input */ )
                {
                    // store HWND into vector

                }

                // after finishing validation, redraw window INCLUDING THE FRAME
                // This solves the problem with edges entirely

                RedrawWindow( (HWND)lParam, NULL, NULL,
                    RDW_ERASE | RDW_FRAME | RDW_INVALIDATE );
            }
        }
        break;

نصائح أخرى

Please try handling case for message CTLCOLOR_MSGBOX as well. Refer to this MSDN article for more details.

How to change the background color of an MFC edit control

Snapshot of sample code given in link

  case CTLCOLOR_EDIT:
  case CTLCOLOR_MSGBOX:
      // Set color to green on black and return the background
         brush.
      pDC->SetTextColor(RGB(0, 255, 0));
      pDC->SetBkColor(RGB(0, 0, 0));
      return (HBRUSH)(m_pEditBkBrush->GetSafeHandle());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top