Visual Studio MFC modifier le texte dans le contrôle d'édition lors de la saisie / dynamiquement

Dec 04 2020

J'essaie de configurer une application MFC C ++ dans Visual Studio 2019 de manière à modifier le texte de l'utilisateur lors de la frappe.

La disposition actuelle est de 2 boutons radio,

ID = rdbOn(défini sur Group = True, avec Value int variable m_isOn= 1)

ID = rdbOff, la m_isOnvaleur serait =0

et 1 contrôle d'édition, ID = txtInputBox, avec la CStringvariable Valuem_inputString

Actuellement, pour le test, je peux voir comment cela fonctionnerait pour un bouton sur un clic, cela prendrait quelque chose comme ce qui suit et juste SetDlgItemTextdu résultat. Mais ce serait après qu'ils ont tapé, pas pendant qu'ils tapent.

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

Mise à jour: je me suis mis EN_CHANGEau travail J'ai pu EN_CHANGEtravailler avec la suggestion de drapeau de l'utilisateur @GoGoWorx. Cependant, maintenant j'ai juste un léger problème que le curseur est de retour au début du contrôle d'édition txtInput.
Je lis sur l'utilisation d'un CEdit::SetSelmais je ne sais pas comment l'utiliser directement dans mon code. J'ai essayé le contrôle CEdit MFC, en plaçant le curseur à la fin de la chaîne après 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);
}

Réponses

3 GoGoWorx Dec 04 2020 at 08:04

Il semble que vous deviez utiliser la ON_EN_CHANGEnotification de mappage de messages (appelée après la mise à jour du contrôle en raison de la saisie ou du collage, par exemple)

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
}

Je ne suis pas sûr de ce que vous utilisez pour l'identificateur numérique du contrôle d'édition, car ce sont généralement des définitions en majuscules - remplacez IDC_EDIT_CONTROLci-dessus par votre définition (peut txtInputBox- être , mais encore une fois, ce sont normalement des majuscules , donc je ne suis pas sûr ).

Modifiez également CMyDialogle nom de votre classe de dialogue.

Notez que nous utilisons ON_EN_CHANGEici le gestionnaire de mappage de messages au lieu du ON_EN_UPDATE, car le ON_EN_CHANGEmessage est envoyé après la mise à jour du contrôle, alors qu'il ON_EN_UPDATEest appelé juste avant sa mise à jour.

Les gestionnaires de mappage de messages sont décrits dans la section Notes de la CEditdocumentation du contrôle:https://docs.microsoft.com/en-us/cpp/mfc/reference/cedit-class?view=msvc-160

En ce qui concerne votre préoccupation concernant la modification des choses au fur et à mesure que l'utilisateur tape, cela devrait être bien, car chaque changement (frappe ou collage à partir du presse-papiers, etc.) devrait déclencher l'appel de ce gestionnaire, où vous pouvez modifier ce dont vous avez besoin. Assurez-vous simplement que lorsque vous mettez à jour le contrôle, vous ne le déclenchez pas à ON_EN_CHANGEnouveau et vous vous retrouvez dans une boucle de «changement» récursive.

Vous pourrez peut-être le faire avec une sorte d'indicateur pour indiquer que vous êtes celui qui met à jour le contrôle, par opposition à l'utilisateur, mais il est probablement préférable de sous-classer le CEditcontrôle pour faire ce que vous voulez. Il existe quelques exemples de la façon de procéder (ce n'est pas aussi difficile que cela puisse paraître), par exemple:https://www.codeproject.com/Articles/27376/Avoiding-EN-CHANGE-notifications