SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

タスクトレイにアイコンとバルーンを表示する

Visual Studio 2005で簡単に実装できるようになったバルーンTips

レベル3:NotifyIconの本来の使い方

 実は、NotifyIcon本来の使い方は、前述してきたレベル1、レベル2の方法ではありません。では、実際にはどのような使い方をするのでしょうか。タスクトレイに常駐しているソフトを見ると、さまざまな使い方があることを想像できるかと思いますが、NotifyIconはタスクトレイに常駐しているという性質上、次のような使い方が一般的(基本)です。

  1. Formを閉じた時にNotifyIcon(通知アイコン)を表示する
  2. タスクトレイのNotifyIconをダブルクリックするとFormが表示される
  3. タスクトレイ内で通知アイコンを右クリックするとメニューが表示され、そのメニューの[終了]をクリックするとアプリケーションが終了する

 以下に、NotifyIconの一般的なコーディング手順を示します。

手順1:「Formを閉じた時にNotifyIconを表示する」をコーディング

 FormClosingイベントにNotifyIcon(通知アイコン)を表示する処理を書きます。詳しく記載すると次のようになります。

  1. Formをクローズする処理をキャンセル
  2. フォームを非表示
  3. NotifyIconを表示
  4. NotifyIconのバルーンTip表示

 この4つの処理をコードで記述すると次のようになります。

NotifyIconを表示する
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イベント
 .NET Framework 1.1でWindows Formアプリケーションを作っていた人は、ここで躓くことが多いでしょう。というのは、.NET Framework 1.1時代にあったClosingイベントが無くなっているからです。
画面6 Closingイベントが無くなっている
画面6 Closingイベントが無くなっている
 Visual Studio 2005(.NET Framework 2.0)になり、.NET Framework 1.1のClosingイベントは、FormClosingイベントへと変更になっているので注意してください。.NET Framework 1.1時代の逆引き辞典などでサンプルを探している方は特に要注意です。
 FormClosingイベントを作成するには、Visual Studio 2005のデザイン画面から[イベント選択]アイコンをクリックします。
画面7 [イベント選択]アイコンをクリック
画面7 [イベント選択]アイコンをクリック
 デザイン画面でのイベント生成は、C#でも、VBでも同じことができます(以前のVB .NETではデザイン画面に[イベント選択]アイコンはなく、コード画面からイベントを生成していました)。

手順2:「NotifyIconをダブルクリックするとFormが表示される」をコーディング

 notifyIconのイベントを作成します。デザイン画面の[notifyIcon1]をダブルクリックすると、notifyIcon1のダブルクリックイベントが自動生成されます。

画面8 notifyIconのイベントを作成
画面8 notifyIconのイベントを作成

 自動生成されない場合は、notifyIcon1のプロパティで、イベントの[MouseDoubleClick]をダブルクリックしてイベントを生成してください。

 コーディングする処理の内容を詳しく記載すると次のようになります。

  1. Formを表示する
  2. Formが最小化していればフォームの状態をノーマルに戻す
  3. Notifyアイコンを非表示にする
  4. Formをアクティブにする

 この4つの処理をコードで記述すると次のようになります。

notifyIcon1のダブルクリックイベント
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]をドラッグ&ドロップし、必要なプロパティを設定します。

画面9 contextMenuStripをドラッグ&ドロップ
画面9 contextMenuStripをドラッグ&ドロップ

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

画面10 contextMenuStripの必要なプロパティ設定(「終了」メニュー作成)
画面10 contextMenuStripの必要なプロパティ設定(「終了」メニュー作成)

 [終了]メニューが作成できたら、[終了]メニューそのものをダブルクリックすると、Clickイベントが自動生成されます。

画面11 終了イベント生成
画面11 終了イベント生成

 このとき、メニュー項目がそのまま、ContextMenuStripの下にぶら下がる、ToolStripMenuItemになるため、名前が「終了ToolStripMenuItem」となり、イベント名が「終了ToolStripMenuItem_Click」になってしまうのが、違和感の残るところです。気に入らない方は、プロパティ(Name)で変更するか、項目の編集から起動する、[項目コレクションエディタ]でメニューアイテムを追加し、名前を入力すると防ぐことができます。

