Détecter si un événement coller s’est produit dans une zone de texte enrichi

Existe-t-il un moyen de savoir si un événement de collage dans le presse-papier s’est produit dans une zone de texte riche? Cet événement serait utilisé pour faire certaines choses, avec le bloc de texte collé.

Merci

Voici mon code

protected override void WndProc(ref System.Windows.Forms.Message m) { if (m.Msg == WM_PASTE) { OnPasteOccurred(); MessageBox.Show("Pas"); } if (m.Msg == 0x000F) { if (PaintControl) { base.WndProc(ref m); } else { m.Result = IntPtr.Zero; } } else { base.WndProc(ref m); } } 

modifier

Je souhaite effectuer une mise en surbrillance syntaxique ou une indentation basée sur des événements de collage, ce que cet éditeur de code particulier semble faire très efficacement. Je ne sais pas comment ça se passe. Besoin d’aide dans cette direction particulière. Je suis à peu près sûr qu’il doit y avoir un code Win32 natif ou quelque chose comme ça qui peut être intercepté. J’ai essayé de localiser des clés, des événements de souris et ce n’est pas joli.

Il est un peu difficile de détecter une opération de RichTextBox dans RichTextBox .

La première solution consiste peut-être à détecter le message WM_PASTE WndProc le WndProc mais le contrôle WndProc malheureusement pas ce message à lui-même lorsqu’il effectue une opération de WndProc .

Détection naïve

Pour détecter les événements de clavier peuvent fonctionner (vous devez remplacer la fonction OnKeyDown ), puis vérifiez si les combinaisons de touches ( CTRL + V et SHIFT + INS ). Quelque chose comme ça:

 protected override OnKeyDown(KeyEventArgs e) { bool ctrlV = e.Modifiers == Keys.Control && e.KeyCode == Keys.V; bool shiftIns = e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert; if (ctrlV || shiftIns) DoSomething(); } 

Cela fonctionne bien, mais vous ne pouvez pas saisir l’opération de collage effectuée à l’aide de la souris (clic droit pour ouvrir le menu contextuel) et les opérations de collage effectuées par glisser-déposer. Si vous n’en avez pas besoin, vous pouvez utiliser cette solution (au moins, c’est simple et direct).

Meilleure détection

Hypothèse: lorsque l’utilisateur tape à l’intérieur de la RichTextBox il insère un caractère à la fois. Comment pouvez-vous l’utiliser? Eh bien, lorsque vous détectez un changement plus important, vous détectez une opération de collage car l’utilisateur ne peut pas saisir plus d’un caractère à la fois (d’accord, vous pouvez affirmer que ce n’est pas toujours le cas à cause des substituts Unicode). Voir aussi la version VB.NET et plus de détails sur les choses Unicode .

 private int _previousLength = 0; private void richTextBox_TextChanged(object sender, EventArgs e) { int currentLength = richTextBox.Text.Length; if (Math.Abs(currentLength - _previousLength) > 1) ProcessAllLines(); _previousLength = currentLength; } 

Veuillez noter que vous ne pouvez pas (en raison de la façon dont les différents IME fonctionnent) utiliser OnKeyDown (ou similaire). Cela ne fonctionne que pour les langues occidentales, mais il y a des problèmes avec les trucs Unicode (parce que, par exemple, la propriété Ssortingng.Length peut être augmentée de deux caractères lorsque l’utilisateur saisit un seul caractère. Voir aussi cet article pour plus de détails à ce sujet ( Une lecture fortement suggérée même, même si – dans ce cas – vous ne vous en souciez pas.) Dans cet article, vous trouverez également du code pour un meilleur algorithme permettant de déterminer la longueur de la chaîne. En bref, vous devez remplacer:

  int currentLength = richTextBox.Text.Length; 

Avec ça:

  int currentLength = SsortingngInfo.GetTextElementEnumerator(richTextBox.Text) .Cast() .Count(); 

Après tous ces efforts, vous réaliserez peut-être que… l’utilisateur peut même coller un seul caractère et celui-ci risque de ne pas être détecté. Vous avez raison, c’est pourquoi il s’agit d’une meilleure détection plutôt que d’une solution parfaite .

Solution parfaite

La solution idéale (si vous utilisez Windows 8) existe bien sûr, le contrôle d’édition riche natif envoie un message de notification EN_CLIPFORMAT . Il est destiné à notifier la fenêtre parent d’un contrôle d’édition enrichi qu’un collage a eu lieu avec un format de presse-papiers particulier. Vous pouvez ensuite remplacer le WndProc de son parent pour détecter le message WM_NOTIFY pour cette notification. Quoi qu’il en soit, il ne s’agit pas de quelques lignes de code, consultez cet article MSDN pour plus de détails.

À partir de .Net 3.0, il existe une méthode intégrée pour détecter l’événement de collage:

 DataObject.AddPastingHandler(this, OnPaste); 

Appelez simplement cette méthode dans le constructeur. Si vous souhaitez par exemple gérer l’événement Coller vous-même comme si l’utilisateur avait saisi le texte manuellement, vous pouvez utiliser

 private void OnPaste(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(ssortingng))) { var text = (ssortingng)e.DataObject.GetData(typeof(ssortingng)); var composition = new TextComposition(InputManager.Current, this, text); TextCompositionManager.StartComposition(composition); } e.CancelCommand(); }