Processing Ajax...

Title
Close Dialog

Message

Confirm
Close Dialog

Confirm
Close Dialog

Span Custom Set of Monitors (Horizontal Only)

Description
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.
Language
C#.net
Minimum Version
Created By
Keith Lammers (BFS)
Contributors
-
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)
            {
                LoadWindowPosition(windowHandle);
            }
        else
        {
            SaveWindowPosition(windowHandle);
            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(
				Convert.ToInt32(settings[1]),
				Convert.ToInt32(settings[2]),
				Convert.ToInt32(settings[3]),
				Convert.ToInt32(settings[4]));
				
            // Move the window
            BFS.Window.SetSizeAndLocation(window, savedWindowPosition.X, savedWindowPosition.Y, savedWindowPosition.Width, savedWindowPosition.Height);
	}
}