You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows系统托盘应用开发:C#是否有可复用基类或SDK?

C#系统托盘应用复用标准控件实现方案

Windows没有直接提供完全匹配你需求的现成控件类,但可以基于.NET原生组件结合系统API,实现和Windows标准音量控制、日历一致的体验,无需从零实现所有逻辑:

1. 点击托盘图标弹出窗体+关闭隐藏图标面板

用.NET自带的NotifyIcon处理点击事件,配合Windows API关闭隐藏图标面板:

[DllImport("shell32.dll")]
private static extern bool Shell_NotifyIconGetRect(ref NOTIFYICONIDENTIFIER identifier, out RECT iconRect);

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
private static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

// 定义所需结构体
[StructLayout(LayoutKind.Sequential)]
public struct NOTIFYICONIDENTIFIER
{
    public uint cbSize;
    public IntPtr hWnd;
    public uint uID;
    public Guid guidItem;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

private void NotifyIcon_Click(object sender, EventArgs e)
{
    // 关闭隐藏图标面板
    IntPtr overflowWindow = FindWindow("NotifyIconOverflowWindow", null);
    if (overflowWindow != IntPtr.Zero)
    {
        SendMessage(overflowWindow, 0x0010, IntPtr.Zero, IntPtr.Zero); // WM_CLOSE
    }
    // 弹出自定义窗体
    var trayForm = new TrayPopupForm();
    trayForm.Show();
}

2. 窗体对齐托盘所在屏幕的右下角

先通过API获取托盘图标位置,再定位到对应屏幕的右下角:

private void PositionForm(Form form)
{
    var identifier = new NOTIFYICONIDENTIFIER
    {
        cbSize = (uint)Marshal.SizeOf(typeof(NOTIFYICONIDENTIFIER)),
        hWnd = notifyIcon1.Handle,
        uID = notifyIcon1.ID
    };

    if (Shell_NotifyIconGetRect(ref identifier, out RECT iconRect))
    {
        Point iconCenter = new Point((iconRect.Left + iconRect.Right) / 2, (iconRect.Top + iconRect.Bottom) / 2);
        Screen targetScreen = Screen.FromPoint(iconCenter);
        // 对齐屏幕工作区右下角
        form.Location = new Point(
            targetScreen.WorkingArea.Right - form.Width,
            targetScreen.WorkingArea.Bottom - form.Height
        );
    }
}

调用:在窗体Show()前执行PositionForm(trayForm)。

3. 失去焦点自动关闭窗体

给窗体添加Deactivate事件,加短延迟避免误关闭:

private void TrayPopupForm_Deactivate(object sender, EventArgs e)
{
    Task.Delay(100).ContinueWith(_ => this.Invoke(new Action(() => this.Close())));
}

外观一致性保障

  • 设置窗体FormBorderStyle = FormBorderStyle.None,模拟原生弹出面板样式
  • 控件使用FlatStyle.System,确保跟随系统主题渲染
  • 可借助VisualStyleRenderer自定义绘制控件,完全匹配系统视觉风格

内容的提问来源于stack exchange,提问作者Deling Ren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:03:30