Edit control not repainted entirely with chosen brush

Deadly 提交于 2019-12-12 18:27:22

问题


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:

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

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:

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?


回答1:


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;



回答2:


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());


来源:https://stackoverflow.com/questions/23378938/edit-control-not-repainted-entirely-with-chosen-brush

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!