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# 判断字符为空的6种方法的效率实测对比

    我来详细讲解“C# 判断字符为空的6种方法的效率实测对比”的完整攻略。 1. 引言 在C#编程中,判断字符是否为空是一项非常基础的操作。为了提高代码效率,我们需要选择最合适的方法。本文从六种不同的判断字符为空的方式进行效率实测,以便找到一种最优解。 2. 方法介绍 以下是六种不同的判断字符为空的方式: 2.1 判断字符串是否为空或null if (strin…

    C# 2023年6月1日
    00
  • C# 将数据库SqlServer数据绑定到类中的过程详解

    标题 C# 将数据库 SqlServer 数据绑定到类中的过程详解 简介 本篇攻略主要介绍 C# 中如何将数据库 SqlServer 数据绑定到类中,从而方便数据操作和管理。 过程分析 3.1 使用 DataSet 进行绑定 在 C# 中,使用 DataSet 对象可以将数据库中的数据绑定到类中。具体操作步骤如下: (1)建立 C# 项目,并在项目中添加 S…

    C# 2023年6月2日
    00
  • C#读写文件的方法汇总

    C#读写文件的方法汇总 在C#编程中,读写文件是一项非常常见的操作。本文将介绍C#语言中常用的文件读写方法。 1. FileStream类 FileStream是.NET Framework中用于读取、写入和操作文件的类。以下是使用FileStream类进行文件读写的示例代码: 读取文件 string path = @"C:\test.txt&qu…

    C# 2023年5月31日
    00
  • python接口自动化(十六)–参数关联接口后传(详解)

    Python接口自动化–参数关联接口后传 在接口自动化测试中,有时需要在一个接口的返回结果中提取某些参数,并将这些参数传递给后续的接口。这个过程称为参数关联。本攻略将介绍如何在 Python 接口自动化测试中实现参数关联接口后传。 参数关联 参数关联是指在一个接口的返回结果中提取某些参数,并将这些参数传递给后续的接口。参数关联通常用于测试场景中,例如登录接…

    C# 2023年5月17日
    00
  • C#使用HttpHelper框架重启路由器

    我们一步一步来。 概述 要使用HttpHelper框架重启路由器,我们需要先了解什么是HttpHelper框架和路由器重启的过程。 HttpHelper框架是一个基于.NET Framework的HTTP请求框架,可以帮助我们实现请求数据、提交数据、模拟浏览器,进而实现网络爬虫等多种功能。而路由器重启,则是通过模拟客户端向路由器发送重启指令,实现路由器远程重…

    C# 2023年6月3日
    00
  • C#图书管理系统 附源码下载

    项目简介 “C#图书管理系统 附源码下载”是一个基于C#语言和微软.NET框架的图书管理系统项目,插图库采用DevExpress控件。该项目是一个班级的课程设计作业,其目的是为了让学生们在实践中掌握C#语言和.NET框架的应用。 项目结构 该项目主要分为以下三个部分: 登录界面:用户需要先进行注册并登录才能进行图书管理操作。 图书查询/添加:用户可以查询已有…

    C# 2023年5月31日
    00
  • C#获取存储过程返回值和输出参数值的方法

    下面是详细的攻略: 获取存储过程返回值和输出参数值的方法 存储过程返回值与输出参数概述 在使用 C# 调用存储过程时,往往需要获取存储过程的返回值和输出参数的值。其中,返回值是存储过程完成操作后返回的整数值,而输出参数是从存储过程中返回的数据值。在 C# 中,可以使用 SqlCommand 类的 ExecuteNonQuery() 方法来执行存储过程,并通过…

    C# 2023年5月15日
    00
  • c#继承中的函数调用实例

    下面是针对”C#继承中的函数调用实例”的完整攻略: 概述 在C#中,继承是一种非常常见的实现代码重用和减少冗余的方式。在子类中可以重写父类中的方法,也可以从父类中继承方法。当子类继承父类的方法时,可能会出现相同名称的方法,因此在调用方法时要注意调用哪个方法。这里就介绍在继承中如何调用不同层次的方法。 基本概念 在C#中,继承是一种创建新类的机制,新类可以继承…

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