public void Draw(Pair <VirtualDesktop, HMONITOR> key)
        {
            ObservableCollection <DesktopWindow> windows = Windows[key];
            KeyValuePair <Pair <VirtualDesktop, HMONITOR>, ObservableCollection <DesktopWindow> > desktopMonitor = new KeyValuePair <Pair <VirtualDesktop, HMONITOR>, ObservableCollection <DesktopWindow> >(key, windows);
            float ScreenScalingFactorVert;
            int   mX, mY;
            IEnumerable <Rectangle> gridGenerator;

            DrawMonitor(desktopMonitor, out ScreenScalingFactorVert, out mX, out mY, out gridGenerator);

            HDWP hDWP1 = User32.BeginDeferWindowPos(windows.Count);

            foreach (var w in desktopMonitor.Value.Select((value, i) => new Tuple <int, DesktopWindow>(i, value)))
            {
                Rectangle adjustedSize = new Rectangle(
                    gridGenerator.ToArray()[w.Item1].X,
                    gridGenerator.ToArray()[w.Item1].Y,
                    gridGenerator.ToArray()[w.Item1].Width,
                    gridGenerator.ToArray()[w.Item1].Height
                    );

                User32.ShowWindow(w.Item2.Window, ShowWindowCommand.SW_RESTORE);

                DrawWindow1(ScreenScalingFactorVert, mX, mY, adjustedSize, w, hDWP1);
            }
            User32.EndDeferWindowPos(hDWP1.DangerousGetHandle());

            HDWP hDWP2 = User32.BeginDeferWindowPos(windows.Count);

            foreach (var w in desktopMonitor.Value.Select((value, i) => new Tuple <int, DesktopWindow>(i, value)))
            {
                Rectangle adjustedSize = new Rectangle(
                    gridGenerator.ToArray()[w.Item1].X,
                    gridGenerator.ToArray()[w.Item1].Y,
                    gridGenerator.ToArray()[w.Item1].Width,
                    gridGenerator.ToArray()[w.Item1].Height
                    );

                DrawWindow2(ScreenScalingFactorVert, mX, mY, adjustedSize, w, hDWP2);
            }
            User32.EndDeferWindowPos(hDWP2.DangerousGetHandle());

            foreach (var w in desktopMonitor.Value.Select((value, i) => new Tuple <int, DesktopWindow>(i, value)))
            {
                w.Item2.GetWindowInfo();
            }
        }
        public void Draw()
        {
            foreach (var desktopMonitor in Windows)
            {
                float ScreenScalingFactorVert;
                int   mX, mY;
                IEnumerable <Rectangle> gridGenerator;
                DrawMonitor(desktopMonitor, out ScreenScalingFactorVert, out mX, out mY, out gridGenerator);

                HDWP hDWP1 = User32.BeginDeferWindowPos(Windows.Count);
                foreach (var w in desktopMonitor.Value.Select((value, i) => new Tuple <int, DesktopWindow>(i, value)))
                {
                    Rectangle adjustedSize = new Rectangle(
                        gridGenerator.ToArray()[w.Item1].X,
                        gridGenerator.ToArray()[w.Item1].Y,
                        gridGenerator.ToArray()[w.Item1].Width,
                        gridGenerator.ToArray()[w.Item1].Height
                        );

                    User32.ShowWindow(w.Item2.Window, ShowWindowCommand.SW_RESTORE);

                    DrawWindow1(ScreenScalingFactorVert, mX, mY, adjustedSize, w, hDWP1);
                }
                User32.EndDeferWindowPos(hDWP1.DangerousGetHandle());

                HDWP hDWP2 = User32.BeginDeferWindowPos(Windows.Count);
                foreach (var w in desktopMonitor.Value.Select((value, i) => new Tuple <int, DesktopWindow>(i, value)))
                {
                    Rectangle adjustedSize = new Rectangle(
                        gridGenerator.ToArray()[w.Item1].X,
                        gridGenerator.ToArray()[w.Item1].Y,
                        gridGenerator.ToArray()[w.Item1].Width,
                        gridGenerator.ToArray()[w.Item1].Height
                        );

                    DrawWindow2(ScreenScalingFactorVert, mX, mY, adjustedSize, w, hDWP2);
                }
                User32.EndDeferWindowPos(hDWP2.DangerousGetHandle());

                foreach (var w in desktopMonitor.Value.Select((value, i) => new Tuple <int, DesktopWindow>(i, value)))
                {
                    w.Item2.GetWindowInfo();
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        ///   Reposition/resize a set of windows, or change their visiblity. When changing visibilty, windows can't be repositioned/resized.
        ///   This is a limitation of the underlying Win32 API.
        /// </summary>
        /// <remarks>
        ///   When invalid window handles are passed, they are simply ignored.
        /// </remarks>
        /// <param name="windows">The windows to perform the operation on.</param>
        /// <param name="changeZOrder">
        ///   When true and changeVisibility is not set, the windows's Z orders are changed to reflect the order of the toPosition list.
        ///   The first item in the list will appear at the top, while the last item will appear at the bottom.
        /// </param>
        /// <param name="changeVisibility">When set to true only the visiblity of windows can be changed. When set to false, only the other parameters can be changed.</param>
        static void RepositionWindowsInner(ICollection <RepositionWindowInfo> windows, bool changeZOrder, bool changeVisibility)
        {
            if (windows.Count == 0)
            {
                // Nothing to reposition.
                return;
            }

            bool succeeded  = false;
            var  windowList = windows.ToList();

            while (!succeeded)
            {
                IntPtr windowsPositionInfo = User32.BeginDeferWindowPos(windowList.Count);

                bool errorEncountered = false;
                for (int i = 0; i < windowList.Count; ++i)
                {
                    RepositionWindowInfo window = windowList[i];

                    // Activating windows is outside of the scope of this function, otherwise it gets too complex.
                    var commands = User32.DeferWindowPosCommands.NoActivate;

                    if (changeVisibility && window.HasVisibilityChanged())
                    {
                        commands |= window.Visible ? User32.DeferWindowPosCommands.ShowWindow : User32.DeferWindowPosCommands.HideWindow;
                    }

                    if (changeVisibility || !window.HasSizeChanged())
                    {
                        commands |= User32.DeferWindowPosCommands.NoResize;
                    }
                    if (changeVisibility || !window.HasPositionChanged())
                    {
                        commands |= User32.DeferWindowPosCommands.NoMove;
                    }
                    if (changeVisibility || (i == 0 || !changeZOrder))
                    {
                        commands |= User32.DeferWindowPosCommands.NoZOrder;
                        commands |= User32.DeferWindowPosCommands.NoOwnerZOrder;
                    }

                    windowsPositionInfo = User32.DeferWindowPos(
                        windowsPositionInfo,
                        window.ToPosition.Handle,
                        i == 0 ? IntPtr.Zero : windowList[i - 1].ToPosition.Handle,
                        window.X, window.Y,
                        window.Width, window.Height,
                        commands);

                    // Handle possible errors.
                    if (windowsPositionInfo == IntPtr.Zero)
                    {
                        var error = (ErrorCode)Marshal.GetLastWin32Error();
                        switch (error)
                        {
                        case ErrorCode.InvalidWindowHandle:
                            windowList = windowList.Where(w => !w.ToPosition.IsDestroyed()).ToList();
                            break;

                        case ErrorCode.InvalidMultipleWindowPositionStructure:
                            // Nothing to do, EndDeferWindowPos will fail, and a new operation will be attempted.
                            break;

                        case ErrorCode.AccessDenied:
                            windowList.RemoveAt(i);
                            break;
                        }

                        // Try again starting over with a new iteration.
                        errorEncountered = true;
                        break;
                    }
                }

                if (!errorEncountered)
                {
                    succeeded = User32.EndDeferWindowPos(windowsPositionInfo);
                    if (succeeded && User32.GetActiveWindow() == IntPtr.Zero)
                    {
                        // All windows are hidden and there is no more active window.
                        // This causes a bug next time a window is shown which doesn't show up on the taskbar. Another window is shown on the taskbar, but not made visible.
                        // To prevent this, activate the start bar.
                        WindowInfo startBar = GetWindows().FirstOrDefault(w => w.GetClassName() == "Shell_TrayWnd");
                        if (startBar != null)
                        {
                            startBar.SetForegroundWindow();
                        }
                    }
                }
            }
        }