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
    }


详见工程  托盘显示演示

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值