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的资料请关注毛票票其它相关文章!