{ "name": "Restore Window Positions and ZOrder", "language": 0, "code": "using System;\r\nusing System.Collections.Generic;\r\nusing System.Drawing;\r\nusing System.Runtime.InteropServices;\r\nusing System.Windows.Forms;\r\n\r\n// The 'windowHandle' parameter will contain the window handle for the:\r\n// - Active window when run by hotkey\r\n// - Window Location target when run by a Window Location rule\r\n// - TitleBar Button owner when run by a TitleBar Button\r\n// - Jump List owner when run from a Taskbar Jump List\r\n// - Currently focused window if none of these match\r\npublic static class DisplayFusionFunction\r\n{\r\n\t[DllImport(\"user32.dll\", SetLastError = true)]\r\n\tprivate static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);\r\n\t\r\n [DllImport(\"user32.dll\", SetLastError = true)]\r\n private static extern bool SetWindowPos(\r\n IntPtr hWnd,\r\n IntPtr hWndInsertAfter,\r\n int X,\r\n int Y,\r\n int cx,\r\n int cy,\r\n uint uFlags);\r\n\t\r\n\t//some constants\r\n\tconst uint GW_HWNDNEXT = 2;\r\n\tprivate const int SWP_NOSIZE = 0x0001;\r\n private const int SWP_NOMOVE = 0x0002;\r\n private const int SWP_NOACTIVATE = 0x0010;\r\n private const int SWP_NOSENDCHANGING = 0x0400;\r\n\t\r\n\tpublic static void Run(IntPtr windowHandle)\r\n\t{ \r\n\t\t// Get the saved window info\r\n\t\tDictionary savedWindowInfo = new Dictionary();\r\n\t\tforeach(WindowInfo info in System.Text.Json.JsonSerializer.Deserialize>(BFS.ScriptSettings.ReadValue(\"WindowInfoList\")))\r\n\t\t{\r\n\t\t\tif(savedWindowInfo.ContainsKey(info.HandleAsPtr()))\r\n\t\t\t\tcontinue;\r\n\t\t\t\r\n\t\t\tsavedWindowInfo.Add(info.HandleAsPtr(), info);\r\n\t\t}\r\n\t\t\r\n\t\t// A list to store the windows\r\n\t\tList windows = new List();\r\n\t\t\r\n // Enumerate through the monitors, starting with the focused window, and moving down\r\n\t\tfor(IntPtr window = BFS.Window.GetFocusedWindow(); ; window = GetWindow(window, GW_HWNDNEXT))\r\n\t\t{\r\n\t\t\t// Check to see if there are any windows left\r\n\t\t\tif(window == IntPtr.Zero)\r\n\t\t\t\tbreak;\r\n\t\t\t\r\n\t\t\t// we don't care about windows we have no info about\r\n\t\t\tif(!savedWindowInfo.ContainsKey(window))\r\n\t\t\t\tcontinue;\r\n\t\t\t\r\n\t\t\t// Store the window with its info\r\n windows.Add(window);\r\n\t\t}\r\n \r\n // Bubble sort!\r\n\t\tbool swapped;\r\n\t\tfor(int i = 0; i < windows.Count - 1; i++)\r\n\t\t{\r\n\t\t\tswapped = false;\r\n\t\t\tfor(int j = 0; j < windows.Count - i - 1; j++)\r\n\t\t\t{\r\n\t\t\t\tWindowInfo a = savedWindowInfo[windows[j]];\r\n\t\t\t\tWindowInfo b = savedWindowInfo[windows[j+1]];\r\n\t\t\t\tif(a.ZOrder <= b.ZOrder)\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t\r\n\t\t\t\tswapped = true;\r\n\t\t\t\tSwapWindowZOrder(a.HandleAsPtr(), b.HandleAsPtr());\r\n\t\t\t\twindows[j] = b.HandleAsPtr();\r\n\t\t\t\twindows[j+1] = a.HandleAsPtr();\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(!swapped)\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t// Restore state and positions\r\n\t\tforeach(IntPtr window in windows)\r\n\t\t{\r\n\t\t\tWindowInfo saved = savedWindowInfo[window];\r\n\t\t\tWindowInfo current = new WindowInfo(window, 0); // we dont care about the zorder here\r\n\t\t\tif(saved.State != current.State)\r\n\t\t\t{\r\n\t\t\t\tif(saved.State == FormWindowState.Normal)\r\n\t\t\t\t\tBFS.Window.Restore(window);\r\n\t\t\t\tif(saved.State == FormWindowState.Minimized)\r\n\t\t\t\t\tBFS.Window.Minimize(window);\r\n\t\t\t\tif(saved.State == FormWindowState.Maximized)\r\n\t\t\t\t\tBFS.Window.Maximize(window);\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif(saved.Bounds != current.Bounds)\r\n\t\t\t\tBFS.Window.SetSizeAndLocation(window, saved.Bounds.X, saved.Bounds.Y, saved.Bounds.Width, saved.Bounds.Height);\r\n\t\t}\r\n\t}\r\n\t\r\n\t// A method to swap two window z orders\r\n\tprivate static void SwapWindowZOrder(IntPtr a, IntPtr b)\r\n\t{\r\n\t\tSetWindowPos(a, b, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);\r\n\t\tSetWindowPos(b, a, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);\r\n\t}\r\n\t\r\n\tprivate static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)\r\n\t{\r\n // Ignore any DisplayFusion windows (title bar buttons, etc.)\r\n // Ignore pesky hidden explorer.exe windows\r\n string windowClass = BFS.Window.GetClass(window);\r\n if((windowClass.StartsWith(\"DF\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"EdgeUiInputTopWndClass\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"EdgeUiInputWndClass\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"NativeHWNDHost\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"ModeInputWnd\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"MetroGhostWindow\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"ImmersiveLauncher\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"ApplicationManager_ImmersiveShellWindow\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"Shell_TrayWnd\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"WorkerW\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"Progman\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"SearchPane\", StringComparison.OrdinalIgnoreCase)))\r\n {\r\n return true;\r\n }\r\n \r\n return false;\r\n\t}\r\n\t\r\n\tpublic class WindowInfo\r\n\t{\t\t\r\n\t\tpublic long Handle { get; set; }\r\n\t\tpublic FormWindowState State { get; set; }\r\n\t\tpublic Rectangle Bounds { get; set; }\r\n\t\tpublic int ZOrder { get; set; }\r\n\t\t\r\n\t\t// for json deseriealization\r\n\t\tpublic WindowInfo(){}\r\n\t\t\r\n\t\tpublic WindowInfo(IntPtr handle, int zOrder)\r\n\t\t{\r\n\t\t\tthis.Handle = handle.ToInt64();\r\n\t\t\tif(BFS.Window.IsMinimized(handle))\r\n\t\t\t\tthis.State = FormWindowState.Minimized;\t\t\t\r\n\t\t\telse if(BFS.Window.IsMaximized(handle))\r\n\t\t\t\tthis.State = FormWindowState.Maximized;\r\n\t\t\telse\r\n\t\t\t\tthis.State = FormWindowState.Normal;\r\n\t\t\t\r\n\t\t\tthis.Bounds = BFS.Window.GetBounds(handle);\r\n\t\t\tthis.ZOrder = zOrder;\r\n\t\t}\r\n\t\t\r\n\t\tpublic IntPtr HandleAsPtr()\r\n\t\t{\r\n\t\t\treturn new IntPtr(this.Handle);\r\n\t\t}\r\n\t}\r\n}", "description": "", "references": "Microsoft.VisualBasic.Core.dll|Microsoft.Win32.Primitives.dll|Microsoft.Win32.Registry.dll|netstandard.dll|Newtonsoft.Json.dll|System.Collections.Concurrent.dll|System.Collections.dll|System.Collections.Immutable.dll|System.Collections.NonGeneric.dll|System.Collections.Specialized.dll|System.ComponentModel.Primitives.dll|System.ComponentModel.TypeConverter.dll|System.Console.dll|System.Core.dll|System.Data.dll|System.Diagnostics.Process.dll|System.dll|System.Drawing.Common.dll|System.Drawing.dll|System.Drawing.Primitives.dll|System.IO.Compression.dll|System.IO.dll|System.IO.FileSystem.Watcher.dll|System.Linq.dll|System.Linq.Expressions.dll|System.Linq.Parallel.dll|System.Linq.Queryable.dll|System.Management.dll|System.Net.dll|System.Net.Primitives.dll|System.Net.Requests.dll|System.Net.WebClient.dll|System.Net.WebHeaderCollection.dll|System.Private.CoreLib.dll|System.Private.Uri.dll|System.Private.Xml.dll|System.Runtime.dll|System.Runtime.InteropServices.dll|System.Runtime.Serialization.Formatters.dll|System.Security.Cryptography.Algorithms.dll|System.Security.Cryptography.Csp.dll|System.Security.Cryptography.dll|System.Security.Cryptography.Primitives.dll|System.Text.Json.dll|System.Text.RegularExpressions.dll|System.Threading.dll|System.Threading.Tasks.dll|System.Threading.Tasks.Parallel.dll|System.Web.dll|System.Web.HttpUtility.dll|System.Windows.Extensions.dll|System.Windows.Forms.dll|System.Windows.Forms.Primitives.dll|System.Xml.dll" }