using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
// The 'windowHandle' parameter will contain the window handle for the:
// - Active window when run by hotkey
// - Window Location target when run by a Window Location rule
// - TitleBar Button owner when run by a TitleBar Button
// - Jump List owner when run from a Taskbar Jump List
// - Currently focused window if none of these match
public static class DisplayFusionFunction
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
//some constants
const uint GW_HWNDNEXT = 2;
public static void Run(IntPtr windowHandle)
{
// Get a list of each visible window on our monitors, and throw them in a HashSet
HashSet<IntPtr> visibleWindows = new HashSet<IntPtr>(BFS.Window.GetVisibleAndMinimizedWindowHandles());
// A list to store the windows
List<WindowInfo> windows = new List<WindowInfo>();
// Enumerate through the monitors, starting with the focused window, and moving down
int order = 0;
for(IntPtr window = BFS.Window.GetFocusedWindow(); ; window = GetWindow(window, GW_HWNDNEXT))
{
// Check to see if there are any windows left
if(window == IntPtr.Zero)
break;
// If it is a window we should ignore, ignore it
if(IsDisplayFusionWindowOrHiddenExplorerWindow(window))
continue;
// Check to see if the window exists in the hashset.
// If it does, store it
if(!visibleWindows.Contains(window))
continue;
// Store the window with its info
windows.Add(new WindowInfo(window, order++));
}
// Save the windows
BFS.ScriptSettings.WriteValue("WindowInfoList", System.Text.Json.JsonSerializer.Serialize(windows));
}
private static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)
{
// Ignore any DisplayFusion windows (title bar buttons, etc.)
// Ignore pesky hidden explorer.exe windows
string windowClass = BFS.Window.GetClass(window);
if((windowClass.StartsWith("DF", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("EdgeUiInputTopWndClass", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("EdgeUiInputWndClass", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("NativeHWNDHost", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("ModeInputWnd", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("MetroGhostWindow", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("ImmersiveLauncher", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("ApplicationManager_ImmersiveShellWindow", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("Shell_TrayWnd", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("WorkerW", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("Progman", StringComparison.OrdinalIgnoreCase)) ||
(windowClass.Equals("SearchPane", StringComparison.OrdinalIgnoreCase)))
{
return true;
}
return false;
}
public class WindowInfo
{
public long Handle { get; set; }
public FormWindowState State { get; set; }
public Rectangle Bounds { get; set; }
public int ZOrder { get; set; }
public WindowInfo(IntPtr handle, int zOrder)
{
this.Handle = handle.ToInt64();
if(BFS.Window.IsMinimized(handle))
this.State = FormWindowState.Minimized;
else if(BFS.Window.IsMaximized(handle))
this.State = FormWindowState.Maximized;
else
this.State = FormWindowState.Normal;
this.Bounds = BFS.Window.GetBounds(handle);
this.ZOrder = zOrder;
}
}
}