/// <summary> /// Determines whether the specified System.Windows.Forms.NotifyIcon is contained within the Windows 7 notification area fly-out. /// Note that this function will return false if the fly-out is closed. /// </summary> /// <param name="notifyicon">Notify icon to test.</param> /// <param name="taskbarinfo">Taskbar information structure containing taskbar alignment (bottom/top/left/right).</param> /// <returns>True if the notify icon is in the fly-out, false if not.</returns> public static bool IsNotifyIconInFlyOut(NotifyIcon notifyicon, TaskBarInfo taskbarinfo) { if (Compatibility.CurrentWindowsVersion != Compatibility.WindowsVersion.Windows7Plus) { return(false); // nothing to worry about in earlier versions } Rectangle?nirect = GetNotifyIconRectangle(notifyicon); if (nirect == null) { return(false); // if we can't find the notify icon, return false } return(IsNotifyIconInFlyOut((Rectangle)nirect, taskbarinfo.Position)); }
/// <summary> /// Determines whether the specified System.Windows.Forms.NotifyIcon is contained within the Windows 7 notification area fly-out. /// Note that this function will return false if the fly-out is closed. /// </summary> /// <param name="notifyicon">Notify icon to test.</param> /// <param name="taskbarinfo">Taskbar information structure containing taskbar alignment (bottom/top/left/right).</param> /// <returns>True if the notify icon is in the fly-out, false if not.</returns> public static bool IsNotifyIconInFlyOut(NotifyIcon notifyicon, TaskBarInfo taskbarinfo) { if (Compatibility.CurrentWindowsVersion != Compatibility.WindowsVersion.Windows7Plus) return false; // nothing to worry about in earlier versions Rect? nirect = GetNotifyIconRectangle(notifyicon); if (nirect == null) return false; // if we can't find the notify icon, return false return IsNotifyIconInFlyOut((Rect)nirect, taskbarinfo.Position); }
/// <summary> /// Returns the optimum window position in relation to the specified notify icon. /// </summary> /// <param name="notifyicon">The notify icon that the window should be aligned to.</param> /// <param name="windowwidth">The width of the window.</param> /// <param name="windowheight">The height of the window.</param> /// <param name="dpi">The system's DPI (in relative units: 1.0 = 96 DPI, 1.25 = 120 DPI, etc.).</param> /// <param name="pinned">Whether the window is pinned open or not. Affects positioning in Windows 7 only.</param> /// <returns>A Point specifying the suggested location of the window (top left point).</returns> public static Point GetWindowPosition(NotifyIcon notifyicon, double windowwidth, double windowheight, double dpi, bool pinned) { // retrieve taskbar information TaskBarInfo taskbarinfo = GetTaskBarInfo(); // retrieve notify icon location Rectangle?nipositiontemp = GetNotifyIconRectangle(notifyicon); // if our functions can't find the rectangle, align it to a corner of the screen Rectangle niposition; if (nipositiontemp == null) { switch (taskbarinfo.Alignment) { case TaskBarAlignment.Bottom: // bottom right corner niposition = new Rectangle(taskbarinfo.Position.Right - 1, taskbarinfo.Position.Bottom - 1, 1, 1); break; case TaskBarAlignment.Top: // top right corner niposition = new Rectangle(taskbarinfo.Position.Right - 1, taskbarinfo.Position.Top, 1, 1); break; case TaskBarAlignment.Right: // bottom right corner niposition = new Rectangle(taskbarinfo.Position.Right - 1, taskbarinfo.Position.Bottom - 1, 1, 1); break; case TaskBarAlignment.Left: // bottom left corner niposition = new Rectangle(taskbarinfo.Position.Left, taskbarinfo.Position.Bottom - 1, 1, 1); break; default: goto case TaskBarAlignment.Bottom; } } else { niposition = (Rectangle)nipositiontemp; } // check if notify icon is in the fly-out bool inflyout = IsNotifyIconInFlyOut(niposition, taskbarinfo.Position); // if the window is pinned open and in the fly-out (Windows 7 only), // we should position the window above the 'show hidden icons' button if (inflyout && pinned) { niposition = (Rectangle)GetNotifyAreaButtonRectangle(); } // determine centre of notify icon Point nicentre = new Point(niposition.Left + (niposition.Width / 2), niposition.Top + (niposition.Height / 2)); // get window offset from edge double edgeoffset = Compatibility.WindowEdgeOffset * dpi; // get working area bounds Rectangle workarea = GetWorkingArea(niposition); // calculate window position double windowleft = 0, windowtop = 0; switch (taskbarinfo.Alignment) { case TaskBarAlignment.Bottom: // horizontally centre above icon windowleft = nicentre.X - (windowwidth / 2); if (inflyout) { windowtop = niposition.Top - windowheight - edgeoffset; } else { windowtop = taskbarinfo.Position.Top - windowheight - edgeoffset; } break; case TaskBarAlignment.Top: // horizontally centre below icon windowleft = nicentre.X - (windowwidth / 2); if (inflyout) { windowtop = niposition.Bottom + edgeoffset; } else { windowtop = taskbarinfo.Position.Bottom + edgeoffset; } break; case TaskBarAlignment.Left: // vertically centre to the right of icon (or above icon if in flyout and not pinned) if (inflyout && !pinned) { windowleft = nicentre.X - (windowwidth / 2); windowtop = niposition.Top - windowheight - edgeoffset; } else { windowleft = taskbarinfo.Position.Right + edgeoffset; windowtop = nicentre.Y - (windowheight / 2); } break; case TaskBarAlignment.Right: // vertically centre to the left of icon (or above icon if in flyout and not pinned) if (inflyout && !pinned) { windowleft = nicentre.X - (windowwidth / 2); windowtop = niposition.Top - windowheight - edgeoffset; } else { windowleft = taskbarinfo.Position.Left - windowwidth - edgeoffset; windowtop = nicentre.Y - (windowheight / 2); } break; default: goto case TaskBarAlignment.Bottom; // should be unreachable } //// check that the window is within the working area //// if not, put it next to the closest edge if (windowleft + windowwidth + edgeoffset > workarea.Right) // too far right { windowleft = workarea.Right - windowwidth - edgeoffset; } else if (windowleft < workarea.Left) // too far left { windowleft = workarea.Left + edgeoffset; } if (windowtop + windowheight + edgeoffset > workarea.Bottom) // too far down { windowtop = workarea.Bottom - windowheight - edgeoffset; } //// the window should never be too far up, so we can skip checking for that return(new Point((int)windowleft, (int)windowtop)); }