2010-02-09 30 views
38

C# programımda bu özelliğe sahip olmak istiyorum: Kullanıcı, Ctrl + C veya Kopyalama yeri (pano içeriği değiştiğinde) olduğunda, programım bildirim alacak ve içeriğin belirli ölçütleri karşılayıp karşılamadığını kontrol edecek , eğer öyleyse, etkin program haline gelir ve içeriği işler vb.C# 'ta pano içeriği değişikliklerini nasıl izlerim?

İçeriği System.Windows.Forms.Clipboard'dan alabilirim, ancak içerik değişikliklerini panodan nasıl izleyeceğimi bilmiyorum.

Windows   Vista kullanıyorsanız veya daha sonra Windows   XP için kabul ettim cevap olarak, daha yaşlı, daha kırılgan SetClipboardViewer API kullanmak zorunda John Knoeller yanıtında olarak AddClipboardFormatListener kullanın.

+1

WPF'de nasıl yapılır: http://stackoverflow.com/a/33018459/2122718 – marbel82

cevap

16

Sen Win32 API AddClipboardFormatListener

dinleyici bir pencere kolu (Form.Handle) 'dir ve form Öyle

bir WM_CLIPBOARDUPDATE bildirimle değişikliklerden haberdar edilecektir pinvoke'tur ile yapabilirsiniz Daha eski SetClipboardViewer API için daha sağlam bir yedek.

+0

Teşekkürler. Ancak msdn sayfasında bu API için minimum OS gereksinimi Vista'dır. bu doğru mu? (Yine de XP'nin altındayım. Aslında, kullanıcılarım da XP kullanıyor olacaklar.) – Weiming

+2

Evet, minimum gereksinim Vista. XP'de iseniz, SetClipboarViewer'ı kullanmaktan başka seçeneğiniz yoktur. SetClipboardViewer'ın hassas olduğunu unutmayın, ancak _your_ kodu doğruysa ve _only_ görüntüleyicisiyseniz hiçbir sorun yaşamamalısınız. –

+0

Tamam, çok dikkatli olacağım. Cevabınız aksi takdirde en iyisi olurdu. Teşekkürler! – Weiming

45

Sadece bunu yapmanın bir Message-only pencere ile AddClipboardFormatListener function fonksiyonunu kullanan küçük bir yardımcı programdır sınıfını yazdım.

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

Bu sınıf ancak gerekirse RemoveClipboardFormatListener function yoluyla abonelikten yeteneği sağlamak için değiştirilmiş olabilir, bildirimleri her zaman uygulamaları ömrü boyunca gerekli olduğunu varsayar.

+0

Güzel. Bunu XP'yi de dahil etmek için güncellediniz mi? – tofutim

+0

@tofutim Hayır, XP makinelerinde hangi API'nin kullanılabileceğinden emin değilim, bu bunu – Justin

+0

[bu XP için geçerlidir] (http://stackoverflow.com/a/2226957/3331861) –