web-dev-qa-db-ja.com

C#でクリップボードのコンテンツの変更を監視するにはどうすればよいですか?

C#プログラムでこの機能を使用したい:ユーザーが Ctrl + C またはどこかにコピーします(つまり、クリップボードのコンテンツが変更された場合)、プログラムに通知が送信され、コンテンツが特定の基準を満たしているかどうかが確認されます。条件を満たす場合は、アクティブなプログラムになり、コンテンツを処理します。

System.Windows.Forms.Clipboardからコンテンツを取得できますが、クリップボードからコンテンツの変更を監視する方法がわかりません。

Windows Vista以降を使用している場合は、John Knoellerの回答のようにAddClipboardFormatListenerを使用します。WindowsXPの場合、受け入れられた回答のように、古くて壊れやすいSetClipboardViewer AP​​Iを使用する必要があります。

41
Weiming

(P/Invokeを介して)Win32 APIによって提供される SetClipboardViewer を使用できます。

これは、C#で設定するためのコードを含むページです。 http://www.codeguru.com/csharp/.net/net_general/tipstricks/article.php/c7315/

13
Aryabhatta

AddClipboardFormatListener function 関数と Message-only ウィンドウを使用してこれを行う小さなユーティリティクラスを作成しました。

/// <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 を介してサブスクリプションを解除する機能を提供するように変更できます。

52
Justin

Win32 APIへのpinvokeでこれを行うことができます AddClipboardFormatListener

リスナーはウィンドウハンドル(Form.Handle)であり、フォームには WM_CLIPBOARDUPDATE 通知で変更が通知されます

古いSetClipboardViewer AP​​Iのより堅牢な代替品です。

16
John Knoeller

Win32 APIには、SetClipboardViewer関数が含まれています。

これは(一目でわかるように)かなり良い記事です

4
µBio