Squashed 'NHotkey/' content from commit e16cceb

git-subtree-dir: NHotkey
git-subtree-split: e16cceb7b3e108413d409dbf355a67835822a5e7
This commit is contained in:
maier_S
2022-03-23 10:15:54 +01:00
commit b78f6541dc
24 changed files with 1188 additions and 0 deletions

Binary file not shown.

71
NHotkey/Hotkey.cs Normal file
View File

@@ -0,0 +1,71 @@
using System;
using System.Runtime.InteropServices;
namespace NHotkey
{
internal class Hotkey
{
private static int _nextId;
private readonly int _id;
private readonly uint _virtualKey;
private readonly HotkeyFlags _flags;
private readonly EventHandler<HotkeyEventArgs> _handler;
public Hotkey(uint virtualKey, HotkeyFlags flags, EventHandler<HotkeyEventArgs> handler)
{
_id = ++_nextId;
_virtualKey = virtualKey;
_flags = flags;
_handler = handler;
}
public int Id
{
get { return _id; }
}
public uint VirtualKey
{
get { return _virtualKey; }
}
public HotkeyFlags Flags
{
get { return _flags; }
}
public EventHandler<HotkeyEventArgs> Handler
{
get { return _handler; }
}
private IntPtr _hwnd;
public void Register(IntPtr hwnd, string name)
{
if (!NativeMethods.RegisterHotKey(hwnd, _id, _flags, _virtualKey))
{
var hr = Marshal.GetHRForLastWin32Error();
var ex = Marshal.GetExceptionForHR(hr);
if ((uint) hr == 0x80070581)
throw new HotkeyAlreadyRegisteredException(name, ex);
throw ex;
}
_hwnd = hwnd;
}
public void Unregister()
{
if (_hwnd != IntPtr.Zero)
{
if (!NativeMethods.UnregisterHotKey(_hwnd, _id))
{
var hr = Marshal.GetHRForLastWin32Error();
throw Marshal.GetExceptionForHR(hr);
}
_hwnd = IntPtr.Zero;
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
namespace NHotkey
{
[Serializable]
public class HotkeyAlreadyRegisteredException : Exception
{
private readonly string _name;
public HotkeyAlreadyRegisteredException(string name, Exception inner) : base(inner.Message, inner)
{
_name = name;
HResult = Marshal.GetHRForException(inner);
}
protected HotkeyAlreadyRegisteredException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
_name = (string) info.GetValue("_name", typeof (string));
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("_name", _name);
}
public string Name
{
get { return _name; }
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace NHotkey
{
public class HotkeyEventArgs : EventArgs
{
private readonly string _name;
internal HotkeyEventArgs(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
}
public bool Handled { get; set; }
}
}

15
NHotkey/HotkeyFlags.cs Normal file
View File

@@ -0,0 +1,15 @@
using System;
namespace NHotkey
{
[Flags]
internal enum HotkeyFlags : uint
{
None = 0x0000,
Alt = 0x0001,
Control = 0x0002,
Shift = 0x0004,
Windows = 0x0008,
NoRepeat = 0x4000
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
namespace NHotkey
{
public abstract class HotkeyManagerBase
{
private readonly Dictionary<int, string> _hotkeyNames = new Dictionary<int, string>();
private readonly Dictionary<string, Hotkey> _hotkeys = new Dictionary<string, Hotkey>();
private IntPtr _hwnd;
internal static readonly IntPtr HwndMessage = (IntPtr)(-3);
internal HotkeyManagerBase()
{
}
internal void AddOrReplace(string name, uint virtualKey, HotkeyFlags flags, EventHandler<HotkeyEventArgs> handler)
{
var hotkey = new Hotkey(virtualKey, flags, handler);
lock (_hotkeys)
{
Remove(name);
_hotkeys.Add(name, hotkey);
_hotkeyNames.Add(hotkey.Id, name);
if (_hwnd != IntPtr.Zero)
hotkey.Register(_hwnd, name);
}
}
public void Remove(string name)
{
lock (_hotkeys)
{
Hotkey hotkey;
if (_hotkeys.TryGetValue(name, out hotkey))
{
_hotkeys.Remove(name);
_hotkeyNames.Remove(hotkey.Id);
if (_hwnd != IntPtr.Zero)
hotkey.Unregister();
}
}
}
public bool IsEnabled { get; set; } = true;
internal void SetHwnd(IntPtr hwnd)
{
_hwnd = hwnd;
}
private const int WmHotkey = 0x0312;
internal IntPtr HandleHotkeyMessage(
IntPtr hwnd,
int msg,
IntPtr wParam,
IntPtr lParam,
ref bool handled,
out Hotkey hotkey)
{
hotkey = null;
if (IsEnabled && msg == WmHotkey)
{
int id = wParam.ToInt32();
string name;
if (_hotkeyNames.TryGetValue(id, out name))
{
hotkey = _hotkeys[name];
var handler = hotkey.Handler;
if (handler != null)
{
var e = new HotkeyEventArgs(name);
handler(this, e);
handled = e.Handled;
}
}
}
return IntPtr.Zero;
}
}
}

10
NHotkey/NHotkey.csproj Normal file
View File

@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net40;net45;net472;netcoreapp3.0;net6.0-windows</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Label="Package properties">
<Description>A managed library to handle global hotkeys in Windows Forms and WPF applications. NOTE: this package doesn't contain a concrete HotkeyManager implementation; you should add either the NHotkey.Wpf or NHotkey.WindowsForms package to get one.</Description>
</PropertyGroup>
</Project>

14
NHotkey/NativeMethods.cs Normal file
View File

@@ -0,0 +1,14 @@
using System;
using System.Runtime.InteropServices;
namespace NHotkey
{
static class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyFlags fsModifiers, uint vk);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}
}

View File

@@ -0,0 +1,4 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("NHotkey.WindowsForms, PublicKey=00240000048000009400000006020000002400005253413100040000010001000d37f28dea0d86462d702c5ff882a20c5701fc1421107b336430c0af082910e58ff42c9030dcfe5739ab99f74b91b11dd4de06bfcd30bc9402beb15f023becb0c6b92ad9496e8e5474f3f5684ed32bf9fb69da84593b8be9bebd86542bd452c5bb77e071bbb2f0024a501ebfa897a62798fe2f2a4e72f250fc9c8277e17db1d5")]
[assembly: InternalsVisibleTo("NHotkey.Wpf, PublicKey=00240000048000009400000006020000002400005253413100040000010001000d37f28dea0d86462d702c5ff882a20c5701fc1421107b336430c0af082910e58ff42c9030dcfe5739ab99f74b91b11dd4de06bfcd30bc9402beb15f023becb0c6b92ad9496e8e5474f3f5684ed32bf9fb69da84593b8be9bebd86542bd452c5bb77e071bbb2f0024a501ebfa897a62798fe2f2a4e72f250fc9c8277e17db1d5")]