HOWTO · Csharp
システム トレイのアプリケーションを最小化する
この記事では、C# を使用してシステム トレイ内の Windows フォーム アプリケーションを最小化する方法について説明します。
このページの内容
この記事では、C# を使って Windows フォーム アプリケーションをタスクバーではなくシステム トレイに最小化する方法を説明します。これにより、アプリはバックグラウンドで実行を続けながら、小さなトレイ アイコンからいつでもアクセスできる状態を保てます。
Windows フォーム アプリをシステム トレイに最小化する理由
Windows フォームは、.NET に組み込まれたデスクトップ GUI フレームワークです。そのコントロール (ボタン、メニュー、テキスト フィールド、チェックボックスなど) は System.Windows.Forms 名前空間に含まれており、サインアップ フォームやログイン フォームは、これで構築できる代表的な例です。Windows フォーム アプリケーションの背景について詳しくは、こちらを参照してください。
既定では、Windows フォーム アプリを最小化しても、そのボタンはタスクバーに残ります。頻繁に切り替えるアプリケーションならそれで問題ありませんが、バックグラウンドで実行するだけのプログラムではタスクバーの領域を無駄にし、タスクバーはすぐに乱雑になって操作しづらくなります。
こうしたアプリケーションの一般的な置き場所が、タスクバー右下の通知領域であるシステム トレイです。バックグラウンドで動く各アプリは小さなアイコンで表され、目立たないもののワンクリックでアクセスできます。チャット クライアントやウイルス対策ソフトウェアは一般にこの方式を採っており、トレイ アプリは注意が必要なときにバルーン ヒントでユーザーに通知することもできます。
つまり、NotifyIcon を使えば、Windows フォーム アプリは実行を続けたまま、タスクバーではなくシステム トレイに最小化できます。この記事の残りでは、その動作を実装する方法を説明します。
NotifyIcon を構成する
NotifyIcon は System.Windows.Forms 名前空間のコンポーネントで、アプリがシステム トレイに表示するアイコンを描画・管理します。これは目に見えるコントロールではありません。フォームにドラッグすると、フォームの表面ではなくデザイナー下部のコンポーネント トレイに配置されます。
Visual Studio でツールボックスを開き、NotifyIcon をダブルクリックするかフォーム上にドラッグします。
これにより、notifyIcon1 コンポーネントがフォームに追加されます。このチュートリアルで重要なプロパティは次のとおりです。
Icon: システム トレイに表示されるアイコンで、最も重要なプロパティです。System.Drawing.Iconを受け取り、Visual Studio デザイナーの選択ダイアログは.icoファイルを直接受け付けます。それ以外の画像形式はコードで先にIconに変換する必要があるため、トレイには.icoファイルが実際的な選択肢です。Text: トレイ アイコンにカーソルを合わせたときに表示されるツールチップです。Visible: アイコンをトレイに表示するかどうかです。フォームが表示されている間はFalseのままにし、アプリがタスクバーとトレイを同時に占有しないようにします。BalloonTipTitle、BalloonTipText、BalloonTipIcon:ShowBalloonTipが表示するバルーン通知のタイトル、本文、および重要度アイコンです。
プロパティ ウィンドウで Icon に .ico ファイルを割り当て、最初は Visible を False のままにしておきます。
次に、フォームの読み込み時にテキスト関連のプロパティを設定します。Form1_Load ハンドラーで、notifyIcon1.BalloonTipTitle = "System Tray"、notifyIcon1.BalloonTipText = "Some Notification"、notifyIcon1.Text = "System Tray App" を割り当てます。次のセクションの実行可能なプログラムでは、Form1_Load メソッド全体をコンテキスト内で示しています。
メンバーの完全な一覧は、NotifyIcon API リファレンスに記載されています。
フォームを非表示にして復元する
ここでは手順を順に示します。3 つのハンドラー (Form1_Load、Form1_Resize、notifyIcon1_MouseDoubleClick) は、Visual Studio デザイナーがイベントに結び付ける Form1 部分クラスのメンバーであり、スタンドアロン プログラムとしてではなく、Windows 上の Windows フォーム プロジェクト内でコンパイル・実行されます。
-
Visual Studio を開き、スタート ウィンドウで
Create a new projectを選択します。
-
Windows Forms Appテンプレートを選択し、Nextをクリックします。
-
プロジェクト名を入力し、
Createをクリックします。
-
ツールボックスから
NotifyIconをフォームにドラッグし、前のセクションで説明したようにIconを割り当ててVisibleをFalseのままにします。アイコンを省略すると、フォームが非表示になったときにシステム トレイに何も表示されません。 -
フォームの
Resizeイベントを配線します。フォームを選択し、プロパティ ウィンドウでイベント一覧 (稲妻アイコンのボタン) を開き、ResizeをダブルクリックしてForm1_Resizeを作成します。
-
同様に
notifyIcon1のMouseDoubleClickイベントも配線します。コンポーネント トレイでnotifyIcon1を選択し、イベント一覧を開いてMouseDoubleClickをダブルクリックし、notifyIcon1_MouseDoubleClickを作成します。 -
3 つのハンドラーを実装します。これらは以下の実行可能なプログラム内でコンテキストと共に示されています。Visual Studio では、
Form1_Load、Form1_Resize、notifyIcon1_MouseDoubleClickの各メソッドだけをForm1.csに貼り付けてください。
これらのハンドラーは Windows フォーム プロジェクト内にのみ存在する System.Windows.Forms の型に依存するため、以下のプログラムでは同じメンバー名を持つ小さな代用型 (FormWindowState、MouseEventArgs、NotifyIcon) でラップし、単体でコンパイル・実行できるようにしています。Main はユーザーの役割を果たします。ウィンドウを最小化して Resize に反応させ、その後トレイ アイコンをダブルクリックします。なお、以下のコードと出力に表示されるラベルや文字列は英語のままです。この例を実行してみましょう。
using System;
// Minimal stand-ins so the handler logic compiles and runs as a plain
// console program. In a real project these types come from
// System.Windows.Forms and the handlers live in the Form1 partial class.
enum FormWindowState { Normal, Minimized }
class MouseEventArgs { }
class NotifyIcon
{
public bool Visible;
public string Text;
public string BalloonTipTitle;
public string BalloonTipText;
public void ShowBalloonTip(int timeout)
{
Console.WriteLine("Balloon tip: " + BalloonTipTitle + " - " + BalloonTipText);
}
}
class Form1
{
FormWindowState WindowState = FormWindowState.Normal;
NotifyIcon notifyIcon1 = new NotifyIcon();
void Hide() { Console.WriteLine("Form hidden"); }
void Show() { Console.WriteLine("Form shown"); }
private void Form1_Load(object sender, EventArgs e)
{
notifyIcon1.BalloonTipTitle = "System Tray";
notifyIcon1.BalloonTipText = "Some Notification";
notifyIcon1.Text = "System Tray App";
}
private void Form1_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
this.Hide();
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(1000);
}
else if (FormWindowState.Normal == this.WindowState)
{
notifyIcon1.Visible = false;
}
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
notifyIcon1.Visible = false;
WindowState = FormWindowState.Normal;
}
static void Main()
{
Form1 form = new Form1();
form.Form1_Load(null, new EventArgs());
form.WindowState = FormWindowState.Minimized;
form.Form1_Resize(null, new EventArgs());
form.notifyIcon1_MouseDoubleClick(null, null);
form.Form1_Resize(null, new EventArgs());
}
}
Form hidden
Balloon tip: System Tray - Some Notification
Form shown
Resize は WindowState が変化するたびに発生するため、最小化への反応を置く場所として適切です。this.Hide() はフォームのタスクバー ボタンを完全に取り除きます。通常の最小化ではタスクバーに小さく残るだけです。アイコンを Visible にして ShowBalloonTip を呼び出すことで移動を知らせます。1000 という引数はバルーンの表示時間 (ミリ秒) です。else if 分岐は、ウィンドウが Normal に戻るたびにアイコンを再び非表示にするもので、トレイ アイコン経由ではない復元にも対応します。
復元ハンドラーでは、this.Show() が非表示のフォームを再表示し、WindowState = FormWindowState.Normal が最小化を解除します。フォームにタスクバー ボタンが戻ったので、アイコンは再び非表示になります。
トレイの動作をテストする
アプリケーションを実行します (F5)。空の Form1 ウィンドウが表示されます。
この時点では、アプリはタスクバーを占有しており、システム トレイにはまだ何も追加されていません。
フォームの最小化ボタンをクリックします。
Form1_Resize ハンドラーが発生します。フォームとそのタスクバー ボタンが消え、システム トレイにアイコンが現れ、設定したタイトルとテキストのバルーン ヒントがポップアップします。これは、上の実行可能なプログラムが 3 行の出力として表示するのと同じ一連の動作です。
トレイ アイコンをダブルクリックして復元経路を確認します。フォームが通常の状態で再表示され、タスクバー ボタンが戻り、トレイ アイコンは消えます。アプリケーションは終始実行を続けています。トレイへの最小化は表示場所を変えるだけで、実行の有無は変わりません。
最小化後にアイコンが現れない場合は、デザイナーまたはコードで Icon が割り当てられているか確認してください。アイコンがなければ NotifyIcon は何も描画せず (ShowBalloonTip も何も表示しません)、非表示になったアプリが復元手段の見えないまま実行を続けることになります。