1. タスクトレイ(タスクバー)にアイコンを置く
1-1. サンプルコード
このままのプログラムだと何も役には立たない。
使い道としては、外部exeを実行したりするとか。
using System;
using System.ComponentModel; // CancelEventArgsを使用するため
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
static class MyIconUtil
{
static class NativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public extern static bool DestroyIcon(IntPtr handle);
}
public static Icon Create16x16Icon(string[] iconDot)
{
Bitmap bmp = new Bitmap(16,16);
using ( Graphics g = Graphics.FromImage(bmp) ) {
g.Clear(Color.White);
}
for(int y=0;y<16;y++){
for(int x=0;x<16;x++){
if (iconDot[y][x]=='#') {
bmp.SetPixel(x,y,Color.Black);
}
}
}
IntPtr Hicon = bmp.GetHicon();
return Icon.FromHandle(Hicon);
}
public static void DestroyIcon(Icon icon)
{
NativeMethods.DestroyIcon(icon.Handle);
}
}
class TaskTrayTest
{
static string[] iconDot = new string[]{
"................",
".###...##...##..",
"..#...#..#.#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#....#..#.",
"..#...#..#.#..#.",
".###...##...##..",
"................",
};
TaskTrayTest()
{
//this.ShowInTaskbar = false; // TaskTrayTestがFormを継承する場合はコメントアウトを外す
NotifyIcon trayIcon = new NotifyIcon();
//trayIcon.Icon = new Icon("hogehoge.ico"); // 何かしらのアイコンを設定しないとタスクトレイに表示されない
Icon tmpIcon = MyIconUtil.Create16x16Icon(iconDot);
trayIcon.Icon = tmpIcon;
trayIcon.Visible = true;
// MyIconUtil.DestroyIcon(tmpIcon);
trayIcon.Text = "常駐テスト";
var menu = new ContextMenuStrip();
menu.Items.AddRange(new ToolStripMenuItem[]{
new ToolStripMenuItem("&Open", null, (s,e)=>{MyDoSomething();}, "Open"),
new ToolStripMenuItem("E&xit", null, (s,e)=>{MyExit();}, "Exit")
});
trayIcon.DoubleClick += (s,e)=>{MyDoSomething();};
trayIcon.ContextMenuStrip = menu;
}
void MyDoSomething()
{
Console.WriteLine("MyDoSomething is called.");
}
void MyExit()
{
var e = new CancelEventArgs();
Application.Exit(e);
if (e.Cancel) {
Console.WriteLine("Application.Exit is canceled.");
}
}
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("Main() Start.");
new TaskTrayTest();
Console.WriteLine("Instance is created.");
Application.Run();
Console.WriteLine("Main() End.");
}
}
1-2. 説明
-
NotifyIcon
が、タスクトレイにアイコンを表示させるためのクラス(Microsoft Docs参照1)。
このクラスのメンバがWndProc
を持っていて、メッセージループを処理してイベントを処理しているようである。(ILSpyで見た感じでは。) -
Application.Run()
が、プログラムが終了しないようにしている。NotifyIconとApplication.Runのループがやりとりしているのかはよくわからない。。
(Application.Run() - Microsoft Docs)
■気を付けるべきこと
- タスクトレイからFormを表示させたりする場合は、アプリの終了のさせ方に気を付ける必要がありそう。参考サイト3参照。
1-3. 参考サイト
- C#: タスクトレイに常駐するアプリの作り方
- フォームを表示させずにトレイアイコンを表示する - dobon.net
- アプリケーション(自分自身)を終了させる - dobon.net
- 通知領域のアイコン情報のレジストリについて
1-4. アイコン
アイコンを準備する必要があるので、それ用のソフトを持っていない・フリーソフトを入れたくない場合は、手前味噌ですが下記あたりで適当に対応ください。
- C# - ちょー雑な方法でFormのアイコンを生成する (Windows)
- C#で、文字と図形からなるWindowsアイコン(.Ico)【透過】を作成するプログラムを作ってみた
- C#で画像からWindowsアイコン(.ico)に変換するソフトつくった - 透過対応
2. スタートアップへの登録
2-1. 参考サイト
まだ試せていない
[C#] スタートアップメニューにショートカットを登録する方法
3. 多重起動の防止
まだ試せていない。Mutexを使うらしい。
4. タスクバーの常時表示領域に置く設定方法(※手作業)
2020.10.31追記しました。
-
日本語版は機械翻訳が酷かったので英語のほうにしてます。 ↩