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 をダブルクリックするかフォーム上にドラッグします。

NotifyIcon コンポーネントが選択された Visual Studio のツールボックス

これにより、notifyIcon1 コンポーネントがフォームに追加されます。このチュートリアルで重要なプロパティは次のとおりです。

  • Icon: システム トレイに表示されるアイコンで、最も重要なプロパティです。System.Drawing.Icon を受け取り、Visual Studio デザイナーの選択ダイアログは .ico ファイルを直接受け付けます。それ以外の画像形式はコードで先に Icon に変換する必要があるため、トレイには .ico ファイルが実際的な選択肢です。
  • Text: トレイ アイコンにカーソルを合わせたときに表示されるツールチップです。
  • Visible: アイコンをトレイに表示するかどうかです。フォームが表示されている間は False のままにし、アプリがタスクバーとトレイを同時に占有しないようにします。
  • BalloonTipTitle、BalloonTipText、BalloonTipIcon: ShowBalloonTip が表示するバルーン通知のタイトル、本文、および重要度アイコンです。

プロパティ ウィンドウで Icon に .ico ファイルを割り当て、最初は Visible を False のままにしておきます。

アイコンが割り当てられ、Visible が False に設定された NotifyIcon のプロパティ

次に、フォームの読み込み時にテキスト関連のプロパティを設定します。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 を選択します。

    Visual Studio のスタート ウィンドウ

  • Windows Forms App テンプレートを選択し、Next をクリックします。

    Windows Forms App テンプレートが選択された新しいプロジェクトの作成ダイアログ

  • プロジェクト名を入力し、Create をクリックします。

    新しい Windows フォーム プロジェクトの名前付け

  • ツールボックスから NotifyIcon をフォームにドラッグし、前のセクションで説明したように Icon を割り当てて Visible を False のままにします。アイコンを省略すると、フォームが非表示になったときにシステム トレイに何も表示されません。
  • フォームの Resize イベントを配線します。フォームを選択し、プロパティ ウィンドウでイベント一覧 (稲妻アイコンのボタン) を開き、Resize をダブルクリックして Form1_Resize を作成します。

    Resize が Form1_Resize に配線された Form1 のイベント一覧

  • 同様に 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 ウィンドウ

この時点では、アプリはタスクバーを占有しており、システム トレイにはまだ何も追加されていません。

最小化前にアプリのボタンを表示しているタスクバー

フォームの最小化ボタンをクリックします。

最小化ボタンが強調表示された Form1

Form1_Resize ハンドラーが発生します。フォームとそのタスクバー ボタンが消え、システム トレイにアイコンが現れ、設定したタイトルとテキストのバルーン ヒントがポップアップします。これは、上の実行可能なプログラムが 3 行の出力として表示するのと同じ一連の動作です。

最小化後にアプリのアイコンを表示しているシステム トレイ

トレイ アイコンをダブルクリックして復元経路を確認します。フォームが通常の状態で再表示され、タスクバー ボタンが戻り、トレイ アイコンは消えます。アプリケーションは終始実行を続けています。トレイへの最小化は表示場所を変えるだけで、実行の有無は変わりません。

最小化後にアイコンが現れない場合は、デザイナーまたはコードで Icon が割り当てられているか確認してください。アイコンがなければ NotifyIcon は何も描画せず (ShowBalloonTip も何も表示しません)、非表示になったアプリが復元手段の見えないまま実行を続けることになります。