2010-02-09 37 views
38

Tôi muốn có tính năng này trong chương trình C# của mình: Khi người dùng thực hiện Ctrl + C hoặc Sao chép bất kỳ nơi nào (tức là khi nội dung của khay nhớ tạm thay đổi), chương trình của tôi sẽ được thông báo và kiểm tra xem nội dung có đáp ứng các tiêu chí nhất định không , nếu có, hãy trở thành chương trình đang hoạt động và xử lý nội dung, v.v.Làm cách nào để theo dõi các thay đổi nội dung của clipboard trong C#?

Tôi có thể lấy nội dung từ số System.Windows.Forms.Clipboard, tuy nhiên, tôi không biết cách theo dõi các thay đổi nội dung từ khay nhớ tạm.

Nếu sử dụng Windows Vista   hay muộn, sử dụng AddClipboardFormatListener như trong câu trả lời John Knoeller của, cho Windows XP  , tôi phải sử dụng lớn hơn, mong manh hơn SetClipboardViewer API, như trong câu trả lời chấp nhận.

+1

Cách thực hiện việc này trong WPF có tại đây: http://stackoverflow.com/a/33018459/2122718 – marbel82

Trả lời

16

Bạn có thể làm điều này với pinvoke để Win32 API AddClipboardFormatListener

Người nghe là một handle cửa sổ (Form.Handle), và dưới hình thức sẽ được thông báo về những thay đổi với một thông báo WM_CLIPBOARDUPDATE

Đó là một sự thay thế mạnh mẽ hơn cho API cũ hơn SetClipboardViewer.

+0

Cảm ơn. nhưng trên trang msdn, yêu cầu hệ điều hành tối thiểu cho API này là Vista. điều đó có đúng không? (Tôi vẫn còn trong XP mặc dù trên thực tế, người dùng của tôi cũng sẽ sử dụng XP.) – Weiming

+2

Vâng, yêu cầu tối thiểu là Vista. Nếu bạn đang sử dụng XP thì bạn không còn lựa chọn nào khác ngoài việc sử dụng SetClipboarViewer. Lưu ý rằng SetClipboardViewer rất mỏng manh, mặc dù bạn không gặp vấn đề gì nếu mã _your_ đúng và bạn là người xem _only_. –

+0

Ok, tôi sẽ rất thận trọng. Câu trả lời của bạn sẽ là tốt nhất. Cảm ơn! – Weiming

45

Tôi đã viết lên một lớp tiện ích nhỏ mà sử dụng AddClipboardFormatListener function chức năng với một cửa sổ Message-only làm chỉ này.

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

lớp này giả định rằng các thông báo luôn luôn cần thiết trong suốt thời gian các ứng dụng đời, tuy nhiên nó có thể được sửa đổi để cung cấp khả năng để bỏ đăng ký qua RemoveClipboardFormatListener function nếu cần thiết.

+0

Đẹp. Bạn có bao giờ cập nhật điều này để kết hợp XP không? – tofutim

+0

@tofutim Không, tôi không chắc API nào có sẵn trên các máy XP có thể thực hiện điều này – Justin

+0

[đây là dành cho XP] (http://stackoverflow.com/a/2226957/3331861) –

Các vấn đề liên quan