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 = "HideMonitor_MessageFormForm_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 = !IsMessageWindowRunning(); //if we are exiting, exit if(isExiting) return; //add all but the primary monitor to the list of monitors that will be dimmed List
forms = new List(); //get the monitor id that the mouse is on foreach(uint monitorId in BFS.Monitor.GetMonitorIDs()) forms.Add(new MessageForm(monitorId, "It is not polite to look at someone's screen.\nLook me in the eyes")); //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 IsMessageWindowRunning() { 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 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 MessageForm : Form { //this will tell us what monitor to open on private uint MonitorId; //this is the message that will show on the form private string Message; private Font MessageFont; //the contructor for our class internal MessageForm(uint monitorId, string message) { this.MonitorId = monitorId; this.Message = message; this.MessageFont = new Font(this.Font.FontFamily, 50f, FontStyle.Regular); 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 will override the form painting this.Paint += Form_Paint; this.ResumeLayout(false); } protected override void Dispose(bool disposing) { //make sure that the font gets released if(this.MessageFont != null) this.MessageFont.Dispose(); base.Dispose(disposing); } private void Form_Load(object sender, EventArgs e) { //set the window to be always on top BFS.Window.SetAlwaysOnTop(this.Handle, true); //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); this.Invalidate(); //start up a thread to listen for an exit event new Thread(new ThreadStart(ExitListener)).Start(); } private void Form_Paint(object sender, PaintEventArgs e) { //clear the screen with black e.Graphics.Clear(Color.Black); //skip drawing the message if the font or message doesn't exist if(string.IsNullOrEmpty(this.Message)) return; if(this.MessageFont == null) return; //set up the string format to be centered StringFormat format = new StringFormat(StringFormatFlags.NoWrap); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; //draw the message on the form e.Graphics.DrawString(this.Message, this.MessageFont, Brushes.White, new RectangleF(0, 0, this.Width, this.Height), format); } private void ExitListener() { while(true) { //if we should close, tell the main thread to close the form if(!IsMessageWindowRunning()) { try { this.Invoke((MethodInvoker) delegate { this.Close(); }); } catch //something went wrong, ignore { } break; } //sleep for a quarter of a second BFS.General.ThreadWait(250); } } } }