サンプルアプリの仕様概要
Windows10で動作します。ただしVisual Studio等でWindows SDK入れてないとwindows.winmdファイルがなくてコンパイルできないっぽい
- アイコンを左クリックで通知が出ます。(連打すると通知が延々と何度も出るので注意)
- アイコンを右クリック→Exitで終了できます。
ソースコード
ToastNotificationManager.CreateToastNotifier("Microsoft.Windows.Computer");
のところはかなり強引です。1
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Windows.UI.Notifications;
public static class IconUtil
{
static class NativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public extern static bool DestroyIcon(IntPtr handle);
}
static readonly string[] iconDot = new string[]{
"................",
".###.###..##.###",
"..#..#...#....#.",
"..#..#...#....#.",
"..#..#...#....#.",
"..#..#...#....#.",
"..#..#...#....#.",
"..#..###..#...#.",
"..#..#.....#..#.",
"..#..#.....#..#.",
"..#..#.....#..#.",
"..#..#.....#..#.",
"..#..#.....#..#.",
"..#..#.....#..#.",
"..#..###.##...#.",
"................",
};
public static Icon MakeDefaultIcon()
{
using ( Bitmap bmp = new Bitmap(16,16) ) {
using ( Graphics g = Graphics.FromImage(bmp) ) {
g.Clear(Color.Blue);
}
for(int y=0;y<16;y++){
for(int x=0;x<16;x++){
if (iconDot[y][x]=='#') {
bmp.SetPixel(x,y,Color.Yellow);
}
}
}
IntPtr Hicon = bmp.GetHicon();
return Icon.FromHandle(Hicon);
}
}
public static void DestroyIcon(Icon ico)
{
NativeMethods.DestroyIcon(ico.Handle);
}
}
class TaskTrayLauncher
{
NotifyIcon trayIcon;
static void ShowSampleToast()
{
string xmlStr = File.ReadAllText("sample.xml", Encoding.GetEncoding("Shift_JIS"));
var content = new Windows.Data.Xml.Dom.XmlDocument();
content.LoadXml(xmlStr);
var notifier = ToastNotificationManager.CreateToastNotifier("Microsoft.Windows.Computer");
notifier.Show(new ToastNotification(content));
}
TaskTrayLauncher()
{
trayIcon = new NotifyIcon();
Icon tmpIcon = IconUtil.MakeDefaultIcon();
trayIcon.Icon = tmpIcon;
trayIcon.Visible = true;
trayIcon.Text = "Launcher";
var menu = new ContextMenuStrip();
var menuItem = new ToolStripMenuItem();
menu.Items.AddRange(new ToolStripMenuItem[]{
new ToolStripMenuItem("E&xit", null, (s,e)=>{Application.Exit();}, "Exit")
});
trayIcon.MouseClick += TrayIcon_MouseClick;
trayIcon.ContextMenuStrip = menu;
}
void TrayIcon_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
ShowSampleToast();
}
// 右クリックはcontextmenuを表示させるので、ここでは何もしない
}
[STAThread]
static void Main(string[] args)
{
new TaskTrayLauncher();
Application.Run();
}
}
toastのxml
同じフォルダにおいてください。
Shift_JIS2で保存してください。
sample.xml
<toast activationType='foreground' launch='args'>
<visual>
<binding template='ToastGeneric'>
<text>test</text>
<text>testtest</text>
</binding>
</visual>
<audio src='ms-winsoundevent:Notification.SMS' />
</toast>
コンパイルバッチ
使い方:
compile.bat ファイル名.cs
compile.bat
csc /r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.WindowsRuntime\v4.0_4.0.0.0__b77a5c561934e089\system.runtime.windowsruntime.dll ^
/r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.InteropServices.WindowsRuntime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.InteropServices.WindowsRuntime.dll ^
/r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.dll ^
"/r:C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winmd" %*
参考記事(参考サイト)
ボタンの追加とイベント処理
参考記事2にあるように、xmlを修正すればToast通知上にボタンを追加することは簡単にできるのですが、
参考記事1で言及されている通り、イベントを受け取るのは困難で、特に、
https://docs.microsoft.com/ja-jp/windows/uwp/design/shell/tiles-and-notifications/send-local-toast-desktop#step-4-implement-the-activator
にあるGUIDの登録が必要になるっぽいです。
-
詳しくは参考記事1のコードの説明を参照ください。 ↩
-
UTF-8を使うべきだと思いますが、PC環境の私的な事情でShift_JISにしています・・ ↩