using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
// 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;
private static readonly string ToggleTopmostWindowProperty = "ToggleTopmostWindowMinimized_Property";
private static readonly string ToggleTopmostWindowMode = "ToggleTopmostWindowMinimized_Setting";
public static void Run(IntPtr windowHandle)
{
//check to see if we've run this script before. if we have, restore the windows
if(BFS.ScriptSettings.ReadValueBool(ToggleTopmostWindowMode))
{
//loop through each window, restore the ones we minimized before, and remove the property from them
foreach(IntPtr window in BFS.Window.GetAllWindowHandles())
{
IntPtr property = BFS.Window.GetWindowProperty(window, ToggleTopmostWindowProperty);
if(property == IntPtr.Zero)
continue;
BFS.Window.Restore(window);
BFS.Window.RemoveWindowProperty(window, ToggleTopmostWindowProperty);
}
//set the script setting so our next run will minimize the windows
BFS.ScriptSettings.WriteValueBool(ToggleTopmostWindowMode, false);
}
else //minimize topmost windows mode
{
//get the monitor that the mouse is on
uint mouseMonitorId = BFS.Monitor.GetMonitorIDByXY(BFS.Input.GetMousePositionX(), BFS.Input.GetMousePositionY());
//loop through all of the monitors
foreach(uint id in BFS.Monitor.GetMonitorIDs())
{
//skip the monitor that the mouse is on
if(id == mouseMonitorId)
continue;
//get the topmost window on that monitor
IntPtr topmost = GetTopmostWindowOnMonitor(id);
if(topmost == IntPtr.Zero)
continue;
//minimize the window
BFS.Window.Minimize(topmost);
//set a property so we know which window to restore after
BFS.Window.SetWindowProperty(topmost, ToggleTopmostWindowProperty, new IntPtr(1));
}
//set the script setting so our next run will restore the windows
BFS.ScriptSettings.WriteValueBool(ToggleTopmostWindowMode, true);
}
}
private static IntPtr GetTopmostWindowOnMonitor(uint id)
{
//get the visible window handles for that monitor
HashSet<IntPtr> visibleWindows = new HashSet<IntPtr>( BFS.Window.GetVisibleWindowHandlesByMonitor(id) );
//enumerate through the monitors, starting with the focused window, and moving down
//only enumerate if we havn't found the windows yet
for(IntPtr window = BFS.Window.GetFocusedWindow(); ; window = GetWindow(window, GW_HWNDNEXT))
{
//check to see if there are no windows left
if(window == IntPtr.Zero)
break;
//check to see if the window is visible. if it's not, ignore it
if(!visibleWindows.Contains(window))
continue;
//if it is a window we should ignore, ignore it
if(IsDisplayFusionWindowOrHiddenExplorerWindow(window))
continue;
//get the monitor this window is in
uint monitor = BFS.Monitor.GetMonitorIDByWindow(window);
//if the monitor isn't in our collection, get the next window
if(id != monitor)
continue;
return window;
}
//return IntPtr.Zero if we didn't find anything
return IntPtr.Zero;
}
private static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)
{
//ignore any DisplayFusion windows (title bar buttons, etc.)
//ignore pesky hidden explorer.exe windows
if((BFS.Window.GetClass(window).StartsWith("DF", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("EdgeUiInputTopWndClass", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("EdgeUiInputWndClass", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("NativeHWNDHost", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("ModeInputWnd", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("MetroGhostWindow", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("ImmersiveLauncher", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("ApplicationManager_ImmersiveShellWindow", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("Shell_TrayWnd", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("WorkerW", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("Progman", StringComparison.OrdinalIgnoreCase)) ||
(BFS.Window.GetClass(window).Equals("SearchPane", StringComparison.OrdinalIgnoreCase)))
{
return true;
}
return false;
}
}