クリップボードに変更があると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();
}
}
非常にわかりやすく、助かりました。
参考にさせていただきました。