以前、クリップボードの履歴をとるアプリを作成しました。

クリップボードの履歴をとるアプリの作り方

ただ、これは履歴をとるだけでそこからワンタッチでそれらをペーストする機能はありませんでした。ここではその機能を追加します。実際にクリップボードの履歴をとり、そこからペーストをすることができるアプリは存在します。しかし履歴をとられては不味いものもあるはずです。このようなコントロールができないので自作することにしました。

前回グローバルキーフックをする方法を解説しました。

C#でグローバルキーフックをする方法

これを使えば他のアプリを使っていてもクリップボードの履歴をとったり、そこからテキストをペーストすることができそうです。

KeyboardHookクラスをそのまま使います。KeyboardHookクラスの内容は

C#でグローバルキーフックをする方法

を参照してください。

まずグローバルフックをするために

とやる必要があります。それからグローバルフックを解除するためにアプリケーションが終了するときに

という処理も必要です。

またクリップボードの変更されたことを知るために以下も追加します。

ではキーボードが押されたときやクリップボード内のテキストデータが変更されたときはどうすればよいのでしょうか?

ここではクリップボードのデータが変更されたら、クリップボード内のデータがテキストなのかどうかを調べます。そしてテキストであれば、これをリストに保存します。

あとになってメニューを表示して、どれをペーストするのかを選択できるようにしておかないといけません。そこでペーストするための文字列を格納するリストを用意します(List<string> CopiedStrings)。

Shiftキーを2回連続して押すとコピーされた文字列の履歴を表示されるようにします。

コピーされた文字列は複数行で文字数も相当な文字数になることが予想されます。そこでメニューには先頭の一部のみを表示します。

メニューが選択されたらそれに対応するテキストがクリップボードにコピーされペーストされます。このときもクリップボード内のデータがかわってしまうのでメニューの項目が無意味に増えてしまいます。そこでそうならないようにペースト処理のときはクリップボード内のテキストデータが変更されても無視するようにしています。

ペースト処理をするときだけ isIgnoreUpdateClipboard フラグをセットして終わったらすぐに戻してしまう方法ではうまくいきません。そこでペースト処理がおわってから1秒待ってからisIgnoreUpdateClipboard フラグをクリアしています。

それからクリップボード内のテキストによっては履歴をとりたくないものもあるはずです。マスターパスワードだけ覚えておけばたくさんの異なるパスワードを管理することができるパスワード管理ソフト(KeePassなど)は便利ですが、これだとクリップボードに転送されたパスワードまで履歴に残ってしまいます。これは困りますね。

そこでパスワードらしきものがクリップボードに転送された場合は履歴に残らないようにします。パスワードには全角文字はないはずなので、すべて半角英数や記号である場合はパスワードかもしれないと見なして記録しないようにしています。