From 6e4fb21bc760c8e05a9734ced1bf58e9ff65e357 Mon Sep 17 00:00:00 2001
From: Sparronator9999 <86388887+Sparronator9999@users.noreply.github.com>
Date: Wed, 5 Feb 2025 08:22:41 +1100
Subject: [PATCH] YAMDCC hotkey handler: initial version
Currently the only hotkey supported is the MSI Center key (which opens the YAMDCC config editor by default, and will be configurable).
Please test and report if the MSI Center key isn't working with Hotkey Handler.
---
YAMDCC.HotkeyHandler/App.config | 10 +
YAMDCC.HotkeyHandler/KeyHook.cs | 160 ++++
YAMDCC.HotkeyHandler/KeyHookEventArgs.cs | 40 +
YAMDCC.HotkeyHandler/MainForm.Designer.cs | 719 ++++++++++++++++++
YAMDCC.HotkeyHandler/MainForm.cs | 114 +++
YAMDCC.HotkeyHandler/MainForm.resx | 225 ++++++
YAMDCC.HotkeyHandler/Program.cs | 18 +
YAMDCC.HotkeyHandler/Win32/User32.cs | 41 +
.../YAMDCC.HotkeyHandler.csproj | 28 +
YAMDCC.HotkeyHandler/app.manifest | 1 +
YAMDCC.HotkeyHandler/hkey.ico | Bin 0 -> 7801 bytes
YAMDCC.sln | 6 +
12 files changed, 1362 insertions(+)
create mode 100644 YAMDCC.HotkeyHandler/App.config
create mode 100644 YAMDCC.HotkeyHandler/KeyHook.cs
create mode 100644 YAMDCC.HotkeyHandler/KeyHookEventArgs.cs
create mode 100644 YAMDCC.HotkeyHandler/MainForm.Designer.cs
create mode 100644 YAMDCC.HotkeyHandler/MainForm.cs
create mode 100644 YAMDCC.HotkeyHandler/MainForm.resx
create mode 100644 YAMDCC.HotkeyHandler/Program.cs
create mode 100644 YAMDCC.HotkeyHandler/Win32/User32.cs
create mode 100644 YAMDCC.HotkeyHandler/YAMDCC.HotkeyHandler.csproj
create mode 100644 YAMDCC.HotkeyHandler/app.manifest
create mode 100644 YAMDCC.HotkeyHandler/hkey.ico
diff --git a/YAMDCC.HotkeyHandler/App.config b/YAMDCC.HotkeyHandler/App.config
new file mode 100644
index 0000000..c7373b8
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/App.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/YAMDCC.HotkeyHandler/KeyHook.cs b/YAMDCC.HotkeyHandler/KeyHook.cs
new file mode 100644
index 0000000..1693a89
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/KeyHook.cs
@@ -0,0 +1,160 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+using YAMDCC.HotkeyHandler.Win32;
+
+namespace YAMDCC.HotkeyHandler;
+
+internal class KeyHook : IDisposable
+{
+ private readonly HookProc KbdHookProc;
+ private IntPtr KbdHookPtr;
+
+ ///
+ /// Used to determine if we should raise the
+ /// event when is .
+ ///
+ private readonly HashSet HeldKeys = [];
+
+ ///
+ /// Gets or sets whether to raise events when
+ /// a key press is automatically repeated due to the key being held down.
+ ///
+ public bool IgnoreRepeats { get; set; }
+
+ ///
+ /// Gets or sets whether to raise or
+ /// events when a modifier key (Ctrl, Shift, or Alt) is pressed.
+ ///
+ public bool IgnoreModifiers { get; set; }
+
+ ///
+ /// Gets the currently held modifier keys.
+ ///
+ public ConsoleModifiers Modifiers { get; private set; }
+
+ ///
+ /// Occurs when a key is pressed.
+ ///
+ public event EventHandler KeyDown;
+
+ ///
+ /// Occurs when a key is released.
+ ///
+ public event EventHandler KeyUp;
+
+ public KeyHook(bool ignoreRepeats = true, bool ignoreModifiers = false)
+ {
+ KbdHookProc = new HookProc(HookProcCallback);
+ IgnoreRepeats = ignoreRepeats;
+ IgnoreModifiers = ignoreModifiers;
+ }
+
+ ///
+ /// Uninstalls the keyboard hook and releases all unmanaged
+ /// resources associated with this instance.
+ ///
+ public void Dispose()
+ {
+ Uninstall();
+ GC.SuppressFinalize(this);
+ }
+
+ ~KeyHook()
+ {
+ Uninstall();
+ }
+
+ public bool Install()
+ {
+ if (KbdHookPtr == IntPtr.Zero)
+ {
+ KbdHookPtr = User32.SetWindowsHookEx(13, KbdHookProc,
+ Marshal.GetHINSTANCE(typeof(KeyHook).Module), 0);
+ return KbdHookPtr != IntPtr.Zero;
+ }
+ // keyboard hook already installed
+ return true;
+ }
+
+ public bool Uninstall()
+ {
+ // uninstall keyboard hook if installed (KbdHookPtr != IntPtr.Zero),
+ // otherwise just return true
+ return KbdHookPtr == IntPtr.Zero || User32.UnhookWindowsHookEx(KbdHookPtr);
+ }
+
+ private IntPtr HookProcCallback(int nCode, IntPtr wParam, IntPtr lParam)
+ {
+ if (nCode >= 0 && wParam.ToInt32() is 0x100 or 0x101 or 0x104 or 0x105)
+ {
+ KbdLLHookStruct kbdStruct = Marshal.PtrToStructure(lParam);
+ KeyHookEventArgs e = new(
+ kbdStruct.KeyCode,
+ kbdStruct.ScanCode,
+ (kbdStruct.Flags & 0x01) == 1,
+ (kbdStruct.Flags & 0x02) == 1,
+ (kbdStruct.Flags & 0x10) == 1);
+
+ switch (wParam.ToInt32())
+ {
+ case 0x100: // WM_KEYDOWN
+ case 0x104: // WM_SYSKEYDOWN
+ if (HandleModifiers(e.KeyCode, true) &&
+ (!IgnoreRepeats || !HeldKeys.Contains(e.ScanCode)))
+ {
+ KeyDown?.Invoke(this, e);
+ }
+ HeldKeys.Add(e.ScanCode);
+ break;
+ case 0x101: // WM_KEYUP
+ case 0x105: // WM_SYSKEYUP
+ if (HandleModifiers(e.KeyCode, false))
+ {
+ KeyUp?.Invoke(this, e);
+ }
+ HeldKeys.Remove(e.ScanCode);
+ break;
+ }
+
+ if (e.SuppressKeyPress)
+ {
+ return new IntPtr(1);
+ }
+ }
+ return User32.CallNextHookEx(KbdHookPtr, nCode, wParam, lParam);
+ }
+
+ private bool HandleModifiers(Keys key, bool pressed)
+ {
+ ConsoleModifiers modifier;
+ switch (key)
+ {
+ case Keys.LMenu:
+ case Keys.RMenu:
+ modifier = ConsoleModifiers.Alt;
+ break;
+ case Keys.LShiftKey:
+ case Keys.RShiftKey:
+ modifier = ConsoleModifiers.Shift;
+ break;
+ case Keys.LControlKey:
+ case Keys.RControlKey:
+ modifier = ConsoleModifiers.Control;
+ break;
+ default:
+ return true;
+ }
+
+ if (pressed)
+ {
+ Modifiers |= modifier;
+ }
+ else
+ {
+ Modifiers &= ~modifier;
+ }
+ return !IgnoreModifiers;
+ }
+}
diff --git a/YAMDCC.HotkeyHandler/KeyHookEventArgs.cs b/YAMDCC.HotkeyHandler/KeyHookEventArgs.cs
new file mode 100644
index 0000000..d62c898
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/KeyHookEventArgs.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Windows.Forms;
+
+namespace YAMDCC.HotkeyHandler;
+
+internal class KeyHookEventArgs : EventArgs
+{
+ public Keys KeyCode { get; }
+ public uint ScanCode { get; }
+ public bool ExtendedKey { get; }
+ public bool LowerILInjected { get; }
+ public bool Injected { get; }
+
+ ///
+ /// Gets or sets a value indicating whether the
+ /// key event should be sent to other applications.
+ ///
+ ///
+ /// if the key event should not be sent
+ /// to other applications, otherwise .
+ ///
+ public bool SuppressKeyPress { get; set; }
+
+ ///
+ /// Initialises a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public KeyHookEventArgs(Keys keyCode, uint scanCode, bool extendedKey, bool lowerILInjected, bool injected)
+ {
+ KeyCode = keyCode;
+ ScanCode = scanCode;
+ ExtendedKey = extendedKey;
+ LowerILInjected = lowerILInjected;
+ Injected = injected;
+ }
+}
diff --git a/YAMDCC.HotkeyHandler/MainForm.Designer.cs b/YAMDCC.HotkeyHandler/MainForm.Designer.cs
new file mode 100644
index 0000000..a793d93
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/MainForm.Designer.cs
@@ -0,0 +1,719 @@
+namespace YAMDCC.HotkeyHandler
+{
+ partial class MainForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.Windows.Forms.MenuStrip menuStrip;
+ System.Windows.Forms.ToolStripMenuItem tsiFile;
+ System.Windows.Forms.ToolStripMenuItem tsiExit;
+ System.Windows.Forms.ToolStripMenuItem tsiOptions;
+ System.Windows.Forms.ToolStripMenuItem tsiEnabled;
+ System.Windows.Forms.ToolStripMenuItem tsiAppBtn;
+ System.Windows.Forms.ToolStripMenuItem tsiAppBtnAction;
+ System.Windows.Forms.ToolStripSeparator sep3;
+ System.Windows.Forms.ToolStripSeparator sep1;
+ System.Windows.Forms.ToolStripMenuItem tsiSysStart;
+ System.Windows.Forms.ToolStripMenuItem tsiHelp;
+ System.Windows.Forms.ToolStripMenuItem tsiAbout;
+ System.Windows.Forms.ToolStripMenuItem tsiSource;
+ System.Windows.Forms.Label label1;
+ System.Windows.Forms.Label label2;
+ System.Windows.Forms.ContextMenuStrip TrayMenu;
+ System.Windows.Forms.ToolStripMenuItem tsiTrayAbout;
+ System.Windows.Forms.ToolStripSeparator sep2;
+ System.Windows.Forms.ToolStripMenuItem tsiTrayExit;
+ System.Windows.Forms.Label lblKeyLightUp;
+ System.Windows.Forms.Label lblConfEditor;
+ System.Windows.Forms.Label lblWinFn;
+ System.Windows.Forms.Label lblFullBlast;
+ System.Windows.Forms.Label lblKeyLightDown;
+ System.Windows.Forms.Button btnProf1Clear;
+ System.Windows.Forms.Button btnProf2Clear;
+ System.Windows.Forms.Button btnProf3Clear;
+ System.Windows.Forms.Button btnConfEditorClear;
+ System.Windows.Forms.Button btnFullBlastClear;
+ System.Windows.Forms.Button btnWinFnClear;
+ System.Windows.Forms.Button btnKeyLightUpClear;
+ System.Windows.Forms.Button btnKeyLightDownClear;
+ this.tsiAppBtnDisabled = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsiAppBtnConfEditor = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsiAppBtnDefaultDisable = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsiTrayMin = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsiTrayClose = new System.Windows.Forms.ToolStripMenuItem();
+ this.TrayIcon = new System.Windows.Forms.NotifyIcon(this.components);
+ this.tcHotkeys = new System.Windows.Forms.TabControl();
+ this.tabGeneral = new System.Windows.Forms.TabPage();
+ this.tblGeneral = new System.Windows.Forms.TableLayoutPanel();
+ this.txtKeyLightDown = new System.Windows.Forms.TextBox();
+ this.txtKeyLightUp = new System.Windows.Forms.TextBox();
+ this.txtConfEditor = new System.Windows.Forms.TextBox();
+ this.txtFullBlast = new System.Windows.Forms.TextBox();
+ this.txtWinFn = new System.Windows.Forms.TextBox();
+ this.tabFanProfs = new System.Windows.Forms.TabPage();
+ this.tblFanProfs = new System.Windows.Forms.TableLayoutPanel();
+ this.txtProf1 = new System.Windows.Forms.TextBox();
+ this.txtProf2 = new System.Windows.Forms.TextBox();
+ this.txtProf3 = new System.Windows.Forms.TextBox();
+ this.lblProf1 = new System.Windows.Forms.Label();
+ this.lblProf3 = new System.Windows.Forms.Label();
+ this.lblProf2 = new System.Windows.Forms.Label();
+ menuStrip = new System.Windows.Forms.MenuStrip();
+ tsiFile = new System.Windows.Forms.ToolStripMenuItem();
+ tsiExit = new System.Windows.Forms.ToolStripMenuItem();
+ tsiOptions = new System.Windows.Forms.ToolStripMenuItem();
+ tsiEnabled = new System.Windows.Forms.ToolStripMenuItem();
+ tsiAppBtn = new System.Windows.Forms.ToolStripMenuItem();
+ tsiAppBtnAction = new System.Windows.Forms.ToolStripMenuItem();
+ sep3 = new System.Windows.Forms.ToolStripSeparator();
+ sep1 = new System.Windows.Forms.ToolStripSeparator();
+ tsiSysStart = new System.Windows.Forms.ToolStripMenuItem();
+ tsiHelp = new System.Windows.Forms.ToolStripMenuItem();
+ tsiAbout = new System.Windows.Forms.ToolStripMenuItem();
+ tsiSource = new System.Windows.Forms.ToolStripMenuItem();
+ label1 = new System.Windows.Forms.Label();
+ label2 = new System.Windows.Forms.Label();
+ TrayMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ tsiTrayAbout = new System.Windows.Forms.ToolStripMenuItem();
+ sep2 = new System.Windows.Forms.ToolStripSeparator();
+ tsiTrayExit = new System.Windows.Forms.ToolStripMenuItem();
+ lblKeyLightUp = new System.Windows.Forms.Label();
+ lblConfEditor = new System.Windows.Forms.Label();
+ lblWinFn = new System.Windows.Forms.Label();
+ lblFullBlast = new System.Windows.Forms.Label();
+ lblKeyLightDown = new System.Windows.Forms.Label();
+ btnProf1Clear = new System.Windows.Forms.Button();
+ btnProf2Clear = new System.Windows.Forms.Button();
+ btnProf3Clear = new System.Windows.Forms.Button();
+ btnConfEditorClear = new System.Windows.Forms.Button();
+ btnFullBlastClear = new System.Windows.Forms.Button();
+ btnWinFnClear = new System.Windows.Forms.Button();
+ btnKeyLightUpClear = new System.Windows.Forms.Button();
+ btnKeyLightDownClear = new System.Windows.Forms.Button();
+ menuStrip.SuspendLayout();
+ TrayMenu.SuspendLayout();
+ this.tcHotkeys.SuspendLayout();
+ this.tabGeneral.SuspendLayout();
+ this.tblGeneral.SuspendLayout();
+ this.tabFanProfs.SuspendLayout();
+ this.tblFanProfs.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // menuStrip
+ //
+ menuStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
+ menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ tsiFile,
+ tsiOptions,
+ tsiHelp});
+ menuStrip.Location = new System.Drawing.Point(0, 0);
+ menuStrip.Name = "menuStrip";
+ menuStrip.Padding = new System.Windows.Forms.Padding(5, 2, 0, 2);
+ menuStrip.Size = new System.Drawing.Size(624, 24);
+ menuStrip.TabIndex = 1;
+ menuStrip.Text = "menuStrip1";
+ //
+ // tsiFile
+ //
+ tsiFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ tsiExit});
+ tsiFile.Name = "tsiFile";
+ tsiFile.Size = new System.Drawing.Size(37, 20);
+ tsiFile.Text = "&File";
+ //
+ // tsiExit
+ //
+ tsiExit.Name = "tsiExit";
+ tsiExit.Size = new System.Drawing.Size(180, 22);
+ tsiExit.Text = "E&xit";
+ tsiExit.Click += new System.EventHandler(this.Exit);
+ //
+ // tsiOptions
+ //
+ tsiOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ tsiEnabled,
+ tsiAppBtn,
+ sep3,
+ this.tsiTrayMin,
+ this.tsiTrayClose,
+ sep1,
+ tsiSysStart});
+ tsiOptions.Name = "tsiOptions";
+ tsiOptions.Size = new System.Drawing.Size(61, 20);
+ tsiOptions.Text = "&Options";
+ //
+ // tsiEnabled
+ //
+ tsiEnabled.Checked = true;
+ tsiEnabled.CheckState = System.Windows.Forms.CheckState.Checked;
+ tsiEnabled.Enabled = false;
+ tsiEnabled.Name = "tsiEnabled";
+ tsiEnabled.Size = new System.Drawing.Size(244, 22);
+ tsiEnabled.Text = "Enable hotkeys";
+ //
+ // tsiAppBtn
+ //
+ tsiAppBtn.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ tsiAppBtnAction,
+ this.tsiAppBtnDefaultDisable});
+ tsiAppBtn.Enabled = false;
+ tsiAppBtn.Name = "tsiAppBtn";
+ tsiAppBtn.Size = new System.Drawing.Size(244, 22);
+ tsiAppBtn.Text = "MSI Center shortcut key settings";
+ //
+ // tsiAppBtnAction
+ //
+ tsiAppBtnAction.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsiAppBtnDisabled,
+ this.tsiAppBtnConfEditor});
+ tsiAppBtnAction.Name = "tsiAppBtnAction";
+ tsiAppBtnAction.Size = new System.Drawing.Size(222, 22);
+ tsiAppBtnAction.Text = "Shortcut key action";
+ //
+ // tsiAppBtnDisabled
+ //
+ this.tsiAppBtnDisabled.Name = "tsiAppBtnDisabled";
+ this.tsiAppBtnDisabled.Size = new System.Drawing.Size(226, 22);
+ this.tsiAppBtnDisabled.Text = "Do nothing";
+ //
+ // tsiAppBtnConfEditor
+ //
+ this.tsiAppBtnConfEditor.Name = "tsiAppBtnConfEditor";
+ this.tsiAppBtnConfEditor.Size = new System.Drawing.Size(226, 22);
+ this.tsiAppBtnConfEditor.Text = "Open YAMDCC config editor";
+ //
+ // tsiAppBtnDefaultDisable
+ //
+ this.tsiAppBtnDefaultDisable.Name = "tsiAppBtnDefaultDisable";
+ this.tsiAppBtnDefaultDisable.Size = new System.Drawing.Size(222, 22);
+ this.tsiAppBtnDefaultDisable.Text = "Try to prevent default action";
+ //
+ // sep3
+ //
+ sep3.Name = "sep3";
+ sep3.Size = new System.Drawing.Size(241, 6);
+ //
+ // tsiTrayMin
+ //
+ this.tsiTrayMin.Checked = true;
+ this.tsiTrayMin.CheckOnClick = true;
+ this.tsiTrayMin.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.tsiTrayMin.Name = "tsiTrayMin";
+ this.tsiTrayMin.Size = new System.Drawing.Size(244, 22);
+ this.tsiTrayMin.Text = "&Minimise to tray";
+ //
+ // tsiTrayClose
+ //
+ this.tsiTrayClose.CheckOnClick = true;
+ this.tsiTrayClose.Name = "tsiTrayClose";
+ this.tsiTrayClose.Size = new System.Drawing.Size(244, 22);
+ this.tsiTrayClose.Text = "&Close to tray";
+ //
+ // sep1
+ //
+ sep1.Name = "sep1";
+ sep1.Size = new System.Drawing.Size(241, 6);
+ //
+ // tsiSysStart
+ //
+ tsiSysStart.Enabled = false;
+ tsiSysStart.Name = "tsiSysStart";
+ tsiSysStart.Size = new System.Drawing.Size(244, 22);
+ tsiSysStart.Text = "&Start on boot";
+ //
+ // tsiHelp
+ //
+ tsiHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ tsiAbout,
+ tsiSource});
+ tsiHelp.Name = "tsiHelp";
+ tsiHelp.Size = new System.Drawing.Size(44, 20);
+ tsiHelp.Text = "&Help";
+ //
+ // tsiAbout
+ //
+ tsiAbout.Name = "tsiAbout";
+ tsiAbout.Size = new System.Drawing.Size(180, 22);
+ tsiAbout.Text = "&About";
+ tsiAbout.Click += new System.EventHandler(this.tsiAbout_Click);
+ //
+ // tsiSource
+ //
+ tsiSource.Name = "tsiSource";
+ tsiSource.Size = new System.Drawing.Size(180, 22);
+ tsiSource.Text = "Source &code";
+ tsiSource.Click += new System.EventHandler(this.tsiSource_Click);
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ this.tblGeneral.SetColumnSpan(label1, 2);
+ label1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ label1.ForeColor = System.Drawing.Color.Red;
+ label1.Location = new System.Drawing.Point(3, 145);
+ label1.Name = "label1";
+ label1.Size = new System.Drawing.Size(546, 30);
+ label1.TabIndex = 13;
+ label1.Text = "Most of these options do not work yet.\r\nPlease do not open an issue regarding non" +
+ "-functioning Hotkey Handler functionality; it is still WIP.";
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ this.tblFanProfs.SetColumnSpan(label2, 2);
+ label2.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ label2.ForeColor = System.Drawing.Color.Red;
+ label2.Location = new System.Drawing.Point(3, 87);
+ label2.Name = "label2";
+ label2.Size = new System.Drawing.Size(546, 30);
+ label2.TabIndex = 14;
+ label2.Text = "Most of these options do not work yet.\r\nPlease do not open an issue regarding non" +
+ "-functioning Hotkey Handler functionality; it is still WIP.";
+ //
+ // TrayIcon
+ //
+ this.TrayIcon.ContextMenuStrip = TrayMenu;
+ this.TrayIcon.Text = "YAMDCC hotkey handler";
+ this.TrayIcon.Visible = true;
+ this.TrayIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.TrayIcon_MouseDoubleClick);
+ //
+ // TrayMenu
+ //
+ TrayMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
+ TrayMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ tsiTrayAbout,
+ sep2,
+ tsiTrayExit});
+ TrayMenu.Name = "TrayMenu";
+ TrayMenu.Size = new System.Drawing.Size(169, 54);
+ //
+ // tsiTrayAbout
+ //
+ tsiTrayAbout.Name = "tsiTrayAbout";
+ tsiTrayAbout.Size = new System.Drawing.Size(168, 22);
+ tsiTrayAbout.Text = "About YAMDCC...";
+ tsiTrayAbout.Click += new System.EventHandler(this.tsiAbout_Click);
+ //
+ // sep2
+ //
+ sep2.Name = "sep2";
+ sep2.Size = new System.Drawing.Size(165, 6);
+ //
+ // tsiTrayExit
+ //
+ tsiTrayExit.Name = "tsiTrayExit";
+ tsiTrayExit.Size = new System.Drawing.Size(168, 22);
+ tsiTrayExit.Text = "Exit";
+ tsiTrayExit.Click += new System.EventHandler(this.Exit);
+ //
+ // tcHotkeys
+ //
+ this.tcHotkeys.Controls.Add(this.tabGeneral);
+ this.tcHotkeys.Controls.Add(this.tabFanProfs);
+ this.tcHotkeys.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tcHotkeys.Location = new System.Drawing.Point(0, 24);
+ this.tcHotkeys.Name = "tcHotkeys";
+ this.tcHotkeys.SelectedIndex = 0;
+ this.tcHotkeys.Size = new System.Drawing.Size(624, 357);
+ this.tcHotkeys.TabIndex = 2;
+ //
+ // tabGeneral
+ //
+ this.tabGeneral.Controls.Add(this.tblGeneral);
+ this.tabGeneral.Location = new System.Drawing.Point(4, 24);
+ this.tabGeneral.Name = "tabGeneral";
+ this.tabGeneral.Size = new System.Drawing.Size(616, 329);
+ this.tabGeneral.TabIndex = 1;
+ this.tabGeneral.Text = "General";
+ this.tabGeneral.UseVisualStyleBackColor = true;
+ //
+ // tblGeneral
+ //
+ this.tblGeneral.ColumnCount = 3;
+ this.tblGeneral.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tblGeneral.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tblGeneral.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tblGeneral.Controls.Add(btnKeyLightDownClear, 2, 4);
+ this.tblGeneral.Controls.Add(btnKeyLightUpClear, 2, 3);
+ this.tblGeneral.Controls.Add(btnWinFnClear, 2, 2);
+ this.tblGeneral.Controls.Add(btnFullBlastClear, 2, 1);
+ this.tblGeneral.Controls.Add(btnConfEditorClear, 2, 0);
+ this.tblGeneral.Controls.Add(this.txtKeyLightDown, 1, 4);
+ this.tblGeneral.Controls.Add(this.txtKeyLightUp, 1, 3);
+ this.tblGeneral.Controls.Add(lblKeyLightUp, 0, 3);
+ this.tblGeneral.Controls.Add(lblConfEditor, 0, 0);
+ this.tblGeneral.Controls.Add(lblWinFn, 0, 2);
+ this.tblGeneral.Controls.Add(lblFullBlast, 0, 1);
+ this.tblGeneral.Controls.Add(this.txtConfEditor, 1, 0);
+ this.tblGeneral.Controls.Add(this.txtFullBlast, 1, 1);
+ this.tblGeneral.Controls.Add(this.txtWinFn, 1, 2);
+ this.tblGeneral.Controls.Add(lblKeyLightDown, 0, 4);
+ this.tblGeneral.Controls.Add(label1, 0, 5);
+ this.tblGeneral.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tblGeneral.Location = new System.Drawing.Point(0, 0);
+ this.tblGeneral.Name = "tblGeneral";
+ this.tblGeneral.RowCount = 6;
+ this.tblGeneral.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblGeneral.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblGeneral.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblGeneral.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblGeneral.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblGeneral.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblGeneral.Size = new System.Drawing.Size(616, 329);
+ this.tblGeneral.TabIndex = 7;
+ //
+ // txtKeyLightDown
+ //
+ this.txtKeyLightDown.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtKeyLightDown.Enabled = false;
+ this.txtKeyLightDown.Location = new System.Drawing.Point(170, 119);
+ this.txtKeyLightDown.Name = "txtKeyLightDown";
+ this.txtKeyLightDown.Size = new System.Drawing.Size(414, 23);
+ this.txtKeyLightDown.TabIndex = 12;
+ //
+ // txtKeyLightUp
+ //
+ this.txtKeyLightUp.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtKeyLightUp.Enabled = false;
+ this.txtKeyLightUp.Location = new System.Drawing.Point(170, 90);
+ this.txtKeyLightUp.Name = "txtKeyLightUp";
+ this.txtKeyLightUp.Size = new System.Drawing.Size(414, 23);
+ this.txtKeyLightUp.TabIndex = 11;
+ //
+ // lblKeyLightUp
+ //
+ lblKeyLightUp.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ lblKeyLightUp.AutoSize = true;
+ lblKeyLightUp.Location = new System.Drawing.Point(7, 94);
+ lblKeyLightUp.Name = "lblKeyLightUp";
+ lblKeyLightUp.Size = new System.Drawing.Size(157, 15);
+ lblKeyLightUp.TabIndex = 9;
+ lblKeyLightUp.Text = "Increase keyboard backlight:";
+ //
+ // lblConfEditor
+ //
+ lblConfEditor.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ lblConfEditor.AutoSize = true;
+ lblConfEditor.Location = new System.Drawing.Point(54, 7);
+ lblConfEditor.Name = "lblConfEditor";
+ lblConfEditor.Size = new System.Drawing.Size(110, 15);
+ lblConfEditor.TabIndex = 3;
+ lblConfEditor.Text = "Open config editor:";
+ //
+ // lblWinFn
+ //
+ lblWinFn.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ lblWinFn.AutoSize = true;
+ lblWinFn.Location = new System.Drawing.Point(47, 65);
+ lblWinFn.Name = "lblWinFn";
+ lblWinFn.Size = new System.Drawing.Size(117, 15);
+ lblWinFn.TabIndex = 5;
+ lblWinFn.Text = "Toggle Win/Fn swap:";
+ //
+ // lblFullBlast
+ //
+ lblFullBlast.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ lblFullBlast.AutoSize = true;
+ lblFullBlast.Location = new System.Drawing.Point(69, 36);
+ lblFullBlast.Name = "lblFullBlast";
+ lblFullBlast.Size = new System.Drawing.Size(95, 15);
+ lblFullBlast.TabIndex = 2;
+ lblFullBlast.Text = "Toggle Full Blast:";
+ //
+ // txtConfEditor
+ //
+ this.txtConfEditor.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtConfEditor.Enabled = false;
+ this.txtConfEditor.Location = new System.Drawing.Point(170, 3);
+ this.txtConfEditor.Name = "txtConfEditor";
+ this.txtConfEditor.Size = new System.Drawing.Size(414, 23);
+ this.txtConfEditor.TabIndex = 6;
+ //
+ // txtFullBlast
+ //
+ this.txtFullBlast.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtFullBlast.Enabled = false;
+ this.txtFullBlast.Location = new System.Drawing.Point(170, 32);
+ this.txtFullBlast.Name = "txtFullBlast";
+ this.txtFullBlast.Size = new System.Drawing.Size(414, 23);
+ this.txtFullBlast.TabIndex = 7;
+ //
+ // txtWinFn
+ //
+ this.txtWinFn.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtWinFn.Enabled = false;
+ this.txtWinFn.Location = new System.Drawing.Point(170, 61);
+ this.txtWinFn.Name = "txtWinFn";
+ this.txtWinFn.Size = new System.Drawing.Size(414, 23);
+ this.txtWinFn.TabIndex = 8;
+ //
+ // lblKeyLightDown
+ //
+ lblKeyLightDown.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ lblKeyLightDown.AutoSize = true;
+ lblKeyLightDown.Location = new System.Drawing.Point(3, 123);
+ lblKeyLightDown.Name = "lblKeyLightDown";
+ lblKeyLightDown.Size = new System.Drawing.Size(161, 15);
+ lblKeyLightDown.TabIndex = 10;
+ lblKeyLightDown.Text = "Decrease keyboard backlight:";
+ //
+ // tabFanProfs
+ //
+ this.tabFanProfs.Controls.Add(this.tblFanProfs);
+ this.tabFanProfs.Location = new System.Drawing.Point(4, 24);
+ this.tabFanProfs.Name = "tabFanProfs";
+ this.tabFanProfs.Size = new System.Drawing.Size(616, 329);
+ this.tabFanProfs.TabIndex = 2;
+ this.tabFanProfs.Text = "Fan profiles";
+ this.tabFanProfs.UseVisualStyleBackColor = true;
+ //
+ // tblFanProfs
+ //
+ this.tblFanProfs.ColumnCount = 3;
+ this.tblFanProfs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tblFanProfs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tblFanProfs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tblFanProfs.Controls.Add(btnProf3Clear, 2, 2);
+ this.tblFanProfs.Controls.Add(btnProf2Clear, 2, 1);
+ this.tblFanProfs.Controls.Add(label2, 0, 3);
+ this.tblFanProfs.Controls.Add(this.txtProf1, 1, 0);
+ this.tblFanProfs.Controls.Add(this.txtProf2, 1, 1);
+ this.tblFanProfs.Controls.Add(this.txtProf3, 1, 2);
+ this.tblFanProfs.Controls.Add(this.lblProf1, 0, 0);
+ this.tblFanProfs.Controls.Add(this.lblProf3, 0, 2);
+ this.tblFanProfs.Controls.Add(this.lblProf2, 0, 1);
+ this.tblFanProfs.Controls.Add(btnProf1Clear, 2, 0);
+ this.tblFanProfs.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tblFanProfs.Location = new System.Drawing.Point(0, 0);
+ this.tblFanProfs.Name = "tblFanProfs";
+ this.tblFanProfs.RowCount = 4;
+ this.tblFanProfs.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblFanProfs.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblFanProfs.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblFanProfs.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tblFanProfs.Size = new System.Drawing.Size(616, 329);
+ this.tblFanProfs.TabIndex = 8;
+ //
+ // txtProf1
+ //
+ this.txtProf1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtProf1.Enabled = false;
+ this.txtProf1.Location = new System.Drawing.Point(136, 3);
+ this.txtProf1.Name = "txtProf1";
+ this.txtProf1.Size = new System.Drawing.Size(448, 23);
+ this.txtProf1.TabIndex = 6;
+ //
+ // txtProf2
+ //
+ this.txtProf2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtProf2.Enabled = false;
+ this.txtProf2.Location = new System.Drawing.Point(136, 32);
+ this.txtProf2.Name = "txtProf2";
+ this.txtProf2.Size = new System.Drawing.Size(448, 23);
+ this.txtProf2.TabIndex = 7;
+ //
+ // txtProf3
+ //
+ this.txtProf3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtProf3.Enabled = false;
+ this.txtProf3.Location = new System.Drawing.Point(136, 61);
+ this.txtProf3.Name = "txtProf3";
+ this.txtProf3.Size = new System.Drawing.Size(448, 23);
+ this.txtProf3.TabIndex = 8;
+ //
+ // lblProf1
+ //
+ this.lblProf1.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.lblProf1.AutoSize = true;
+ this.lblProf1.Location = new System.Drawing.Point(33, 7);
+ this.lblProf1.Name = "lblProf1";
+ this.lblProf1.Size = new System.Drawing.Size(97, 15);
+ this.lblProf1.TabIndex = 5;
+ this.lblProf1.Text = "Switch to Default";
+ //
+ // lblProf3
+ //
+ this.lblProf3.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.lblProf3.AutoSize = true;
+ this.lblProf3.Location = new System.Drawing.Point(3, 65);
+ this.lblProf3.Name = "lblProf3";
+ this.lblProf3.Size = new System.Drawing.Size(127, 15);
+ this.lblProf3.TabIndex = 2;
+ this.lblProf3.Text = "Switch to Performance";
+ //
+ // lblProf2
+ //
+ this.lblProf2.Anchor = System.Windows.Forms.AnchorStyles.Right;
+ this.lblProf2.AutoSize = true;
+ this.lblProf2.Location = new System.Drawing.Point(42, 36);
+ this.lblProf2.Name = "lblProf2";
+ this.lblProf2.Size = new System.Drawing.Size(88, 15);
+ this.lblProf2.TabIndex = 3;
+ this.lblProf2.Text = "Switch to Silent";
+ //
+ // btnProf1Clear
+ //
+ btnProf1Clear.Enabled = false;
+ btnProf1Clear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnProf1Clear.Location = new System.Drawing.Point(590, 3);
+ btnProf1Clear.Name = "btnProf1Clear";
+ btnProf1Clear.Size = new System.Drawing.Size(23, 23);
+ btnProf1Clear.TabIndex = 15;
+ btnProf1Clear.Text = "X";
+ btnProf1Clear.UseVisualStyleBackColor = true;
+ //
+ // btnProf2Clear
+ //
+ btnProf2Clear.Enabled = false;
+ btnProf2Clear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnProf2Clear.Location = new System.Drawing.Point(590, 32);
+ btnProf2Clear.Name = "btnProf2Clear";
+ btnProf2Clear.Size = new System.Drawing.Size(23, 23);
+ btnProf2Clear.TabIndex = 16;
+ btnProf2Clear.Text = "X";
+ btnProf2Clear.UseVisualStyleBackColor = true;
+ //
+ // btnProf3Clear
+ //
+ btnProf3Clear.Enabled = false;
+ btnProf3Clear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnProf3Clear.Location = new System.Drawing.Point(590, 61);
+ btnProf3Clear.Name = "btnProf3Clear";
+ btnProf3Clear.Size = new System.Drawing.Size(23, 23);
+ btnProf3Clear.TabIndex = 17;
+ btnProf3Clear.Text = "X";
+ btnProf3Clear.UseVisualStyleBackColor = true;
+ //
+ // btnConfEditorClear
+ //
+ btnConfEditorClear.Enabled = false;
+ btnConfEditorClear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnConfEditorClear.Location = new System.Drawing.Point(590, 3);
+ btnConfEditorClear.Name = "btnConfEditorClear";
+ btnConfEditorClear.Size = new System.Drawing.Size(23, 23);
+ btnConfEditorClear.TabIndex = 16;
+ btnConfEditorClear.Text = "X";
+ btnConfEditorClear.UseVisualStyleBackColor = true;
+ //
+ // btnFullBlastClear
+ //
+ btnFullBlastClear.Enabled = false;
+ btnFullBlastClear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnFullBlastClear.Location = new System.Drawing.Point(590, 32);
+ btnFullBlastClear.Name = "btnFullBlastClear";
+ btnFullBlastClear.Size = new System.Drawing.Size(23, 23);
+ btnFullBlastClear.TabIndex = 17;
+ btnFullBlastClear.Text = "X";
+ btnFullBlastClear.UseVisualStyleBackColor = true;
+ //
+ // btnWinFnClear
+ //
+ btnWinFnClear.Enabled = false;
+ btnWinFnClear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnWinFnClear.Location = new System.Drawing.Point(590, 61);
+ btnWinFnClear.Name = "btnWinFnClear";
+ btnWinFnClear.Size = new System.Drawing.Size(23, 23);
+ btnWinFnClear.TabIndex = 18;
+ btnWinFnClear.Text = "X";
+ btnWinFnClear.UseVisualStyleBackColor = true;
+ //
+ // btnKeyLightUpClear
+ //
+ btnKeyLightUpClear.Enabled = false;
+ btnKeyLightUpClear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnKeyLightUpClear.Location = new System.Drawing.Point(590, 90);
+ btnKeyLightUpClear.Name = "btnKeyLightUpClear";
+ btnKeyLightUpClear.Size = new System.Drawing.Size(23, 23);
+ btnKeyLightUpClear.TabIndex = 19;
+ btnKeyLightUpClear.Text = "X";
+ btnKeyLightUpClear.UseVisualStyleBackColor = true;
+ //
+ // btnKeyLightDownClear
+ //
+ btnKeyLightDownClear.Enabled = false;
+ btnKeyLightDownClear.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ btnKeyLightDownClear.Location = new System.Drawing.Point(590, 119);
+ btnKeyLightDownClear.Name = "btnKeyLightDownClear";
+ btnKeyLightDownClear.Size = new System.Drawing.Size(23, 23);
+ btnKeyLightDownClear.TabIndex = 20;
+ btnKeyLightDownClear.Text = "X";
+ btnKeyLightDownClear.UseVisualStyleBackColor = true;
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
+ this.ClientSize = new System.Drawing.Size(624, 381);
+ this.Controls.Add(this.tcHotkeys);
+ this.Controls.Add(menuStrip);
+ this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.MainMenuStrip = menuStrip;
+ this.Name = "MainForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
+ menuStrip.ResumeLayout(false);
+ menuStrip.PerformLayout();
+ TrayMenu.ResumeLayout(false);
+ this.tcHotkeys.ResumeLayout(false);
+ this.tabGeneral.ResumeLayout(false);
+ this.tblGeneral.ResumeLayout(false);
+ this.tblGeneral.PerformLayout();
+ this.tabFanProfs.ResumeLayout(false);
+ this.tblFanProfs.ResumeLayout(false);
+ this.tblFanProfs.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.NotifyIcon TrayIcon;
+ private System.Windows.Forms.TabControl tcHotkeys;
+ private System.Windows.Forms.TabPage tabGeneral;
+ private System.Windows.Forms.TableLayoutPanel tblGeneral;
+ private System.Windows.Forms.TextBox txtConfEditor;
+ private System.Windows.Forms.TextBox txtFullBlast;
+ private System.Windows.Forms.TextBox txtWinFn;
+ private System.Windows.Forms.ToolStripMenuItem tsiAppBtnDisabled;
+ private System.Windows.Forms.ToolStripMenuItem tsiAppBtnConfEditor;
+ private System.Windows.Forms.ToolStripMenuItem tsiAppBtnDefaultDisable;
+ private System.Windows.Forms.TextBox txtKeyLightDown;
+ private System.Windows.Forms.TextBox txtKeyLightUp;
+ private System.Windows.Forms.TabPage tabFanProfs;
+ private System.Windows.Forms.TableLayoutPanel tblFanProfs;
+ private System.Windows.Forms.Label lblProf2;
+ private System.Windows.Forms.Label lblProf1;
+ private System.Windows.Forms.Label lblProf3;
+ private System.Windows.Forms.TextBox txtProf1;
+ private System.Windows.Forms.TextBox txtProf2;
+ private System.Windows.Forms.TextBox txtProf3;
+ private System.Windows.Forms.ToolStripMenuItem tsiTrayMin;
+ private System.Windows.Forms.ToolStripMenuItem tsiTrayClose;
+ }
+}
diff --git a/YAMDCC.HotkeyHandler/MainForm.cs b/YAMDCC.HotkeyHandler/MainForm.cs
new file mode 100644
index 0000000..e35a5e9
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/MainForm.cs
@@ -0,0 +1,114 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+using YAMDCC.Common;
+using YAMDCC.Common.Dialogs;
+
+namespace YAMDCC.HotkeyHandler;
+
+public partial class MainForm : Form
+{
+ private readonly KeyHook KeyHook = new();
+
+ public MainForm()
+ {
+ InitializeComponent();
+
+ Text = $"YAMDCC hotkey handler - v{Utils.GetVerString()}";
+ Icon = Utils.GetEntryAssemblyIcon();
+ TrayIcon.Icon = Icon;
+
+ KeyHook.KeyDown += KeyHook_KeyDown;
+ //KeyHook.KeyUp += KeyHook_KeyUp;
+ if (!KeyHook.Install())
+ {
+ int err = Marshal.GetLastWin32Error();
+ Utils.ShowError("Failed to install keyboard hook:\n" +
+ $"{new Win32Exception(err).Message} ({err})");
+ }
+ }
+
+ protected override void SetVisibleCore(bool value)
+ {
+ // hide form on first launch
+ if (!IsHandleCreated)
+ {
+ value = false;
+ CreateHandle();
+ }
+ base.SetVisibleCore(value);
+ }
+
+ private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ if (e.CloseReason == CloseReason.UserClosing && tsiTrayClose.Checked)
+ {
+ Hide();
+ e.Cancel = true;
+ }
+ }
+
+ protected override void WndProc(ref Message m)
+ {
+ // catch Minimise events before the form actually minimises
+ // 0x112 = WM_SYSCOMMAND, 0xF020 = SC_MINIMIZE
+ if (tsiTrayMin.Checked && m.Msg == 0x0112 &&
+ (m.WParam.ToInt32() & 0xfff0) == 0xF020)
+ {
+ Hide();
+ return;
+ }
+ base.WndProc(ref m);
+ }
+
+ private void tsiAbout_Click(object sender, EventArgs e)
+ {
+ new VersionDialog().ShowDialog();
+ }
+
+ private void tsiSource_Click(object sender, EventArgs e)
+ {
+ Process.Start(Paths.GitHubPage);
+ }
+
+ private void Exit(object sender, EventArgs e)
+ {
+ TrayIcon.Visible = false;
+ KeyHook.Uninstall();
+ Application.Exit();
+ }
+
+ private void TrayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
+ {
+ Show();
+ Activate();
+ }
+
+ private void KeyHook_KeyDown(object sender, KeyHookEventArgs e)
+ {
+ // corresponds to the MSI Center key (Fn+F7) on my laptop (GF63 Thin 11SC)
+ if (e.KeyCode == (Keys)255 && e.ScanCode == 10 && e.ExtendedKey)
+ {
+ try
+ {
+ Process p = Process.Start("ConfigEditor.exe");
+ }
+ catch (Exception ex)
+ {
+ if (ex is FileNotFoundException)
+ {
+ Utils.ShowError("Could not find ConfigEditor.exe!");
+ }
+ // If UAC is denied, a Win32Exception is thrown.
+ // Ignore and throw all other exceptions.
+ else if (ex is not Win32Exception)
+ {
+ throw;
+ }
+ }
+ }
+ }
+}
diff --git a/YAMDCC.HotkeyHandler/MainForm.resx b/YAMDCC.HotkeyHandler/MainForm.resx
new file mode 100644
index 0000000..0dadf84
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/MainForm.resx
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+ 221, 17
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ 17, 17
+
+
+ False
+
+
+ 115, 17
+
+
+ False
+
+
+ False
+
+
+ False
+
+
\ No newline at end of file
diff --git a/YAMDCC.HotkeyHandler/Program.cs b/YAMDCC.HotkeyHandler/Program.cs
new file mode 100644
index 0000000..f8e3b65
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/Program.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Windows.Forms;
+
+namespace YAMDCC.HotkeyHandler;
+
+internal static class Program
+{
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ private static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainForm());
+ }
+}
diff --git a/YAMDCC.HotkeyHandler/Win32/User32.cs b/YAMDCC.HotkeyHandler/Win32/User32.cs
new file mode 100644
index 0000000..ffda28a
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/Win32/User32.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+namespace YAMDCC.HotkeyHandler.Win32;
+
+internal delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
+
+internal static class User32
+{
+ [DllImport("user32.dll", SetLastError = true, ExactSpelling = true,
+ CharSet = CharSet.Unicode, EntryPoint = "SetWindowsHookExW")]
+ internal static extern IntPtr SetWindowsHookEx(
+ int idHook,
+ HookProc lpfn,
+ IntPtr hmod,
+ uint threadId
+ );
+
+ [DllImport("user32.dll", SetLastError = true, ExactSpelling = true)]
+ internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
+
+ [DllImport("user32.dll", SetLastError = true, ExactSpelling = true)]
+ internal static extern IntPtr CallNextHookEx(
+ IntPtr hhk,
+ int nCode,
+ IntPtr wParam,
+ IntPtr lParam
+ );
+}
+
+internal struct KbdLLHookStruct
+{
+#pragma warning disable CS0649 // CS0649: Fields are never assigned to (they are by Marshal.PtrToStructure)
+ public Keys KeyCode;
+ public uint ScanCode;
+ public uint Flags;
+ public uint Time;
+ public UIntPtr ExtraInfo;
+#pragma warning restore CS0649
+}
diff --git a/YAMDCC.HotkeyHandler/YAMDCC.HotkeyHandler.csproj b/YAMDCC.HotkeyHandler/YAMDCC.HotkeyHandler.csproj
new file mode 100644
index 0000000..bf092eb
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/YAMDCC.HotkeyHandler.csproj
@@ -0,0 +1,28 @@
+
+
+ net48
+ WinExe
+ true
+ true
+ HotkeyHandler
+ hkey.ico
+ 13.0
+ True
+ 13.0
+ 1.0.1
+ dev
+ app.manifest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/YAMDCC.HotkeyHandler/app.manifest b/YAMDCC.HotkeyHandler/app.manifest
new file mode 100644
index 0000000..0688b63
--- /dev/null
+++ b/YAMDCC.HotkeyHandler/app.manifest
@@ -0,0 +1 @@
+true
\ No newline at end of file
diff --git a/YAMDCC.HotkeyHandler/hkey.ico b/YAMDCC.HotkeyHandler/hkey.ico
new file mode 100644
index 0000000000000000000000000000000000000000..3fff519144320fccdfbe193b1c7c9e637263944b
GIT binary patch
literal 7801
zcmeHMJ8Tm{5FIBG0poxn7BT^Zktkfcp+ubX5m-c)38@f;Ds!vs6&HLKK9G3eg~3K!cEuH#@ubdF@N=#Q2BDH#;+L_vU71KRzc!5!y>k5lYb;
z$opW=i^HCv8&RTcgea3S_8y{*{Y2@s*zYHZ4jm>+rNsU=Mznc^D48@i?tOcdD3K8R
z1?-JuMDe)TY1o%e5Irp9&rd~X@HCprU6^0uXqd;wAx<6lenIRjEG{oV`e35#&u3#0
zkvmKI%jA9ibPYx^H=kX;7y17ARfOV+x$MO&AD(_(Tl@Lr?#k`e*JpE2e$V*`uy_?w
z8;XwKd}pi&kH*NmC3tD>3Wg?V96*YV<@G7l_WLf=j$AO*kbqs@ZEz<Th1Xa@GH+zgY#kU7whp
z4<*sK&maDNvlBw|-)+CCYpDO>?w9Opt-HQzJ*EzJJsLUcudhJs^$R=UZJqyZe|^*g
zX5k&6E&3z*of}DAh`y^sTa$^w{GOQs7r}%5p4nuRD
zr8Cm$1@rA0F4NW+PZ-{3@$0}%6RhU|W{Zj9|+4mmf2m(iXHK2}STrtI!sJfSexfn)t
z^tny^0WwsJ#UjD@dVx6$i$icA9dj+TPH1{x!cmyy^Y0+|f0bc%u{fV$DX<6bt8*+C
zTssOo%e8@7;$0^@PmoU8*3XV5$82KLK3qH4w*y_WmE76CB^&RqY`5NyZGE>W^?EbS
z7oy2-aPXPD&XeE_xF_qpT0TXDO9%=sAt<tC7ZJ$JqL0$@825v+U_Sa}^Xf*q+=dZno7iRN3*NI!~?f89FB5XZz>cIn*PY
zH@;uNyj2igW>;+e@chKVDR4LDDJD5e-O%d#)k((cKKOfWooy@xtTjg(|BMESf18!?
L@7Z>l?_>T8)mILS
literal 0
HcmV?d00001
diff --git a/YAMDCC.sln b/YAMDCC.sln
index 3c3005a..7b74c3f 100644
--- a/YAMDCC.sln
+++ b/YAMDCC.sln
@@ -26,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YAMDCC.ECInspector", "YAMDC
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YAMDCC.Updater", "YAMDCC.Updater\YAMDCC.Updater.csproj", "{E8EAC9DC-D7E2-4464-897E-C6E9E28B8C89}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YAMDCC.HotkeyHandler", "YAMDCC.HotkeyHandler\YAMDCC.HotkeyHandler.csproj", "{00A0A259-1B03-4D7D-A1BA-52D54D565B65}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -68,6 +70,10 @@ Global
{E8EAC9DC-D7E2-4464-897E-C6E9E28B8C89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8EAC9DC-D7E2-4464-897E-C6E9E28B8C89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8EAC9DC-D7E2-4464-897E-C6E9E28B8C89}.Release|Any CPU.Build.0 = Release|Any CPU
+ {00A0A259-1B03-4D7D-A1BA-52D54D565B65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {00A0A259-1B03-4D7D-A1BA-52D54D565B65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {00A0A259-1B03-4D7D-A1BA-52D54D565B65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {00A0A259-1B03-4D7D-A1BA-52D54D565B65}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE