diff --git a/GlobalKeyboardHook.cs b/GlobalKeyboardHook.cs new file mode 100644 index 0000000..5670b7a --- /dev/null +++ b/GlobalKeyboardHook.cs @@ -0,0 +1,85 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace HTPCAVRVolume +{ + public class GlobalKeyboardHook : IDisposable + { + private const int WH_KEYBOARD_LL = 13; + private const int WM_KEYDOWN = 0x0100; + + private IntPtr _hookID = IntPtr.Zero; + private LowLevelKeyboardProc _proc; + + public event EventHandler VolumeUpPressed; + public event EventHandler VolumeDownPressed; + public event EventHandler VolumeMutePressed; + + // Delegate declaration + private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); + + public GlobalKeyboardHook() + { + _proc = HookCallback; + _hookID = SetHook(_proc); + } + + private IntPtr SetHook(LowLevelKeyboardProc proc) + { + using Process curProcess = Process.GetCurrentProcess(); + using ProcessModule curModule = curProcess.MainModule; + return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); + } + + private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) + { + if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) + { + int vkCode = Marshal.ReadInt32(lParam); + Keys key = (Keys)vkCode; + + switch (key) + { + case Keys.VolumeUp: + VolumeUpPressed?.Invoke(this, EventArgs.Empty); + return (IntPtr)1; // // Prevents the key from being passed to Windows + + case Keys.VolumeDown: + VolumeDownPressed?.Invoke(this, EventArgs.Empty); + return (IntPtr)1; // Block the key + + case Keys.VolumeMute: + VolumeMutePressed?.Invoke(this, EventArgs.Empty); + return (IntPtr)1; // Block the key + } + } + return CallNextHookEx(_hookID, nCode, wParam, lParam); + } + + public void Dispose() + { + UnhookWindowsHookEx(_hookID); + } + + #region PInvoke + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, + IntPtr hMod, uint dwThreadId); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool UnhookWindowsHookEx(IntPtr hhk); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, + IntPtr wParam, IntPtr lParam); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr GetModuleHandle(string lpModuleName); + + #endregion + } +} diff --git a/HTPCAVRVolume.cs b/HTPCAVRVolume.cs index eaba789..10b94ae 100644 --- a/HTPCAVRVolume.cs +++ b/HTPCAVRVolume.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Drawing; using System.Windows.Forms; using System.IO; @@ -10,6 +10,8 @@ public partial class HTPCAVRVolume : Form { private readonly string config = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\HTPCAVRVolumeConfig.txt"; private bool _muted = false; + private GlobalKeyboardHook globalHook; + private KeyboardHook hookVolUp; private KeyboardHook hookVolDown; @@ -31,14 +33,12 @@ private void HTPCAVRVolume_Load(object sender, EventArgs e) { LoadDevice(); - hookVolUp = new KeyboardHook(Constants.NOMOD, Keys.VolumeUp, this); - hookVolDown = new KeyboardHook(Constants.NOMOD, Keys.VolumeDown, this); - hookToggleMute = new KeyboardHook(Constants.NOMOD, Keys.VolumeMute, this); + globalHook = new GlobalKeyboardHook(); - hookVolUp.Register(); - hookVolDown.Register(); - hookToggleMute.Register(); - } + globalHook.VolumeUpPressed += (s, args) => btnVolUp.PerformClick(); + globalHook.VolumeDownPressed += (s, args) => btnVolDown.PerformClick(); + globalHook.VolumeMutePressed += (s, args) => btnToggleMute.PerformClick(); + } // Use globalHook instead private void LoadDevice() { @@ -117,9 +117,7 @@ private void BtnToggleMute_Click(object sender, EventArgs e) private void HTPCAVRVolume_FormClosed(object sender, FormClosedEventArgs e) { - hookVolUp.Unregister(); - hookVolDown.Unregister(); - hookToggleMute.Unregister(); + globalHook?.Dispose(); } private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) @@ -130,15 +128,15 @@ private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) private void HTPCAVRVolume_Resize(object sender, EventArgs e) { - if (FormWindowState.Minimized == WindowState) + if (WindowState == FormWindowState.Minimized) { notifyIcon.Visible = true; - Hide(); + ShowInTaskbar = false; // window hidden in the taskbar, but still active. } - - else if (FormWindowState.Normal == WindowState) + else if (WindowState == FormWindowState.Normal) { notifyIcon.Visible = false; + ShowInTaskbar = true; } } @@ -150,4 +148,4 @@ private void HTPCAVRVolume_Shown(object sender, EventArgs e) } } } -} \ No newline at end of file +} diff --git a/HTPCAVRVolume.csproj b/HTPCAVRVolume.csproj index c0de4ac..3f75650 100644 --- a/HTPCAVRVolume.csproj +++ b/HTPCAVRVolume.csproj @@ -1,4 +1,4 @@ - + @@ -9,6 +9,7 @@ HTPCAVRVolume HTPCAVRVolume v4.7.2 + 8.0 512 true true @@ -66,6 +67,7 @@ + Form @@ -119,4 +121,4 @@ - \ No newline at end of file + diff --git a/HTPCAVRVolume.ico b/HTPCAVRVolume.ico index 3b5e257..e1ffe38 100644 Binary files a/HTPCAVRVolume.ico and b/HTPCAVRVolume.ico differ diff --git a/Readme.md b/Readme.md index 9d10e2d..63d9639 100644 --- a/Readme.md +++ b/Readme.md @@ -1,4 +1,4 @@ -# HTPCAVRVolume +# HTPCAVRVolume functional with Windows 11 24H2 and above This is a simple program that captures your HTPC's volume control buttons and instead sends the commands directly to your home theater AVR. @@ -24,7 +24,7 @@ The only supported controls are: Support for other AVRs could be pretty easily added to the existing code. -Please contact me if you would like me to support another AVR, especially if it's one already supported by [HTWebRemote](https://github.com/nicko88/HTWebRemote) +Original autor note from [nicko88](https://github.com/nicko88) : Please contact me if you would like me to support another AVR, especially if it's one already supported by [HTWebRemote](https://github.com/nicko88/HTWebRemote) ### How To Use @@ -32,5 +32,10 @@ Simply download the latest release, place the program .exe wherever you like, an After running it, select your AVR from the dropown and enter it's network IP address, then hit Save. -You can also add the program, or a shortcut to it to your HTPC's startup folder so that the program automatically -starts with your PC. \ No newline at end of file +You can also add the program, or a shortcut to it to your HTPC's startup folder so that the program automatically starts with your PC. +To access your startup folder press Win+R and type `shell:Startup` + +### Optional experimental : +`VolumUp.exe` and `VolumeDown.exe` in the project files are optional .exe shortcuts than can be placed directly as buttons in the taskbar. +Probably needs HTPCAVRVolume.exe and HTPCAVRVolumeConfig.txt to be located in `C:\ProgramData\HTPCAVRVolume.v1.1` +Honestly I don't remember how and when I built those, maybe with AutoHotkey idk. diff --git a/VolumUp.exe b/VolumUp.exe new file mode 100644 index 0000000..fda7094 Binary files /dev/null and b/VolumUp.exe differ diff --git a/VolumeDown.exe b/VolumeDown.exe new file mode 100644 index 0000000..7fd4781 Binary files /dev/null and b/VolumeDown.exe differ