using System; using System.Collections.Generic; using Microsoft.Win32; using Win32_SystemEvents = Microsoft.Win32.SystemEvents; using System.Windows.Forms; using System.Drawing; using Trigger.Classes.Screen; namespace Trigger.Events { class Screen : EventPlugin { #region Properties private enum EventType : byte { DisplaySettingsChanged, } private Dictionary oldValues = new Dictionary(); #region Register Parent Events private byte displaySettingsChangedEnabled; private bool DisplaySettingsChangedEnabled { set { if (value) displaySettingsChangedEnabled++; else displaySettingsChangedEnabled--; if (value && displaySettingsChangedEnabled == 1) Win32_SystemEvents.DisplaySettingsChanged += Win32_SystemEvents_DisplaySettingsChanged; else if (displaySettingsChangedEnabled == 0) Win32_SystemEvents.DisplaySettingsChanged -= Win32_SystemEvents_DisplaySettingsChanged; } get { return displaySettingsChangedEnabled > 0; } } #endregion #region Events #region DisplaySettingsChanged private EventPlugin.Event OnDisplaySettingsChanged; /// Occurs when the user changes the display settings (resolution, color depth, ...). public event EventPlugin.Event DisplaySettingsChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnDisplaySettingsChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnDisplaySettingsChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenAdded private EventPlugin.EventValue OnScreenAdded; /// Occurs when the user plugges a new screen. public event EventPlugin.EventValue ScreenAdded { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenAdded += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenAdded -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenRemoved private EventPlugin.EventValue OnScreenRemoved; /// Occurs when the user unplugges a screen. public event EventPlugin.EventValue ScreenRemoved { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenRemoved += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenRemoved -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenChanged private EventPlugin.EventValues OnScreenChanged; /// Occurs when the user changes the resolution or color depth of a screen. public event EventPlugin.EventValues ScreenChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenColorDepthChanged private EventPlugin.EventValues OnScreenColorDepthChanged; /// Occurs when the user changes the color depth of a screen. public event EventPlugin.EventValues ScreenColorDepthChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenColorDepthChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenColorDepthChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenResolutionChanged private EventPlugin.EventValues OnScreenResolutionChanged; /// Occurs when the user changes the resolution of a screen. public event EventPlugin.EventValues ScreenResolutionChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenResolutionChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenResolutionChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenRefreshRateChanged private EventPlugin.EventValues OnScreenRefreshRateChanged; /// Occurs when the user changes the RefreshRate of a screen. public event EventPlugin.EventValues ScreenRefreshRateChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenRefreshRateChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenRefreshRateChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenLocationChanged private EventPlugin.EventValues OnScreenLocationChanged; /// Occurs when the user changes the Position of a screen. public event EventPlugin.EventValues ScreenLocationChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenLocationChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenLocationChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - ScreenOrientationChanged private EventPlugin.EventValues OnScreenOrientationChanged; /// Occurs when the user changes the Orientation of a screen. public event EventPlugin.EventValues ScreenOrientationChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnScreenOrientationChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnScreenOrientationChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #region - PrimaryScreenChanged private EventPlugin.EventValues OnPrimaryScreenChanged; /// Occurs when the user The user chooses another screen as primary screen. public event EventPlugin.EventValues PrimaryScreenChanged { add { if (!oldValues.ContainsKey(EventType.DisplaySettingsChanged)) oldValues[EventType.DisplaySettingsChanged] = new List(Status.Screen.AllScreens); this.OnPrimaryScreenChanged += value; DisplaySettingsChangedEnabled = true; } remove { this.OnPrimaryScreenChanged -= value; DisplaySettingsChangedEnabled = false; } } #endregion #endregion #endregion #region Constructor & Destructor /// /// Disables all SystemEvents because they are static /// /// http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.displaysettingschanged%28v=vs.110%29.aspx ~Screen() { if (displaySettingsChangedEnabled > 0) Win32_SystemEvents.DisplaySettingsChanged -= Win32_SystemEvents_DisplaySettingsChanged; } #endregion #region Methods public override EventList EventNames() { EventList list = new EventList(); EventListRow row = list.NewEventListRow(); row.Name = "DisplaySettingsChanged"; row.Text = "Display settings changed"; row.Description = "The user changed the display settings (resolution, color depth, ...)"; row.Type = Manager.EventTypes.Simple; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "ScreenAdded"; row.Text = "Screen added"; row.Description = "The user plugged in a new screen."; row.Type = Manager.EventTypes.SingleValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "ScreenRemoved"; row.Text = "Screen removed"; row.Description = "The user unplugged a screen."; row.Type = Manager.EventTypes.SingleValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "ScreenChanged"; row.Text = "Screen settings changed"; row.Description = "The user changed the resolution or color depth of a screen."; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "ScreenColorDepthChanged"; row.Text = "Screen color depth changed"; row.Description = "The user changed the color depth of a screen."; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "ScreenResolutionChanged"; row.Text = "Screen resolution changed"; row.Description = "The user changed the resolution of a screen."; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); row = list.NewEventListRow(); row.Name = "PrimaryScreenChanged"; row.Text = "Primary screen changed"; row.Description = "The user chose another screen as primary screen."; row.Type = Manager.EventTypes.ChangingValue; list.AddEventListRow(row); return list; } public override TreeNode GetStatus() { TreeNode tnMain = new TreeNode("Screen"); TreeNode tnEvents = tnMain.Nodes.Add("Registered events"); if (DisplaySettingsChangedEnabled) { TreeNode tnEvent = tnEvents.Nodes.Add("DisplaySettingsChanged"); tnEvent.ToolTipText = "Microsoft.Win32.SystemEvents.DisplaySettingsChanged"; } return tnMain; } #endregion #region Event Handlers void Win32_SystemEvents_DisplaySettingsChanged(object sender, EventArgs e) { if (OnDisplaySettingsChanged != null) OnDisplaySettingsChanged(this, e); List oldScreens = (List)oldValues[EventType.DisplaySettingsChanged]; List newScreens = Status.Screen.AllScreens; ScreenEx oldPrimary = null; foreach (ScreenEx newScreen in newScreens) { ScreenEx found = oldScreens.Find(new Predicate(item => { return item.Name == newScreen.Name; })); if (found == null) { if (OnScreenAdded != null) OnScreenAdded(this, new EventArgsValue(newScreen)); } else { bool changed = false; EventArgsValues eav = new EventArgsValues(found, newScreen); if (newScreen.BitsPerPixel != found.BitsPerPixel) { changed = true; if (OnScreenColorDepthChanged != null) OnScreenColorDepthChanged(this, eav); } if (newScreen.Bounds.Size != found.Bounds.Size) { changed = true; if (OnScreenResolutionChanged != null) OnScreenResolutionChanged(this, eav); } if (newScreen.Bounds.Location != found.Bounds.Location) { changed = true; if (OnScreenLocationChanged != null) OnScreenLocationChanged(this, eav); } if (newScreen.Frequency != found.Frequency) { changed = true; if (OnScreenRefreshRateChanged != null) OnScreenRefreshRateChanged(this, eav); } if (newScreen.Orientation != found.Orientation) { changed = true; if (OnScreenOrientationChanged != null) OnScreenOrientationChanged(this, eav); } if (changed && OnScreenChanged != null) OnScreenChanged(this, eav); if (found.Primary) oldPrimary = found; oldScreens.Remove(found); } } if (OnScreenRemoved != null) foreach (ScreenEx oldScreen in oldScreens) OnScreenRemoved(this, new EventArgsValue(oldScreen)); ScreenEx newPrimary = Status.Screen.PrimaryScreen; if (OnPrimaryScreenChanged != null && oldPrimary != newPrimary) OnPrimaryScreenChanged(this, new EventArgsValues(oldPrimary, newPrimary)); oldValues[EventType.DisplaySettingsChanged] = newScreens; } #endregion } }