Processing Ajax...

Title
Close Dialog

Message

Confirm
Close Dialog

Confirm
Close Dialog

Move Windows Through Pre-Configured Smaller Offset Locations

Description
Moves the window through pre-configured locations as set in the script.
Language
C#.net
Minimum Version
Created By
William Rawls
Contributors
-
Date Created
May 22, 2020
Date Last Modified
May 22, 2020

Scripted Function (Macro) Code

using System;
using System.Drawing;

public static class DisplayFusionFunction 
{
	public static void Run(IntPtr windowHandle) 
	{
		if (windowHandle == null)   return;

		Rectangle window = BFS.Window.GetBounds(windowHandle);
		if (window == null) return;

		Rectangle screenWorkArea = BFS.Monitor.GetMonitorWorkAreaByWindow(windowHandle);
		if (screenWorkArea == null)	return;

		bool isRestored = BFS.Window.IsRestored(windowHandle);
		if (!isRestored) BFS.Window.Restore(windowHandle);

        // You can add, change or remove some lines from the locations array below.
        // Each line is a set of cooridinates for the selected window to move to
        // Each coordinate can be set from 0% to 100%
        //    Left %, Top %, Width %, Height %
        //
        // Example: If one of the entries in the locations array is
        //   CalculateNewLocation(screenWorkArea, 10, 25, 30, 44)
        //
        // The current window would move to
        //    10% (of the monitor's width) from the left edge
        //    25% (of the monitor's height) from the top edge
        //
        // It would resize the window to 
        //    30% wide (of the monitor's width)
        //    44% tall (of the monitor's height)
        //
        //  Sometimes two positions may interfere with each other.
        //  You can tell because when a window moves through the locations
        //    one or both of the locations will get skipped.
        //  It may even cause the rest of the locations to be skipped.
        //  When this happens, you'll need to adjust the location's 
        //    first two numbers (the window's new top left corner) 
        //    until all locations work well together.
        //  Luckily this doesn't happen often
        //

		// Small (less than large)
        Rectangle[] locations = new Rectangle[]
        {
            CalculateNewLocation(screenWorkArea,  0, 15, 45, 60),
            CalculateNewLocation(screenWorkArea,  2, 15, 25, 80),
            CalculateNewLocation(screenWorkArea,  3, 10, 20, 30),
            CalculateNewLocation(screenWorkArea, 30,  0, 50, 40),
            CalculateNewLocation(screenWorkArea, 47, 37, 50, 60),
            CalculateNewLocation(screenWorkArea, 68, 58, 31, 41),
            CalculateNewLocation(screenWorkArea, 80, 70, 21, 31),
            CalculateNewLocation(screenWorkArea, 80, 15, 20, 85),
        }; 

		// Start with the first location and look for the first matching X and Y
		Rectangle newLocation = locations[0];
		for(int i = 0; i < locations.Length; i++)
		{
			Rectangle location = locations[i];
			if (IsCloseEnough(window, location))
			{
				if (i < locations.Length - 1)
				{
					// Set the new location to the next location.
					// If it's the last location, use the already set first location.
					newLocation = locations[i+1];
				}
				
				break;
			}
		}
		
		// Move and resize the window to it's new location
		BFS.Window.SetSizeAndLocation(windowHandle, newLocation.X, newLocation.Y, newLocation.Width, newLocation.Height);
	}
	
    //
	// Checks to see if the upper left coordinates of each rectangle 
	//   are close enough to each other within a number of pixels (a tolerance)
	// Initially, tolerance is 25 pixels. You may want to play with it
	//   to get a better personal flow
	//
	// This is used with a window's starting location 
	//   to figure out what the next location 
	//   the window should be moved to
	//
	public static bool IsCloseEnough(Rectangle a, Rectangle b)
	{
		const int TOLERANCE = 25; //50;
		int deltaX = a.X - b.X;
		if (deltaX < 0)
			deltaX = -deltaX;

		int deltaY = a.Y - b.Y;
		if (deltaY < 0)
			deltaY = -deltaY;

		return (deltaX <= TOLERANCE) && (deltaY <= TOLERANCE);
	}

    //
	// Scales the boundaries of a window to fit within certain percentages of the boundaries
	//
	public static Rectangle CalculateNewLocation(Rectangle bounds, double percentX, double percentY, double percentWidth, double percentHeight)
	{
		// Adjust the top randomly by up to +/- 10 pixels 
		//   and the left coordinate randomly by up to +/- 10 pixels
		// This done to let each window move (probably) not exactly overlap another
		// So if you move one window to x,y (+/-10 pixels) and then a different
		//   window to the same location, both will not exactly overlap
		//
		Random rnd = new Random();
		percentX += (int) (rnd.Next(-10, +10) / 10.0);
		percentY += (int) (rnd.Next(-10, +10) / 10.0);

        var x = bounds.X + (int) (bounds.Width * (percentX / 100.0));
        var y = bounds.Y + (int) (bounds.Height * (percentY / 100.0));
        var w = (int) (bounds.Width * (percentWidth / 100.0));
        var h = (int) (bounds.Height * (percentHeight / 100.0));
		
		if(x < 0) x = 0;
		if(y < 0) y = 0;
		if(w > bounds.Width) w = bounds.Width;
		if(h > bounds.Height) h = bounds.Height;
		
		return new Rectangle(x, y, w, h);
	}	
}