前回
id:seiunsky:20070404:1175710724
なんということだ
Clipboardクラスを調べればクリップボードの監視もすぐに見つかると思っていたんだけど、どうやら Win32API を使わなくてはいけないらしい。
技術メモ
- ウィンドウメッセージを取得するには
protected override void WndProc(ref Message msg) でメソッドをオーバーライドする - WM_DRAWCLIPBOARD イベントがクリップボード動作時のイベントなので、その時にクリップボードの中身を取得する処理を書く
- WM_CHANGECBCHAIN イベントで、次のクリップボードチェインにメッセージを送信してやる?(よくわかってない)
- Form 終了時に、クリップボードチェインから自身をはずす処理を入れる
this.closing イベントにデリゲートを登録して、 Win32 の ChangeClipboardChain 関数を呼び出す。
メインソース
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace クリクリボード { public partial class クリクリボード : Form { // Win32 API で必要らしい private IntPtr NextHandle; private const int WM_DRAWCLIPBOARD = 0x0308; private const int WM_CHANGECBCHAIN = 0x030D; [DllImport("user32")] public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); [DllImport("user32", CharSet = CharSet.Auto)] public extern static int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32")] extern static IntPtr ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext); public クリクリボード() { InitializeComponent(); // クリップボードチェインにへ自分のハンドラを追加? NextHandle = SetClipboardViewer(this.Handle); // クリップボードチェインからはずすためのデリゲート登録 // Form 終了時に行う this.Closing += new CancelEventHandler(Form1_Closing); } // 終了イベント(デリゲート登録される) void Form1_Closing(object sender, CancelEventArgs e) { ChangeClipboardChain(this.Handle, this.NextHandle); } protected override void WndProc(ref Message msg) { switch (msg.Msg) { // クリップボードにコピーされた case WM_DRAWCLIPBOARD: this.textBox1.Text += (string)Clipboard.GetDataObject().GetData(DataFormats.Text); this.textBox1.Text += "\r\n"; if ((int)NextHandle != 0) { SendMessage(NextHandle, msg.Msg, msg.WParam, msg.LParam); } break; // 次のクリップボードチェインにメッセージ送信? case WM_CHANGECBCHAIN: if ((IntPtr)msg.WParam == NextHandle) { NextHandle = (IntPtr)msg.LParam; } else if ((int)NextHandle != 0) { SendMessage(NextHandle, msg.Msg, msg.WParam, msg.LParam); } break; } base.WndProc(ref msg); } } }
このソースにヘタれな書き方があれば
ぜひ指摘してくだしあ!