/// <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); } } } }
/// <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; } } } } }