using System;
using System.Drawing;
using System.Collections.Generic;
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
{
public static void Run(IntPtr windowHandle)
{
//a list to store the potential windows
List<IntPtr> windows = new List<IntPtr>();
//get the current position of the mouse
Point mousePosition = new Point(BFS.Input.GetMousePositionX(), BFS.Input.GetMousePositionY());
//loop through all of the visible windows
foreach(IntPtr window in BFS.Window.GetVisibleWindowHandles())
{
//skip any DisplayFusion window (title bar buttons, etc) or the search pane
string windowClass = BFS.Window.GetClass(window);
if(windowClass.StartsWith("DF", StringComparison.Ordinal) ||
windowClass.Equals("SearchPane", StringComparison.Ordinal) ||
windowClass.Equals("ImmersiveLauncher", StringComparison.Ordinal) ||
windowClass.Equals("Windows.UI.Core.CoreWindow", StringComparison.Ordinal) ||
windowClass.Equals("WorkerW", StringComparison.Ordinal))
{
continue;
}
//skip if this is the charms bar
if(BFS.Window.GetText(window).Equals("Charm Bar", StringComparison.Ordinal))
continue;
//get the bounds of the window and see if the mouse is over it
Rectangle bounds = BFS.Window.GetBounds(window);
if(!bounds.Contains(mousePosition))
continue;
//if it's over it, add it to the potential windows
windows.Add(window);
}
//we found no eligable windows, exit
if(windows.Count == 0)
return;
//sort the windows by their z-order
windows.Sort(ZOrderComparer.Instance);
//the first window in the list should now be the topmost window.
//focus and maximize it
BFS.Window.Focus(windows[0]);
}
//this custom comparer will sort window handles by their z-order
private class ZOrderComparer : IComparer<IntPtr>
{
//this function is needed to find the z-order of windows
[DllImport("User32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern IntPtr GetWindow(IntPtr hWnd, GetWindowCommandEnum uCmd);
//an enum so we can only put valid parameters into the GetWindow function
private enum GetWindowCommandEnum : uint
{
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6,
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
}
//make it so this class only gets created once for the life of the script
private static ZOrderComparer _Instance = null;
internal static ZOrderComparer Instance
{
get
{
if(_Instance == null)
_Instance = new ZOrderComparer();
return _Instance;
}
}
private ZOrderComparer(){}
//a function that gets the z-order of windows. static to boost the speed a little
private static int GetWindowZOrder(IntPtr handle)
{
int order = 0;
for (IntPtr h = handle; h != IntPtr.Zero; h = GetWindow(h, GetWindowCommandEnum.GW_HWNDPREV))
order++;
return order;
}
//get the z-order of the windows and compare them
public int Compare(IntPtr first, IntPtr second)
{
int z1 = GetWindowZOrder(first);
int z2 = GetWindowZOrder(second);
if(z1 > z2)
return 1;
if(z1 < z2)
return -1;
return 0;
}
}
}