In MFC CEdit control, calling setwindowtext and setsel in EN_UPDATE makes ctrl+z not working?

abc abc 351 Reputation points
2022-05-22T12:09:34.997+00:00

Hi,

In MFC CEdit control, calling setwindowtext and setsel in EN_UPDATE makes ctrl+z not working?

I need to allow only 0 to 2147483647 if user typ more than this value, in EN_UPDATE I am resetting the value previously typed valid value.

If I reset the value in EN_UPDATE, the ctrl+z (undo/redo) is not working?

void CObjIdEdit::OnEnUpdate()
{
 CString szText;
    GetWindowText( OUT szText );

 // Get the number of digits in the INT_MAX.
 CString szIntMax;
 szIntMax.Format( L"%ld", INT_MAX ); // void.
 int iLength = szIntMax.GetLength();
 __int64 i64Data = _wtoi64( szText );
 int iGoodValueLength = m_szGoodValue.GetLength();

 // If the value is greater than INT_MAX(2147483647), get the number with digits  
 // of one subtracted from number of digits of INT_MAX.
 if( i64Data > INT_MAX )
 {
 // Find the caret position.
 int iStartChar = 0;
 int iEndChar = 0;
 GetSel( OUT iStartChar, OUT iEndChar ); // void.
 int nTotalLength = szText.GetLength();

 // Get good value by subtracting digits.
 if( iGoodValueLength != iLength )
 {
 // Get good value by subtracting digits.
 CString szValue = szText;
 //int nTotalLength = szText.GetLength();
 int iDiff = ( nTotalLength - ( iLength - 1 ) );
 int iIndex = iStartChar - iDiff - 1;
 szValue.Delete( iIndex, iDiff );
 m_szGoodValue = szValue;

 // Calculate start and end position.
 int iLenDiff = nTotalLength - iLength ;
 if( iStartChar > iLength) iStartChar -= iLenDiff;
 if( iEndChar > iLength) iEndChar -= iLenDiff;
 }

 // Set Value.
 SetSel( 0, -1, true );
 ReplaceSel( m_szGoodValue, true);
 //SetWindowText( m_szGoodValue ); // void.

 // Restore the caret.
 if( iStartChar > iLength ) iStartChar = iLength;
 if( iEndChar > iLength ) iEndChar = iLength;
 SetSel( iStartChar - 1, iEndChar - 1, true ); // void.
 }
 else
 {
 // Copy the text.
  m_szGoodValue = szText;
 }
}

How to resolve this issue?

Thanks

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,849 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. RLWA32 46,941 Reputation points
    2022-05-22T13:57:07.907+00:00

    Calling SetWindowText clears the edit control undo flag. Use ReplaceSel instead but be careful of reentering the event handler and stack overflows.


  2. RLWA32 46,941 Reputation points
    2022-05-23T18:19:01.017+00:00

    Take a look at this.

    In CMyEdit header -

        afx_msg void OnEnUpdate();
        CString m_strOld;
        bool m_bEnter{ true };
    

    In CMyEdit cpp file -

    void CMyEdit::OnEnUpdate()
    {
        ASSERT((GetStyle() & ES_NUMBER) == ES_NUMBER);
        if (m_bEnter)
        {
            CString str;
            GetWindowText(str);
            LPTSTR ptr{};
            ULONG val = _tcstoul(str, &ptr, 10);
            if (val > 0 && val <= (ULONG) MAXINT)
            {
                m_strOld = str;
            }
            else
            {
                m_bEnter = !m_bEnter;
                SetSel(0, -1);
                ReplaceSel(m_strOld, TRUE);
                m_bEnter = !m_bEnter;
            }
        }
    }
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.