C# WinForm调用Shell_NotifyIcon的示例代码
publicclassInnerClass:Form
{
privateShell_NotifyIconExservicesClass=null;//接受主CLASS的实例句柄
internalInnerClass(Shell_NotifyIconEx_servicesClass)
{
servicesClass=_servicesClass;
}
privateconstintWM_LBUTTONDOWN=0x0201;//左键
privateconstintWM_RBUTTONDOWN=0x204;//右键
privateconstintWM_MBUTTONDOWN=0x207;//中键
[DllImport("user32.dll",EntryPoint="TrackPopupMenu")]
privatestaticexternintTrackPopupMenu(//c#和vb.net好象没有了随地popup了,只要请它老人家出马了
IntPtrhMenu,
intwFlags,
intx,
inty,
intnReserved,
IntPtrhwnd,
refRECTlprc
);
[StructLayout(LayoutKind.Sequential)]
privatestructRECT
{//上面那位用的结构,表示前弹出菜单可用的一个范围大小(一般是全屏幕都让它用,留着搞游戏或视频对话之类的朋友指定菜单可用的范围)
internalintLeft;
internalintTop;
internalintRight;
internalintBottom;
}
protectedoverridevoidWndProc(refMessagemsg)
{
if(msg.Msg==servicesClass.WM_NOTIFY_TRAY)
{//如果消息相符
if((int)msg.WParam==servicesClass.uID)
{//并且消息的WParam相符
MouseButtonsmb=MouseButtons.None;
if((int)msg.LParam==WM_LBUTTONDOWN)
{//如果点击的是左键
mb=MouseButtons.Left;
}
elseif((int)msg.LParam==WM_MBUTTONDOWN)
{//中键
mb=MouseButtons.Middle;
}
elseif((int)msg.LParam==WM_RBUTTONDOWN)
{//右键
if(servicesClass.contextMenuHwnd!=IntPtr.Zero)
{//如果有定义过菜单关联
RECTr=newRECT();
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,
refr
);
}
else
{//如果没有定义过菜单关联
mb=MouseButtons.Right;
}
}
if(mb!=MouseButtons.None&&servicesClass._delegateOfCallBack!=null)
{
servicesClass._delegateOfCallBack(mb);//执行回调
return;
}
}
}
base.WndProc(refmsg);
}
}
publicclassShell_NotifyIconEx
{
///
///ArLi,lastfix:2003.9.12,reference:ArLi.CommonPrjLib@http://zpcity.com/arli/
///
publicstaticreadonlySystem.VersionmyVersion=newSystem.Version(1,2);//版本声明
privatereadonlyInnerClassformTmp=null;//这个很重要,不能放在构造里,因为它必须和此实例同等生存期才不会被中止消息循环
privatereadonlyIntPtrformTmpHwnd=IntPtr.Zero;//这是上一行的句柄
privatereadonlyboolVersionOk=false;//这是一个由VersionPass返回的属性,它允许开发者检测当前机子的Shell32.dll(可能在win95或未知平台上版本)合适此组,不符则用.net自己的notifyicon
privateboolforgetDelNotifyBox=false;//这是一个私有标志,它允许开发者在程序退出时忘记调用DelNotifyBox来清除图标时会自动在析构里清掉它。
internalIntPtrformHwnd=IntPtr.Zero;//这是调用此组件的主窗口句柄(当前实例有效,可多个icon不冲突)
internalIntPtrcontextMenuHwnd=IntPtr.Zero;//这是菜单的句柄(当前实例有效,可多个icon不冲突)
internaldelegatevoiddelegateOfCallBack(System.Windows.Forms.MouseButtonsmb);
internaldelegateOfCallBack_delegateOfCallBack=null;
publicShell_NotifyIconEx()//构造
{
WM_NOTIFY_TRAY+=1;//消息ID+1,避免多个ICON消息处理冲突
uID+=1;//同上
formTmp=newInnerClass(this);//新实例一个消息循环
formTmpHwnd=formTmp.Handle;//新实例句柄
VersionOk=this.GetShell32VersionInfo()>=5;//版本是否合适,此组件由于重点在气泡提示,它要求Shell32.dll5.0(ie5.0)以上
}
~Shell_NotifyIconEx()
{//析构
if(forgetDelNotifyBox)this.DelNotifyBox();//如果开发者忘记则清理icon
}
#regionAPI_Consts
internalreadonlyintWM_NOTIFY_TRAY=0x0400+2001;//readonly表示只在构造可付值
internalreadonlyintuID=5000;
//常数定义,有VC的可以参见shellapi.h
privateconstintNIIF_NONE=0x00;
privateconstintNIIF_INFO=0x01;
privateconstintNIIF_WARNING=0x02;
privateconstintNIIF_ERROR=0x03;
privateconstintNIF_MESSAGE=0x01;
privateconstintNIF_ICON=0x02;
privateconstintNIF_TIP=0x04;
privateconstintNIF_STATE=0x08;
privateconstintNIF_INFO=0x10;
privateconstintNIM_ADD=0x00;
privateconstintNIM_MODIFY=0x01;
privateconstintNIM_DELETE=0x02;
privateconstintNIM_SETFOCUS=0x03;
privateconstintNIM_SETVERSION=0x04;
privateconstintNIS_HIDDEN=0x01;
privateconstintNIS_SHAREDICON=0x02;
privateconstintNOTIFYICON_OLDVERSION=0x00;
privateconstintNOTIFYICON_VERSION=0x03;
[DllImport("shell32.dll",EntryPoint="Shell_NotifyIcon")]
privatestaticexternboolShell_NotifyIcon(//这位是主角
intdwMessage,
refNOTIFYICONDATAlpData
);
///
///此API的作用是当this.focus()无效时可以考虑使用,效果很好
///
///this.Handle,当前窗体句柄
[DllImport("user32.dll",EntryPoint="SetForegroundWindow")]
publicstaticexternintSetForegroundWindow(
IntPtrhwnd
);
[StructLayout(LayoutKind.Sequential)]
privatestructNOTIFYICONDATA
{//主角用的结构
internalintcbSize;
internalIntPtrhwnd;
internalintuID;
internalintuFlags;
internalintuCallbackMessage;
internalIntPtrhIcon;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=0x80)]
internalstringszTip;
internalintdwState;//这里往下几个是5.0的精华
internalintdwStateMask;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=0xFF)]
internalstringszInfo;
internalintuTimeoutAndVersion;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=0x40)]
internalstringszInfoTitle;
internalintdwInfoFlags;
}
#endregion
///
///建一个结构
///
privateNOTIFYICONDATAGetNOTIFYICONDATA(IntPtriconHwnd,stringsTip,stringboxTitle,stringboxText)
{
NOTIFYICONDATAnData=newNOTIFYICONDATA();
nData.cbSize=System.Runtime.InteropServices.Marshal.SizeOf(nData);//结构的大小
nData.hwnd=formTmpHwnd;//处理消息循环的窗体句柄,可以移成主窗体
nData.uID=uID;//消息的WParam,回调时用
nData.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP|NIF_INFO;//标志,表示由消息、图标、提示、信息组成
nData.uCallbackMessage=WM_NOTIFY_TRAY;//消息ID,回调用
nData.hIcon=iconHwnd;//图标的句柄,有兴趣的话可以定时改变它变成动画ICON
nData.uTimeoutAndVersion=10*1000|NOTIFYICON_VERSION;//提示的超时值(几秒后自动消失)和版本
nData.dwInfoFlags=NIIF_INFO;//类型标志,有INFO、WARNING、ERROR,更改此值将影响气泡提示框的图标类型
nData.szTip=sTip;//图标的提示信息
nData.szInfoTitle=boxTitle;//气泡提示框的标题
nData.szInfo=boxText;//气泡提示框的提示内容
returnnData;//这个嘛。。。
}
privateintGetShell32VersionInfo()
{//返回shell32的版本
FileInfofi=newFileInfo(Path.Combine(System.Environment.SystemDirectory,"shell32.dll"));//将来的平台shell32放哪目前不得而知,碰到再改
if(fi.Exists)
{
FileVersionInfotheVersion=FileVersionInfo.GetVersionInfo(fi.FullName);
inti=theVersion.FileVersion.IndexOf('.');
if(i>0)
{
try
{
returnint.Parse(theVersion.FileVersion.Substring(0,i));
}
catch{}
}
}
return0;
}
///
///加一个新图标
///
///图标句柄
///提示,5.0最大:128char
///气泡标题,最大:64char
///气泡内容,最大:256char
///成功、失败或错误(-1)
publicintAddNotifyBox(IntPtriconHwnd,stringsTip,stringboxTitle,stringboxText)
{
if(!this.VersionOk)return-1;
NOTIFYICONDATAnData=GetNOTIFYICONDATA(iconHwnd,sTip,boxTitle,boxText);
if(Shell_NotifyIcon(NIM_ADD,refnData))
{
this.forgetDelNotifyBox=true;
return1;
}
else
{
return0;
}
}
///
///和add差不多,不重复了
///
publicintDelNotifyBox()
{
if(!this.VersionOk)return-1;
NOTIFYICONDATAnData=GetNOTIFYICONDATA(IntPtr.Zero,null,null,null);
if(Shell_NotifyIcon(NIM_DELETE,refnData))
{
this.forgetDelNotifyBox=false;
return1;
}
else
{
return0;
}
}
publicintModiNotifyBox(IntPtriconHwnd,stringsTip,stringboxTitle,stringboxText)
{
if(!this.VersionOk)return-1;
NOTIFYICONDATAnData=GetNOTIFYICONDATA(iconHwnd,sTip,boxTitle,boxText);
returnShell_NotifyIcon(NIM_MODIFY,refnData)?1:0;
}
#regionOptionalModule//这里是可选方法
///
///连接一个已存在的contextMenu
///
///窗体句柄,用来处理菜单的消息
///菜单的句柄
publicvoidConnectMyMenu(IntPtr_formHwnd,IntPtr_contextMenuHwnd)
{
formHwnd=_formHwnd;
contextMenuHwnd=_contextMenuHwnd;
}
///
///立即清理掉图标、委托和formtmp资源(好象没什么资源,考虑到可能二次开发挂接就开了这个东东)
///
publicvoidDispose()
{
_delegateOfCallBack=null;
this.formTmp.Dispose();
}
///
///版本适合
///
publicboolVersionPass
{
get
{
returnthis.VersionOk;
}
}
#endregion
}
用法示例:
privatevoidbutton2_Click(objectsender,System.EventArgse){
Shell_NotifyIconEx().AddNotifyBox(this.Icon.Handle,this.Text,"这是标题","单击这里开始,我将带你畅游API世界");
}
privatevoidGetPoc1(MouseButtonsmb){//回调处理
if(mb==MouseButtons.Left){
MessageBox.Show("来自菜单1");
}
}
privateShell_NotifyIconExo1=newShell_NotifyIconEx();//这个放外面是用在o.DelNotifyBox
privatevoidbutton1_Click(objectsender,System.EventArgse){
o1.AddNotifyBox(this.Icon.Handle,this.Text,"菜单1","单击这里开始,我将带你畅游API世界");
o1.ConnectMyMenu(this.Handle,this.contextMenu1.Handle);//挂上菜单,可选
o1._delegateOfCallBack=newShell_NotifyIconEx.delegateOfCallBack(GetPoc1);//定义回调
}
privatevoidGetPoc1(MouseButtonsmb){//回调处理
if(mb==MouseButtons.Left){
MessageBox.Show("来自菜单1");
}
}
privateShell_NotifyIconExo1=newShell_NotifyIconEx();//这个放外面是用在o.DelNotifyBox
privatevoidbutton1_Click(objectsender,System.EventArgse){
o1.AddNotifyBox(this.Icon.Handle,this.Text,"菜单1","单击这里开始,我将带你畅游API世界");
o1.ConnectMyMenu(this.Handle,this.contextMenu1.Handle);//挂上菜单,可选
o1._delegateOfCallBack=newShell_NotifyIconEx.delegateOfCallBack(GetPoc1);//定义回调
}
privatevoidGetPoc2(MouseButtonsmb){
if(mb==MouseButtons.Left){
MessageBox.Show("来自菜单2");
}
}
privateShell_NotifyIconExo2=newShell_NotifyIconEx();//第二个nofityicon和上面一样
privatevoidbutton2_Click(objectsender,System.EventArgse){
o2.AddNotifyBox(this.Icon.Handle,this.Text,"菜单2","单击这里开始,我将带你畅游API世界");
o2.ConnectMyMenu(this.Handle,this.contextMenu2.Handle);
o2._delegateOfCallBack=newShell_NotifyIconEx.delegateOfCallBack(GetPoc2);
}
以上就是C#WinForm调用Shell_NotifyIcon的示例代码的详细内容,更多关于C#WinForm调用Shell_NotifyIcon的资料请关注毛票票其它相关文章!