2010-02-09 651 views
38

Quiero tener esta característica en mi programa en C#: Cuando el usuario haga Ctrl + C o copiar cualquier lugar (es decir, cuando los cambios en el contenido del portapapeles), mi programa recibirán una notificación, y comprobar si el contenido se reunió con ciertos criterios Si es así, conviértase en el programa activo y procese el contenido, etc.¿Cómo controlo el contenido del portapapeles en C#?

Puedo obtener los contenidos del System.Windows.Forms.Clipboard, sin embargo, no sé cómo controlar los cambios de contenido desde el portapapeles.

Si utiliza Windows Vista o posterior  , utilice AddClipboardFormatListener como en la respuesta de Juan Knoeller, para Windows XP  , tengo que usar el viejo, más frágil SetClipboardViewer API, como en la respuesta aceptada.

+1

Cómo hacer esto en WPF está aquí: http://stackoverflow.com/a/33018459/2122718 – marbel82

Respuesta

16

Usted puede hacer esto con PInvoke a la API de Win32 AddClipboardFormatListener

El oyente es un identificador de ventana (Form.Handle), y la forma será notificado de cambios con una notificación WM_CLIPBOARDUPDATE

Es un reemplazo más robusto para la API SetClipboardViewer anterior.

+0

Gracias. pero en la página msdn, el requisito mínimo del sistema operativo para esta API es Vista. ¿es eso cierto? (Todavía estoy en XP, de hecho, mis usuarios también usarán XP.) – Weiming

+2

Sí, el requisito mínimo es Vista. Si está en XP, no tiene más remedio que usar SetClipboarViewer. Tenga en cuenta que SetClipboardViewer es frágil, aunque no debería tener problemas si _su_código es correcto y usted es el _único_ espectador. –

+0

Ok, seré muy cauteloso. Tu respuesta sería la mejor. ¡Gracias! – Weiming

45

He escrito una pequeña clase de utilidad que utiliza la función AddClipboardFormatListener function con una ventana Message-only para hacer precisamente esto.

/// <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); 
} 

Esta clase supone que las notificaciones son siempre necesarios para la duración de la vida útil de las aplicaciones, sin embargo, podría ser modificado para proporcionar la posibilidad de darse de baja a través de la RemoveClipboardFormatListener function si es necesario.

+0

Agradable. ¿Alguna vez actualizaste esto para incorporar XP también? – tofutim

+0

@tofutim No, no estoy seguro de qué API está disponible en las máquinas XP que pueden hacer esto – Justin

+0

[esto es para XP] (http://stackoverflow.com/a/2226957/3331861) –

Cuestiones relacionadas