From adc79f02ced87f2622685905f03b355694c774ec Mon Sep 17 00:00:00 2001 From: MustSave <58774251+MustSave@users.noreply.github.com> Date: Thu, 10 Feb 2022 00:56:55 +0900 Subject: [PATCH 1/5] Resizable Window --- Configuration.cs | 172 +++++++++++ ScreenDimmer.cs | 743 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 915 insertions(+) create mode 100644 Configuration.cs create mode 100644 ScreenDimmer.cs diff --git a/Configuration.cs b/Configuration.cs new file mode 100644 index 0000000..069bd99 --- /dev/null +++ b/Configuration.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Augustine.ScreenDimmer +{ + [DataContract] + internal class Configuration + { + [DataMember(Name = "AllowZeroBrightness")] + internal bool IsZeroBrightness; + [DataMember(Name = "EnforceOnTop")] + internal bool IsEnforceOnTop; + [DataMember(Name = "DebuggingMode")] + internal bool IsDebug; + [DataMember(Name = "AllowTransition")] + internal bool IsTransition; + [DataMember(Name = "MonitorIndex")] + internal byte MonitorIndex; + /// + /// Range: 0-100 + /// + [DataMember(Name = "CurrentBrightness")] + internal byte CurrentBrightness; + [DataMember(Name = "MinimumNonzeroBrightness")] + internal readonly byte MinimumNonZeroBrightness = 20; + [DataMember(Name = "EnforcingPeriod")] + internal int EnforcingPeriod; + [DataMember(Name = "TransitionDuration")] + internal double FadeDuration; + [DataMember(Name = "Color")] + internal Color DimColor = Color.Black; + + [DataMember(Name = "HotkeyDim")] + private string hotKeyDim { + get { return HotKeyDim.ToString(); } + set { HotKeyDim = GlobalHotkeyParser.Parse(value); } } + internal GlobalHotKey HotKeyDim; + + [DataMember(Name = "HotkeyBrighten")] + private string hotKeyBright { + get { return HotKeyBrighten.ToString(); } + set { HotKeyBrighten = GlobalHotkeyParser.Parse(value); } } + internal GlobalHotKey HotKeyBrighten; + + [DataMember(Name = "HotkeyDecreaseBrightness")] + private string hotKeyDecreaseBrightness { + get { return HotKeyDecreaseBrightness.ToString(); } + set { HotKeyDecreaseBrightness = GlobalHotkeyParser.Parse(value); } } + internal GlobalHotKey HotKeyDecreaseBrightness; + + [DataMember(Name = "HotkeyIncreaseBrightness")] + private string hotKeyIncreaseBrightness { + get { return HotKeyIncreaseBrightness.ToString(); } + set { HotKeyIncreaseBrightness = GlobalHotkeyParser.Parse(value); } } + internal GlobalHotKey HotKeyIncreaseBrightness; + + [DataMember(Name = "HotkeyForceOnTop")] + private string hotKeyForceOnTop { + get { return HotKeyForceOnTop.ToString(); } + set { HotKeyForceOnTop = GlobalHotkeyParser.Parse(value); } } + internal GlobalHotKey HotKeyForceOnTop; + + [DataMember(Name = "HotkeyHalt")] + private string hotKeyHalt { + get { return HotKeyHalt.ToString(); } + set { HotKeyHalt = GlobalHotkeyParser.Parse(value); } } + internal GlobalHotKey HotKeyHalt; + + [DataMember(Name = "HotkeyResize")] + private string hotKeyResize + { + get { return HotKeyResize.ToString(); } + set { HotKeyResize = GlobalHotkeyParser.Parse(value); } + } + internal GlobalHotKey HotKeyResize; + + internal Configuration() + { + HotKeyDim = new GlobalHotKey(); + HotKeyBrighten = new GlobalHotKey(); + HotKeyIncreaseBrightness = new GlobalHotKey(); + HotKeyDecreaseBrightness = new GlobalHotKey(); + HotKeyForceOnTop = new GlobalHotKey(); + HotKeyHalt = new GlobalHotKey(); + HotKeyResize = new GlobalHotKey(); + } + + private void setHotkeyDescriptions() + { + HotKeyDim.SetDescription("Dim (minimum brightness)"); + HotKeyBrighten.SetDescription("Brighten (maximum brightness)"); + HotKeyIncreaseBrightness.SetDescription("Increase Brightness"); + HotKeyDecreaseBrightness.SetDescription("Decrease Brightness"); + HotKeyForceOnTop.SetDescription("Force on Top"); + HotKeyHalt.SetDescription("Immediately Halt Program"); + HotKeyResize.SetDescription("Adjust Window Size"); + } + + internal void LoadDefault() + { + MonitorIndex = 0; + CurrentBrightness = 70; + IsZeroBrightness = true; + IsEnforceOnTop = false; + IsDebug = false; + IsTransition = true; + EnforcingPeriod = 30; + FadeDuration = 250; + HotKeyDim.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Left); + HotKeyBrighten.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Right); + HotKeyDecreaseBrightness.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Down); + HotKeyIncreaseBrightness.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Up); + HotKeyForceOnTop.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.T); + HotKeyHalt.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.H); + HotKeyResize.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.B); + setHotkeyDescriptions(); + } + + internal static Configuration LoadFromFile(string fileName) + { + Configuration deserialized; + try + { + deserialized = Serializer.DeSerializeObject(fileName); + } + catch (Exception ex) + { + throw new Exception("Cannot parse configuration from file.", ex); + } + deserialized.setHotkeyDescriptions(); + // For the purpose of robustness. Non-positive fade duration will cause trouble. + if (deserialized.FadeDuration < 1) + { + deserialized.FadeDuration = 250; + } + return deserialized; + //this.CurrentBrightness = deserialized.CurrentBrightness; + //this.DimColor = deserialized.DimColor; + //this.EnforcingPeriod = deserialized.EnforcingPeriod; + //this.IsDebug = deserialized.IsDebug; + //this.IsEnforceOnTop = deserialized.IsEnforceOnTop; + //this.IsTransition = deserialized.IsTransition; + //this.IsZeroBrightness = deserialized.IsZeroBrightness; + ////this.MinimumNonZeroBrightness = deserialized.MinimumNonZeroBrightness; + //this.MonitorIndex = deserialized.MonitorIndex; + //this.HotKeyBright = deserialized.HotKeyBright; + //this.HotKeyDecreaseBrightness = deserialized.HotKeyBright; + //this.HotKeyDim = deserialized.HotKeyDim; + //this.HotKeyForceOnTop = deserialized.HotKeyForceOnTop; + //this.HotKeyHalt = deserialized.HotKeyHalt; + //this.HotKeyIncreaseBrightness = deserialized.HotKeyIncreaseBrightness; + } + + internal void SaveToFile(string fileName) + { + try + { + Serializer.SerializeObject(this, fileName); + } + catch (Exception ex) + { + throw new Exception("Cannot save current configuration to file.", ex); + } + } + + } +} diff --git a/ScreenDimmer.cs b/ScreenDimmer.cs new file mode 100644 index 0000000..a8a3a62 --- /dev/null +++ b/ScreenDimmer.cs @@ -0,0 +1,743 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Augustine.ScreenDimmer +{ + internal partial class ScreenDimmer : Form + { + #region private properties + /// + /// Configuration file path. + /// + private readonly string confFile = "ScreenDimmer.conf"; + + // child forms + /// + /// The overlay window. + /// + private Form overlayWindow; + /// + /// The about box. + /// + private AboutBox1 aboutBox; + /// + /// The help window ("show hotkeys" window). + /// + private HelpWindow helpWindow; + /// + /// The brightness OSD. + /// + private OsdWindow osdWindow; + + /// + /// Contains all the settings. + /// + private Configuration configuration; + + /// + /// Used for governing brightness increasing/decreasing speed. + /// + private int hotkeyRepeatCount; + /// + /// State variable to check if a hotkey is repeatedly pressed. + /// + private int lastHotkeyId = -1; + /// + /// Flag to check if closing to tray or exitting application. + /// + private bool isContextClose = false; + /// + /// State variable to decide to refresh the screen list or not. + /// + private int numberOfScreens = -1; + + // transition effect + /// + /// The total change in brightness track bar value. + /// + private int fadeDistance; + /// + /// The brightness track bar value when enabling the transition timer. + /// + private int fadeOrigin; + /// + /// The current time when enabling the transition timer. + /// + private DateTime fadeStartTime; + #endregion + + #region static members + /// + /// Icon to use in system tray. + /// + public static readonly Icon IconMediumBright = TextIcon.CreateTextIcon("\uE286", Color.White); + /// + /// Main icon. + /// + public static readonly Icon IconMediumBright32x32 = TextIcon.CreateTextIcon("\uE286", Color.White, "", 32); + #endregion + + public partial class Form1 : Form + { + public Form1() + { + //InitializeComponent(); + } + + const int WM_NCHITTEST = 0x0084; + const int HTCLIENT = 1; + const int HTCAPTION = 2; + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + switch (m.Msg) + { + case WM_NCHITTEST: + if (m.Result == (IntPtr)HTCLIENT) + { + var p = this.PointToClient(new Point(m.LParam.ToInt32())); + + m.Result = + (IntPtr) + (p.X <= 6 + ? p.Y <= 6 ? 13 : p.Y >= this.Height - 7 ? 16 : 10 + : p.X >= this.Width - 7 + ? p.Y <= 6 ? 14 : p.Y >= this.Height - 7 ? 17 : 11 + : p.Y <= 6 ? 12 : p.Y >= this.Height - 7 ? 15 : p.Y <= 24 ? 2 : 1); + } + break; + } + } + } + + public ScreenDimmer() + { + InitializeComponent(); + initOverlayWindow(); + + aboutBox = new AboutBox1(); + helpWindow = new HelpWindow(); + configuration = new Configuration(); + osdWindow = new OsdWindow(); + + // has to be in this order! + populateScreenList(); + loadConfiguration(); + hookKeys(); + + notifyIcon1.Icon = IconMediumBright; + Icon = IconMediumBright32x32; + Text = string.Format("Screen Dimmer {0}", Assembly.GetExecutingAssembly().GetName().Version.ToString()); + } + + /// + /// Initializes the overlay window (no border, click-through, see-through, invisible to Alt+Tab). + /// + private void initOverlayWindow() + { + overlayWindow = new Form1(); + overlayWindow.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + overlayWindow.ShowInTaskbar = false; + overlayWindow.Show(); + overlayWindow.WindowState = FormWindowState.Maximized; + enforceOnTop(); + NativeMethods.SetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE, + // get current GWL_EXSTYLE + NativeMethods.GetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE) + // click-through. Need to be combined with see-through. + // Need to recalled if opacity changed by setting Form.Cpacity. + // Using SetLayeredWindowAttributes will not require to recall this. + | (int)ExtendedWindowStyles.WS_EX_LAYERED + // see-through + | (int)ExtendedWindowStyles.WS_EX_TRANSPARENT + // alt+tab invisible, need to set ShowInTaskbar to false. + | (int)ExtendedWindowStyles.WS_EX_TOOLWINDOW); + //NativeMethods.SetLayeredWindowAttributes(overlayWindow.Handle, 0, 192, + // (int)LayeredWindowAttributeFlags.LWA_ALPHA); + } + + #region hotkey management + /// + /// Tries to register all the global hotkeys. + /// (!) Has to be called after loading configuration (when the hotkeys are defined). + /// + private void hookKeys() + { + StringBuilder sb = new StringBuilder(); + bool success = true; + success &= tryHookKeyAppendError(configuration.HotKeyIncreaseBrightness, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyDecreaseBrightness, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyBrighten, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyDim, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyForceOnTop, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyHalt, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyResize, ref sb); + if (!success) + { + notifyIcon1.ShowBalloonTip(0, "Cannot register one or more hotkeys.", sb.ToString(), ToolTipIcon.Warning); + } + } + + /// + /// Pupulates the hotkeys on to the help window. + /// + private void populateHotkeys() + { + helpWindow.ResetHotkeyPanel(); + helpWindow.AddHotKey(configuration.HotKeyDim); + helpWindow.AddHotKey(configuration.HotKeyBrighten); + helpWindow.AddHotKey(configuration.HotKeyIncreaseBrightness); + helpWindow.AddHotKey(configuration.HotKeyDecreaseBrightness); + helpWindow.AddHotKey(configuration.HotKeyForceOnTop); + helpWindow.AddHotKey(configuration.HotKeyHalt); + helpWindow.AddHotKey(configuration.HotKeyResize); + } + + /// + /// Tries to register one hotkey and handle the error message if there are any. + /// + /// + /// + /// true if successfully register the hotkey + private bool tryHookKeyAppendError(GlobalHotKey hotkey, ref StringBuilder sb) + { + try + { + hotkey.Register(Handle); + return true; + } + catch (Exception e) + { + sb.AppendLine(e.Message); + } + return false; + } + + /// + /// WndProc message listener. + /// + /// + protected override void WndProc(ref Message m) + { + // Listen for operating system messages. + switch (m.Msg) + { + case (int)WindowMessage.WM_HOTKEY: + int hotkeyId = (int)m.WParam; + if (hotkeyId == lastHotkeyId) + { + hotkeyRepeatCount++; + } + else + { + hotkeyRepeatCount = 0; + lastHotkeyId = hotkeyId; + } + //Console.WriteLine("Last {0} | Current {1} | Repeat {2}", lastHotkeyId, hotkeyId, hotkeyRepeatCount); + // Id can change, then cannot use switch case. + if (hotkeyId == configuration.HotKeyIncreaseBrightness.Id) + { + increseBrightness(hotkeyRepeatCount); + } + else if (hotkeyId == configuration.HotKeyDecreaseBrightness.Id) + { + decreaseBrightness(hotkeyRepeatCount); + } + else if (hotkeyId == configuration.HotKeyDim.Id) + { + dim(); + } + else if (hotkeyId == configuration.HotKeyBrighten.Id) + { + brighten(); + } + else if (hotkeyId == configuration.HotKeyForceOnTop.Id) + { + enforceOnTop(); + } + else if (hotkeyId == configuration.HotKeyHalt.Id) + { + isContextClose = true; + Close(); + } + else if (hotkeyId == configuration.HotKeyResize.Id) + { + NativeMethods.SetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE, + NativeMethods.GetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE) + ^ (int)ExtendedWindowStyles.WS_EX_TRANSPARENT); + } + break; + } + base.WndProc(ref m); + } + #endregion + + #region color management + /// + /// Gets and updates the color from the color picker tool. + /// + /// + /// + private void colorToolStripMenuItem_Click(object sender, EventArgs e) + { + colorDialog1.Color = overlayWindow.BackColor; + if (colorDialog1.ShowDialog() == DialogResult.OK) + { + setDimColor(colorDialog1.Color); + } + } + + /// + /// Sets the backcolor of the overlay window and dim button to the desired color. + /// + /// + private void setDimColor(Color color) + { + buttonDim.BackColor = color; + overlayWindow.BackColor = color; + } + + /// + /// Gets the current color of the overlay window. + /// + /// + private Color getDimColor() { + return overlayWindow.BackColor; + } + #endregion + + #region brightness management + private void checkBoxZeroBrightness_CheckedChanged(object sender, EventArgs e) + { + setTrackBarBrightnessMinimum(checkBoxZeroBrightness.Checked ? 0 : 20); + } + + /// + /// Sets the minimum for the brightness track bar. + /// If the current track bar value is smaller than the desired value, + /// it will be set to the desired value as well. + /// Note that the case that the desired value is larger than maximum value is not handled here! + /// + /// + private void setTrackBarBrightnessMinimum(int minimum) + { + if (trackBarBrightness.Value < minimum) + { + trackBarBrightness.Value = minimum; + } + trackBarBrightness.Minimum = minimum; + } + + /// + /// Updates the ovelay opacity level according to current brightness track bar value. + /// + /// + private void setBrightness(int brightness) + { + toolTipHint.SetToolTip(trackBarBrightness, string.Format("{0}%", brightness)); + NativeMethods.SetLayeredWindowAttributes(overlayWindow.Handle, 0, (byte)(255 - (brightness / 100f) * 255), + (int)LayeredWindowAttributeFlags.LWA_ALPHA); + } + + /// + /// Increases brightness track bar value. + /// + private void increseBrightness(int speed) + { + if (trackBarBrightness.Value == trackBarBrightness.Maximum) + { + return; + } + + int modifiedSpeed = speed / 3 + 1; + if (trackBarBrightness.Value+modifiedSpeed >= trackBarBrightness.Maximum) + { + trackBarBrightness.Value = trackBarBrightness.Maximum; + } else { + trackBarBrightness.Value += modifiedSpeed; + } + } + + /// + /// Decreases brightness track bar value. + /// + private void decreaseBrightness(int speed) + { + if (trackBarBrightness.Value == trackBarBrightness.Minimum) + { + return; + } + + int modifiedSpeed = speed / 3 + 1; + if (trackBarBrightness.Value - modifiedSpeed <= trackBarBrightness.Minimum) + { + trackBarBrightness.Value = trackBarBrightness.Minimum; + } + else + { + trackBarBrightness.Value -= modifiedSpeed; + } + } + + /// + /// Dims the screen to minimum brightness. + /// + private void dim() + { + if (checkBoxAllowTransition.Checked) + { + fade(trackBarBrightness.Minimum); + } + else + { + trackBarBrightness.Value = trackBarBrightness.Minimum; + } + } + + /// + /// Brightens the sceen to maximum brightness. + /// + private void brighten() + { + if (checkBoxAllowTransition.Checked) + { + fade(trackBarBrightness.Maximum); + } + else + { + trackBarBrightness.Value = trackBarBrightness.Maximum; + } + } + + /// + /// Initializes state variables for transition effect. + /// + /// + private void fade(int target) + { + + fadeDistance = target - trackBarBrightness.Value; + if (fadeDistance == 0) + { + return; + } + fadeOrigin = trackBarBrightness.Value; + timerFade.Enabled = true; + fadeStartTime = DateTime.Now; + } + + /// + /// Interpolates brightness in real time to ensure the transition happens in the period defined in configuration.FadeDuration. + /// + /// + /// + private void timerFade_Tick(object sender, EventArgs e) + { + TimeSpan currentTime = DateTime.Now - fadeStartTime; + double target1 = (currentTime.TotalMilliseconds * fadeDistance / configuration.FadeDuration); + int target = (int)(fadeOrigin + target1); + if ((target >= trackBarBrightness.Maximum) && (fadeDistance > 0)) + { + trackBarBrightness.Value = trackBarBrightness.Maximum; + timerFade.Enabled = false; + } + else if ((target <= trackBarBrightness.Minimum) && (fadeDistance < 0)) + { + trackBarBrightness.Value = trackBarBrightness.Minimum; + timerFade.Enabled = false; + } + else + { + trackBarBrightness.Value = target; + } + //Console.WriteLine("{0} Current {1} | Different {3} | Target {2}:{5}| Total Distance {4}", + // currentTime.TotalMilliseconds, 0, target, target1, fadeDistance, 0 + target1); + } + + private void buttonDim_Click(object sender, EventArgs e) + { + dim(); + } + + private void buttonBright_Click(object sender, EventArgs e) + { + brighten(); + } + + private void trackBarBrightness_ValueChanged(object sender, EventArgs e) + { + setBrightness(((TrackBar)sender).Value); + if (!Visible) + { + osdWindow.Display(((TrackBar)sender).Value.ToString() + "%", new Font("Segeo UI", 32), Color.Black, Color.White, 20, 20, 255, 100, 1000, 1000); + } + } + #endregion + + #region screen management + /// + /// Sets the size and position of the form to cover the desired screen. + /// Does nothing if the desired screen index is invalid. + /// + /// + /// + private void setScreen(Form form, int screenIndex) + { + if (Screen.AllScreens.Length - 1 < screenIndex) + { + return; // invalid index + } + FormWindowState currentState = form.WindowState; + if (currentState != FormWindowState.Normal) + { + form.WindowState = FormWindowState.Normal; + } + form.Location = Screen.AllScreens[screenIndex].WorkingArea.Location; + form.WindowState = currentState; + } + + /// + /// Pupulates the sceen list into the combo box. + /// + private void populateScreenList() + { + Screen[] screens = Screen.AllScreens; + if (numberOfScreens != screens.Length) + { + numberOfScreens = screens.Length; + List screensNames = new List(); + foreach (Screen item in screens) + { + screensNames.Add(item.DeviceName); + } + int currentSelected = comboBoxScreens.SelectedIndex; + comboBoxScreens.Items.Clear(); + comboBoxScreens.Items.AddRange(screensNames.ToArray()); + if (currentSelected < numberOfScreens) + { + comboBoxScreens.SelectedIndex = currentSelected; + } + else + { + comboBoxScreens.SelectedIndex = 0; + } + } + } + + private void comboBoxScreens_SelectedIndexChanged(object sender, EventArgs e) + { + setScreen(overlayWindow, ((ComboBox)sender).SelectedIndex); + } + + private void comboBoxScreens_DropDown(object sender, EventArgs e) + { + populateScreenList(); + } + #endregion + + #region configuration management + private void saveConfiguration() + { + uiToConfig(); + configuration.SaveToFile(confFile); + } + + /// + /// (!) Has to be called after initializing all UI components. + /// + private void loadConfiguration() + { + try + { + configuration = Configuration.LoadFromFile(confFile); + } + catch (Exception) + { + configuration.LoadDefault(); + } + configToUi(); + } + + private void uiToConfig() + { + configuration.CurrentBrightness = (byte) trackBarBrightness.Value; + configuration.DimColor = getDimColor(); + configuration.EnforcingPeriod = (int) numericUpDown1.Value; + configuration.IsDebug = checkBoxDebug.Checked; + configuration.IsEnforceOnTop = checkBoxEnforceOnTop.Checked; + configuration.IsTransition = checkBoxAllowTransition.Checked; + configuration.IsZeroBrightness = checkBoxZeroBrightness.Checked; + configuration.MonitorIndex = (byte) comboBoxScreens.SelectedIndex; + } + + private void configToUi() + { + if (configuration.CurrentBrightness < trackBarBrightness.Minimum) + { + trackBarBrightness.Value = trackBarBrightness.Minimum; + } + else if (configuration.CurrentBrightness > trackBarBrightness.Maximum) + { + trackBarBrightness.Value = trackBarBrightness.Maximum; + } + else + { + trackBarBrightness.Value = configuration.CurrentBrightness; + } + + if (configuration.EnforcingPeriod < numericUpDown1.Minimum) + { + numericUpDown1.Value = numericUpDown1.Minimum; + } + else if (configuration.CurrentBrightness > trackBarBrightness.Maximum) + { + numericUpDown1.Value = numericUpDown1.Maximum; + } + else + { + numericUpDown1.Value = configuration.EnforcingPeriod; + } + + if (comboBoxScreens.Items.Count > configuration.MonitorIndex) + { + comboBoxScreens.SelectedIndex = configuration.MonitorIndex; + } + else + { + comboBoxScreens.SelectedIndex = 0; + } + + setDimColor(configuration.DimColor); + checkBoxEnforceOnTop.Checked = configuration.IsEnforceOnTop; + checkBoxZeroBrightness.Checked = configuration.IsZeroBrightness; + checkBoxDebug.Checked = configuration.IsDebug; + checkBoxAllowTransition.Checked = configuration.IsTransition; + } + #endregion + + #region other UI callbacks + private void labelExpandCollapse_Click(object sender, EventArgs e) + { + toggleAdvancedSettings(); + } + + private void toggleAdvancedSettings() + { + tableLayoutPanel3.Visible = !tableLayoutPanel3.Visible; + if (tableLayoutPanel3.Visible) + { + labelExpandCollapse.Text = "◁"; + toolTipHint.SetToolTip(labelExpandCollapse, "Less"); + } + else + { + labelExpandCollapse.Text = "▷"; + toolTipHint.SetToolTip(labelExpandCollapse, "More..."); + } + } + + private void timerEnforceOnTop_Tick(object sender, EventArgs e) + { + enforceOnTop(); + } + + /// + /// Forces the application to top most. + /// + private void enforceOnTop() + { + overlayWindow.TopMost = true; // overlay window is set to top most + TopMost = true; // main form has to be on top of overlay window + } + + /// + /// Updates the interval of enforcing-on-top timer. + /// + /// + /// + private void numericUpDown1_ValueChanged(object sender, EventArgs e) + { + timerEnforceOnTop.Interval = (int)(((NumericUpDown)sender).Value * 1000); + } + + /// + /// Starts/stops enforcing-on-top timer. + /// + /// + /// + private void checkBoxEnforceOnTop_CheckedChanged(object sender, EventArgs e) + { + bool isEnabled = ((CheckBox)sender).Checked; + numericUpDown1.Enabled = isEnabled; + label1.Enabled = isEnabled; + if (isEnabled) + { + timerEnforceOnTop.Start(); + } + else + { + timerEnforceOnTop.Stop(); + } + } + + private void labelAbout_Click(object sender, EventArgs e) + { + aboutBox.TopMost = true; + aboutBox.ShowDialog(); + } + + private void labelHelp_Click(object sender, EventArgs e) + { + populateHotkeys(); + helpWindow.TopMost = true; + helpWindow.ShowDialog(); + } + + private void labelBug_Click(object sender, System.EventArgs e) + { + //TODO + } + + private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) + { + Show(); + } + + private void controlPanelToolStripMenuItem_Click(object sender, EventArgs e) + { + this.Show(); + } + + private void screenDimmer_FormClosing(object sender, FormClosingEventArgs e) + { + saveConfiguration(); + if (e.CloseReason == CloseReason.WindowsShutDown) + { + return; + } + if (!isContextClose) + { + this.Hide(); + e.Cancel = true; + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + isContextClose = true; + notifyIcon1.Dispose(); + Close(); + } + #endregion + } +} From e8604866b338f6e3449bee1c0bb884fe96617947 Mon Sep 17 00:00:00 2001 From: MustSave <58774251+MustSave@users.noreply.github.com> Date: Thu, 10 Feb 2022 00:57:24 +0900 Subject: [PATCH 2/5] Delete ScreenDimmer.cs --- ScreenDimmer.cs | 743 ------------------------------------------------ 1 file changed, 743 deletions(-) delete mode 100644 ScreenDimmer.cs diff --git a/ScreenDimmer.cs b/ScreenDimmer.cs deleted file mode 100644 index a8a3a62..0000000 --- a/ScreenDimmer.cs +++ /dev/null @@ -1,743 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.Drawing; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace Augustine.ScreenDimmer -{ - internal partial class ScreenDimmer : Form - { - #region private properties - /// - /// Configuration file path. - /// - private readonly string confFile = "ScreenDimmer.conf"; - - // child forms - /// - /// The overlay window. - /// - private Form overlayWindow; - /// - /// The about box. - /// - private AboutBox1 aboutBox; - /// - /// The help window ("show hotkeys" window). - /// - private HelpWindow helpWindow; - /// - /// The brightness OSD. - /// - private OsdWindow osdWindow; - - /// - /// Contains all the settings. - /// - private Configuration configuration; - - /// - /// Used for governing brightness increasing/decreasing speed. - /// - private int hotkeyRepeatCount; - /// - /// State variable to check if a hotkey is repeatedly pressed. - /// - private int lastHotkeyId = -1; - /// - /// Flag to check if closing to tray or exitting application. - /// - private bool isContextClose = false; - /// - /// State variable to decide to refresh the screen list or not. - /// - private int numberOfScreens = -1; - - // transition effect - /// - /// The total change in brightness track bar value. - /// - private int fadeDistance; - /// - /// The brightness track bar value when enabling the transition timer. - /// - private int fadeOrigin; - /// - /// The current time when enabling the transition timer. - /// - private DateTime fadeStartTime; - #endregion - - #region static members - /// - /// Icon to use in system tray. - /// - public static readonly Icon IconMediumBright = TextIcon.CreateTextIcon("\uE286", Color.White); - /// - /// Main icon. - /// - public static readonly Icon IconMediumBright32x32 = TextIcon.CreateTextIcon("\uE286", Color.White, "", 32); - #endregion - - public partial class Form1 : Form - { - public Form1() - { - //InitializeComponent(); - } - - const int WM_NCHITTEST = 0x0084; - const int HTCLIENT = 1; - const int HTCAPTION = 2; - protected override void WndProc(ref Message m) - { - base.WndProc(ref m); - switch (m.Msg) - { - case WM_NCHITTEST: - if (m.Result == (IntPtr)HTCLIENT) - { - var p = this.PointToClient(new Point(m.LParam.ToInt32())); - - m.Result = - (IntPtr) - (p.X <= 6 - ? p.Y <= 6 ? 13 : p.Y >= this.Height - 7 ? 16 : 10 - : p.X >= this.Width - 7 - ? p.Y <= 6 ? 14 : p.Y >= this.Height - 7 ? 17 : 11 - : p.Y <= 6 ? 12 : p.Y >= this.Height - 7 ? 15 : p.Y <= 24 ? 2 : 1); - } - break; - } - } - } - - public ScreenDimmer() - { - InitializeComponent(); - initOverlayWindow(); - - aboutBox = new AboutBox1(); - helpWindow = new HelpWindow(); - configuration = new Configuration(); - osdWindow = new OsdWindow(); - - // has to be in this order! - populateScreenList(); - loadConfiguration(); - hookKeys(); - - notifyIcon1.Icon = IconMediumBright; - Icon = IconMediumBright32x32; - Text = string.Format("Screen Dimmer {0}", Assembly.GetExecutingAssembly().GetName().Version.ToString()); - } - - /// - /// Initializes the overlay window (no border, click-through, see-through, invisible to Alt+Tab). - /// - private void initOverlayWindow() - { - overlayWindow = new Form1(); - overlayWindow.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - overlayWindow.ShowInTaskbar = false; - overlayWindow.Show(); - overlayWindow.WindowState = FormWindowState.Maximized; - enforceOnTop(); - NativeMethods.SetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE, - // get current GWL_EXSTYLE - NativeMethods.GetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE) - // click-through. Need to be combined with see-through. - // Need to recalled if opacity changed by setting Form.Cpacity. - // Using SetLayeredWindowAttributes will not require to recall this. - | (int)ExtendedWindowStyles.WS_EX_LAYERED - // see-through - | (int)ExtendedWindowStyles.WS_EX_TRANSPARENT - // alt+tab invisible, need to set ShowInTaskbar to false. - | (int)ExtendedWindowStyles.WS_EX_TOOLWINDOW); - //NativeMethods.SetLayeredWindowAttributes(overlayWindow.Handle, 0, 192, - // (int)LayeredWindowAttributeFlags.LWA_ALPHA); - } - - #region hotkey management - /// - /// Tries to register all the global hotkeys. - /// (!) Has to be called after loading configuration (when the hotkeys are defined). - /// - private void hookKeys() - { - StringBuilder sb = new StringBuilder(); - bool success = true; - success &= tryHookKeyAppendError(configuration.HotKeyIncreaseBrightness, ref sb); - success &= tryHookKeyAppendError(configuration.HotKeyDecreaseBrightness, ref sb); - success &= tryHookKeyAppendError(configuration.HotKeyBrighten, ref sb); - success &= tryHookKeyAppendError(configuration.HotKeyDim, ref sb); - success &= tryHookKeyAppendError(configuration.HotKeyForceOnTop, ref sb); - success &= tryHookKeyAppendError(configuration.HotKeyHalt, ref sb); - success &= tryHookKeyAppendError(configuration.HotKeyResize, ref sb); - if (!success) - { - notifyIcon1.ShowBalloonTip(0, "Cannot register one or more hotkeys.", sb.ToString(), ToolTipIcon.Warning); - } - } - - /// - /// Pupulates the hotkeys on to the help window. - /// - private void populateHotkeys() - { - helpWindow.ResetHotkeyPanel(); - helpWindow.AddHotKey(configuration.HotKeyDim); - helpWindow.AddHotKey(configuration.HotKeyBrighten); - helpWindow.AddHotKey(configuration.HotKeyIncreaseBrightness); - helpWindow.AddHotKey(configuration.HotKeyDecreaseBrightness); - helpWindow.AddHotKey(configuration.HotKeyForceOnTop); - helpWindow.AddHotKey(configuration.HotKeyHalt); - helpWindow.AddHotKey(configuration.HotKeyResize); - } - - /// - /// Tries to register one hotkey and handle the error message if there are any. - /// - /// - /// - /// true if successfully register the hotkey - private bool tryHookKeyAppendError(GlobalHotKey hotkey, ref StringBuilder sb) - { - try - { - hotkey.Register(Handle); - return true; - } - catch (Exception e) - { - sb.AppendLine(e.Message); - } - return false; - } - - /// - /// WndProc message listener. - /// - /// - protected override void WndProc(ref Message m) - { - // Listen for operating system messages. - switch (m.Msg) - { - case (int)WindowMessage.WM_HOTKEY: - int hotkeyId = (int)m.WParam; - if (hotkeyId == lastHotkeyId) - { - hotkeyRepeatCount++; - } - else - { - hotkeyRepeatCount = 0; - lastHotkeyId = hotkeyId; - } - //Console.WriteLine("Last {0} | Current {1} | Repeat {2}", lastHotkeyId, hotkeyId, hotkeyRepeatCount); - // Id can change, then cannot use switch case. - if (hotkeyId == configuration.HotKeyIncreaseBrightness.Id) - { - increseBrightness(hotkeyRepeatCount); - } - else if (hotkeyId == configuration.HotKeyDecreaseBrightness.Id) - { - decreaseBrightness(hotkeyRepeatCount); - } - else if (hotkeyId == configuration.HotKeyDim.Id) - { - dim(); - } - else if (hotkeyId == configuration.HotKeyBrighten.Id) - { - brighten(); - } - else if (hotkeyId == configuration.HotKeyForceOnTop.Id) - { - enforceOnTop(); - } - else if (hotkeyId == configuration.HotKeyHalt.Id) - { - isContextClose = true; - Close(); - } - else if (hotkeyId == configuration.HotKeyResize.Id) - { - NativeMethods.SetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE, - NativeMethods.GetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE) - ^ (int)ExtendedWindowStyles.WS_EX_TRANSPARENT); - } - break; - } - base.WndProc(ref m); - } - #endregion - - #region color management - /// - /// Gets and updates the color from the color picker tool. - /// - /// - /// - private void colorToolStripMenuItem_Click(object sender, EventArgs e) - { - colorDialog1.Color = overlayWindow.BackColor; - if (colorDialog1.ShowDialog() == DialogResult.OK) - { - setDimColor(colorDialog1.Color); - } - } - - /// - /// Sets the backcolor of the overlay window and dim button to the desired color. - /// - /// - private void setDimColor(Color color) - { - buttonDim.BackColor = color; - overlayWindow.BackColor = color; - } - - /// - /// Gets the current color of the overlay window. - /// - /// - private Color getDimColor() { - return overlayWindow.BackColor; - } - #endregion - - #region brightness management - private void checkBoxZeroBrightness_CheckedChanged(object sender, EventArgs e) - { - setTrackBarBrightnessMinimum(checkBoxZeroBrightness.Checked ? 0 : 20); - } - - /// - /// Sets the minimum for the brightness track bar. - /// If the current track bar value is smaller than the desired value, - /// it will be set to the desired value as well. - /// Note that the case that the desired value is larger than maximum value is not handled here! - /// - /// - private void setTrackBarBrightnessMinimum(int minimum) - { - if (trackBarBrightness.Value < minimum) - { - trackBarBrightness.Value = minimum; - } - trackBarBrightness.Minimum = minimum; - } - - /// - /// Updates the ovelay opacity level according to current brightness track bar value. - /// - /// - private void setBrightness(int brightness) - { - toolTipHint.SetToolTip(trackBarBrightness, string.Format("{0}%", brightness)); - NativeMethods.SetLayeredWindowAttributes(overlayWindow.Handle, 0, (byte)(255 - (brightness / 100f) * 255), - (int)LayeredWindowAttributeFlags.LWA_ALPHA); - } - - /// - /// Increases brightness track bar value. - /// - private void increseBrightness(int speed) - { - if (trackBarBrightness.Value == trackBarBrightness.Maximum) - { - return; - } - - int modifiedSpeed = speed / 3 + 1; - if (trackBarBrightness.Value+modifiedSpeed >= trackBarBrightness.Maximum) - { - trackBarBrightness.Value = trackBarBrightness.Maximum; - } else { - trackBarBrightness.Value += modifiedSpeed; - } - } - - /// - /// Decreases brightness track bar value. - /// - private void decreaseBrightness(int speed) - { - if (trackBarBrightness.Value == trackBarBrightness.Minimum) - { - return; - } - - int modifiedSpeed = speed / 3 + 1; - if (trackBarBrightness.Value - modifiedSpeed <= trackBarBrightness.Minimum) - { - trackBarBrightness.Value = trackBarBrightness.Minimum; - } - else - { - trackBarBrightness.Value -= modifiedSpeed; - } - } - - /// - /// Dims the screen to minimum brightness. - /// - private void dim() - { - if (checkBoxAllowTransition.Checked) - { - fade(trackBarBrightness.Minimum); - } - else - { - trackBarBrightness.Value = trackBarBrightness.Minimum; - } - } - - /// - /// Brightens the sceen to maximum brightness. - /// - private void brighten() - { - if (checkBoxAllowTransition.Checked) - { - fade(trackBarBrightness.Maximum); - } - else - { - trackBarBrightness.Value = trackBarBrightness.Maximum; - } - } - - /// - /// Initializes state variables for transition effect. - /// - /// - private void fade(int target) - { - - fadeDistance = target - trackBarBrightness.Value; - if (fadeDistance == 0) - { - return; - } - fadeOrigin = trackBarBrightness.Value; - timerFade.Enabled = true; - fadeStartTime = DateTime.Now; - } - - /// - /// Interpolates brightness in real time to ensure the transition happens in the period defined in configuration.FadeDuration. - /// - /// - /// - private void timerFade_Tick(object sender, EventArgs e) - { - TimeSpan currentTime = DateTime.Now - fadeStartTime; - double target1 = (currentTime.TotalMilliseconds * fadeDistance / configuration.FadeDuration); - int target = (int)(fadeOrigin + target1); - if ((target >= trackBarBrightness.Maximum) && (fadeDistance > 0)) - { - trackBarBrightness.Value = trackBarBrightness.Maximum; - timerFade.Enabled = false; - } - else if ((target <= trackBarBrightness.Minimum) && (fadeDistance < 0)) - { - trackBarBrightness.Value = trackBarBrightness.Minimum; - timerFade.Enabled = false; - } - else - { - trackBarBrightness.Value = target; - } - //Console.WriteLine("{0} Current {1} | Different {3} | Target {2}:{5}| Total Distance {4}", - // currentTime.TotalMilliseconds, 0, target, target1, fadeDistance, 0 + target1); - } - - private void buttonDim_Click(object sender, EventArgs e) - { - dim(); - } - - private void buttonBright_Click(object sender, EventArgs e) - { - brighten(); - } - - private void trackBarBrightness_ValueChanged(object sender, EventArgs e) - { - setBrightness(((TrackBar)sender).Value); - if (!Visible) - { - osdWindow.Display(((TrackBar)sender).Value.ToString() + "%", new Font("Segeo UI", 32), Color.Black, Color.White, 20, 20, 255, 100, 1000, 1000); - } - } - #endregion - - #region screen management - /// - /// Sets the size and position of the form to cover the desired screen. - /// Does nothing if the desired screen index is invalid. - /// - /// - /// - private void setScreen(Form form, int screenIndex) - { - if (Screen.AllScreens.Length - 1 < screenIndex) - { - return; // invalid index - } - FormWindowState currentState = form.WindowState; - if (currentState != FormWindowState.Normal) - { - form.WindowState = FormWindowState.Normal; - } - form.Location = Screen.AllScreens[screenIndex].WorkingArea.Location; - form.WindowState = currentState; - } - - /// - /// Pupulates the sceen list into the combo box. - /// - private void populateScreenList() - { - Screen[] screens = Screen.AllScreens; - if (numberOfScreens != screens.Length) - { - numberOfScreens = screens.Length; - List screensNames = new List(); - foreach (Screen item in screens) - { - screensNames.Add(item.DeviceName); - } - int currentSelected = comboBoxScreens.SelectedIndex; - comboBoxScreens.Items.Clear(); - comboBoxScreens.Items.AddRange(screensNames.ToArray()); - if (currentSelected < numberOfScreens) - { - comboBoxScreens.SelectedIndex = currentSelected; - } - else - { - comboBoxScreens.SelectedIndex = 0; - } - } - } - - private void comboBoxScreens_SelectedIndexChanged(object sender, EventArgs e) - { - setScreen(overlayWindow, ((ComboBox)sender).SelectedIndex); - } - - private void comboBoxScreens_DropDown(object sender, EventArgs e) - { - populateScreenList(); - } - #endregion - - #region configuration management - private void saveConfiguration() - { - uiToConfig(); - configuration.SaveToFile(confFile); - } - - /// - /// (!) Has to be called after initializing all UI components. - /// - private void loadConfiguration() - { - try - { - configuration = Configuration.LoadFromFile(confFile); - } - catch (Exception) - { - configuration.LoadDefault(); - } - configToUi(); - } - - private void uiToConfig() - { - configuration.CurrentBrightness = (byte) trackBarBrightness.Value; - configuration.DimColor = getDimColor(); - configuration.EnforcingPeriod = (int) numericUpDown1.Value; - configuration.IsDebug = checkBoxDebug.Checked; - configuration.IsEnforceOnTop = checkBoxEnforceOnTop.Checked; - configuration.IsTransition = checkBoxAllowTransition.Checked; - configuration.IsZeroBrightness = checkBoxZeroBrightness.Checked; - configuration.MonitorIndex = (byte) comboBoxScreens.SelectedIndex; - } - - private void configToUi() - { - if (configuration.CurrentBrightness < trackBarBrightness.Minimum) - { - trackBarBrightness.Value = trackBarBrightness.Minimum; - } - else if (configuration.CurrentBrightness > trackBarBrightness.Maximum) - { - trackBarBrightness.Value = trackBarBrightness.Maximum; - } - else - { - trackBarBrightness.Value = configuration.CurrentBrightness; - } - - if (configuration.EnforcingPeriod < numericUpDown1.Minimum) - { - numericUpDown1.Value = numericUpDown1.Minimum; - } - else if (configuration.CurrentBrightness > trackBarBrightness.Maximum) - { - numericUpDown1.Value = numericUpDown1.Maximum; - } - else - { - numericUpDown1.Value = configuration.EnforcingPeriod; - } - - if (comboBoxScreens.Items.Count > configuration.MonitorIndex) - { - comboBoxScreens.SelectedIndex = configuration.MonitorIndex; - } - else - { - comboBoxScreens.SelectedIndex = 0; - } - - setDimColor(configuration.DimColor); - checkBoxEnforceOnTop.Checked = configuration.IsEnforceOnTop; - checkBoxZeroBrightness.Checked = configuration.IsZeroBrightness; - checkBoxDebug.Checked = configuration.IsDebug; - checkBoxAllowTransition.Checked = configuration.IsTransition; - } - #endregion - - #region other UI callbacks - private void labelExpandCollapse_Click(object sender, EventArgs e) - { - toggleAdvancedSettings(); - } - - private void toggleAdvancedSettings() - { - tableLayoutPanel3.Visible = !tableLayoutPanel3.Visible; - if (tableLayoutPanel3.Visible) - { - labelExpandCollapse.Text = "◁"; - toolTipHint.SetToolTip(labelExpandCollapse, "Less"); - } - else - { - labelExpandCollapse.Text = "▷"; - toolTipHint.SetToolTip(labelExpandCollapse, "More..."); - } - } - - private void timerEnforceOnTop_Tick(object sender, EventArgs e) - { - enforceOnTop(); - } - - /// - /// Forces the application to top most. - /// - private void enforceOnTop() - { - overlayWindow.TopMost = true; // overlay window is set to top most - TopMost = true; // main form has to be on top of overlay window - } - - /// - /// Updates the interval of enforcing-on-top timer. - /// - /// - /// - private void numericUpDown1_ValueChanged(object sender, EventArgs e) - { - timerEnforceOnTop.Interval = (int)(((NumericUpDown)sender).Value * 1000); - } - - /// - /// Starts/stops enforcing-on-top timer. - /// - /// - /// - private void checkBoxEnforceOnTop_CheckedChanged(object sender, EventArgs e) - { - bool isEnabled = ((CheckBox)sender).Checked; - numericUpDown1.Enabled = isEnabled; - label1.Enabled = isEnabled; - if (isEnabled) - { - timerEnforceOnTop.Start(); - } - else - { - timerEnforceOnTop.Stop(); - } - } - - private void labelAbout_Click(object sender, EventArgs e) - { - aboutBox.TopMost = true; - aboutBox.ShowDialog(); - } - - private void labelHelp_Click(object sender, EventArgs e) - { - populateHotkeys(); - helpWindow.TopMost = true; - helpWindow.ShowDialog(); - } - - private void labelBug_Click(object sender, System.EventArgs e) - { - //TODO - } - - private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) - { - Show(); - } - - private void controlPanelToolStripMenuItem_Click(object sender, EventArgs e) - { - this.Show(); - } - - private void screenDimmer_FormClosing(object sender, FormClosingEventArgs e) - { - saveConfiguration(); - if (e.CloseReason == CloseReason.WindowsShutDown) - { - return; - } - if (!isContextClose) - { - this.Hide(); - e.Cancel = true; - } - } - - private void exitToolStripMenuItem_Click(object sender, EventArgs e) - { - isContextClose = true; - notifyIcon1.Dispose(); - Close(); - } - #endregion - } -} From a63acd9ae1519ce18bbc06cf86e01f1f690a9db1 Mon Sep 17 00:00:00 2001 From: MustSave <58774251+MustSave@users.noreply.github.com> Date: Thu, 10 Feb 2022 00:57:32 +0900 Subject: [PATCH 3/5] Delete Configuration.cs --- Configuration.cs | 172 ----------------------------------------------- 1 file changed, 172 deletions(-) delete mode 100644 Configuration.cs diff --git a/Configuration.cs b/Configuration.cs deleted file mode 100644 index 069bd99..0000000 --- a/Configuration.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace Augustine.ScreenDimmer -{ - [DataContract] - internal class Configuration - { - [DataMember(Name = "AllowZeroBrightness")] - internal bool IsZeroBrightness; - [DataMember(Name = "EnforceOnTop")] - internal bool IsEnforceOnTop; - [DataMember(Name = "DebuggingMode")] - internal bool IsDebug; - [DataMember(Name = "AllowTransition")] - internal bool IsTransition; - [DataMember(Name = "MonitorIndex")] - internal byte MonitorIndex; - /// - /// Range: 0-100 - /// - [DataMember(Name = "CurrentBrightness")] - internal byte CurrentBrightness; - [DataMember(Name = "MinimumNonzeroBrightness")] - internal readonly byte MinimumNonZeroBrightness = 20; - [DataMember(Name = "EnforcingPeriod")] - internal int EnforcingPeriod; - [DataMember(Name = "TransitionDuration")] - internal double FadeDuration; - [DataMember(Name = "Color")] - internal Color DimColor = Color.Black; - - [DataMember(Name = "HotkeyDim")] - private string hotKeyDim { - get { return HotKeyDim.ToString(); } - set { HotKeyDim = GlobalHotkeyParser.Parse(value); } } - internal GlobalHotKey HotKeyDim; - - [DataMember(Name = "HotkeyBrighten")] - private string hotKeyBright { - get { return HotKeyBrighten.ToString(); } - set { HotKeyBrighten = GlobalHotkeyParser.Parse(value); } } - internal GlobalHotKey HotKeyBrighten; - - [DataMember(Name = "HotkeyDecreaseBrightness")] - private string hotKeyDecreaseBrightness { - get { return HotKeyDecreaseBrightness.ToString(); } - set { HotKeyDecreaseBrightness = GlobalHotkeyParser.Parse(value); } } - internal GlobalHotKey HotKeyDecreaseBrightness; - - [DataMember(Name = "HotkeyIncreaseBrightness")] - private string hotKeyIncreaseBrightness { - get { return HotKeyIncreaseBrightness.ToString(); } - set { HotKeyIncreaseBrightness = GlobalHotkeyParser.Parse(value); } } - internal GlobalHotKey HotKeyIncreaseBrightness; - - [DataMember(Name = "HotkeyForceOnTop")] - private string hotKeyForceOnTop { - get { return HotKeyForceOnTop.ToString(); } - set { HotKeyForceOnTop = GlobalHotkeyParser.Parse(value); } } - internal GlobalHotKey HotKeyForceOnTop; - - [DataMember(Name = "HotkeyHalt")] - private string hotKeyHalt { - get { return HotKeyHalt.ToString(); } - set { HotKeyHalt = GlobalHotkeyParser.Parse(value); } } - internal GlobalHotKey HotKeyHalt; - - [DataMember(Name = "HotkeyResize")] - private string hotKeyResize - { - get { return HotKeyResize.ToString(); } - set { HotKeyResize = GlobalHotkeyParser.Parse(value); } - } - internal GlobalHotKey HotKeyResize; - - internal Configuration() - { - HotKeyDim = new GlobalHotKey(); - HotKeyBrighten = new GlobalHotKey(); - HotKeyIncreaseBrightness = new GlobalHotKey(); - HotKeyDecreaseBrightness = new GlobalHotKey(); - HotKeyForceOnTop = new GlobalHotKey(); - HotKeyHalt = new GlobalHotKey(); - HotKeyResize = new GlobalHotKey(); - } - - private void setHotkeyDescriptions() - { - HotKeyDim.SetDescription("Dim (minimum brightness)"); - HotKeyBrighten.SetDescription("Brighten (maximum brightness)"); - HotKeyIncreaseBrightness.SetDescription("Increase Brightness"); - HotKeyDecreaseBrightness.SetDescription("Decrease Brightness"); - HotKeyForceOnTop.SetDescription("Force on Top"); - HotKeyHalt.SetDescription("Immediately Halt Program"); - HotKeyResize.SetDescription("Adjust Window Size"); - } - - internal void LoadDefault() - { - MonitorIndex = 0; - CurrentBrightness = 70; - IsZeroBrightness = true; - IsEnforceOnTop = false; - IsDebug = false; - IsTransition = true; - EnforcingPeriod = 30; - FadeDuration = 250; - HotKeyDim.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Left); - HotKeyBrighten.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Right); - HotKeyDecreaseBrightness.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Down); - HotKeyIncreaseBrightness.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Up); - HotKeyForceOnTop.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.T); - HotKeyHalt.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.H); - HotKeyResize.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.B); - setHotkeyDescriptions(); - } - - internal static Configuration LoadFromFile(string fileName) - { - Configuration deserialized; - try - { - deserialized = Serializer.DeSerializeObject(fileName); - } - catch (Exception ex) - { - throw new Exception("Cannot parse configuration from file.", ex); - } - deserialized.setHotkeyDescriptions(); - // For the purpose of robustness. Non-positive fade duration will cause trouble. - if (deserialized.FadeDuration < 1) - { - deserialized.FadeDuration = 250; - } - return deserialized; - //this.CurrentBrightness = deserialized.CurrentBrightness; - //this.DimColor = deserialized.DimColor; - //this.EnforcingPeriod = deserialized.EnforcingPeriod; - //this.IsDebug = deserialized.IsDebug; - //this.IsEnforceOnTop = deserialized.IsEnforceOnTop; - //this.IsTransition = deserialized.IsTransition; - //this.IsZeroBrightness = deserialized.IsZeroBrightness; - ////this.MinimumNonZeroBrightness = deserialized.MinimumNonZeroBrightness; - //this.MonitorIndex = deserialized.MonitorIndex; - //this.HotKeyBright = deserialized.HotKeyBright; - //this.HotKeyDecreaseBrightness = deserialized.HotKeyBright; - //this.HotKeyDim = deserialized.HotKeyDim; - //this.HotKeyForceOnTop = deserialized.HotKeyForceOnTop; - //this.HotKeyHalt = deserialized.HotKeyHalt; - //this.HotKeyIncreaseBrightness = deserialized.HotKeyIncreaseBrightness; - } - - internal void SaveToFile(string fileName) - { - try - { - Serializer.SerializeObject(this, fileName); - } - catch (Exception ex) - { - throw new Exception("Cannot save current configuration to file.", ex); - } - } - - } -} From cd6c22d22e03b51549050155da2277daca4470ec Mon Sep 17 00:00:00 2001 From: MustSave <58774251+MustSave@users.noreply.github.com> Date: Thu, 10 Feb 2022 01:00:20 +0900 Subject: [PATCH 4/5] Resizable Window --- ScreenDimmer/Configuration.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ScreenDimmer/Configuration.cs b/ScreenDimmer/Configuration.cs index fc75e18..069bd99 100644 --- a/ScreenDimmer/Configuration.cs +++ b/ScreenDimmer/Configuration.cs @@ -71,6 +71,14 @@ private string hotKeyHalt { set { HotKeyHalt = GlobalHotkeyParser.Parse(value); } } internal GlobalHotKey HotKeyHalt; + [DataMember(Name = "HotkeyResize")] + private string hotKeyResize + { + get { return HotKeyResize.ToString(); } + set { HotKeyResize = GlobalHotkeyParser.Parse(value); } + } + internal GlobalHotKey HotKeyResize; + internal Configuration() { HotKeyDim = new GlobalHotKey(); @@ -79,6 +87,7 @@ internal Configuration() HotKeyDecreaseBrightness = new GlobalHotKey(); HotKeyForceOnTop = new GlobalHotKey(); HotKeyHalt = new GlobalHotKey(); + HotKeyResize = new GlobalHotKey(); } private void setHotkeyDescriptions() @@ -89,6 +98,7 @@ private void setHotkeyDescriptions() HotKeyDecreaseBrightness.SetDescription("Decrease Brightness"); HotKeyForceOnTop.SetDescription("Force on Top"); HotKeyHalt.SetDescription("Immediately Halt Program"); + HotKeyResize.SetDescription("Adjust Window Size"); } internal void LoadDefault() @@ -107,6 +117,7 @@ internal void LoadDefault() HotKeyIncreaseBrightness.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.Up); HotKeyForceOnTop.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.T); HotKeyHalt.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.H); + HotKeyResize.SetKey(KeyModifiers.MOD_WIN | KeyModifiers.MOD_CONTROL, System.Windows.Forms.Keys.B); setHotkeyDescriptions(); } From 85f9402b3e14598150d4ffc4d9e7aeb8ed5ab346 Mon Sep 17 00:00:00 2001 From: MustSave <58774251+MustSave@users.noreply.github.com> Date: Thu, 10 Feb 2022 01:01:17 +0900 Subject: [PATCH 5/5] Resizable Window --- ScreenDimmer/ScreenDimmer.cs | 43 +++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/ScreenDimmer/ScreenDimmer.cs b/ScreenDimmer/ScreenDimmer.cs index 3fed4cf..a8a3a62 100644 --- a/ScreenDimmer/ScreenDimmer.cs +++ b/ScreenDimmer/ScreenDimmer.cs @@ -87,6 +87,39 @@ internal partial class ScreenDimmer : Form public static readonly Icon IconMediumBright32x32 = TextIcon.CreateTextIcon("\uE286", Color.White, "", 32); #endregion + public partial class Form1 : Form + { + public Form1() + { + //InitializeComponent(); + } + + const int WM_NCHITTEST = 0x0084; + const int HTCLIENT = 1; + const int HTCAPTION = 2; + protected override void WndProc(ref Message m) + { + base.WndProc(ref m); + switch (m.Msg) + { + case WM_NCHITTEST: + if (m.Result == (IntPtr)HTCLIENT) + { + var p = this.PointToClient(new Point(m.LParam.ToInt32())); + + m.Result = + (IntPtr) + (p.X <= 6 + ? p.Y <= 6 ? 13 : p.Y >= this.Height - 7 ? 16 : 10 + : p.X >= this.Width - 7 + ? p.Y <= 6 ? 14 : p.Y >= this.Height - 7 ? 17 : 11 + : p.Y <= 6 ? 12 : p.Y >= this.Height - 7 ? 15 : p.Y <= 24 ? 2 : 1); + } + break; + } + } + } + public ScreenDimmer() { InitializeComponent(); @@ -112,7 +145,7 @@ public ScreenDimmer() /// private void initOverlayWindow() { - overlayWindow = new Form(); + overlayWindow = new Form1(); overlayWindow.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; overlayWindow.ShowInTaskbar = false; overlayWindow.Show(); @@ -148,6 +181,7 @@ private void hookKeys() success &= tryHookKeyAppendError(configuration.HotKeyDim, ref sb); success &= tryHookKeyAppendError(configuration.HotKeyForceOnTop, ref sb); success &= tryHookKeyAppendError(configuration.HotKeyHalt, ref sb); + success &= tryHookKeyAppendError(configuration.HotKeyResize, ref sb); if (!success) { notifyIcon1.ShowBalloonTip(0, "Cannot register one or more hotkeys.", sb.ToString(), ToolTipIcon.Warning); @@ -166,6 +200,7 @@ private void populateHotkeys() helpWindow.AddHotKey(configuration.HotKeyDecreaseBrightness); helpWindow.AddHotKey(configuration.HotKeyForceOnTop); helpWindow.AddHotKey(configuration.HotKeyHalt); + helpWindow.AddHotKey(configuration.HotKeyResize); } /// @@ -235,6 +270,12 @@ protected override void WndProc(ref Message m) isContextClose = true; Close(); } + else if (hotkeyId == configuration.HotKeyResize.Id) + { + NativeMethods.SetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE, + NativeMethods.GetWindowLong(overlayWindow.Handle, NativeMethods.GWL_EXSTYLE) + ^ (int)ExtendedWindowStyles.WS_EX_TRANSPARENT); + } break; } base.WndProc(ref m);