C#|クリップボードの変更を監視する

クリップボードに変更があるとDrawClipBoardイベントを発生するクラス。
使用後は必ずDisposeする必要がある。

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

/// <summary>
/// クリップボードを監視するクラス。
/// 使用後は必ずDispose()メソッドを呼び出して下さい。
/// </summary>
public class ClipBoardWatcher :IDisposable {
    ClipBoardWatcherForm form;

    /// <summary>
    /// クリップボードに内容に変更があると発生します。
    /// </summary>
    public event EventHandler DrawClipBoard;

    /// <summary>
    /// ClipBoardWatcherクラスを初期化して
    /// クリップボードビューアチェインに登録します。
    /// 使用後は必ずDispose()メソッドを呼び出して下さい。
    /// </summary>
    public ClipBoardWatcher() {
        form = new ClipBoardWatcherForm();
        form.StartWatch(raiseDrawClipBoard);
    }

    private void raiseDrawClipBoard() {
        if(DrawClipBoard != null) {
            DrawClipBoard(this, EventArgs.Empty);
        }
    }

    /// <summary>
    /// ClipBoardWatcherクラスを
    /// クリップボードビューアチェインから削除します。
    /// </summary>
    public void Dispose() {
        form.Dispose();
    }

    private class ClipBoardWatcherForm :Form {
        [DllImport("user32.dll")]
        private static extern IntPtr SetClipboardViewer(IntPtr hwnd);
        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll")]
        private static extern bool ChangeClipboardChain(IntPtr hwnd, IntPtr hWndNext);

        const int WM_DRAWCLIPBOARD = 0x0308;
        const int WM_CHANGECBCHAIN = 0x030D;

        IntPtr nextHandle;
        System.Threading.ThreadStart proc;

        public void StartWatch(System.Threading.ThreadStart proc) {
            this.proc = proc;
            nextHandle = SetClipboardViewer(this.Handle);
        }

        protected override void WndProc(ref Message m) {
            if(m.Msg == WM_DRAWCLIPBOARD) {
                SendMessage(nextHandle, m.Msg, m.WParam, m.LParam);
                proc();
            } else if(m.Msg == WM_CHANGECBCHAIN) {
                if(m.WParam == nextHandle) {
                    nextHandle = m.LParam;
                } else {
                    SendMessage(nextHandle, m.Msg, m.WParam, m.LParam);
                }
            }
            base.WndProc(ref m);
        }

        protected override void Dispose(bool disposing) {
            ChangeClipboardChain(this.Handle, nextHandle);
            base.Dispose(disposing);
        }
    }
}

 

以下の様に使用する。

using System;
using System.Windows.Forms;

public partial class Form1 :Form {
    ClipBoardWatcher cbw;

    public Form1() {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {
        cbw = new ClipBoardWatcher();
        cbw.DrawClipBoard += (sender2, e2) => {
            if(Clipboard.ContainsText()) {
                this.listBox1.Items.Add(Clipboard.GetText());
            }
        };
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
        cbw.Dispose();
    }
}

 

One thought on “C#|クリップボードの変更を監視する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください