C#托盘窗口显示

 托盘显示许多软件都有这个功能,在C#中如何实现呢,下面的方法可以实现托盘显示,不过可能有些复杂。
 首先,需要在工具栏拖入NotifyIcon,如图1的那个控件。

图一:


 然后,设置NotifyIcon的属性,加图标什么的。
 最后,最主要的,就是NotifyIcon点击事件,要实现点击托盘图标隐藏窗口,再点击显示窗口,还有右键托盘能显示菜单等。
 下面着重介绍一下这一部分的实现。
 一、点击托盘右键菜单
     这个NotifyIcon本身就有这个属性,即NotifyIcon.ContextMenu,添加相应菜单即可。
     详见托盘显示演示的 AddTrayMenuItem()方法。
二、隐藏至托盘和显示
    该部分使用user32.dll中的函数,如下:
 1、bool SetWindowPos( IntPtr hWnd, IntPtr hWndAfter, int x, int y, int cx, int cy, uint flags)
 函数功能:
 该函数改变一个子窗口,弹出式窗口式顶层窗口的尺寸,位置和Z序。   子窗口,弹出式窗口,及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高,并且被设置为Z序的第一个窗口。
 2、IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter,string lpszClass,string lpszWindow)
 函数功能:
 该函数获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找子窗口,从排在给定的子窗口后面的下一个子窗口开始。在查找时不区分大小写。
 3、int GetWindowRect(IntPtr hwnd, ref RECT lpRect)
 函数功能:
 该函数返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出。
 4、DrawAnimatedRects( IntPtr hwnd, int ani, ref RECT from,ref RECT to)
 函数功能:
 在窗口缩放时产生动画效果

部分代码如下:

ChangeTrayStateManager类:

public class ChangeTrayStateManager      {          public static void Animate( IntPtr handle, Rectangle fromRect, Rectangle toRect)          {              try              {                  TrayStateMethods.RECT from = TrayStateMethods.RECT.FromRectangle(fromRect);                    TrayStateMethods.RECT to = TrayStateMethods.RECT.FromRectangle(toRect);                    TrayStateMethods.DrawAnimatedRects(                        handle,                        TrayStateMethods.IDANI_CAPTION,                        ref from,                        ref to);              }              catch              { }          }            public static void Animate( Form animateForm, Control owner)          {              Animate(animateForm.Handle, animateForm.Bounds, owner.RectangleToScreen(owner.ClientRectangle));          }            public static void Animate(  Form animateForm,Rectangle bounds,bool minimized)          {              try              {                  if (minimized)                  {                      Animate( animateForm.Handle, GetNotificationRect(), animateForm.Bounds);                  }                  else                  {                      Animate(animateForm.Handle, animateForm.Bounds, GetNotificationRect());                  }              }              catch              { }          }            private static Rectangle GetNotificationRect()          {              TrayStateMethods.RECT rect = new TrayStateMethods.RECT();                IntPtr hwnd = TrayStateMethods.FindWindowEx( IntPtr.Zero, IntPtr.Zero,"Shell_TrayWnd", null);                if (hwnd == IntPtr.Zero)              {                  throw new Win32Exception();              }                hwnd = TrayStateMethods.FindWindowEx(hwnd, IntPtr.Zero,"TrayNotifyWnd", null);                if (hwnd == IntPtr.Zero)              {                  throw new Win32Exception();              }                hwnd = TrayStateMethods.FindWindowEx( hwnd, IntPtr.Zero, "SysPager",  null);                if (hwnd == IntPtr.Zero)              {                  throw new Win32Exception();              }                hwnd = TrayStateMethods.FindWindowEx( hwnd,IntPtr.Zero,"ToolbarWindow32", null);                if (hwnd == IntPtr.Zero)              {                  throw new Win32Exception();              }                TrayStateMethods.GetWindowRect(hwnd, ref rect);                return rect.Rect;          }      }

TrayStateMethods类,引用user32.dll方法。

  public class TrayStateMethods      {          public const int IDANI_CAPTION = 0x3;            public const int WM_SYSCOMMAND = 0x0112;            public const uint SWP_NOZORDER = 0x0004;            public const uint SWP_NOREDRAW = 0x0008;            public const int HWND_TOPMOST = -1;            public const int SW_HIDE = 0x0;            public const int SW_NORMAL = 0x1;            public const int SW_RESTORE = 9;            public const int SW_MAXIMIZE = 3;            public enum SystemCommands          {              SC_SIZE = 0xF000,                SC_MOVE = 0xF010,                SC_MINIMIZE = 0xF020,                SC_MAXIMIZE = 0xF030,                SC_MAXIMIZE2 = 0xF032,	                SC_NEXTWINDOW = 0xF040,                SC_PREVWINDOW = 0xF050,                SC_CLOSE = 0xF060,                SC_VSCROLL = 0xF070,                SC_HSCROLL = 0xF080,                SC_MOUSEMENU = 0xF090,                SC_KEYMENU = 0xF100,                SC_ARRANGE = 0xF110,                SC_RESTORE = 0xF120,                SC_RESTORE2 = 0xF122,	                SC_TASKLIST = 0xF130,                SC_SCREENSAVE = 0xF140,                SC_HOTKEY = 0xF150,                SC_DEFAULT = 0xF160,                SC_MONITORPOWER = 0xF170,                SC_CONTEXTHELP = 0xF180,                SC_SEPARATOR = 0xF00F          }            [StructLayout(LayoutKind.Sequential)]            public struct RECT          {              public int Left;                public int Top;                public int Right;                public int Bottom;                public RECT(int left, int top, int right, int bottom)              {                  this.Left = left;                    this.Top = top;                    this.Right = right;                    this.Bottom = bottom;              }                public Rectangle Rect              {                  get                  {                      return new Rectangle(                            this.Left, this.Top, this.Right - this.Left, this.Bottom - this.Top);                  }              }                public static RECT FromXYWH(int x, int y, int width, int height)              {                  return new RECT(x,                                    y,                                    x + width,                                    y + height);              }                public static RECT FromRectangle(Rectangle rect)              {                  return new RECT(rect.Left,                                    rect.Top,                                    rect.Right,                                    rect.Bottom);              }          }            [DllImport("user32.dll")]            public static extern IntPtr FindWindowEx(                IntPtr hwndParent,                IntPtr hwndChildAfter,                string lpszClass,                string lpszWindow);            [DllImport("user32.dll")]            public static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect);            [DllImport("user32.dll")]            public static extern bool DrawAnimatedRects(                IntPtr hwnd,                int ani,                ref RECT from,                ref RECT to);            [DllImport("user32.dll")]            [return: MarshalAs(UnmanagedType.Bool)]            public static extern bool SetWindowPos(                IntPtr hWnd,                IntPtr hWndAfter,                int x,                int y,                int cx,                int cy,                uint flags);      }

主界面调用:

   public partial class Form1 : Form      {          private bool isInTray = false;            private Rectangle rectBounds;            public Form1()          {              InitializeComponent();                new Thread(new ThreadStart(AddTrayMenuItem)).Start();          }            #region Event          private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)          {              if (e.Button == MouseButtons.Left)              {                  if (isInTray)                  {                      ShowForm();                  }                  else                  {                      MiniToTray();                  }              }          }            private void Form1_Load(object sender, EventArgs e)          {              this.WindowState = FormWindowState.Normal;          }            void hideItem_Click(object sender, EventArgs e)          {              MiniToTray();          }            void showItem_Click(object sender, EventArgs e)          {              ShowForm();          }            void exitItem_Click(object sender, EventArgs e)          {              this.Close();          }           #endregion            #region Method            private void AddTrayMenuItem()          {              ContextMenu cm = new ContextMenu();                MenuItem showItem = new MenuItem("显示主界面");                showItem.Click += new EventHandler(showItem_Click);                MenuItem miSeparator0 = new MenuItem("-");                miSeparator0.Enabled = false;                MenuItem hideItem = new MenuItem("最小化到托盘");                hideItem.Click += new EventHandler(hideItem_Click);                MenuItem miSeparator1 = new MenuItem("-");                miSeparator1.Enabled = false;                MenuItem exitItem = new MenuItem("退出");                exitItem.Click += new EventHandler(exitItem_Click);                cm.MenuItems.AddRange(new MenuItem[] { showItem, miSeparator0, hideItem, miSeparator1, exitItem });                this.notifyIcon1.ContextMenu = cm;                this.notifyIcon1.ContextMenu.MenuItems[0].Visible = false;                this.notifyIcon1.ContextMenu.MenuItems[1].Visible = false;          }            private void MiniToTray()          {              ChangeTrayStateManager.Animate(this, Bounds, false);                rectBounds = Bounds;                Hide();                isInTray = true;                this.notifyIcon1.ContextMenu.MenuItems[0].Visible = true;                this.notifyIcon1.ContextMenu.MenuItems[1].Visible = true;                this.notifyIcon1.ContextMenu.MenuItems[2].Visible = false;                this.notifyIcon1.ContextMenu.MenuItems[3].Visible = false;          }            private void ShowForm()          {              if (isInTray)              {                  TrayStateMethods.SetWindowPos(                        Handle,                        new IntPtr(-1),                        rectBounds.X,                        rectBounds.Y,                        rectBounds.Width,                        rectBounds.Height,                        TrayStateMethods.SWP_NOREDRAW | TrayStateMethods.SWP_NOZORDER);                    ChangeTrayStateManager.Animate(this, rectBounds, true);                    this.Show();                    this.Activate();                    isInTray = false;                    this.notifyIcon1.ContextMenu.MenuItems[0].Visible = false;                    this.notifyIcon1.ContextMenu.MenuItems[1].Visible = false;                    this.notifyIcon1.ContextMenu.MenuItems[2].Visible = true;                    this.notifyIcon1.ContextMenu.MenuItems[3].Visible = true;                    if (this.WindowState == FormWindowState.Minimized)                  {                      this.WindowState = FormWindowState.Normal;                  }              }                    }          #endregion      }


详见工程  托盘显示演示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值