DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

フォームを表示させずにトレイアイコンを表示する

ここでは、アプリケーション起動時にフォームを表示させないで、NotifyIconコンポーネントを使用してタスクトレイにアイコンを表示する方法を考えます。ここで紹介する幾つかの方法は、メインフォームを表示せずにアプリケーションを開始する方法としても利用できます。

補足:アプリケーション開始時にはフォームを作成せず、条件によって作成、表示する方法については、「アプリケーション開始時のフォームを非表示にする」をご覧ください。

なお、NotifyIconコンポーネントでタスクトレイにアイコンを表示する方法については、ここでは説明しません。分からないという場合は、まず「タスクトレイにアイコンを表示する」をご覧ください。

普通に考えれば、NotifyIconコンポーネントをフォームに貼り付けて、そのフォームのVisibleプロパティをFalseにしてアプリケーションを開始すれば目的が果たせるように思われますが、このようにしてもメインフォームは表示されてしまいます。よって、メインフォームを隠す何らかの対策が必要になります。

フォームを最小化しておく方法

最もオーソドックスと思われるのは、起動時のフォームの状態を最小化にして、さらにタスクバーに表示させないように設定しておくという方法です。つまり、フォームのプロパティの「WindowState」を「Minimized」、「ShowInTaskbar」を「False」にしておきます。これで見た目には起動時にフォームが表示されないようになるでしょう。

これでもフォームが表示される恐れはありますが、フォームにバージョン情報のようなものを表示させておけば、問題はないでしょう。

パラメータを指定せずにApplication.Runを呼び出す方法

エントリポイントのMainメソッドでフォームのインスタンスを作成し、フォームを表示することなく、パラメータを指定せずにApplication.Runメソッドを呼び出すという方法があります。具体的には、次のようなMainメソッドを作成し、これをエントリポイントにします。エントリポイントについて詳しくは、こちらをご覧ください。

VB.NET
コードを隠すコードを選択
''' <summary>
''' アプリケーションのメイン エントリ ポイントです。
''' </summary>
<STAThread()> _
Shared Sub Main()
    'フォーム(Form1)のインスタンスを作成
    Dim f1 As New Form1
    'メッセージループを開始する
    Application.Run()
End Sub
C#
コードを隠すコードを選択
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main() 
{
    //フォーム(Form1)のインスタンスを作成
    Form1 f1 = new Form1();
    //メッセージループを開始する
    Application.Run();
}

なおこの方法では、フォームを閉じても(破棄しても)アプリケーションは終了しません。アプリケーションを終了するには、Application.ExitやExitThreadメソッドを呼び出します。Application.Exitに関しては、こちらもご覧ください。

Opacityを0にする方法

マイクロソフトの配布した「.NET なんでだろ? CD-ROM」内の「Visual Studio .NET Family製品 サンプル プログラム」に「Windowsシステム トレイ サンプル(Windows System Tray Sample)」というのがあります。このサンプルでは、Opacityプロパティを0とすることにより、フォームを非表示にしているようでした。

ところがOpacityプロパティはWindows98/Meでは対応していないため、この方法ではWindows98/Meではフォームが表示されてしまいます。

CreateParamsをオーバーライドする方法

Visual Studio Magazineの「How's Your Form?」(リンク切れ)では、CreateParamsプロパティをオーバーライドすることにより、フォームを表示しないようにする方法が紹介されています。この方法を使うこともできそうです。

この方法により、フォームを表示しないようにする例を示します。表示しないようにするフォームのクラスに記述してください。

VB.NET
コードを隠すコードを選択
'Imports System.Security.Permissions

'フォームのCreateParamsプロパティをオーバーライドする
Protected Overrides ReadOnly Property CreateParams() As CreateParams
    <SecurityPermission(SecurityAction.Demand, _
        Flags:=SecurityPermissionFlag.UnmanagedCode)> _
    Get
        Const WS_EX_TOOLWINDOW As Int32 = &H80
        Const WS_POPUP As Int32 = &H80000000
        Const WS_VISIBLE As Int32 = &H10000000
        Const WS_SYSMENU As Int32 = &H80000
        Const WS_MAXIMIZEBOX As Int32 = &H10000

        Dim cp As System.Windows.Forms.CreateParams
        cp = MyBase.CreateParams
        cp.ExStyle = WS_EX_TOOLWINDOW
        cp.Style = WS_POPUP Or WS_VISIBLE Or _
            WS_SYSMENU Or WS_MAXIMIZEBOX
        cp.Height = 0
        cp.Width = 0
        Return cp
    End Get
End Property
C#
コードを隠すコードを選択
//using System.Security.Permissions;

//フォームのCreateParamsプロパティをオーバーライドする
protected override CreateParams CreateParams
{
    [SecurityPermission(SecurityAction.Demand,
        Flags = SecurityPermissionFlag.UnmanagedCode)]
    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;
    }
}

フォームを使わない方法

こちらの投稿によると、NotifyIconコンポーネントはフォームに配置しなくて使用しても大丈夫のようです。この投稿で紹介されている方法は、次のようなものです。

  1. コンポーネントを作成します。Visual Studioのメニュー[プロジェクト]-[コンポーネントの追加]で作成できます(作成したコンポーネントは「Component1」という名前であるとします)。
  2. デザイナでコンポーネントにNotifyIconを配置します。
  3. 上記の「パラメータを指定せずにApplication.Runを呼び出す方法」と同様に、エントリポイントのMainメソッドでComponent1のインスタンスを作成し、Application.Runをパラメータなしで呼び出します。具体的には、次のようなコードです。
VB.NET
コードを隠すコードを選択
''' <summary>
''' アプリケーションのメイン エントリ ポイントです。
''' </summary>
<STAThread()> _
Shared Sub Main()
    'Component1のインスタンスを作成
    Dim comp As New Component1
    'メッセージループを開始する
    Application.Run()
End Sub
C#
コードを隠すコードを選択
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main() 
{
    //Component1のインスタンスを作成
    Component1 comp = new Component1();
    //メッセージループを開始する
    Application.Run();
}

「パラメータを指定せずにApplication.Runを呼び出す方法」と同様に、アプリケーションを終了するには、Application.ExitやExitThreadメソッドを呼び出してください。

  • 履歴:
  • 2006/11/5 「パラメータを指定せずにApplication.Runを呼び出す方法」と「フォームを使わない方法」を追加。
  • 2010/6/30 CreateParamsにSecurityPermissionAttributeを付けた。
  • 2013/12/9 SecurityAction.LinkDemandの代わりにSecurityAction.Demandを使うようにした。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。