Skip to content

Windows でクリップボードの内容が変更されたら通知する

Windows 環境でサーバやネットワーク機器を扱う際には、PoderosaPuTTYTeraTerm といったターミナルエミュレータが頻繁に利用されていると思います。ここでは「ターミナルエミュレータでのオペレーションにおける、ペーストミス削減」の工夫について考えてみます。

TeraTerm でペースト時に、確認ダイアログを表示する

TeraTerm ではデフォルトで「選択範囲を自動的にクリップボードへコピー」「右クリックでペースト」という動作をします。これはこれで便利なのですが、思いがけず右クリックしてしまうと、意図しないコマンドをペーストしてしまい、実行してはいけないコマンドを実行してしまう可能性があります。

対策として、TeraTerm のメニューから「Setup → Additional Settings → Copy and Paste → ConfirmChangePaste」にチェックすると、改行を含む文字をペーストする場合には、本当にペーストして良いか?確認するダイアログが表示されるようになり、より安全なオペレーションが出来るようになります。

file

クリップブックで、クリップボードの変更を監視する

Windows XP 以前であれば、標準でインストールされているクリップブックというツールで、クリップボードの変更をリアルタイムで監視することが出来ます。クリップブックを起動するには、ファイル名を指定して実行から「clipbrd」と入力します。

file

クリップブックを起動させたままにしておけばクリップボードの変更を監視しながらオペレーション出来ますので、作業ミスを減らせます。

file

クリップブックには以下のような特徴があります。

  • よく出来ているな、と思う点
    1. 様々なファイル形式に対応している
    2. クリップボードの内容を削除することも出来る
  • もう少し、頑張って欲しい点
    1. 常に前面に表示するオプションを付けて欲しかった(仮に、最前面に表示出来たとしても、多かれ、少なかれ、ウインドウが画面を占有するのは邪魔かも)
    2. クリップボードの内容がテキストの場合、フォントを変更出来るようにして欲しかった(フォントが大きめなので、ウインドウが大きくなりがち)
    3. 改行コードが含まれているのか、よく分からない(改行コードが見えない)

C# でクリップボードが変更されたか、監視するツールを作ってみる クリップブックの「もう少し、頑張って欲しい点」を踏まえ、C# でクリップボードを監視するツール「ClipboardMonitor」を作ってみました。

  • ClipboardMonitor-1.0.0.0

.NET Framework 3.5 でビルドしています。起動するとタスクトレイに常駐し、クリップボードの内容が変更されるとバルーンで通知します。

file

Windows.Forms.Form では「ウインドウを表示させない」という設定が出来ないようなので、CreateParams をオーバーライドし、起動後にメインウインドウが表示されないようにしています。また、.NET Framework にはクリップボードの変更を検知するイベントが無いようなので、タイマー(System.Windows.Forms.Timer)で定期的にクリップボードの内容を監視し、変更されていた場合にバルーンで通知するようにしています。ただし、バルーンには表示出来る文字数が制限があるようで、際限無く、文字を表示出来るわけでは無いようです。

ソースコードは以下の通りです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System;
using System.Windows.Forms;

namespace ClipboardMonitor
{
    public partial class Form1 : Form
    {
        private string clipboard_new = "";
        private string clipboard_old = "";

        private const int CHECK_INTERVAL = 100;  // クリップボードを監視する間隔

        public Form1()
        {
            InitializeComponent();
            notifyIcon1.Text = Application.ProductName + " " + Application.ProductVersion;

            if (Clipboard.ContainsText())
                clipboard_old = Clipboard.GetText();

            // .NET Framework にはクリップボードの変更を検知するイベントが無いようなので、
            // タイマーオブジェクトを作成し、定期的にクリップボードを監視します。
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Tick += new EventHandler(CheckClipboard);
            timer.Interval = CHECK_INTERVAL;
            timer.Enabled = true;
        }

        /// <summary>
        /// クリップボードが変更されていないか、確認します。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckClipboard(object sender, EventArgs e)
        {
            try
            {
                if (Clipboard.ContainsText())
                {
                    clipboard_new = Clipboard.GetText();
                }

                if (clipboard_new != clipboard_old)
                {
                    notifyIcon1.BalloonTipTitle = "Clipboard was changed.";
                    notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
                    notifyIcon1.BalloonTipText = clipboard_new;
                    notifyIcon1.ShowBalloonTip(1000);

                    clipboard_old = clipboard_new;
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
            }
        }

        /// <summary>
        /// Windows Form が表示されないように、CreateParams をオーバーライドします。
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                const int WS_EX_TOOLWINDOW = 0x80;
                const long WS_POPUP = 0x80000000L;
                const int WS_VISIBLE = 0x10000000;
                const int WS_SYSMENU = 0x80000;
                const int WS_MAXIMIZEBOX = 0x10000;

                CreateParams cp = base.CreateParams;
                cp.ExStyle = WS_EX_TOOLWINDOW;
                cp.Style = unchecked((int)WS_POPUP) |
                    WS_VISIBLE | WS_SYSMENU | WS_MAXIMIZEBOX;
                cp.Width = 0;
                cp.Height = 0;

                return cp;
            }
        }

        /// <summary>
        /// アプリケーションを終了します。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exitToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            notifyIcon1.Visible = false;
            Application.Exit();
        }
    }
}