2003的NotifyIcon没有气泡提示功能,所以扩展了一个新的,能达到2005的NotifyIcon的同样功能,并且提供了两个新的功能。
静态方法
FindNotifyIcon 在系统托盘里查找提示文本相同的托盘句柄,以便以向它发送消息。
事件 DoWndProc 托盘WndProc时触发。
下面是程序清单:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
![](/Images/OutliningIndicators/None.gif)
namespace FaibClass.Windows.Forms
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public sealed class NotifyIcon : Component
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
private bool added;
private ContextMenu contextMenu;
private bool doubleClick;
private ToolTipIcon balloonTipIcon;
private string balloonTipText;
private string balloonTipTitle;
private IntPtr handle = IntPtr.Zero;
![](/Images/OutliningIndicators/InBlock.gif)
private Icon icon;
private int id;
private static int nextId = 0;
private string text;
private bool visible = true;
private NotifyIconNativeWindow window;
private static int WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
private const int WM_USER = 0x400;
private const int WM_TRAYMOUSEMESSAGE = 2048;
private const int WM_MOUSEMOVE = 0x200;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_LBUTTONUP = 0x202;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_RBUTTONUP = 0x205;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_MBUTTONUP = 0x208;
private const int WM_MBUTTONDBLCLK = 0x209;
private const int NIN_BALLOONSHOW = 0x402;
private const int NIN_BALLOONHIDE = 0x403;
private const int NIN_BALLOONTIMEOUT = 0x404;
private const int NIN_BALLOONUSERCLICK = 0x405;
![](/Images/OutliningIndicators/InBlock.gif)
private const int READ_CONTROL = 0x20000;
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int STANDARD_RIGHTS_READ = READ_CONTROL;
private const int STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
private const int STANDARD_RIGHTS_ALL = 0x1F0000;
private const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
private const int SYNCHRONIZE = 0x100000;
private const int PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF;
private const int PROCESS_TERMINATE = 0x1;
![](/Images/OutliningIndicators/InBlock.gif)
private const int PROCESS_VM_OPERATION = 0x8;
private const int PROCESS_VM_READ = 0x10;
private const int PROCESS_VM_WRITE = 0x20;
private const int MEM_RESERVE = 0x2000;
private const int MEM_COMMIT = 0x1000;
private const int MEM_RELEASE = 0x8000;
private const int PAGE_READWRITE = 0x4;
![](/Images/OutliningIndicators/InBlock.gif)
private const int TB_BUTTONCOUNT = (WM_USER + 24);
private const int TB_HIDEBUTTON = (WM_USER + 4);
private const int TB_GETBUTTON = (WM_USER + 23);
private const int TB_GETBITMAP = (WM_USER + 44);
private const int TB_DELETEBUTTON = (WM_USER + 22);
private const int TB_ADDBUTTONS = (WM_USER + 20);
private const int TB_INSERTBUTTON = (WM_USER + 21);
private const int TB_ISBUTTONHIDDEN = (WM_USER + 12);
private const int ILD_NORMAL = 0x0;
![](/Images/OutliningIndicators/InBlock.gif)
private const int TPM_NONOTIFY = 0x80;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
枚举#region 枚举
[Flags]
private enum NotifyCommand
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Add = 0,
Modify = 1,
Delete = 2
}
![](/Images/OutliningIndicators/InBlock.gif)
[Flags]
private enum NotifyFlags
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Message = 1,
Icon = 2,
Tip = 4,
State = 8,
Info = 16
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
结构#region 结构
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
private struct NotifyIconData
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public int cbSize;
public IntPtr hWnd;
public int uID;
public NotifyFlags uFlags;
public int uCallbackMessage;
public IntPtr hIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x80)]
public string szTip;
public int dwState;
public int dwStateMask;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x100)]
public string szInfo;
public int uTimeoutOrVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=0x40)]
public string szInfoTitle;
public ToolTipIcon dwInfoFlags;
}
![](/Images/OutliningIndicators/InBlock.gif)
[StructLayout(LayoutKind.Sequential)]
private class TPMPARAMS
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public int cbSize;
public int rcExclude_left;
public int rcExclude_top;
public int rcExclude_right;
public int rcExclude_bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public int x;
public int y;
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
Win32 API 引用#region Win32 API 引用
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr PostMessage(HandleRef hwnd, int msg, int wparam, int lparam);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern bool PostMessage(HandleRef hwnd, int msg, IntPtr wparam, IntPtr lparam);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("shell32.Dll")]
private static extern int Shell_NotifyIcon(NotifyCommand cmd, ref NotifyIconData data);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
private static extern int TrackPopupMenuEx(HandleRef hMenu, int uFlags,
int x, int y, HandleRef hWnd, TPMPARAMS tpm);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
private static extern int GetCursorPos(ref POINT point);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
private static extern bool SetForegroundWindow(HandleRef hWnd);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern int RegisterWindowMessage(string msg);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("kernel32", EntryPoint="OpenProcess")]
private static extern IntPtr OpenProcess (
int dwDesiredAccess,
IntPtr bInheritHandle,
IntPtr dwProcessId
);
[DllImport("kernel32", EntryPoint="CloseHandle")]
private static extern int CloseHandle (
IntPtr hObject
);
[DllImport("user32", EntryPoint="GetWindowThreadProcessId")]
private static extern IntPtr GetWindowThreadProcessId (
IntPtr hwnd,
ref IntPtr lpdwProcessId
);
[DllImport("user32", EntryPoint="FindWindow")]
private static extern IntPtr FindWindow (
string lpClassName,
string lpWindowName
);
[DllImport("user32", EntryPoint="FindWindowEx")]
private static extern IntPtr FindWindowEx (
IntPtr hWnd1,
IntPtr hWnd2,
string lpsz1,
string lpsz2
);
[DllImport("user32", EntryPoint="SendMessage")]
private static extern int SendMessage (
IntPtr hwnd,
int wMsg,
int wParam,
int lParam
);
[DllImport("user32", EntryPoint="SendMessage")]
private static extern int SendMessage (
IntPtr hwnd,
int wMsg,
int wParam,
IntPtr lParam
);
[DllImport("kernel32", EntryPoint="ReadProcessMemory")]
private static extern int ReadProcessMemory (
IntPtr hProcess,
IntPtr lpBaseAddress,
ref IntPtr lpBuffer,
int nSize,
int lpNumberOfBytesWritten
);
[DllImport("kernel32", EntryPoint="ReadProcessMemory")]
private static extern int ReadProcessMemory (
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] lpBuffer,
int nSize,
int lpNumberOfBytesWritten
);
[DllImport("kernel32", EntryPoint="WriteProcessMemory")]
private static extern int WriteProcessMemory (
IntPtr hProcess,
ref int lpBaseAddress,
ref int lpBuffer,
int nSize,
ref int lpNumberOfBytesWritten
);
[DllImport("kernel32", EntryPoint="VirtualAllocEx")]
private static extern IntPtr VirtualAllocEx (
IntPtr hProcess,
int lpAddress,
int dwSize,
int flAllocationType,
int flProtect
);
[DllImport("kernel32", EntryPoint="VirtualFreeEx")]
private static extern int VirtualFreeEx (
IntPtr hProcess,
IntPtr lpAddress,
int dwSize,
int dwFreeType
);
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
public event EventHandler Click;
public event EventHandler DoubleClick;
public event MouseEventHandler MouseDown;
public event MouseEventHandler MouseMove;
public event MouseEventHandler MouseUp;
public event EventHandler BalloonTipClicked;
public event EventHandler BalloonTipClosed;
public event EventHandler BalloonTipShown;
public event WndProcEventHandler DoWndProc;
![](/Images/OutliningIndicators/InBlock.gif)
public NotifyIcon()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
icon = null;
text = "";
id = 0;
added = false;
window = null;
contextMenu = null;
doubleClick = false;
id = ++nextId;
window = new NotifyIconNativeWindow(this);
//UpdateIcon(visible);
}
![](/Images/OutliningIndicators/InBlock.gif)
public NotifyIcon(IContainer container) : this()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
container.Add(this);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
属性#region 属性
public ContextMenu ContextMenu
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return contextMenu;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
contextMenu = value;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public IntPtr Handle
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return this.window.Handle;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public Icon Icon
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return icon;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (icon != value)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
icon = value;
UpdateIcon(visible);
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public string Text
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return text;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (value == null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
value = "";
}
if ((value != null) && !value.Equals(text))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if ((value != null) && (value.Length > 63))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
throw new Exception("");
}
text = value;
if (added)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
UpdateIcon(true);
}
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
[DefaultValue(true)]
public bool Visible
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return visible;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (visible != value)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
UpdateIcon(value);
visible = value;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public ToolTipIcon BalloonTipIcon
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return balloonTipIcon;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (value != balloonTipIcon)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
balloonTipIcon = value;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public string BalloonTipText
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return balloonTipText;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (value != balloonTipText)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
balloonTipText = value;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public string BalloonTipTitle
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
get
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return balloonTipTitle;
}
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (value != balloonTipTitle)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
balloonTipTitle = value;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
protected override void Dispose(bool disposing)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (disposing)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (window != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
icon = null;
Text = "";
UpdateIcon(false);
window.DestroyHandle();
window = null;
contextMenu = null;
}
}
else if ((window != null) && (window.Handle != IntPtr.Zero))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PostMessage(new HandleRef(window, window.Handle), 16, 0, 0);
window.ReleaseHandle();
}
base.Dispose(disposing);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnBalloonTipClicked()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (BalloonTipClicked != null)
BalloonTipClicked(this, EventArgs.Empty);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnBalloonTipClosed()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (BalloonTipClosed != null)
BalloonTipClosed(this, EventArgs.Empty);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnBalloonTipShown()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (BalloonTipShown != null)
BalloonTipShown(this, EventArgs.Empty);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnClick(EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (Click != null)
Click(this, e);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnDoubleClick(EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (DoubleClick != null)
DoubleClick(this, e);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnMouseDown(MouseEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (MouseDown != null)
MouseDown(this, e);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnMouseMove(MouseEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (MouseMove != null)
MouseMove(this, e);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnMouseUp(MouseEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (MouseUp != null)
MouseUp(this, e);
}
![](/Images/OutliningIndicators/InBlock.gif)
private bool OnDoWndProc(ref Message m)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (DoWndProc != null)
return DoWndProc(this, ref m);
return true;
}
![](/Images/OutliningIndicators/InBlock.gif)
private void ShowContextMenu()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (contextMenu != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
POINT pt = new POINT();
GetCursorPos(ref pt);
SetForegroundWindow(new HandleRef(window, window.Handle));
contextMenu.GetType().InvokeMember("OnPopup",
BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance,
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
null, contextMenu, new Object[]
{new EventArgs()});
TrackPopupMenuEx(new HandleRef(contextMenu, contextMenu.Handle), TPM_NONOTIFY, pt.x, pt.y, new HandleRef(window, window.Handle), null);
PostMessage(new HandleRef(window, window.Handle), 0, IntPtr.Zero, IntPtr.Zero);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
private void UpdateIcon(bool showIconInTray)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
lock (this)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!base.DesignMode)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
window.LockReference(showIconInTray);
NotifyIconData pnid = new NotifyIconData();
pnid.uCallbackMessage = 0x800;
pnid.uFlags = NotifyFlags.Message;
if (showIconInTray && (window.Handle == IntPtr.Zero))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
window.CreateHandle(new CreateParams());
}
pnid.cbSize =Marshal.SizeOf(pnid);
pnid.hWnd = window.Handle;
pnid.uID = id;
pnid.hIcon = IntPtr.Zero;
pnid.szTip = null;
if (icon != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
pnid.uFlags |= NotifyFlags.Icon;
pnid.hIcon = icon.Handle;
}
pnid.uFlags |= NotifyFlags.Tip;
pnid.szTip = text;
if (showIconInTray && (icon != null))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!added)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Shell_NotifyIcon(NotifyCommand.Add, ref pnid);
added = true;
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Shell_NotifyIcon(NotifyCommand.Modify, ref pnid);
}
}
else if (added)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Shell_NotifyIcon(NotifyCommand.Delete, ref pnid);
added = false;
}
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public static IntPtr FindNotifyIcon(string TipTitle)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(TipTitle.Length == 0)return IntPtr.Zero;
IntPtr pid = IntPtr.Zero;
IntPtr ipHandle = IntPtr.Zero; //图标句柄
IntPtr lTextAdr = IntPtr.Zero; //文本内存地址
IntPtr ipTemp = FindWindow("Shell_TrayWnd", null);
//找到托盘
ipTemp = FindWindowEx(ipTemp, IntPtr.Zero, "TrayNotifyWnd", null);
ipTemp = FindWindowEx(ipTemp, IntPtr.Zero, "SysPager", null);
IntPtr ipTray = FindWindowEx(ipTemp, IntPtr.Zero, "ToolbarWindow32", null);
GetWindowThreadProcessId(ipTray, ref pid);
if(pid.Equals(0))return ipHandle;
![](/Images/OutliningIndicators/InBlock.gif)
IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, IntPtr.Zero, pid);
IntPtr lAddress = VirtualAllocEx(hProcess, 0, 4096, MEM_COMMIT, PAGE_READWRITE);
![](/Images/OutliningIndicators/InBlock.gif)
//得到图标个数
int lButton = SendMessage(ipTray, TB_BUTTONCOUNT, 0, 0);
for(int i = 0; i < lButton; i++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
SendMessage(ipTray, TB_GETBUTTON, i, lAddress);
//读文本地址
ReadProcessMemory(hProcess, (IntPtr)(lAddress.ToInt32() + 16), ref lTextAdr, 4, 0);
if(!lTextAdr.Equals(-1))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
byte[] buff = new byte[1024];
//读文本
ReadProcessMemory(hProcess, lTextAdr, buff, 1024, 0);
string title = System.Text.ASCIIEncoding.Unicode.GetString(buff);
// 从字符0处截断
int nullindex = title.IndexOf("\0");
if(nullindex > 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
title = title.Substring(0, nullindex);
}
//ReadProcessMemory(hProcess, lAddress, ref ipButtonID, 4, 0);
//判断是不是要找的图标
if(title.Equals(TipTitle))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
IntPtr ipHandleAdr = IntPtr.Zero;
//读句柄地址
ReadProcessMemory(hProcess, (IntPtr)(lAddress.ToInt32() + 12), ref ipHandleAdr, 4, 0);
ReadProcessMemory(hProcess, ipHandleAdr, ref ipHandle, 4, 0);
break;
}
}
}
VirtualFreeEx(hProcess, lAddress, 4096, MEM_RELEASE);
CloseHandle(hProcess);
return ipHandle;
}
![](/Images/OutliningIndicators/InBlock.gif)
public void ShowBalloonTip(int timeout)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ShowBalloonTip(balloonTipTitle, balloonTipText, balloonTipIcon, timeout);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void ShowBalloonTip(string tipTitle, string tipText, ToolTipIcon tipIcon, int timeout)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (timeout < 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
throw new ArgumentOutOfRangeException("timeout", "超时时间不错误");
}
if (tipText == null || tipText.Length == 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
throw new ArgumentException("显示的信息不能为空");
}
if (added && !base.DesignMode)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
NotifyIconData pnid = new NotifyIconData();
if (window.Handle == IntPtr.Zero)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//创建窗体
window.CreateHandle(new CreateParams());
}
pnid.cbSize =Marshal.SizeOf(pnid);
pnid.hWnd = window.Handle;
pnid.uID = id;
pnid.uFlags = NotifyFlags.Info;
pnid.uTimeoutOrVersion = timeout;
pnid.szInfoTitle = tipTitle;
pnid.szInfo = tipText;
pnid.dwInfoFlags = tipIcon;
Shell_NotifyIcon(NotifyCommand.Modify, ref pnid);
}
//延时后更新图标
System.Threading.Thread.Sleep(50);
UpdateIcon(visible);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void WmMouseDown(ref Message m, MouseButtons button, int clicks)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (clicks == 2) //双击
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnDoubleClick(EventArgs.Empty);
doubleClick = true;
}
OnMouseDown(new MouseEventArgs(button, clicks, 0, 0, 0));
}
![](/Images/OutliningIndicators/InBlock.gif)
private void WmMouseMove(ref Message m)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnMouseMove(new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0));
}
![](/Images/OutliningIndicators/InBlock.gif)
private void WmMouseUp(ref Message m, MouseButtons button)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnMouseUp(new MouseEventArgs(button, 0, 0, 0, 0));
if (!doubleClick)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnClick(EventArgs.Empty);
}
doubleClick = false;
}
![](/Images/OutliningIndicators/InBlock.gif)
private void WmTaskbarCreated(ref Message m)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
added = false;
UpdateIcon(visible);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void WndProc(ref Message msg)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(!OnDoWndProc(ref msg))return; //中断消息
Console.WriteLine(msg.Msg);
switch (msg.Msg)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
case 0x2b://WM_DRAWITEM
break;
case 0x2c://WM_MEASUREITEM
break;
case 0x111://WM_COMMAND
if (IntPtr.Zero == msg.LParam)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Type typeCmd = typeof(Form).Assembly.GetType("System.Windows.Forms.Command");
MethodInfo methodDispId = typeCmd.GetMethod("DispatchID", BindingFlags.Static | BindingFlags.Public);
int code = ((int)msg.WParam) & 0xffff;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
bool res = (bool)methodDispId.Invoke(null, new object[]
{code});
break;
}
window.DefWndProc(ref msg);
return;
case 0x800://WM_TRAYMOUSEMESSAGE:
switch ((int)msg.LParam)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
case WM_MOUSEMOVE:
this.WmMouseMove(ref msg);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_LBUTTONDOWN:
this.WmMouseDown(ref msg, MouseButtons.Left, 1);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_LBUTTONUP:
this.WmMouseUp(ref msg, MouseButtons.Left);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_LBUTTONDBLCLK:
this.WmMouseDown(ref msg, MouseButtons.Left, 2);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_RBUTTONDOWN:
this.WmMouseDown(ref msg, MouseButtons.Right, 1);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_RBUTTONUP:
if (this.contextMenu != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.ShowContextMenu();
}
this.WmMouseUp(ref msg, MouseButtons.Right);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_RBUTTONDBLCLK:
this.WmMouseDown(ref msg, MouseButtons.Right, 2);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_MBUTTONDOWN:
this.WmMouseDown(ref msg, MouseButtons.Middle, 1);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_MBUTTONUP:
this.WmMouseUp(ref msg, MouseButtons.Middle);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_MBUTTONDBLCLK:
this.WmMouseDown(ref msg, MouseButtons.Middle, 2);
return;
![](/Images/OutliningIndicators/InBlock.gif)
case NIN_BALLOONSHOW:
this.OnBalloonTipShown();
return;
![](/Images/OutliningIndicators/InBlock.gif)
case NIN_BALLOONHIDE:
this.OnBalloonTipClosed();
return;
![](/Images/OutliningIndicators/InBlock.gif)
case NIN_BALLOONTIMEOUT:
this.OnBalloonTipClosed();
return;
![](/Images/OutliningIndicators/InBlock.gif)
case NIN_BALLOONUSERCLICK:
this.OnBalloonTipClicked();
return;
![](/Images/OutliningIndicators/InBlock.gif)
}
return;
default:
if (msg.Msg == WM_TASKBARCREATED)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
WmTaskbarCreated(ref msg);
}
window.DefWndProc(ref msg);
break;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
private class NotifyIconNativeWindow : NativeWindow
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
internal NotifyIcon reference;
private GCHandle rootRef;
![](/Images/OutliningIndicators/InBlock.gif)
internal NotifyIconNativeWindow(NotifyIcon control)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
reference = control;
}
![](/Images/OutliningIndicators/InBlock.gif)
~ NotifyIconNativeWindow()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (base.Handle != IntPtr.Zero)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PostMessage(new HandleRef(this, base.Handle), 16, 0, 0);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public void LockReference(bool locked)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (locked)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!rootRef.IsAllocated)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
rootRef = GCHandle.Alloc(reference, GCHandleType.Normal);
}
}
else if (rootRef.IsAllocated)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
rootRef.Free();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
protected override void OnThreadException(Exception e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Application.OnThreadException(e);
}
![](/Images/OutliningIndicators/InBlock.gif)
protected override void WndProc(ref Message m)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
reference.WndProc(ref m);
}
}
}
[Flags]
public enum ToolTipIcon
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
None = 0,
Info = 1,
Warning = 2,
Error = 3
}
![](/Images/OutliningIndicators/InBlock.gif)
public delegate bool WndProcEventHandler (object sender, ref Message m);
![](/Images/OutliningIndicators/InBlock.gif)
}
比如使用它可以使程序只运行一个实例:
[STAThread]
static void Main(params string[] pars)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
//确保只有一个实例运行
Process current = Process.GetCurrentProcess();
Process[] ps = Process.GetProcessesByName(current.ProcessName);
foreach(Process process in ps)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
if(!process.Id.Equals(current.Id))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
IntPtr nti = FbSoft.Assistant.Controls.NotifyIcon.FindNotifyIcon("NotifyIcon标题");
if(nti != IntPtr.Zero)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
//向托盘发送自定消息 WM_USER + 0x33;
Win32.SendMessage(nti, 0x400 + 0x33, 0, 0);
}
Application.Exit();
return;
}
}
frmMain里触发事件:
private bool ntiMain_DoWndProc(object sender, ref System.Windows.Forms.Message m)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
if(m.Msg == 0x400 + 0x33)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
ntiMain_DoubleClick(null, null);
return false;
}
return true;
}
![](/Images/OutliningIndicators/None.gif)
private void ntiMain_DoubleClick(object sender, System.EventArgs e)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
if(Visible)return;
Thread.Sleep(100);
isLoad = true;
if(!ShowInTaskbar)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
ShowInTaskbar = true;
}
isLoad = false;
Win32.SetForegroundWindow(Handle);
Win32.SetActiveWindow(Handle);
WindowState = FormWindowState.Maximized;
Show();
}