您好,登錄后才能下訂單哦!
C#語(yǔ)言中的Shell_NotifyIcon如何使用WinForm進(jìn)行調(diào)用?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
public class InnerClass: Form { private Shell_NotifyIconEx servicesClass = null; // 接受主CLASS 的實(shí)例句柄 internal InnerClass(Shell_NotifyIconEx _servicesClass) { servicesClass = _servicesClass; } private const int WM_LBUTTONDOWN = 0x0201; // 左鍵 private const int WM_RBUTTONDOWN = 0x204; // 右鍵 private const int WM_MBUTTONDOWN = 0x207; // 中鍵 [DllImport("user32.dll", EntryPoint = "TrackPopupMenu")] private static extern int TrackPopupMenu( // c# 和vb.net 好象沒(méi)有了隨地popup 了,只要請(qǐng)它老人家出馬了 IntPtr hMenu, int wFlags, int x, int y, int nReserved, IntPtr hwnd, ref RECT lprc ); [StructLayout(LayoutKind.Sequential)] private struct RECT { // 上面那位用的結(jié)構(gòu),表示前彈出菜單可用的一個(gè)范圍大?。ㄒ话闶侨聊欢甲屗茫糁阌螒蚧蛞曨l對(duì)話之類的朋友指定菜單可用的范圍) internal int Left; internal int Top; internal int Right; internal int Bottom; } protected override void WndProc(ref Message msg) { if (msg.Msg == servicesClass.WM_NOTIFY_TRAY) { // 如果消息相符 if ((int)msg.WParam == servicesClass.uID) { // 并且消息的WParam 相符 MouseButtons mb =MouseButtons.None; if ((int)msg.LParam == WM_LBUTTONDOWN) { //如果點(diǎn)擊的是左鍵 mb =MouseButtons.Left; } else if ((int)msg.LParam == WM_MBUTTONDOWN) { //中鍵 mb =MouseButtons.Middle; } else if ((int)msg.LParam == WM_RBUTTONDOWN) { //右鍵 if (servicesClass.contextMenuHwnd != IntPtr.Zero) { //如果有定義過(guò)菜單關(guān)聯(lián) RECT r = new RECT(); r.Left = Screen.PrimaryScreen.WorkingArea.Left; r.Right =Screen.PrimaryScreen.WorkingArea.Right; r.Top =Screen.PrimaryScreen.WorkingArea.Top; r.Bottom =Screen.PrimaryScreen.WorkingArea.Right; TrackPopupMenu( servicesClass.contextMenuHwnd, 2, Cursor.Position.X, Cursor.Position.Y, 0, servicesClass.formHwnd, ref r ); } else { //如果沒(méi)有定義過(guò)菜單關(guān)聯(lián) mb =MouseButtons.Right; } } if (mb !=MouseButtons.None && servicesClass._delegateOfCallBack != null) { servicesClass._delegateOfCallBack(mb); // 執(zhí)行回調(diào) return; } } } base.WndProc(ref msg); } }
public class Shell_NotifyIconEx { /// <summary> /// ArLi, last fix: 2003.9.12, reference: ArLi.CommonPrj Lib @ http://zpcity.com/arli/ /// </summary> public static readonly System.Version myVersion = new System.Version(1, 2); //版本聲明 private readonly InnerClass formTmp = null; // 這個(gè)很重要,不能放在構(gòu)造里,因?yàn)樗仨毢痛藢?shí)例同等生存期才不會(huì)被中止消息循環(huán) private readonly IntPtr formTmpHwnd = IntPtr.Zero; // 這是上一行的句柄 private readonly bool VersionOk = false; // 這是一個(gè)由VersionPass 返回的屬性,它允許開發(fā)者檢測(cè)當(dāng)前機(jī)子的Shell32.dll(可能在win95 或未知平臺(tái)上版本) 合適此組,不符則用.net 自己的notifyicon private bool forgetDelNotifyBox = false; // 這是一個(gè)私有標(biāo)志,它允許開發(fā)者在程序退出時(shí)忘記調(diào)用DelNotifyBox 來(lái)清除圖標(biāo)時(shí)會(huì)自動(dòng)在析構(gòu)里清掉它。 internal IntPtr formHwnd = IntPtr.Zero; // 這是調(diào)用此組件的主窗口句柄(當(dāng)前實(shí)例有效,可多個(gè)icon 不沖突) internal IntPtr contextMenuHwnd = IntPtr.Zero; // 這是菜單的句柄(當(dāng)前實(shí)例有效,可多個(gè)icon 不沖突) internal delegate void delegateOfCallBack(System.Windows.Forms.MouseButtons mb); internal delegateOfCallBack _delegateOfCallBack = null; public Shell_NotifyIconEx() // 構(gòu)造 { WM_NOTIFY_TRAY += 1; // 消息ID +1,避免多個(gè)ICON 消息處理沖突 uID += 1; // 同上 formTmp = new InnerClass(this); // 新實(shí)例一個(gè)消息循環(huán) formTmpHwnd = formTmp.Handle; // 新實(shí)例句柄 VersionOk = this.GetShell32VersionInfo() >= 5; // 版本是否合適,此組件由于重點(diǎn)在氣泡提示,它要求Shell32.dll 5.0(ie 5.0) 以上 } ~Shell_NotifyIconEx() { // 析構(gòu) if (forgetDelNotifyBox) this.DelNotifyBox(); //如果開發(fā)者忘記則清理icon } #region API_Consts internal readonly int WM_NOTIFY_TRAY = 0x0400 + 2001; //readonly 表示只在構(gòu)造可付值 internal readonly int uID = 5000; // 常數(shù)定義,有VC 的可以參見 shellapi.h private const int NIIF_NONE = 0x00; private const int NIIF_INFO = 0x01; private const int NIIF_WARNING = 0x02; private const int NIIF_ERROR = 0x03; private const int NIF_MESSAGE = 0x01; private const int NIF_ICON = 0x02; private const int NIF_TIP = 0x04; private const int NIF_STATE = 0x08; private const int NIF_INFO = 0x10; private const int NIM_ADD = 0x00; private const int NIM_MODIFY = 0x01; private const int NIM_DELETE = 0x02; private const int NIM_SETFOCUS = 0x03; private const int NIM_SETVERSION = 0x04; private const int NIS_HIDDEN = 0x01; private const int NIS_SHAREDICON = 0x02; private const int NOTIFYICON_OLDVERSION = 0x00; private const int NOTIFYICON_VERSION = 0x03; [DllImport("shell32.dll", EntryPoint = "Shell_NotifyIcon")] private static extern bool Shell_NotifyIcon( // 這位是主角 int dwMessage, ref NOTIFYICONDATA lpData ); /// <summary> /// 此API 的作用是當(dāng) this.focus() 無(wú)效時(shí)可以考慮使用,效果很好 /// </summary> /// <param name="hwnd">this.Handle, 當(dāng)前窗體句柄</param> [DllImport("user32.dll", EntryPoint = "SetForegroundWindow")] public static extern int SetForegroundWindow( IntPtr hwnd ); [StructLayout(LayoutKind.Sequential)] private struct NOTIFYICONDATA { // 主角用的結(jié)構(gòu) internal int cbSize; internal IntPtr hwnd; internal int uID; internal int uFlags; internal int uCallbackMessage; internal IntPtr hIcon; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x80)] internal string szTip; internal int dwState; // 這里往下幾個(gè)是 5.0 的精華 internal int dwStateMask; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0xFF)] internal string szInfo; internal int uTimeoutAndVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x40)] internal string szInfoTitle; internal int dwInfoFlags; } #endregion /// <summary> /// 建一個(gè)結(jié)構(gòu) /// </summary> private NOTIFYICONDATA GetNOTIFYICONDATA(IntPtr iconHwnd, string sTip, string boxTitle, string boxText) { NOTIFYICONDATA nData = new NOTIFYICONDATA(); nData.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(nData); // 結(jié)構(gòu)的大小 nData.hwnd = formTmpHwnd; // 處理消息循環(huán)的窗體句柄,可以移成主窗體 nData.uID = uID; // 消息的 WParam,回調(diào)時(shí)用 nData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO; // 標(biāo)志,表示由消息、圖標(biāo)、提示、信息組成 nData.uCallbackMessage = WM_NOTIFY_TRAY; // 消息ID,回調(diào)用 nData.hIcon = iconHwnd; // 圖標(biāo)的句柄,有興趣的話可以定時(shí)改變它變成動(dòng)畫ICON nData.uTimeoutAndVersion = 10 * 1000 | NOTIFYICON_VERSION; // 提示的超時(shí)值(幾秒后自動(dòng)消失)和版本 nData.dwInfoFlags = NIIF_INFO; // 類型標(biāo)志,有INFO、WARNING、ERROR,更改此值將影響氣泡提示框的圖標(biāo)類型 nData.szTip = sTip; // 圖標(biāo)的提示信息 nData.szInfoTitle = boxTitle; // 氣泡提示框的標(biāo)題 nData.szInfo = boxText; // 氣泡提示框的提示內(nèi)容 return nData; // 這個(gè)嘛。。。 } private int GetShell32VersionInfo() { // 返回shell32 的版本 FileInfo fi = new FileInfo(Path.Combine(System.Environment.SystemDirectory, "shell32.dll")); //將來(lái)的平臺(tái)shell32 放哪目前不得而知,碰到再改 if (fi.Exists) { FileVersionInfo theVersion = FileVersionInfo.GetVersionInfo(fi.FullName); int i = theVersion.FileVersion.IndexOf('.'); if (i > 0) { try { return int.Parse(theVersion.FileVersion.Substring(0, i)); } catch { } } } return 0; } /// <summary> /// 加一個(gè)新圖標(biāo) /// </summary> /// <param name="iconHwnd">圖標(biāo)句柄</param> /// <param name="sTip">提示, 5.0 最大: 128 char</param> /// <param name="boxTitle">氣泡標(biāo)題, 最大: 64 char</param> /// <param name="boxText">氣泡內(nèi)容, 最大: 256 char</param> /// <returns>成功、失敗或錯(cuò)誤(-1)</returns> public int AddNotifyBox(IntPtr iconHwnd, string sTip, string boxTitle, string boxText) { if (!this.VersionOk) return -1; NOTIFYICONDATA nData = GetNOTIFYICONDATA(iconHwnd, sTip, boxTitle, boxText); if (Shell_NotifyIcon(NIM_ADD, ref nData)) { this.forgetDelNotifyBox = true; return 1; } else { return 0; } } /// <summary> /// 和add 差不多,不重復(fù)了 /// </summary> public int DelNotifyBox() { if (!this.VersionOk) return -1; NOTIFYICONDATA nData = GetNOTIFYICONDATA(IntPtr.Zero, null, null, null); if (Shell_NotifyIcon(NIM_DELETE, ref nData)) { this.forgetDelNotifyBox = false; return 1; } else { return 0; } } public int ModiNotifyBox(IntPtr iconHwnd, string sTip, string boxTitle, string boxText) { if (!this.VersionOk) return -1; NOTIFYICONDATA nData = GetNOTIFYICONDATA(iconHwnd, sTip, boxTitle, boxText); return Shell_NotifyIcon(NIM_MODIFY, ref nData) ? 1 : 0; } #region Optional Module //這里是可選方法 /// <summary> /// 連接一個(gè)已存在的 contextMenu /// </summary> /// <param name="_formHwnd">窗體句柄,用來(lái)處理菜單的消息</param> /// <param name="_contextMenuHwnd">菜單的句柄</param> public void ConnectMyMenu(IntPtr _formHwnd, IntPtr _contextMenuHwnd) { formHwnd = _formHwnd; contextMenuHwnd = _contextMenuHwnd; } /// <summary> /// 立即清理掉圖標(biāo)、委托和formtmp 資源(好象沒(méi)什么資源,考慮到可能二次開發(fā)掛接就開了這個(gè)東東) /// </summary> public void Dispose() { _delegateOfCallBack = null; this.formTmp.Dispose(); } /// <summary> /// 版本適合 /// </summary> public bool VersionPass { get { return this.VersionOk; } } #endregion }
用法示例:
private void button2_Click (object sender, System.EventArgs e) { Shell_NotifyIconEx ().AddNotifyBox (this.Icon.Handle, this.Text, "這是標(biāo)題", "單擊這里開始,我將帶你暢游API 世界"); }
private void GetPoc1 (MouseButtons mb) { // 回調(diào)處理 if (mb == MouseButtons.Left) { MessageBox.Show ("來(lái)自菜單1"); } } privateShell_NotifyIconEx o1 = newShell_NotifyIconEx (); //這個(gè)放外面是用在 o.DelNotifyBox private void button1_Click (object sender, System.EventArgs e) { o1.AddNotifyBox (this.Icon.Handle, this.Text, "菜單1", "單擊這里開始,我將帶你暢游API 世界"); o1.ConnectMyMenu (this.Handle, this.contextMenu1.Handle); // 掛上菜單,可選 o1._delegateOfCallBack = newShell_NotifyIconEx.delegateOfCallBack (GetPoc1); //定義回調(diào) }
private void GetPoc1(MouseButtons mb) { // 回調(diào)處理 if (mb == MouseButtons.Left) { MessageBox.Show("來(lái)自菜單1"); } } private Shell_NotifyIconEx o1 = new Shell_NotifyIconEx(); //這個(gè)放外面是用在 o.DelNotifyBox private void button1_Click(object sender, System.EventArgs e) { o1.AddNotifyBox(this.Icon.Handle,this.Text,"菜單1","單擊這里開始,我將帶你暢游API 世界"); o1.ConnectMyMenu(this.Handle,this.contextMenu1.Handle); // 掛上菜單,可選 o1._delegateOfCallBack = new Shell_NotifyIconEx.delegateOfCallBack(GetPoc1); //定義回調(diào) } private void GetPoc2(MouseButtons mb) { if (mb == MouseButtons.Left) { MessageBox.Show("來(lái)自菜單2"); } } private Shell_NotifyIconEx o2 = new Shell_NotifyIconEx(); //第二個(gè)nofityicon 和上面一樣 private void button2_Click(object sender, System.EventArgs e) { o2.AddNotifyBox(this.Icon.Handle,this.Text,"菜單2","單擊這里開始,我將帶你暢游API 世界"); o2.ConnectMyMenu(this.Handle,this.contextMenu2.Handle); o2._delegateOfCallBack = new Shell_NotifyIconEx.delegateOfCallBack(GetPoc2); }
看完上述內(nèi)容,你們掌握C#語(yǔ)言中的Shell_NotifyIcon如何使用WinForm進(jìn)行調(diào)用的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。