C#实现系统托盘通知的方法
在Windows应用程序中,系统托盘是一个很重要的交互方式,在不影响用户正常工作的情况下,可以及时方便的向用户提供各种需要处理和展示的数据。C#提供了丰富的API,帮助我们实现系统托盘通知,本文将介绍两种常见的实现方法。
方法一:使用NotifyIcon
类实现
NotifyIcon
类为我们提供了丰富的事件和属性,使得我们的系统托盘交互变得十分便捷。以下是一个简单的示例:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TrayIconDemo
{
public partial class MainForm : Form
{
private NotifyIcon trayIcon;
public MainForm()
{
InitializeComponent();
trayIcon = new NotifyIcon();
trayIcon.Icon = new Icon("icon.ico");
trayIcon.Text = "Tray Icon Demo";
trayIcon.Visible = true;
trayIcon.Click += TrayIcon_Click;
trayIcon.DoubleClick += TrayIcon_DoubleClick;
}
private void TrayIcon_Click(object sender, EventArgs e)
{
MessageBox.Show("您单击了托盘图标!");
}
private void TrayIcon_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show("您双击了托盘图标!");
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
trayIcon.Visible = false;
trayIcon.Dispose();
}
}
}
在这个示例中,我们创建了一个名为trayIcon
的NotifyIcon
对象,并为其设置了图标和显示文本。然后,我们还为它注册了单击和双击事件,以实现与用户的交互。当用户单击或双击托盘图标时,将弹出一个消息框提示用户。
方法二:使用Win32 API实现
Win32 API是Windows操作系统提供的一组底层API,可以直接调用系统底层操作,实现更加灵活的功能。以下是一个使用Win32 API实现系统托盘通知的示例:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Win32TrayIconDemo
{
public partial class MainForm : Form
{
private IntPtr notificationIconHandle;
private Guid notificationIconGUID;
private uint WM_TASKBARCREATED;
private uint WM_NOTIFYICON;
private uint nfid;
public MainForm()
{
InitializeComponent();
RegisterNotificationIcon();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_TASKBARCREATED)
{
RegisterNotificationIcon();
}
else if (m.Msg == WM_NOTIFYICON)
{
if (m.LParam.ToInt32() == 513)
{
// 单击托盘图标
MessageBox.Show("您单击了托盘图标!");
}
else if (m.LParam.ToInt32() == 516)
{
// 双击托盘图标
MessageBox.Show("您双击了托盘图标!");
}
}
base.WndProc(ref m);
}
private void RegisterNotificationIcon()
{
notificationIconGUID = new Guid("31AC8BA1-6B2A-4ccc-9627-98ECCFC34120");
notificationIconHandle = IntPtr.Zero;
WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
WM_NOTIFYICON = RegisterWindowMessage("Shell_NotifyIcon");
NOTIFYICONDATA notifyIconData = new NOTIFYICONDATA();
notifyIconData.cbSize = Marshal.SizeOf(notifyIconData);
notifyIconData.hWnd = this.Handle;
notifyIconData.uID = (uint)notificationIconGUID.GetHashCode();
notifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
notifyIconData.uCallbackMessage = WM_NOTIFYICON;
notifyIconData.hIcon = new Icon("icon.ico").Handle;
notifyIconData.szTip = "Win32 Tray Icon Demo";
bool success = Shell_NotifyIcon(NIM_ADD, ref notifyIconData);
if (!success)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
nfid = notifyIconData.uID;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
NOTIFYICONDATA notifyIconData = new NOTIFYICONDATA();
notifyIconData.cbSize = Marshal.SizeOf(notifyIconData);
notifyIconData.hWnd = this.Handle;
notifyIconData.uID = nfid;
bool success = Shell_NotifyIcon(NIM_DELETE, ref notifyIconData);
if (!success)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
private struct NOTIFYICONDATA
{
public int cbSize;
public IntPtr hWnd;
public uint uID;
public uint uFlags;
public uint uCallbackMessage;
public IntPtr hIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szTip;
}
private const int NIF_ICON = 0x00000002;
private const int NIF_MESSAGE = 0x00000001;
private const int NIF_TIP = 0x00000004;
private const int NIM_ADD = 0x00000000;
private const int NIM_DELETE = 0x00000002;
[DllImport("shell32.dll")]
private static extern bool Shell_NotifyIcon(int dwMessage, ref NOTIFYICONDATA lpdata);
[DllImport("user32.dll", EntryPoint = "RegisterWindowMessage")]
private static extern uint RegisterWindowMessage(string lpString);
}
}
在这个示例中,我们通过Win32 API实现了和第一种方法相同的功能。首先,我们在窗体类中重写WndProc
方法,监控系统消息的处理。我们通过RegisterNotificationIcon
方法注册了系统托盘图标,并设置了单击和双击事件的处理方式。当用户单击或双击托盘图标时,也会弹出一个消息框提示用户。
这个示例中使用了Win32 API提供的函数来实现操作系统级别的功能,代码量较多,但是实现方式更加灵活,可以满足更加复杂的需求。
结论
无论是使用NotifyIcon
类还是使用Win32 API,实现系统托盘通知都不难。我们可以根据自己的需求选择适合自己的方法。如果只是实现简单的功能,可以选择使用NotifyIcon
类;如果需要更加灵活的控制和操作,可以使用Win32 API实现。
注意:在使用NotifyIcon类时,需要将图标添加为资源文件进行编译;使用Win32 API时,需要引入System.Runtime.InteropServices和System.ComponentModel命名空间。
以上是关于C#实现系统托盘通知的方法的完整攻略,希望对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现系统托盘通知的方法 - Python技术站