登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

NotifyIconEx-加强版NotifyIcon [for VS2003]  

2007-05-18 16:19:45|  分类: C# |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

using System;

using System.Drawing;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using System.ComponentModel;

using System.Reflection;


namespace JCMLib

{

public class NotifyIconEx : System.ComponentModel.Component

{

#region Notify Icon Target Window

private class NotifyIconTarget : System.Windows.Forms.Form

{

public NotifyIconTarget()

{

this.Text = "Hidden NotifyIconTarget Window";

}


protected override void DefWndProc(ref Message msg)

   {

    if(msg.Msg == 0x400) // WM_USER

    {

     uint msgId = (uint)msg.LParam;

     uint >


     switch(msgId)

     {

      case 0x201: // WM_LBUTTONDOWN

       break;


      case 0x202: // WM_LBUTTONUP

       if(ClickNotify != null)

        ClickNotify(this, id);

       break;


      case 0x203: // WM_LBUTTONDBLCLK

       if(DoubleClickNotify != null)

        DoubleClickNotify(this, id);

       break;


      case 0x205: // WM_RBUTTONUP

       if(RightClickNotify != null)

        RightClickNotify(this, id);

       break;


      case 0x200: // WM_MOUSEMOVE

       break;


      case 0x402: // NIN_BALLOONSHOW

       break;


      // this should happen when the balloon is closed using the x

      // - we never seem to get this message!

      case 0x403: // NIN_BALLOONHIDE

       break;


      // we seem to get this next message whether the balloon times

      // out or whether it is closed using the x

      case 0x404: // NIN_BALLOONTIMEOUT

       break;


      case 0x405: // NIN_BALLOONUSERCLICK

       if(ClickBalloonNotify != null)

        ClickBalloonNotify(this, id);

       break;

     }

    }

    else if(msg.Msg == 0xC086) // WM_TASKBAR_CREATED

    {

     if(TaskbarCreated != null)

      TaskbarCreated(this, System.EventArgs.Empty);

    }

    else

    {

     base.DefWndProc(ref msg);

    }

   }


public delegate void NotifyIconHandler(object sender, uint id);


public event NotifyIconHandler ClickNotify;

public event NotifyIconHandler DoubleClickNotify;

public event NotifyIconHandler RightClickNotify;

public event NotifyIconHandler ClickBalloonNotify;

public event EventHandler TaskbarCreated;

}

#endregion


#region Platform Invoke

[StructLayout(LayoutKind.Sequential)]

private struct NotifyIconData

{

public System.UInt32 cbSize; // DWORD

public System.IntPtr hWnd; // HWND

public System.UInt32 uID; // UINT

public NotifyFlags uFlags; // UINT

public System.UInt32 uCallbackMessage; // UINT

public System.IntPtr hIcon; // HICON

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]

public System.String szTip; // char[128]

public NotifyState dwState; // DWORD

public NotifyState dwStateMask; // DWORD

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]

public System.String szInfo; // char[256]

public System.UInt32 uTimeoutOrVersion; // UINT

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]

public System.String szInfoTitle; // char[64]

public NotifyInfoFlags dwInfoFlags; // DWORD

}


[DllImport("shell32.Dll")]

private static extern System.Int32 Shell_NotifyIcon(NotifyCommand cmd, ref NotifyIconData data);


[DllImport("User32.Dll")]

private static extern System.Int32 TrackPopupMenuEx(System.IntPtr hMenu,

System.UInt32 uFlags,

System.Int32 x,

System.Int32 y,

System.IntPtr hWnd,

System.IntPtr ignore);


[StructLayout(LayoutKind.Sequential)]

private struct POINT

{

public System.Int32 x;

public System.Int32 y;

}


[DllImport("User32.Dll")]

private static extern System.Int32 GetCursorPos(ref POINT point);


[DllImport("User32.Dll")]

private static extern System.Int32 SetForegroundWindow(System.IntPtr hWnd);

#endregion


public enum NotifyInfoFlags { Error = 0x03, Info = 0x01, None = 0x00, Warning = 0x02 }

private enum NotifyCommand { Add = 0x00, Delete = 0x02, Modify = 0x01 }

private enum NotifyFlags { Message = 0x01, Icon = 0x02, Tip = 0x04, Info = 0x10, State = 0x08 }

private enum NotifyState { Hidden = 0x01 }


private uint m_id = 0; // each icon in the notification area has an id

private IntPtr m_handle; // save the handle so that we can remove icon

private static NotifyIconTarget m_messageSink = new NotifyIconTarget();

private static uint m_nextId = 1;

private string m_text = "";

private Icon m_icon = null;

private ContextMenu m_contextMenu = null;

private bool m_visible = false;

private bool m_doubleClick = false; // fix for extra mouse up message we want to discard


public event EventHandler Click;

public event EventHandler DoubleClick;

public event EventHandler BalloonClick;


#region Properties

public string Text

{

set

{

if (m_text != value)

{

m_text = value;

CreateOrUpdate();

}

}

get

{

return m_text;

}

}


public Icon Icon

{

set

{

m_icon = value;

CreateOrUpdate();

}

get

{

return m_icon;

}

}


public ContextMenu ContextMenu

{

set

{

m_contextMenu = value;

}

get

{

return m_contextMenu;

}

}


