首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實作智慧型裝置 NotifyIcon:.NET Compact Framework 托盤圖示元件

     編輯:關於C#

背景

.NET Compact Framework (CF) 缺少 NotifyIcon 控制項。參考桌面版用 Shell_NotifyIcon + MessageWindow 實作,發現 CF 同樣支援:

  • Microsoft.WindowsCE.Forms.MessageWindow:提供視窗程序 WndProc 接收訊息。
  • coredll.dll 匯出 Shell_NotifyIcon:WinCE 核心 DLL 包含該 API。

NOTIFYICONDATA 結構


[StructLayout(LayoutKind.Sequential)]
internal struct NOTIFYICONDATA
{
    internal int cbSize;        // 結構大小,CF 固定 152
    internal IntPtr hWnd;       // 接收訊息的視窗控制代碼
    internal uint uID;          // 圖示識別碼
    internal uint uFlags;       // 有效欄位標記
    internal uint uCallbackMessage; // 回呼訊息代碼
    internal IntPtr hIcon;      // 圖示控制代碼
}

完整 NotifyIcon 類別實作


using System;
using System.Drawing;
using System.Runtime.InteropServices;
using Microsoft.WindowsCE.Forms;

public class NotifyIcon : IDisposable
{
    public event EventHandler Click;
    private readonly MessageWindow _msgWin;
    private readonly uint _uid = 5000;
    private Icon _icon;

    public NotifyIcon()
    {
        _msgWin = new MessageWindow();
        _msgWin.WndProc += MsgWin_WndProc;
    }

    public Icon Icon { set => _icon = value; }

    public void Add() => Add(_icon?.Handle ?? IntPtr.Zero);
    public void Add(Icon icon) => Add(icon.Handle);
    public void Add(IntPtr hIcon) => Notify(NIM_ADD, hIcon);
    public void Remove() => Notify(NIM_DELETE, IntPtr.Zero);
    public void Modify(IntPtr hIcon) => Notify(NIM_MODIFY, hIcon);

    private void Notify(int msg, IntPtr hIcon)
    {
        NOTIFYICONDATA nid = new NOTIFYICONDATA
        {
            cbSize = 152,
            hWnd = _msgWin.Hwnd,
            uID = _uid,
            uFlags = NIF_MESSAGE | NIF_ICON,
            uCallbackMessage = WM_NOTIFY_TRAY,
            hIcon = hIcon
        };
        Shell_NotifyIcon(msg, ref nid);
    }

    private void MsgWin_WndProc(ref Message m)
    {
        if (m.Msg == WM_NOTIFY_TRAY && (int)m.LParam == WM_LBUTTONDOWN && (int)m.WParam == _uid)
            Click?.Invoke(this, EventArgs.Empty);
    }

    public void Dispose() { Remove(); _msgWin.Dispose(); }

    // P/Invoke
    private const int NIF_MESSAGE = 0x1, NIF_ICON = 0x2;
    private const int NIM_ADD = 0, NIM_MODIFY = 1, NIM_DELETE = 2;
    private const int WM_LBUTTONDOWN = 0x201;
    private const int WM_NOTIFY_TRAY = 0x400 + 2001;

    [DllImport("coredll.dll")] private static extern int Shell_NotifyIcon(int msg, ref NOTIFYICONDATA nid);
}

使用範例


NotifyIcon tray = new NotifyIcon();
tray.Icon = new Icon(@"\Windows\alarm.ico");
tray.Click += (s, e) => MessageBox.Show("托盤圖示被點擊!");
tray.Add();
// 程式結束時
tray.Dispose();

注意事項

  • CF 視窗預設最大化會遮住工作列,需最小化主視窗才能看見托盤圖示。
  • 圖示建議使用 16x16 .ico,過大會自動縮放失真。
  • MessageWindow 需在 UI 執行緒建立,否則 Hwnd 無效。
  • 支援資源檔圖示:LoadIcon(GetModuleHandle(null), "#201547")。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved