2010-02-09 2 views
38

나는 내 C# 프로그램에서이 기능을 갖고 싶어 : 사용자가 Ctrl 키 + C을하거나 어디서든 복사 할 때 (예 : 클립 보드의 내용 변경시), 내 프로그램 통지하고, 내용이 특정 기준을 충족하는지 확인 얻을 것이다 그렇다면 활성화 된 프로그램이되어 내용 등을 처리 할 수 ​​있습니다.C#에서 클립 보드 내용 변경을 모니터링하려면 어떻게합니까?

콘텐츠를 System.Windows.Forms.Clipboard에서 가져올 수 있지만 클립 보드에서 콘텐츠 변경을 모니터링하는 방법을 알지 못합니다.

만약 윈도우   Vista를 사용하는 이상, Windows   XP, 나는 허용 대답처럼, 오래된, 더 깨지기 쉬운 SetClipboardViewer API를 사용할 필요가 존 Knoeller의 대답으로 AddClipboardFormatListener를 사용합니다.

+1

WPF에서이 작업을 수행하는 방법은 다음과 같습니다. http://stackoverflow.com/a/33018459/2122718 – marbel82

답변

16

당신은 Win32 API를 AddClipboardFormatListener

리스너가 창 핸들 (Form.Handle)이며, 형태가 그것입니다

WM_CLIPBOARDUPDATE 통지와 변경 통보됩니다에 PInvoke를 사용하여이 작업을 수행 할 수 이전 SetClipboardViewer API를보다 강력하게 대체했습니다.

+0

감사합니다. msdn 페이지에서이 API의 최소 OS 요구 사항은 Vista입니다. 그게 사실이야? (나는 여전히 XP 아래에있다. 사실, 내 사용자도 XP를 사용할 것이다.) – Weiming

+2

네, 최소 요구 사항은 Vista입니다. XP를 사용 중이라면 SetClipboarViewer를 사용하는 것보다 선택의 여지가 없습니다. SetClipboardViewer는 허약합니다. _your_ 코드가 정확하고 _only_ 뷰어 만 있으면 문제가 없어야합니다. –

+0

좋아, 나는 매우 신중할 것이다. 그렇지 않으면 당신의 대답이 최고 일 것입니다. 감사! – Weiming

45

난 그냥 이렇게하는 Message-only 창으로 AddClipboardFormatListener function 함수를 사용하는 작은 유틸리티 클래스를 작성했습니다.

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

이 클래스는하지만이 필요한 경우 RemoveClipboardFormatListener function를 통해 취소 할 수있는 기능을 제공하도록 수정 될 수 알림은 항상 응용 프로그램 수명 기간 동안 필요하다고 가정합니다.

+0

니스. XP를 통합하기 위해 이것을 업데이트 한 적이 있습니까? – tofutim

+0

@tofutim 아니요,이 API를 사용할 수있는 API가 무엇인지 모르겠습니다. – Justin

+0

[this is XP] (http://stackoverflow.com/a/2226957/3331861) –