public bool Visible

{

set

{

if (m_visible != value)

{

m_visible = value;

CreateOrUpdate();

}

}

get

{

return m_visible;

}

}

#endregion


public NotifyIconEx()

{

}


// this method adds the notification icon if it has not been added and if we

// have enough data to do so

private void CreateOrUpdate()

{

if (this.DesignMode)

return;


if (m_id == 0)

{

if (m_icon != null)

{

// create icon using available properties

Create(m_nextId++);

}

}

else

{

// update notify icon

Update();

}

}


private void Create(uint id)

{

NotifyIconData data = new NotifyIconData();

data.cbSize = (uint)Marshal.SizeOf(data);


m_handle = m_messageSink.Handle;

data.hWnd = m_handle;

m_id = id;

data.uID = m_id;


data.uCallbackMessage = 0x400;

data.uFlags |= NotifyFlags.Message;


data.hIcon = m_icon.Handle; // this should always be valid

data.uFlags |= NotifyFlags.Icon;


data.szTip = m_text;

data.uFlags |= NotifyFlags.Tip;


if (!m_visible)

data.dwState = NotifyState.Hidden;

data.dwStateMask |= NotifyState.Hidden;


Shell_NotifyIcon(NotifyCommand.Add, ref data);


// add handlers

m_messageSink.ClickNotify += new NotifyIconTarget.NotifyIconHandler(OnClick);

m_messageSink.DoubleClickNotify += new NotifyIconTarget.NotifyIconHandler(OnDoubleClick);

m_messageSink.RightClickNotify += new NotifyIconTarget.NotifyIconHandler(OnRightClick);

m_messageSink.ClickBalloonNotify += new NotifyIconTarget.NotifyIconHandler(OnClickBalloon);

m_messageSink.TaskbarCreated += new EventHandler(OnTaskbarCreated);

}


// update an existing icon

private void Update()

{

NotifyIconData data = new NotifyIconData();

data.cbSize = (uint)Marshal.SizeOf(data);


data.hWnd = m_messageSink.Handle;

data.uID = m_id;


data.hIcon = m_icon.Handle; // this should always be valid

data.uFlags |= NotifyFlags.Icon;


data.szTip = m_text;

data.uFlags |= NotifyFlags.Tip;

data.uFlags |= NotifyFlags.State;


if (!m_visible)

data.dwState = NotifyState.Hidden;

data.dwStateMask |= NotifyState.Hidden;


Shell_NotifyIcon(NotifyCommand.Modify, ref data);

}


protected override void Dispose(bool disposing)

{

Remove();

base.Dispose(disposing);

}


public void Remove()

{

if (m_id != 0)

{

// remove the notify icon

NotifyIconData data = new NotifyIconData();

data.cbSize = (uint)Marshal.SizeOf(data);


data.hWnd = m_handle;

data.uID = m_id;


Shell_NotifyIcon(NotifyCommand.Delete, ref data);


m_id = 0;

}

}


public void ShowBalloon(string title, string text, NotifyInfoFlags type, int timeoutInMilliSeconds)

{

if (timeoutInMilliSeconds < 0)

throw new ArgumentException("The parameter must be positive", "timeoutInMilliseconds");


NotifyIconData data = new NotifyIconData();

data.cbSize = (uint)Marshal.SizeOf(data);


data.hWnd = m_messageSink.Handle;

data.uID = m_id;


data.uFlags = NotifyFlags.Info;

data.uTimeoutOrVersion = (uint)timeoutInMilliSeconds; // this value does not seem to work - any ideas?

data.szInfoTitle = title;

data.szInfo = text;

data.dwInfoFlags = type;


Shell_NotifyIcon(NotifyCommand.Modify, ref data);

}


#region Message Handlers


private void OnClick(object sender, uint id)

{

if (id == m_id)

{

if (!m_doubleClick && Click != null)

Click(this, EventArgs.Empty);

m_doubleClick = false;

}

}


private void OnRightClick(object sender, uint id)

{

if (id == m_id)

{

// show context menu

if (m_contextMenu != null)

{

POINT point = new POINT();

GetCursorPos(ref point);


SetForegroundWindow(m_messageSink.Handle); // this ensures that if we show the menu and then click on another window the menu will close


// call non public member of ContextMenu

m_contextMenu.GetType().InvokeMember("OnPopup",

BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance,

null, m_contextMenu, new Object[] { System.EventArgs.Empty });


TrackPopupMenuEx(m_contextMenu.Handle, 64, point.x, point.y, m_messageSink.Handle, IntPtr.Zero);


// PostMessage(m_messageSink.Handle, 0, IntPtr.Zero, IntPtr.Zero);

}

}

}


private void OnDoubleClick(object sender, uint id)

{

if (id == m_id)

{

m_doubleClick = true;

if (DoubleClick != null)

DoubleClick(this, EventArgs.Empty);

}

}


private void OnClickBalloon(object sender, uint id)

{

if (id == m_id)

if (BalloonClick != null)

BalloonClick(this, EventArgs.Empty);

}


private void OnTaskbarCreated(object sender, EventArgs e)

{

if (m_id != 0)

Create(m_id); // keep the id the same

}

#endregion

}

}

  评论这张
 
阅读(1514)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018