/// <summary> /// Return the screen on which the taskbar with the given handle is displayed /// </summary> /// <param name="taskbarHwnd"></param> /// <returns></returns> private static Screen FindTaskbarScreen(IntPtr taskbarHwnd) { Rectangle taskbarRect = WindowUtils.GetWindowBounds(taskbarHwnd); var screens = Screen.AllScreens.ToList(); return(screens.FirstOrDefault(x => x.Bounds.IntersectsWith(taskbarRect))); }
/// <summary> /// Get the docking position of the taskbar with the given handle /// </summary> /// <param name="taskbarHwnd"></param> /// <returns></returns> internal static TaskbarDockPosition GetTaskbarDockPosition(IntPtr taskbarHwnd) { Screen screen = FindTaskbarScreen(taskbarHwnd); var taskbarRect = WindowUtils.GetWindowBounds(taskbarHwnd); if (screen.Bounds.Left == taskbarRect.Left && screen.Bounds.Top == taskbarRect.Top) { // taskbar touches the top left corner if (taskbarRect.Right == screen.Bounds.Right) { // ... and the top right corner as well return(TaskbarDockPosition.Top); } else { return(TaskbarDockPosition.Left); } } else { // taskbar touches the bottom right corner if (taskbarRect.Left == screen.Bounds.Left) { // and the bottom left corner as welt return(TaskbarDockPosition.Bottom); } else { return(TaskbarDockPosition.Right); } } }
/// <summary> /// Reevaluates the DockPosition and Bounds /// and raises the PositionOrSizeChanged event if necessary /// </summary> public void Update(IntPtr childHwnd) { var oldDockPosition = DockPosition; var oldBounds = Bounds; if (childHwnd == IntPtr.Zero) { DockPosition = TaskbarUtils.GetTaskbarDockPosition(Handle); Bounds = WindowUtils.GetWindowBounds(Handle); // raised by the main taskbar, check if it was moved if (oldDockPosition != DockPosition || oldBounds != Bounds) { RaisePositionOrSizeChanged(IntPtr.Zero); } } else { if (ObservedChildBoundChanges.TryGetValue(childHwnd, out Rectangle childRect)) { // check if the child bounds have really changed var screenRect = WindowUtils.GetWindowBounds(childHwnd); if (!screenRect.Equals(childRect)) { RaisePositionOrSizeChanged(childHwnd); } } } }
public void RegisterObservableChild(IntPtr hwnd) { if (hwnd != IntPtr.Zero) { ObservedChildBoundChanges[hwnd] = WindowUtils.GetWindowBounds(hwnd); } }
/// <summary> /// Show the primary taskbar's calendar flyout at the given location with the given alignment /// </summary> public static void ShowCalendarFlyOut(Rectangle alignTo, FlyoutAlignment alignment) { // get all window handles which have the same class as the // flyout, so that we know these are not the flyout var nonFlyoutHandles = WindowUtils.ListWindowsWithClass(CalendarFlyoutClassName); // invoke the primary taskbar's calendar flyout if (TaskbarUtils.InvokeCalendarFlyOut()) { // wait for it to open (max. 2 seconds) IntPtr flyoutHwnd = IntPtr.Zero; int start = Environment.TickCount; while (flyoutHwnd == IntPtr.Zero && (Environment.TickCount - start <= 2000)) { flyoutHwnd = TaskbarUtils.GetCalendarFlyoutHwnd(nonFlyoutHandles); } if (flyoutHwnd != IntPtr.Zero) { // and move it to this clock's location NativeImports.RECT flyoutRect; if (NativeImports.GetWindowRect(flyoutHwnd, out flyoutRect)) { int flyoutWidth = flyoutRect.Right - flyoutRect.Left; int flyoutHeight = flyoutRect.Bottom - flyoutRect.Top; switch (alignment) { case FlyoutAlignment.Below: // place the calendar flyout below the clock NativeImports.SetWindowPos(flyoutHwnd, IntPtr.Zero, alignTo.Right - flyoutWidth, alignTo.Bottom, 0, 0, NativeImports.SetWindowPosFlags.SWP_NOSIZE); break; case FlyoutAlignment.Above: // place the calendar flyout above the clock NativeImports.SetWindowPos(flyoutHwnd, IntPtr.Zero, alignTo.Right - flyoutWidth, alignTo.Top - flyoutHeight, 0, 0, NativeImports.SetWindowPosFlags.SWP_NOSIZE); break; case FlyoutAlignment.ToTheRight: // place the calendar flyout to the right of the clock NativeImports.SetWindowPos(flyoutHwnd, IntPtr.Zero, alignTo.Right, alignTo.Bottom - flyoutHeight, 0, 0, NativeImports.SetWindowPosFlags.SWP_NOSIZE); break; case FlyoutAlignment.ToTheLeft: // place the calendar flyout to the left of the clock NativeImports.SetWindowPos(flyoutHwnd, IntPtr.Zero, alignTo.Left - flyoutWidth, alignTo.Bottom - flyoutHeight, 0, 0, NativeImports.SetWindowPosFlags.SWP_NOSIZE); break; } } } } }
/// <summary> /// Return the handle of the taskbar's calendar flyout window /// </summary> /// <param name="exceptHandles">Only a potenial flyout window with a handle not in this set is returned</param> /// <returns></returns> private static IntPtr GetCalendarFlyoutHwnd(ISet <IntPtr> exceptHandles) { // since the text of the calendar flyout is language-dependent and the // class name is not unique, we search for a window of class // Windows.UI.Core.CoreWindow which touches the primary taskbar's clock // and is not contained in the passed set exceptHandles IntPtr taskbarClockHwnd = GetPrimaryTaskbarClockHwnd(); Rectangle taskbarClockRect = WindowUtils.GetWindowBounds(taskbarClockHwnd); IntPtr candidateHwnd = NativeImports.FindWindowEx(IntPtr.Zero, IntPtr.Zero, CalendarFlyoutClassName, null); while (candidateHwnd != IntPtr.Zero) { // is this window a potential candidate to be the calendar flyout? if (!exceptHandles.Contains(candidateHwnd)) { // does the current window touch the primary taskbar's clock? Rectangle candidateRect = WindowUtils.GetWindowBounds(candidateHwnd); candidateRect.Intersect(taskbarClockRect); // if the two rectangles touch, intersect results in a rectangle // where exactly one dimension is zero if ((candidateRect.Width == 0 && candidateRect.Height > 0) || (candidateRect.Width > 0 && candidateRect.Height == 0)) { // with a very high probability, this is the calendar flyout return(candidateHwnd); } } // find the next window with the calendar class candidateHwnd = NativeImports.FindWindowEx(IntPtr.Zero, candidateHwnd, CalendarFlyoutClassName, null); } return(IntPtr.Zero); /* * // if we have the localized window text, we may use the following * const string flyoutClassname = "Windows.UI.Core.CoreWindow"; * const string flyoutText = "Datums- und Uhrzeitinformationen"; * * IntPtr hwnd = NativeImports.FindWindowEx(IntPtr.Zero, IntPtr.Zero, flyoutClassname, flyoutText); * return hwnd;*/ }
/// <summary> /// Return all visible taskbars /// </summary> public static IList <TaskbarRef> ListTaskbars() { List <TaskbarRef> taskbars = new List <TaskbarRef>(); // get the primary taskbar var primaryHwnd = GetPrimaryTaskbarHwnd(); taskbars.Add(new TaskbarRef(true, primaryHwnd, WindowUtils.GetWindowBounds(primaryHwnd), GetTaskbarDockPosition(primaryHwnd))); // find all secondary taskbars IntPtr secondaryHwnd = NativeImports.FindWindowEx(IntPtr.Zero, IntPtr.Zero, SecondaryTaskbarClassName, null); while (secondaryHwnd != IntPtr.Zero) { taskbars.Add(new TaskbarRef(false, secondaryHwnd, WindowUtils.GetWindowBounds(secondaryHwnd), GetTaskbarDockPosition(secondaryHwnd))); // get the next secondary taskbar (if any) secondaryHwnd = NativeImports.FindWindowEx(IntPtr.Zero, secondaryHwnd, SecondaryTaskbarClassName, null); } return(taskbars); }