Processing Ajax...

Close Dialog


Close Dialog

Close Dialog

Fade All Monitors Except Primary

This script will fade all monitors except the Primary monitor. When running it a second time, they will return to normal.
Minimum Version
Created By
Date Created
Jun 26, 2015
Date Last Modified
Nov 5, 2019

Scripted Function (Macro) Code

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

// Fade all monitors except the primary monitor to black over a two second period
// Adjust 

// Based entirely on Thomas Malloch's very brilliant Dim All Monitors Except Primary
// Hope he will forgive the change to K&R style and general clean-up to be more abbreviated

// 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 = "BlackenMonitors_Running";
	public static void Run(IntPtr windowHandle) {
		//toggle the setting from running to not running, and vice versa

		//if we are exiting, exit
		if (!IsRunning())

		//add all but the primary monitor to the list of monitors that will be dimmed
		List<Form> forms = new List<Form>();
		uint primaryMonitorID = BFS.Monitor.GetPrimaryMonitorID();
		foreach(uint id in BFS.Monitor.GetMonitorIDs()) {
			if(id != primaryMonitorID)
				forms.Add(new TransparentForm(id));

		//this will open the forms we added to the list by using our custom application context
		Application.Run(new MultipleFormApplicationContext(forms));

	//this function allows us to see the currect state of the script
	private static bool IsRunning() {
		return BFS.ScriptSettings.ReadValue(SettingName) == "running";

	//this function toggles the script settings from running to not running
	private static void ToggleSetting() {
		BFS.ScriptSettings.WriteValue(SettingName, IsRunning() ? "not" : "running");

	//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;

		//when all the forms close, make sure to exit the application
		private void OnFormClosed(object sender, EventArgs e) {
			if(Application.OpenForms.Count == 0)

	//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;
		private uint FadeWait;
		private decimal TransparentIncrement;
		private IntPtr HandleTHREADSAFE;

		//this will tell us our current transparency
		private decimal Transparency;

		//the contructor for our class
		internal TransparentForm(uint monitorId) {	
			this.MonitorId = monitorId;
			this.Transparency = 0m;
			const decimal FadeTime = 2.0m; // seconds
			this.TransparentIncrement = 2m; // percent
			this.FadeWait = (uint)(this.TransparentIncrement * 10m * FadeTime);


			//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;	


		private void Form_Load(object sender, EventArgs e) {
            HandleTHREADSAFE = Handle;
			//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
			Rectangle bounds = BFS.Monitor.GetMonitorBoundsByID(this.MonitorId);
			BFS.Window.SetSizeAndLocation(this.Handle, bounds.X, bounds.Y, bounds.Width, bounds.Height);

			BFS.Window.SetAlwaysOnTop(this.Handle, true);
			BFS.Window.SetTransparency(this.Handle, this.Transparency);

			//start up a thread to listen for an exit event
			new Thread(new ThreadStart(ExitListener)).Start();

		private void ExitListener() {
            try {
                while(true) {
                    //if we should close, tell the main thread to close the form
                    if(IsRunning()) {
                        // Fade to Black
                        if (this.Transparency < 100m) {
                            this.Transparency += this.TransparentIncrement;
                            BFS.Window.SetTransparency(HandleTHREADSAFE, this.Transparency);

                        BFS.General.ThreadWait((this.Transparency < 100m) ? this.FadeWait : 250u);	
                    } else {
                        if (this.Transparency > 0m) {
                            // Fade back in
                            this.Transparency -= this.TransparentIncrement;
                            BFS.Window.SetTransparency(HandleTHREADSAFE, this.Transparency);

                            BFS.General.ThreadWait((this.Transparency < 100m) ? this.FadeWait : 250u);
                        } else {
                            try {
                                this.Invoke((MethodInvoker) delegate {
                            } catch { //something went wrong, ignore

			catch { }