Search code examples
c++visual-studiouser-controlsmfc

How to avoid EN_CHANGE notifications when sending WM_SETTEXT?


I have a CEdit derived control that displays the string "N/A" when the undelying data is null. I recently added code to empty the control(SetWindowText("");) when it gains focus and set if back to "N/A"(SetWindowText("N/A")) when the focus is lost if the user left the control empty.

The only problem is that setting the window text to "" or "N/A" triggers EN_CHANGE, so my dialog thinks that the data has changed.

How can I avoid EN_CHANGE from being fired when calling SetWindowText (WM_SETTEXT)?

NOTES

-I know I can set the edit control to Multiline=TRUE but that's not accpectable for me.

-My application is MBCS so I can't use SetCueBanner

-I want an elegant solution. Setting the parent window to NULL temporarily is not an elegant solution.

EDIT:

-I want the solution to be in my custom control, not in each dialog

Thanks


Solution

  • I finally found a suitable solution to my problem.

    First, I added a flag to my derived control's header file and I initialized it to false in the constructor

    bool m_bNoEnChange;
    

    I overrode the OnChildNotify in my derived control's header file and in the implementation, I checked for the WM_COMMAND message with the EN_CHANGE parameter. I then returned TRUE to prevent the message from being sent to the parent(dialog/page)

    virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult);
    

    BOOL CADEdit::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) 
    {
        if(message == WM_COMMAND && HIWORD(wParam) == EN_CHANGE)
        {
            //If the flag is set, don't send the message to the parent window
            if(m_bNoEnChange)
                return TRUE;
        }
    
        return CEdit::OnChildNotify(message, wParam, lParam, pLResult);
    }
    

    Finally, when the control gains and loses focus, I wrapped the problematic SetWindowText with my flag

    m_bNoEnChange = true;
    SetWindowText(_T(""));
    m_bNoEnChange = false;
    

    This solution is the best in my case because I don't have to modify each dialog.