画面12 項目コレクション エディタ
画面12 項目コレクション エディタ

 [終了]メニューのコーディング内容を詳しく記載すると次のようになります。

  1. タスクトレイのアイコンを非表示にする
  2. アプリケーションを終了する

 この2つの処理をコードで記述すると次のようになります。

終了メニューのコーディング
private void 終了ToolStripMenuItem_Click(object sender, EventArgs e)
{
    this.notifyIcon1.Visible = false; 
        // タスクトレイからアイコンを取り除く
    Application.Exit();
       // アプリケーション終了
}

 ここで作成した終了メニューは、タスクトレイの[NotifyIcon]を右クリックした時に表示するメニューです。

 実行時にこのメニューを表示するには、notifyIcon1ContextMenuStripを関連付けしてあげる必要があります。関連付けの方法は簡単です。

  1. notifyIcon1のプロパティから、ContextMenuStrip項目の値を設定します。
  2. contextMenuStrip1を作成したので、notifyIcon1ContextMenuStripプロパティ内のリストに表示されます。リストから[contextMenuStrip1]を選択して設定してください。
画面13 notifyIcon1のContextMenuStripプロパティの値を設定
画面13 notifyIcon1のContextMenuStripプロパティの値を設定

 さて、終了処理のコードも記述したので、さっそく実行してみたいところですが、まだ実行しないでください。アプリケーションが終了できない形で実行されてしまいます。

 まだ、注意すべき点が残っているのです。Application.Exit();の記述により、終了処理を自動化してくれているのですが、結局、FormClosingを呼び出してしまいます(この動きはFormClosingにブレークポイントを貼ると分かりますね)。

 それでは、これでは終わらないのではないか、と疑問に思うかもしれません。どうすべきでしょうか。

 「クラスのフィールド(変数)にフラグでもつくるのだろうか」と思った方。考え方は正解なのですが、WindowsFormには便利なプロパティがあるので、今回はそちらを使うことにします。

 .NET Framework 2.0から、Formが閉じられた理由を示すプロパティとして、「CloseReason」というプロパティが設けられました。System.Windows.Forms.CloseReasonは列挙体(0~nの数字に意味づけしたようなもの)であり、以下のメンバが用意されています。

用意されているメンバ
メンバ名説明
ApplicationExitCallApplicationクラスのExitメソッドが呼び出されました。
FormOwnerClosing所有側のフォームが閉じられようとしています。
MdiFormClosingこのマルチ ドキュメント インターフェイス(MDI: Multiple Document Interface)フォームの親フォームが閉じられようとしています。
Noneフォームが閉じられる理由が定義されなかったか、確認できませんでした。
TaskManagerClosingMicrosoft Windowsタスクマネージャがアプリケーションを終了しようとしています。
UserClosingユーザーがフォームウィンドウの[閉じる]ボタンを押す、ウィンドウのコントロールメニューの[閉じる]をクリックする、[Alt]キーと[F4]キーを同時に押すなどの方法で、ユーザーインターフェイス (UI) を通じてフォームを閉じようとしています。
WindowsShutDownオペレーティングシステムが終了前にすべてのアプリケーションを終了しようとしています。

 それでは最後に、FormClosingの処理をCloseReasonを使って書き換えます。FormClosingの第2引数のFormClosingEventArgsからも、CloseReasonが使えるので、次のように処理を変更します。

  • FormClosingの第2引数eCloseReasonから判断して、Formがユーザーによって閉じられた場合は従来処理、それ以外は何もしない(Formを閉じる)。
CloseReasonを用いた終了処理
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の新機能を使いこなせるようになっていただければ幸いです。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

おぎわら@.NET道場(オギワラ ヒロユキ)

おぎわら@.NET道場■Blog : http://blogs.wankuma.com/ogiogi/http://blogs.yahoo.co.jp/ogiwara_hsk Microsoft MVP for Visual Developer - C#MCSD for .NET/VB6, MCSE 2000, MCDBA, MCSA 2002/2003, MCAD, MCDST

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/421 2006/07/02 00:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー