- - PR -
Clipboardの監視はできない?
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2001-09-12 21:45
はじめまして、横浜市在住のけいと申します。
私も、WebServiceを使って何か作ってみたくなり、 「クリップボードにコピーした単語をICD WebServiceで自動的に検索して表示」 ってのに挑戦してみました。 で、WebServiceへのアクセスはいとも簡単にできてしまったのですが、 クリップボードの監視って簡単にする方法はないものでしょうか? 今のところ、Timerをおいて、100ミリ秒ごとにチェックするという方法を見つけたのですが、 もう少しスマートに出来そうな気が(^^; |
|
投稿日時: 2001-09-12 22:43
うろ覚えで恐縮なんですが、Windowsでは、クリップボードの内容が変化したときに、メッセージを受け取れるようにできたと思います。これはC#では使えないということでしょうか?
100ミリ秒ごとにポーリングってのは、重くないですか? |
|
投稿日時: 2001-09-13 16:07
確かにクリップボードのクラスを見ると、クリップボードの変化を通知する手段は無いように見えますね。
思想なのか、実装の都合なのか、時間の都合なのかは分かりませんが。 機会があれば真意を聞いてみたいような気もします。 当面は、ポーリングするしかないかもしれませんね。 (でなければunsafeな世界に行くか) _________________ |
|
投稿日時: 2001-09-13 23:20
> Windowsでは、クリップボードの内容が変化したときに、メッセージを受け取れるようにできたと思います。
SetClipboardViewerですね。できれば、unsafeコードは書きたくないもので... > 当面は、ポーリングするしかないかもしれませんね。 そうですね。 100ミリ秒毎のポーリングでも思ったほど重くもなく、 レスポンスも気になるほどでもないので、 とりあえずこれで実装してみました。今のところ快適に動いてます。 |
|
投稿日時: 2001-09-14 10:34
>SetClipboardViewerですね。できれば、unsafeコードは書きたくないもので...
Win32API(user32.dll)の呼び出しは、unmanagedコードを呼び出すということであってunsafeコードを書くということではありません。 現状、C#はunsafeコードが書けますが、VB .NETではunsafeコードは書けません。しかし、VB .NETはWin32APIをP/Invokeで呼び出すことができます。つまり、P/Invokeはunsafeではない(safeである)ということです。 ちなみに、C#でClipboardViewer実装してみました。興味のある人が読んでるかも しれないので、載せてみます。 using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; class GoshItsReallyFun : Form { public TextBox Text1 = new TextBox(); public Label Label1 = new Label(); 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); [STAThread] static void Main() { Application.Run(new GoshItsReallyFun()); } public GoshItsReallyFun() { this.Text = "My first Windows app!"; Label1.Location = new Point(0, 0); Label1.Size = new Size(100, 100); Label1.Text = "Label!"; this.Controls.Add(Label1); Text1.Location = new Point(100, 0); Text1.Size = new Size(100, 100); Text1.Text = "TextBox!"; this.Controls.Add(Text1); NextHandle = SetClipboardViewer(this.Handle); } protected override void WndProc(ref Message msg) { switch (msg.Msg) { case WM_DRAWCLIPBOARD: Text1.Text = (string)Clipboard.GetDataObject().GetData(DataFormats.Text); if((int)NextHandle != 0) SendMessage(NextHandle, msg.Msg, msg.WParam, msg.LParam); break; case WM_CHANGECBCHAIN: NextHandle = (IntPtr)msg.LParam; if((int)NextHandle != 0) SendMessage(NextHandle, msg.Msg, msg.WParam, msg.LParam); break; } base.WndProc(ref msg); } } |
|
投稿日時: 2001-09-14 11:03
少々脱線しますが、「unmanage code」はCLR(Common Language Runtime)ではないネイティブなWin32 APIなどを呼び出すコードのことですよね。「unsafe」とはどのようなコードを指すのでしょうか?
|
|
投稿日時: 2001-09-14 12:34
>「unmanage code」はCLR(Common Language Runtime)ではない
>ネイティブなWin32 APIなどを呼び出すコードのことですよね。 違います。user32.dllのように、CLR上で実行されないコードのことをunmanagedコードと 呼びます。「呼び出すコード」ではありません。「呼び出されているコード」のほうが unmanagedコードです。 .NET Frameworkと同時にマイクロソフトが提供している言語の中で、unmanagedコードが書けるのは、C++だけです。 >「unsafe」とはどのようなコードを指すのでしょうか? CLRがタイプセーフティをべリファイできない(<何語?)コードのことをunsafeコードと言います。unmanagedコードは、CLRで動作しない以上、暗黙のうちにunsafeです。あたりまえですが。C#では以下のコードはunsafeです。
Mainメソッドのループの境界値を11にすると、IndexOutOfBoundsExceptionが 発生しますが、Modifyメソッドのループの境界値を11にしても例外は発生しません。これは配列の要素数が10だという、もとのタイプの情報を利用できないからです。タイプセーフティをべリファイできないわけです。 |
|
投稿日時: 2001-09-14 19:34
> Win32API(user32.dll)の呼び出しは、unmanagedコードを呼び出すということであってunsafeコードを書くということではありません。
なるほど、Win32APIの呼び出しをそれほど嫌がることはないのですね。 > C#でClipboardViewer実装してみました。 ありがとうございます。早速参考にして組んでみたいと思います。 > [DllImport("user32")] Win32APIの呼び出しってそんなに簡単だったのですね。知りませんでした(^^; ところで、 case WM_CHANGECBCHAIN: のなかは、 if((HWND)wParam == NextHandle) { NextHandle = (IntPtr)msg.LParam; } else if((int)NextHandle != 0) { SendMessage(NextHandle, msg.Msg, msg.WParam, msg.LParam); } ですよね。あと、終了時に自分をチェインからはずすための、 ChangeClipboardChain も必要ですね。 |