Visual Studio MFC change text in Edit Control while typing/dynamically

1.5k views Asked by At

I am trying to set up a MFC C++ App in Visual Studio 2019 such that modifies the user's text as they are typing.

Current layout is 2 radio buttons,

ID= rdbOn (set to Group = True, with Value int variable m_isOn = 1)

ID= rdbOff, m_isOn value would be = 0

Layout

and 1 Edit Control, ID= txtInputBox, with Value CString variable m_inputString

Currently, for testing I can see how it would work for a button on click, it would take something like the following and just SetDlgItemText of the result. But that would be after they have typed, not WHILE they are typing.

void Onsomebtnclick()
{
    //convert CString to String of m_inputString
    //do some string manipulation
    //convert back to CString
    //SetDlgItemText(txtInputBox, result)    
}

Update: got EN_CHANGE to work I was able to get EN_CHANGE working with the flag suggestion from user @GoGoWorx. However, now I just have a slight problem that the cursor is back to the beginning of the edit control txtInput.
I'm reading about using a CEdit::SetSel but don't know how to use that directly in my code. I tried CEdit control MFC, placing cursor to end of string after SetWindowText

someDlg::someFunction()
{
    //some logic stuff to get a result string
    SetDlgItemText(txtInputBox, result);
    //need it to set the cursor to the end
    //I tried these, but it didn't recognize (expression must have class type?)
    //txtInputBox.SetSel(0, -1);
    //txtInputBox.SetSel(-1);
}
1

There are 1 answers

2
GoGoWorx On

It sounds like you need to use the ON_EN_CHANGE message-map notification (called after the control has been updated due to typing or pasting for example)

BEGIN_MESSAGE_MAP(CMyDialog, CDialog)   
    ON_EN_CHANGE(IDC_EDIT_CONTROL, &CMyDialog::OnEnChangeEditControl)
END_MESSAGE_MAP()

void CMyDialog::OnEnChangeEditControl()
{
   // Copy or call your Onsomebtnclick() here
}

I'm not sure what you're using for the numeric identifier for the edit control, since these are typically upper case defines - replace IDC_EDIT_CONTROL above with your define (possibly txtInputBox, but again, these are normally upper case, so I'm not sure).

Also change CMyDialog for the name of your dialog class too.

Note that we're using the ON_EN_CHANGE message-map handler here instead of the ON_EN_UPDATE, since the ON_EN_CHANGE message is sent after the control has been updated, whereas ON_EN_UPDATE is called just before it's updated.

The message-map handlers are described in the Remarks section of the CEdit control documentation: https://learn.microsoft.com/en-us/cpp/mfc/reference/cedit-class?view=msvc-160

Regarding your concern about modifying things as the user types - this should be fine, since every change (keystroke or paste from clipboard, etc.) should trigger this handler to be called, where you can change whatever you need. Just be sure that when you're updating the control, you don't trigger the ON_EN_CHANGE again and end up in a recursive 'change' loop.

You might be able to do this with some sort of flag to indicate you're the one updating the control, as opposed to the user, however it's probably better to subclass the CEdit control to do what you're wanting. There are a few examples out there of how to do this (it's not as difficult as it might sound), for example: https://www.codeproject.com/Articles/27376/Avoiding-EN-CHANGE-notifications