C#实现系统托盘通知的方法

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();
        }
    }
}

在这个示例中,我们创建了一个名为trayIconNotifyIcon对象,并为其设置了图标和显示文本。然后,我们还为它注册了单击和双击事件,以实现与用户的交互。当用户单击或双击托盘图标时,将弹出一个消息框提示用户。

方法二:使用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技术站

(1)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • C#中实现登录功能的完整步骤

    下面我会详细讲解在C#中实现登录功能的完整步骤。 一、准备工作 1.设计数据库 首先我们需要设计一个数据库,用于存储用户信息,包括用户名和密码等。可以设计一个类似下面的用户表: CREATE TABLE [dbo].[tb_User]( [UserID] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarchar](…

    C# 2023年5月15日
    00
  • C#实现串口调试工具

    下面是关于C#实现串口调试工具的完整攻略: 1. 前期准备 在使用C#来实现串口调试工具之前,首先要准备好相关的环境和工具。具体的步骤如下: 安装Visual Studio开发工具,选择适合自己的版本。 新建一个项目,选择“Windows窗体应用程序”。 在项目中添加“串口”控件。 2. 界面设计 接下来要进行的步骤是对调试工具的界面进行设计。通过界面设计,…

    C# 2023年6月6日
    00
  • c# 剔除sql语句’尾巴’的五种方法

    接下来我将为大家详细介绍“C#剔除SQL语句‘尾巴’的五种方法”: 一、问题描述 有时候在编写C#程序时,我们需要动态生成SQL语句。但是在动态生成SQL语句中,由于字符串拼接不当可能会导致语句的末尾出现多余的“AND”、“OR”等关键字,这就需要我们对字符串进行处理,去掉这些多余的关键字,以保证SQL语句的正确性。 下面将介绍五种方法来解决这个问题。 二、…

    C# 2023年5月15日
    00
  • C# TextWriter.Write – 写入一个字符

    TextWriter.Write 方法是C#中用于将文本写入流的方法之一。其主要作用是向流中写入指定的文本内容。下面是关于 TextWriter.Write 方法的使用方法的详细攻略: 方法定义 public virtual void Write(string value); 此方法为虚方法,因此可以在子类中进行重写。 参数说明 value(必填参数):要写…

    C# 2023年4月19日
    00
  • 如何在Unity中检测死循环和卡死

    在Unity中如何检测死循环和卡死主要有以下几种方法: 1. 检测MonoBehaviour的Update方法是否失控 MonoBehaviour的Update方法是Unity脚本中常用的一个方法,它每帧都会执行一次。如果Update方法入口出现死循环或长时间阻塞,就会导致游戏卡死或崩溃。 我们可以通过记录Update方法的执行时间,来判断是否出现了死循环或…

    C# 2023年5月15日
    00
  • asp.net 简单验证码验证实现代码

    下面是 “asp.net 简单验证码验证实现代码”的完整攻略: 标题 1. 引入命名空间 使用验证码,需要在代码中引入System.Drawing和System.Drawing.Imaging两个命名空间。在aspx页面的头部引入这两个命名空间即可。 <%@ Import Namespace="System.Drawing" %&g…

    C# 2023年5月31日
    00
  • ASP.NET Core基础之中间件

    关于ASP.NET Core基础之中间件,以下是完整攻略: 什么是中间件? 中间件(Middleware)是ASP.NET Core应用程序中用于处理HTTP请求和响应的组件。中间件按照顺序依次执行,因此需要小心编写顺序,以确保它们按照预期工作。 中间件可以处理请求并返回响应,也可以将请求传递给下一个中间件,以便处理。中间件可以执行许多操作,比如日志记录、异…

    C# 2023年6月3日
    00
  • C#如何连接服务器共享文件夹

    连接服务器共享文件夹是C#程序开发中非常常见的需求,以下是连接服务器共享文件夹的完整攻略: 确定共享文件夹的路径 在连接服务器共享文件夹之前,需要确定共享文件夹的路径。共享文件夹通常是基于服务器的网络共享,因此需要访问服务器的网络位置,例如: \\servername\sharedfolder 其中,servername表示服务器的名称或IP地址,share…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部