How to avoid EN_CHANGE notifications when sending WM_SETTEXT?

I have a CEdit control that displays the string "N / A" when the undetectable data is zero. I recently added code for an empty control (SetWindowText ("");) when it receives focus and sets it back to "N / A" (SetWindowText ("N / A")) when focus is lost if the user leaves Empty control.

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

How can I avoid running EN_CHANGE when calling SetWindowText (WM_SETTEXT)?

NOTES

-I know that I can set the editing control Multiline = TRUE, but that does not match me.

-My application is MBCS, so I can not use SetCueBanner

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

EDIT:

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

thank

+5
source share
5 answers

I finally found a suitable solution to my problem.

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

bool m_bNoEnChange;

I overridden OnChildNotify in my derived control header file and in the implementation, I checked the WM_COMMAND message with the EN_CHANGE parameter. Then I returned TRUE to prevent sending a message to my parents (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);
}

, , SetWindowText

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

, .

+4

, ( , 20 , , ), . , , EN_CHANGE:

void CMyDialog::MyFunction()
{    
    setEditTextProgramatically = true;  
    c_Edit.SetWindowText(_T("Whatever"));  
    setEditTextProgramatically = false;
}

void CMyDialog::OnEnChangeEdit()
{
    if (!setEditTextProgramatically)
    {
        // Do whatever you need to do
    }
}

, , , .

, MFC , , .

+7

(EnableWindow(FALSE) WM_ENABLE FALSE) WM_SETTEXT, . EN_CHANGE

There is probably another elegant method: p

+2
source

The code below uses the C ++ 11 function, but it can be easily changed.

HEADER

// CEditOptionalNotify.h
//
// CEdit derived class allowing the control text value to be
// set without (optionally) causing EN_CHANGE processing.
//
#pragma once

class CEditOptionalNotify : public CEdit
{
    //DECLARE_DYNAMIC(CEditOptionalNotify)
    // Enable use of RUNTIME_CLASS macro and CObject::IsKindOf()

public:

    CEditOptionalNotify();
    virtual ~CEditOptionalNotify();

    enum class PerformOnChangeProcessing { No, Yes };
    void vSetText(const TCHAR* pText, PerformOnChangeProcessing e);

protected:

    afx_msg BOOL bConsiderEnChangeAsHandled();

    bool m_bChangeNotificationsEnabled;

    DECLARE_MESSAGE_MAP()
};

IMPLEMENTATION

// EditOptionalNotify.cpp : implementation file
//

#include "stdafx.h"
#include <EditOptionalNotify.h>

//IMPLEMENT_DYNAMIC(CEditOptionalNotify, CEdit)

CEditOptionalNotify::CEditOptionalNotify() :
    m_bChangeNotificationsEnabled(true)
{ 
}

CEditOptionalNotify::~CEditOptionalNotify()
{
}


BEGIN_MESSAGE_MAP(CEditOptionalNotify, CEdit)
    ON_CONTROL_REFLECT_EX(EN_CHANGE, bConsiderEnChangeAsHandled)
END_MESSAGE_MAP()


BOOL CEditOptionalNotify::bConsiderEnChangeAsHandled()
{
    return (m_bChangeNotificationsEnabled ? FALSE : TRUE);
}


void CEditOptionalNotify::vSetText(const TCHAR* pText, PerformOnChangeProcessing e)
{
    bool bChangeNotificationsDesired = (PerformOnChangeProcessing::No == e ? false : true);

    if (bChangeNotificationsDesired != m_bChangeNotificationsEnabled)
    {
        m_bChangeNotificationsEnabled = bChangeNotificationsDesired;
        CEdit::SetWindowText(pText);
        m_bChangeNotificationsEnabled = (bChangeNotificationsDesired ? false : true);
    }
    else
        CEdit::SetWindowText(pText);
}
+1
source

If anyone else finds this discussion ...

As Stephen wrote, UpdateData does not cause sending EN_CHANGE.

Under the hood, MFC calls AfxSetWindowText, with which you can specify one hwnd.

-1
source

All Articles