Processing Ajax...

Close Dialog


Close Dialog

Close Dialog

Span Custom Set of Monitors (Horizontal Only)

This script will toggle spanning a custom group of horizontally arranged monitors. Make sure to specify the monitor IDs from left-to-right in the monitorsToSpan array on line 16.
Minimum Version
Created By
Keith Lammers (BFS)
Date Created
Feb 26, 2019
Date Last Modified
Jul 8, 2019

Scripted Function (Macro) Code

using System;
using System.Drawing;

// 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
	public static void Run(IntPtr windowHandle)
        // Specify the monitors you want to span here
        // Enter them in order from left to right (check the Monitor Configuration window)
        uint[] monitorsToSpan = { 2, 1 };

        // Calculate the window size
		Rectangle leftMonitorWorkArea = BFS.Monitor.GetMonitorWorkAreaByID(monitorsToSpan[0]);
		int windowWidth = 0;
		int windowHeight = leftMonitorWorkArea.Height;
		// Loop through the monitors to add the widths together, and set the lowest common height
		foreach (uint monitorID in monitorsToSpan)
            Rectangle monitorWorkArea = BFS.Monitor.GetMonitorWorkAreaByID(monitorID);
            windowWidth += monitorWorkArea.Width;
            if (monitorWorkArea.Height < windowHeight)
                windowHeight = monitorWorkArea.Height;

        // Set the target location and size for the spanned window
        int windowLocationX = leftMonitorWorkArea.X;
        int windowLocationY = leftMonitorWorkArea.Y;
        Rectangle calculatedSize = new Rectangle(windowLocationX, windowLocationY, windowWidth, windowHeight);
        // If the window is already spanned (X is ignored because it can vary slightly), restore its previous size
        // Otherwise, save its size and span it
        Rectangle currentWindowBounds = BFS.Window.GetBounds(windowHandle);
        if (currentWindowBounds.Y == calculatedSize.Y &&
            currentWindowBounds.Width == calculatedSize.Width &&
            currentWindowBounds.Height == calculatedSize.Height)
            BFS.Window.SetSizeAndLocation(windowHandle, calculatedSize.X, calculatedSize.Y, calculatedSize.Width, calculatedSize.Height);
	private static void SaveWindowPosition(IntPtr window)
		// Build the settings string with the window values
		Rectangle bounds = BFS.Window.GetBounds(window);
		string settings = string.Format("{0}|{1}|{2}|{3}|{4}", window.ToInt64(), bounds.X, bounds.Y, bounds.Width, bounds.Height);
		// Write the setting to the registry
		BFS.ScriptSettings.WriteValue(BFS.Application.GetMainFileByWindow(window), settings);
	private static void LoadWindowPosition(IntPtr window)
			// Split up the settings string into its seperate values
			string[] settings = BFS.ScriptSettings.ReadValue(BFS.Application.GetMainFileByWindow(window)).Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
			// Check to see if we have enough parameters saved to the setting
			if(settings.Length != 5)
				throw new Exception("Incorrect settings format");
			// Set the values
			Rectangle savedWindowPosition = new Rectangle(
            // Move the window
            BFS.Window.SetSizeAndLocation(window, savedWindowPosition.X, savedWindowPosition.Y, savedWindowPosition.Width, savedWindowPosition.Height);