Search code examples
c#winformspositionnotifyicon

Position form above the clicked notify icon


Is there a way to position a form just above the clicked Notify Icon in windows 7 and windows Vista?


Solution

  • Regarding your comment: "how could i know how is the taskbar positioned?"

    Check out the following article which contains a class which exposes a method for retrieving a Rectangle Structure for the tray: [c#] NotifyIcon - Detect MouseOut

    Using this class you can retrieve the Rectangle Structure for the tray like so:

    Rectangle trayRectangle = WinAPI.GetTrayRectangle();
    

    Which will provide you with the Top, Left, Right and Bottom coordinates for the tray along with its width and height.

    I have included the class below:

    using System;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.ComponentModel;
    
    public class WinAPI
    {
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
    
            public override string ToString()
            {
                return "(" + left + ", " + top + ") --> (" + right + ", " + bottom + ")";
            }
        }
    
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string strClassName, string strWindowName);
    
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);
    
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    
    
        public static IntPtr GetTrayHandle()
        {
            IntPtr taskBarHandle = WinAPI.FindWindow("Shell_TrayWnd", null);
            if (!taskBarHandle.Equals(IntPtr.Zero))
            {
                return WinAPI.FindWindowEx(taskBarHandle, IntPtr.Zero, "TrayNotifyWnd", IntPtr.Zero);
            }
            return IntPtr.Zero;
        }
    
        public static Rectangle GetTrayRectangle()
        {
            WinAPI.RECT rect;
            WinAPI.GetWindowRect(WinAPI.GetTrayHandle(), out rect);
            return new Rectangle(new Point(rect.left, rect.top), new Size((rect.right - rect.left) + 1, (rect.bottom - rect.top) + 1));
        }
    }
    

    Hope this helps.