web-dev-qa-db-fra.com

Comment surveiller les modifications du contenu du presse-papiers en C #?

Je veux avoir cette fonctionnalité dans mon programme C #: lorsque l'utilisateur le fait CtrlC ou Copier n'importe où (c'est-à-dire lorsque le contenu du presse-papiers change), mon programme sera averti et vérifiera si le contenu répond à certains critères, si c'est le cas, devient le programme actif et traite le contenu, etc.

Je peux extraire le contenu de System.Windows.Forms.Clipboard, cependant, je ne sais pas comment surveiller les changements de contenu depuis le presse-papiers.

Si vous utilisez Windows Vista ou version ultérieure, utilisez AddClipboardFormatListener comme dans la réponse de John Knoeller, pour Windows XP, je dois utiliser l'API SetClipboardViewer plus ancienne et plus fragile, comme dans la réponse acceptée.

41
Weiming

Vous pouvez utiliser SetClipboardViewer fourni par l'API Win32 (via P/Invoke).

Voici une page qui contient du code pour en configurer un en C #: http://www.codeguru.com/csharp/.net/net_general/tipstricks/article.php/c7315/

13
Aryabhatta

J'ai écrit une petite classe utilitaire qui utilise la fonction AddClipboardFormatListener avec une fenêtre Message-only pour faire exactement cela.

/// <summary>
/// Provides notifications when the contents of the clipboard is updated.
/// </summary>
public sealed class ClipboardNotification
{
    /// <summary>
    /// Occurs when the contents of the clipboard is updated.
    /// </summary>
    public static event EventHandler ClipboardUpdate;

    private static NotificationForm _form = new NotificationForm();

    /// <summary>
    /// Raises the <see cref="ClipboardUpdate"/> event.
    /// </summary>
    /// <param name="e">Event arguments for the event.</param>
    private static void OnClipboardUpdate(EventArgs e)
    {
        var handler = ClipboardUpdate;
        if (handler != null)
        {
            handler(null, e);
        }
    }

    /// <summary>
    /// Hidden form to recieve the WM_CLIPBOARDUPDATE message.
    /// </summary>
    private class NotificationForm : Form
    {
        public NotificationForm()
        {
            NativeMethods.SetParent(Handle, NativeMethods.HWND_MESSAGE);
            NativeMethods.AddClipboardFormatListener(Handle);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == NativeMethods.WM_CLIPBOARDUPDATE)
            {
                OnClipboardUpdate(null);
            }
            base.WndProc(ref m);
        }
    }
}

internal static class NativeMethods
{
    // See http://msdn.Microsoft.com/en-us/library/ms649021%28v=vs.85%29.aspx
    public const int WM_CLIPBOARDUPDATE = 0x031D;
    public static IntPtr HWND_MESSAGE = new IntPtr(-3);

    // See http://msdn.Microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool AddClipboardFormatListener(IntPtr hwnd);

    // See http://msdn.Microsoft.com/en-us/library/ms633541%28v=vs.85%29.aspx
    // See http://msdn.Microsoft.com/en-us/library/ms649033%28VS.85%29.aspx
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
}

Cette classe suppose que les notifications sont toujours nécessaires pour la durée de vie des applications, mais elle peut être modifiée pour permettre de se désinscrire via la fonction RemoveClipboardFormatListener si nécessaire.

52
Justin

Vous pouvez le faire avec pinvoke à l'API Win32 AddClipboardFormatListener

L'écouteur est un descripteur de fenêtre (Form.Handle), et le formulaire sera notifié des modifications avec une notification WM_CLIPBOARDUPDATE

Il s'agit d'un remplacement plus robuste pour l'ancienne API SetClipboardViewer.

16
John Knoeller

L'API Win32 contient une fonction SetClipboardViewer.

Voici une très bonne écriture (d'un coup d'œil rapide).

4
µBio