Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?

Dim All Monitors Except Primary

Description
This script will dim all monitors except the Primary. When the script is run a second time, the monitors are returned to normal.
Language
C#.net
Minimum Version
Created By
Thomas Malloch (BFS)
Contributors
-
Date Created
Mar 13, 2015
Date Last Modified
Aug 15, 2016

Scripted Function (Macro) Code

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Collections.Generic;

// 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
{
	private static readonly string SettingName = "DimMonitor_TransparentForm_Running";
	public static void Run(IntPtr windowHandle)
	{
		//toggle the setting from running to not running, and vice versa
		ToggleSetting();
		
		//check to see if we should exit
		bool isExiting = !IsTransparentWindowRunning();
				
		//if we are exiting, exit
		if(isExiting)
			return;
			
		//add all but the primary monitor to the list of monitors that will be dimmed
		List<Form> forms = new List<Form>();
		foreach(uint id in BFS.Monitor.GetMonitorIDs())
		{
			if(BFS.Monitor.GetMonitorBoundsByID(id).Equals(Screen.PrimaryScreen.Bounds))
				continue;
			
			forms.Add(new TransparentForm(id, 30m));
		}
		
		//this will open the forms we added to the list by using our custom application context
		Application.Run(new MultipleFormApplicationContext(forms));
	}
	
	//this function toggles the script settings from running to not running
	private static void ToggleSetting()
	{
		string status = BFS.ScriptSettings.ReadValue(SettingName);
		if(status.Equals("running", StringComparison.Ordinal))
			BFS.ScriptSettings.WriteValue(SettingName, "not");
		else
			BFS.ScriptSettings.WriteValue(SettingName, "running");
	}
	
	//this function allows us to see the currect state of the script
	private static bool IsTransparentWindowRunning()
	{
		string status = BFS.ScriptSettings.ReadValue(SettingName);
		return status.Equals("running", StringComparison.Ordinal);
	}
	
	//extend the ApplicationContext class to support opening multiple forms
	private class MultipleFormApplicationContext : ApplicationContext 
	{
		internal MultipleFormApplicationContext(List<Form> forms)
		{
			//open each of the forms, and add our closing event to them
			foreach(Form form in forms)
			{
				form.FormClosed += OnFormClosed;
				form.Show();	
			}		
		}
		
		//when all the forms close, make sure to exit the application
		private void OnFormClosed(object sender, EventArgs e)
		{
			if(Application.OpenForms.Count == 0)
				ExitThread();
		}
	}
	
	//extend the Form class to get the behavior we want
	private class TransparentForm : Form 
	{
		//this will tell us what monitor to open on
		private uint MonitorId;
		
		//this will tell us what transparency to use
		private decimal Transparency;
		
		//the contructor for our class
		internal TransparentForm(uint monitorId, decimal transparency)
		{		
			this.MonitorId = monitorId;
			this.Transparency = transparency;
			
			this.SuspendLayout();
			
			//setup the layout of this form
			this.BackColor = Color.Black;
			this.FormBorderStyle = FormBorderStyle.None;
			this.ShowInTaskbar = false;
			
			//setup the form load event
			this.Load += Form_Load;			
			
			this.ResumeLayout(false);
		}
		
		private void Form_Load(object sender, EventArgs e)
		{
			//set the window to be always on top
			BFS.Window.SetAlwaysOnTop(this.Handle, true);
			
			//make the window transparent
			BFS.Window.SetTransparency(this.Handle, this.Transparency);
			
			//add a windows style to the current style that will
			//tell this window to ignore user input
			uint style = (uint)BFS.Window.GetWindowStyleEx(this.Handle);
			BFS.Window.SetWindowStyleEx((BFS.WindowEnum.WindowStyleEx)(style | (uint)BFS.WindowEnum.WindowStyleEx.WS_EX_TRANSPARENT | (uint)BFS.WindowEnum.WindowStyleEx.WS_EX_LAYERED), this.Handle);
		
			//move the window to the desired monitor
			this.Bounds = BFS.Monitor.GetMonitorBoundsByID(this.MonitorId);
			
			//start up a thread to listen for an exit event
			new Thread(new ThreadStart(ExitListener)).Start();
		}
		
		private void ExitListener()
		{
			while(true)
			{
				//if we should close, tell the main thread to close the form
				if(!IsTransparentWindowRunning())
				{
					try
					{
						this.Invoke((MethodInvoker) delegate
						{
							this.Close();
						});
					}
					catch //something went wrong, ignore
					{
					}
						
					break;
				}
				
				//sleep for a quarter of a second
				BFS.General.ThreadWait(250);
			}
		}
	}
}