レベル3:NotifyIconの本来の使い方
実は、NotifyIcon本来の使い方は、前述してきたレベル1、レベル2の方法ではありません。では、実際にはどのような使い方をするのでしょうか。タスクトレイに常駐しているソフトを見ると、さまざまな使い方があることを想像できるかと思いますが、NotifyIconはタスクトレイに常駐しているという性質上、次のような使い方が一般的(基本)です。
- Formを閉じた時にNotifyIcon(通知アイコン)を表示する
- タスクトレイのNotifyIconをダブルクリックするとFormが表示される
- タスクトレイ内で通知アイコンを右クリックするとメニューが表示され、そのメニューの[終了]をクリックするとアプリケーションが終了する
以下に、NotifyIconの一般的なコーディング手順を示します。
手順1:「Formを閉じた時にNotifyIconを表示する」をコーディング
FormClosingイベントにNotifyIcon(通知アイコン)を表示する処理を書きます。詳しく記載すると次のようになります。
- Formをクローズする処理をキャンセル
- フォームを非表示
- NotifyIconを表示
- NotifyIconのバルーンTip表示
この4つの処理をコードで記述すると次のようになります。
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { e.Cancel = true; // 終了処理キャンセル this.Visible = false; // フォーム非表示 this.notifyIcon1.Visible = true; // Notifyアイコン表示 this.notifyIcon1.ShowBalloonTip(500); // バルーンTip表示 }
Closingイベントが無くなっているからです。
Closingイベントは、FormClosingイベントへと変更になっているので注意してください。.NET Framework 1.1時代の逆引き辞典などでサンプルを探している方は特に要注意です。FormClosingイベントを作成するには、Visual Studio 2005のデザイン画面から[イベント選択]アイコンをクリックします。![画面7 [イベント選択]アイコンをクリック 画面7 [イベント選択]アイコンをクリック](http://cz-cdn.shoeisha.jp/static/images/article/421/005_2.gif)
手順2:「NotifyIconをダブルクリックするとFormが表示される」をコーディング
notifyIconのイベントを作成します。デザイン画面の[notifyIcon1]をダブルクリックすると、notifyIcon1のダブルクリックイベントが自動生成されます。
自動生成されない場合は、notifyIcon1のプロパティで、イベントの[MouseDoubleClick]をダブルクリックしてイベントを生成してください。
コーディングする処理の内容を詳しく記載すると次のようになります。
- Formを表示する
- Formが最小化していればフォームの状態をノーマルに戻す
- Notifyアイコンを非表示にする
- Formをアクティブにする
この4つの処理をコードで記述すると次のようになります。
private void notifyIcon1_MouseDoubleClick(object sender,MouseEventArgs e) { this.Visible = true; // フォームの表示 if (this.WindowState == FormWindowState.Minimized) { this.WindowState = FormWindowState.Normal; // 最小化をやめる } this.notifyIcon1.Visible = false; // Notifyアイコン非表示 this.Activate(); // フォームをアクティブにする }
さて、ここまでコードを記述してきたら、ほぼ完成したように思えますね。ですが、まだまだ完成途中です。現時点で実行してしまうと、落とし穴にはまることになります。この状態だと、このアプリケーションを終了させることができないのです。
アプリケーションを終了させるには、タスクトレイのアイコンを右クリックしたときにメニューを表示させて、そのメニューから「終了」する処理を追加する必要が出てきます。
手順3:「右クリックするとメニューが表示され、[終了]をクリックするとアプリケーションが終了する」をコーディング
右クリックしたときの処理は、contextMenuStripを用います。Formに[contextMenuStrip]をドラッグ&ドロップし、必要なプロパティを設定します。

[ここへ入力]欄に「終了」と記述し、[ContextMenuStripタスク]にある[ShowImageMargin]のチェックをはずします。

[終了]メニューが作成できたら、[終了]メニューそのものをダブルクリックすると、Clickイベントが自動生成されます。
このとき、メニュー項目がそのまま、ContextMenuStripの下にぶら下がる、ToolStripMenuItemになるため、名前が「終了ToolStripMenuItem」となり、イベント名が「終了ToolStripMenuItem_Click」になってしまうのが、違和感の残るところです。気に入らない方は、プロパティ(Name)で変更するか、項目の編集から起動する、[項目コレクションエディタ]でメニューアイテムを追加し、名前を入力すると防ぐことができます。
[終了]メニューのコーディング内容を詳しく記載すると次のようになります。
- タスクトレイのアイコンを非表示にする
- アプリケーションを終了する
この2つの処理をコードで記述すると次のようになります。
private void 終了ToolStripMenuItem_Click(object sender, EventArgs e) { this.notifyIcon1.Visible = false; // タスクトレイからアイコンを取り除く Application.Exit(); // アプリケーション終了 }
ここで作成した終了メニューは、タスクトレイの[NotifyIcon]を右クリックした時に表示するメニューです。
実行時にこのメニューを表示するには、notifyIcon1とContextMenuStripを関連付けしてあげる必要があります。関連付けの方法は簡単です。
notifyIcon1のプロパティから、ContextMenuStrip項目の値を設定します。contextMenuStrip1を作成したので、notifyIcon1のContextMenuStripプロパティ内のリストに表示されます。リストから[contextMenuStrip1]を選択して設定してください。
さて、終了処理のコードも記述したので、さっそく実行してみたいところですが、まだ実行しないでください。アプリケーションが終了できない形で実行されてしまいます。
まだ、注意すべき点が残っているのです。Application.Exit();の記述により、終了処理を自動化してくれているのですが、結局、FormClosingを呼び出してしまいます(この動きはFormClosingにブレークポイントを貼ると分かりますね)。
それでは、これでは終わらないのではないか、と疑問に思うかもしれません。どうすべきでしょうか。
「クラスのフィールド(変数)にフラグでもつくるのだろうか」と思った方。考え方は正解なのですが、WindowsFormには便利なプロパティがあるので、今回はそちらを使うことにします。
.NET Framework 2.0から、Formが閉じられた理由を示すプロパティとして、「CloseReason」というプロパティが設けられました。System.Windows.Forms.CloseReasonは列挙体(0~nの数字に意味づけしたようなもの)であり、以下のメンバが用意されています。
| メンバ名 | 説明 |
ApplicationExitCall | ApplicationクラスのExitメソッドが呼び出されました。 |
FormOwnerClosing | 所有側のフォームが閉じられようとしています。 |
MdiFormClosing | このマルチ ドキュメント インターフェイス(MDI: Multiple Document Interface)フォームの親フォームが閉じられようとしています。 |
None | フォームが閉じられる理由が定義されなかったか、確認できませんでした。 |
TaskManagerClosing | Microsoft Windowsタスクマネージャがアプリケーションを終了しようとしています。 |
UserClosing | ユーザーがフォームウィンドウの[閉じる]ボタンを押す、ウィンドウのコントロールメニューの[閉じる]をクリックする、[Alt]キーと[F4]キーを同時に押すなどの方法で、ユーザーインターフェイス (UI) を通じてフォームを閉じようとしています。 |
WindowsShutDown | オペレーティングシステムが終了前にすべてのアプリケーションを終了しようとしています。 |
それでは最後に、FormClosingの処理をCloseReasonを使って書き換えます。FormClosingの第2引数のFormClosingEventArgsからも、CloseReasonが使えるので、次のように処理を変更します。
FormClosingの第2引数eのCloseReasonから判断して、Formがユーザーによって閉じられた場合は従来処理、それ以外は何もしない(Formを閉じる)。
private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing){ e.Cancel = true; // 終了処理キャンセル this.Visible = false; // フォーム非表示 this.notifyIcon1.Visible = true; // Notifyアイコン表示 this.notifyIcon1.ShowBalloonTip(500); // バルーンTip表示 } }
以上で完成です。
まとめ
Visual Studio 2005は非常に便利になりました。今まで苦労してコードを書いていたことがコントロールのプロパティになっていたり、欲しかった機能がクラスライブラリで提供されていたり、さまざまな発見があるかと思います。
今回、本稿は、そういった発見の一助となることを期待し執筆しました。これをきっかけに、Visual Studio 2005の新機能を使いこなせるようになっていただければ幸いです。
参考資料
- MSDNライブラリ 『NotifyIconクラス』




