2009-10-12 10 views
2

Je fais cela en C#, mais, je suppose, ce n'est pas problème spécifique de la langue ...modifier le contenu du presse-papiers presse-papiers changement

J'ai quelques exemples de code sur la façon de détecter le moment où le contenu des changements de presse-papiers. Maintenant, je veux modifier le texte qui vient d'être copié (dépouiller quelques étiquettes) et remplacer le texte du presse-papiers par un texte fixe. Mais si je SetDataObject() lorsque je détecte que le contenu du Presse-papiers a changé, cela générera le message que le contenu du Presse-papiers a de nouveau changé. En théorie, je suppose, cela ressemble à une boucle infinie (en pratique pour une raison quelconque ce n'est pas le cas).

Quelle est la stratégie pour faire cette modification une fois, et a envoyé le message dans la chaîne de surveillance du presse-papiers?


P.S. Comme un test que je suis en train de suivre, mais ce qui se passe est Clipboard.SetDataObject .. ligne est appelée deux fois. Je ne comprends pas pourquoi, je m'attendrais à le faire infiniment.

case Win32.Msgs.WM_DRAWCLIPBOARD: 

    String clipboardText = GetClipboardText(); 
    if (!String.IsNullOrEmpty(clipboardText)) 
    { 
     Clipboard.SetDataObject("test(" + clipboardText + ")!"); 
    } 

    Win32.User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam); 

Répondre

1

Malheureusement, chaque fois que vous définissez les données du Presse-papiers avec Clipboard.SetDataObject, vous "redessinez" le presse-papiers, puisque vous modifiez son contenu. La meilleure façon de gérer cette situation consiste à vérifier que votre routine vérifie le contenu du Presse-papiers et à ne la définir que si vous modifiez réellement le texte du Presse-papiers.

Dans votre cas, vous dites que vous supprimez certaines balises. Vérifiez simplement la chaîne clipboardText avant et après votre routine, et si la chaîne n'est pas modifiée, ne la définissez pas à nouveau.

De cette façon, la première fois, les étiquettes seront retirées, puis réinitialisées. Ensuite, le feu à nouveau, voir qu'il n'y a pas de changements, et ne pas réinitialiser les données du presse-papiers.

+0

Il attend une boucle inifinite, mais ne voyant que cela se produire deux fois dans cet exemple ... – cjk

+1

Mais ce n'était pas la question. La vraie question était de savoir comment gérer cela correctement. L'évitement de la boucle infitite est probablement dû au fait de ne pas passer le message Windows (le piégeant) lorsqu'il gère le message. –

+0

il y a un meilleur moyen (un général) pour empêcher la récursivité. Voir ma réponse ci-dessous. – Giorgi

1

Pour éviter la récursion, vous ne devez définir réellement le texte du presse-papiers s'il y avait des balises à la bande.

Pour expliquer le comportement, je suppose que WM_DRAWCLIPBOARD n'est pas envoyé récursivement, ce qui signifie que si le presse-papiers est modifié lors d'une notification WM_DRAWCLIPBOARD, il ne sera pas envoyé à nouveau.

1

En fait, il existe une bien meilleure façon d'éviter les boucles infinies qui fonctionnent même lorsque vous ne modifiez pas le contenu du presse-papier et que vous ne pouvez donc pas comparer si vous l'avez modifié ou non.

Lorsque vous détectez le message WM_DRAWCLIPBOARD, appelez le GetClipboardOwner qui renverra le handle à la fenêtre qui a modifié le handle. Une fois que vous avez le handle, vous pouvez obtenir le processus qui possède la fenêtre. Si le processus est différent de votre processus, traitez le presse-papiers, sinon le presse-papier a été modifié par vous, alors ignorez-le.

Questions connexes