Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions GlobalKeyboardHook.cs
Original file line number Diff line number Diff line change
@@ -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
}
}
30 changes: 14 additions & 16 deletions HTPCAVRVolume.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
Expand All @@ -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;
Expand All @@ -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()
{
Expand Down Expand Up @@ -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)
Expand All @@ -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;
}
}

Expand All @@ -150,4 +148,4 @@ private void HTPCAVRVolume_Shown(object sender, EventArgs e)
}
}
}
}
}
6 changes: 4 additions & 2 deletions HTPCAVRVolume.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
Expand All @@ -9,6 +9,7 @@
<RootNamespace>HTPCAVRVolume</RootNamespace>
<AssemblyName>HTPCAVRVolume</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<LangVersion>8.0</LangVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
Expand Down Expand Up @@ -66,6 +67,7 @@
<ItemGroup>
<Compile Include="AVRDevices\StormAudioDevice.cs" />
<Compile Include="AVRDevices\IAVRDevice.cs" />
<Compile Include="GlobalKeyboardHook.cs" />
<Compile Include="HTPCAVRVolume.cs">
<SubType>Form</SubType>
</Compile>
Expand Down Expand Up @@ -119,4 +121,4 @@
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
Binary file modified HTPCAVRVolume.ico
Binary file not shown.
13 changes: 9 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -24,13 +24,18 @@ 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

Simply download the latest release, place the program .exe wherever you like, and run it.

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.
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.
Binary file added VolumUp.exe
Binary file not shown.
Binary file added VolumeDown.exe
Binary file not shown.