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 ToggleSetting(); //if we are exiting, exit if (!IsRunning()) return; //add all but the primary monitor to the list of monitors that will be dimmed List
forms = new List(); foreach(uint id in BFS.Monitor.GetMonitorIDs()) { if(id != 2) 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 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; private uint FadeWait; private decimal TransparentIncrement; //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); 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) { //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); 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() { 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(this.Handle, this.Transparency); } //sleep BFS.General.ThreadWait((this.Transparency < 100m) ? this.FadeWait : 250u); } else { if (this.Transparency > 0m) { // Fade back in this.Transparency -= this.TransparentIncrement; BFS.Window.SetTransparency(this.Handle, this.Transparency); //sleep BFS.General.ThreadWait((this.Transparency < 100m) ? this.FadeWait : 250u); } else { try { this.Invoke((MethodInvoker) delegate { this.Close(); }); } catch { //something went wrong, ignore } break; } } } } } }