using System; using System.Drawing; using System.Runtime.InteropServices; // The 'windowHandle' parameter will contain the window handle for the: // - Active window when run by hotkey // - Trigger target when run by a Trigger 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); const uint GW_HWNDNEXT = 2; public static void Run(IntPtr windowHandle) { //change this to the monitor id of the monitor you expect fullscreen windows to run on uint fullscreenMonitorId = BFS.Monitor.GetPrimaryMonitorID(); //get the handle for the topmost window IntPtr topmost = GetTopmostWindowOfMonitor(fullscreenMonitorId, windowHandle); //if no window was found, exit the script if(topmost == IntPtr.Zero) return; //get the bounds for the monitor and the window Rectangle fullScreenMonitorBounds = BFS.Monitor.GetMonitorBoundsByID(fullscreenMonitorId); Rectangle windowBounds = BFS.Window.GetBounds(topmost); //if the bounds of the two rectangles are not equal, a fullscreen app is not running. exit the script if(!fullScreenMonitorBounds.Equals(windowBounds)) return; //if we got this far that means there's a fullscreen app running //move the window to the second monitor BFS.Window.MoveToMonitor(2, windowHandle); } private static IntPtr GetTopmostWindowOfMonitor(uint monitorId, IntPtr excludeWindow) { //loop backwards through the z-order, starting with the focused window for(IntPtr window = BFS.Window.GetFocusedWindow(); window != IntPtr.Zero; window = GetWindow(window, GW_HWNDNEXT)) { //if we're excluding this window, continue if(window == excludeWindow) continue; //if this window isn't in the monitor we're looking for, continue to the next one if(BFS.Monitor.GetMonitorIDByWindow(window) != monitorId) continue; //ignore the window if it is a pesky hidden explorer window or a displayfusion window if(BFS.Window.GetClass(window).StartsWith("DF", 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("EdgeUiInputTopWndClass", StringComparison.OrdinalIgnoreCase) || BFS.Window.GetClass(window).Equals("SearchPane", StringComparison.OrdinalIgnoreCase) || BFS.Window.GetClass(window).Equals("ImmersiveLauncher", StringComparison.OrdinalIgnoreCase) || BFS.Window.GetClass(window).Equals("Shell_TrayWnd", StringComparison.OrdinalIgnoreCase) || BFS.Window.GetClass(window).Equals("WorkerW", StringComparison.OrdinalIgnoreCase)) { continue; } if(string.IsNullOrEmpty(BFS.Window.GetText(window))) continue; if(BFS.Application.GetMainFileByWindow(window).Contains("growl")) continue; //this must be the topmost window on this monitor. return the value return window; } //if we got this far that means we found nothing. return IntPtr.Zero return IntPtr.Zero; } }