diff --git a/Pilz.Input/KeyboardListener.cs b/Pilz.Input/KeyboardListener.cs
deleted file mode 100644
index 456dcfc..0000000
--- a/Pilz.Input/KeyboardListener.cs
+++ /dev/null
@@ -1,431 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Windows.Input;
-using System.Windows.Threading;
-using System.Collections.Generic;
-
-namespace Pilz.Input
-{
- ///
- /// Listens keyboard globally.
- ///
- /// Uses WH_KEYBOARD_LL.
- ///
- public class KeyboardListener : IDisposable
- {
- ///
- /// Creates global keyboard listener.
- ///
- public KeyboardListener()
- {
- // Dispatcher thread handling the KeyDown/KeyUp events.
- this.dispatcher = Dispatcher.CurrentDispatcher;
-
- // We have to store the LowLevelKeyboardProc, so that it is not garbage collected runtime
- hookedLowLevelKeyboardProc = (InterceptKeys.LowLevelKeyboardProc)LowLevelKeyboardProc;
-
- // Set the hook
- hookId = InterceptKeys.SetHook(hookedLowLevelKeyboardProc);
-
- // Assign the asynchronous callback event
- hookedKeyboardCallbackAsync = new KeyboardCallbackAsync(KeyboardListener_KeyboardCallbackAsync);
- }
-
- private Dispatcher dispatcher;
-
- ///
- /// Destroys global keyboard listener.
- ///
- ~KeyboardListener()
- {
- Dispose();
- }
-
- ///
- /// Fired when any of the keys is pressed down.
- ///
- public event RawKeyEventHandler KeyDown;
-
- ///
- /// Fired when any of the keys is released.
- ///
- public event RawKeyEventHandler KeyUp;
-
- #region Inner workings
-
- ///
- /// Hook ID
- ///
- private IntPtr hookId = IntPtr.Zero;
-
- ///
- /// Asynchronous callback hook.
- ///
- /// Character
- /// Keyboard event
- /// VKCode
- private delegate void KeyboardCallbackAsync(InterceptKeys.KeyEvent keyEvent, int vkCode, string character);
-
- ///
- /// Actual callback hook.
- ///
- /// Calls asynchronously the asyncCallback.
- ///
- ///
- ///
- ///
- ///
- [MethodImpl(MethodImplOptions.NoInlining)]
- private IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
- {
- string chars = "";
-
- if (nCode >= 0)
- if (wParam.ToUInt32() == (int)InterceptKeys.KeyEvent.WM_KEYDOWN ||
- wParam.ToUInt32() == (int)InterceptKeys.KeyEvent.WM_KEYUP ||
- wParam.ToUInt32() == (int)InterceptKeys.KeyEvent.WM_SYSKEYDOWN ||
- wParam.ToUInt32() == (int)InterceptKeys.KeyEvent.WM_SYSKEYUP)
- {
- // Captures the character(s) pressed only on WM_KEYDOWN
- chars = InterceptKeys.VKCodeToString((uint)Marshal.ReadInt32(lParam),
- (wParam.ToUInt32() == (int)InterceptKeys.KeyEvent.WM_KEYDOWN ||
- wParam.ToUInt32() == (int)InterceptKeys.KeyEvent.WM_SYSKEYDOWN));
-
- hookedKeyboardCallbackAsync.BeginInvoke((InterceptKeys.KeyEvent)wParam.ToUInt32(), Marshal.ReadInt32(lParam), chars, null, null);
- }
-
- return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
- }
-
- ///
- /// Event to be invoked asynchronously (BeginInvoke) each time key is pressed.
- ///
- private KeyboardCallbackAsync hookedKeyboardCallbackAsync;
-
- ///
- /// Contains the hooked callback in runtime.
- ///
- private InterceptKeys.LowLevelKeyboardProc hookedLowLevelKeyboardProc;
-
- ///
- /// HookCallbackAsync procedure that calls accordingly the KeyDown or KeyUp events.
- ///
- /// Keyboard event
- /// VKCode
- /// Character as string.
- void KeyboardListener_KeyboardCallbackAsync(InterceptKeys.KeyEvent keyEvent, int vkCode, string character)
- {
- switch (keyEvent)
- {
- // KeyDown events
- case InterceptKeys.KeyEvent.WM_KEYDOWN:
- if (KeyDown != null)
- dispatcher.BeginInvoke(new RawKeyEventHandler(KeyDown), this, new RawKeyEventArgs(vkCode, false, character));
- break;
- case InterceptKeys.KeyEvent.WM_SYSKEYDOWN:
- if (KeyDown != null)
- dispatcher.BeginInvoke(new RawKeyEventHandler(KeyDown), this, new RawKeyEventArgs(vkCode, true, character));
- break;
-
- // KeyUp events
- case InterceptKeys.KeyEvent.WM_KEYUP:
- if (KeyUp != null)
- dispatcher.BeginInvoke(new RawKeyEventHandler(KeyUp), this, new RawKeyEventArgs(vkCode, false, character));
- break;
- case InterceptKeys.KeyEvent.WM_SYSKEYUP:
- if (KeyUp != null)
- dispatcher.BeginInvoke(new RawKeyEventHandler(KeyUp), this, new RawKeyEventArgs(vkCode, true, character));
- break;
-
- default:
- break;
- }
- }
-
- #endregion
-
- #region IDisposable Members
-
- ///
- /// Disposes the hook.
- /// This call is required as it calls the UnhookWindowsHookEx.
- ///
- public void Dispose()
- {
- InterceptKeys.UnhookWindowsHookEx(hookId);
- }
-
- #endregion
- }
-
- ///
- /// Raw KeyEvent arguments.
- ///
- public class RawKeyEventArgs : EventArgs
- {
- ///
- /// VKCode of the key.
- ///
- public int VKCode;
-
- ///
- /// WPF Key of the key.
- ///
- public Key Key;
-
- ///
- /// Is the hitted key system key.
- ///
- public bool IsSysKey;
-
- ///
- /// Convert to string.
- ///
- /// Returns string representation of this key, if not possible empty string is returned.
- public override string ToString()
- {
- return Character;
- }
-
- ///
- /// Unicode character of key pressed.
- ///
- public string Character;
-
- ///
- /// Create raw keyevent arguments.
- ///
- ///
- ///
- /// Character
- public RawKeyEventArgs(int VKCode, bool isSysKey, string Character)
- {
- this.VKCode = VKCode;
- this.IsSysKey = isSysKey;
- this.Character = Character;
- this.Key = System.Windows.Input.KeyInterop.KeyFromVirtualKey(VKCode);
- }
-
- }
-
- ///
- /// Raw keyevent handler.
- ///
- /// sender
- /// raw keyevent arguments
- public delegate void RawKeyEventHandler(object sender, RawKeyEventArgs args);
-
- #region WINAPI Helper class
- ///
- /// Winapi Key interception helper class.
- ///
- internal static class InterceptKeys
- {
- public delegate IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam);
- public static int WH_KEYBOARD_LL = 13;
-
- ///
- /// Key event
- ///
- public enum KeyEvent : int
- {
- ///
- /// Key down
- ///
- WM_KEYDOWN = 256,
-
- ///
- /// Key up
- ///
- WM_KEYUP = 257,
-
- ///
- /// System key up
- ///
- WM_SYSKEYUP = 261,
-
- ///
- /// System key down
- ///
- WM_SYSKEYDOWN = 260
- }
-
- public static IntPtr SetHook(LowLevelKeyboardProc proc)
- {
- using (Process curProcess = Process.GetCurrentProcess())
- using (ProcessModule curModule = curProcess.MainModule)
- {
- return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
- }
- }
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool UnhookWindowsHookEx(IntPtr hhk);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, UIntPtr wParam, IntPtr lParam);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern IntPtr GetModuleHandle(string lpModuleName);
-
- #region Convert VKCode to string
- // Note: Sometimes single VKCode represents multiple chars, thus string.
- // E.g. typing "^1" (notice that when pressing 1 the both characters appear,
- // because of this behavior, "^" is called dead key)
-
- [DllImport("user32.dll")]
- private static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder pwszBuff, int cchBuff, uint wFlags, IntPtr dwhkl);
-
- [DllImport("user32.dll")]
- private static extern bool GetKeyboardState(byte[] lpKeyState);
-
- [DllImport("user32.dll")]
- private static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);
-
- [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
- private static extern IntPtr GetKeyboardLayout(uint dwLayout);
-
- [DllImport("User32.dll")]
- private static extern IntPtr GetForegroundWindow();
-
- [DllImport("User32.dll")]
- private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
-
- [DllImport("user32.dll")]
- private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
-
- [DllImport("kernel32.dll")]
- private static extern uint GetCurrentThreadId();
-
- private static uint lastVKCode = 0;
- private static uint lastScanCode = 0;
- private static byte[] lastKeyState = new byte[255];
- private static bool lastIsDead = false;
-
- ///
- /// Convert VKCode to Unicode.
- /// isKeyDown is required for because of keyboard state inconsistencies!
- ///
- /// VKCode
- /// Is the key down event?
- /// String representing single unicode character.
- public static string VKCodeToString(uint VKCode, bool isKeyDown)
- {
- // ToUnicodeEx needs StringBuilder, it populates that during execution.
- System.Text.StringBuilder sbString = new System.Text.StringBuilder(5);
-
- byte[] bKeyState = new byte[255];
- bool bKeyStateStatus;
- bool isDead = false;
-
- // Gets the current windows window handle, threadID, processID
- IntPtr currentHWnd = GetForegroundWindow();
- uint currentProcessID;
- uint currentWindowThreadID = GetWindowThreadProcessId(currentHWnd, out currentProcessID);
-
- // This programs Thread ID
- uint thisProgramThreadId = GetCurrentThreadId();
-
- // Attach to active thread so we can get that keyboard state
- if (AttachThreadInput(thisProgramThreadId, currentWindowThreadID, true))
- {
- // Current state of the modifiers in keyboard
- bKeyStateStatus = GetKeyboardState(bKeyState);
-
- // Detach
- AttachThreadInput(thisProgramThreadId, currentWindowThreadID, false);
- }
- else
- {
- // Could not attach, perhaps it is this process?
- bKeyStateStatus = GetKeyboardState(bKeyState);
- }
-
- // On failure we return empty string.
- if (!bKeyStateStatus)
- return "";
-
- // Gets the layout of keyboard
- IntPtr HKL = GetKeyboardLayout(currentWindowThreadID);
-
- // Maps the virtual keycode
- uint lScanCode = MapVirtualKeyEx(VKCode, 0, HKL);
-
- // Keyboard state goes inconsistent if this is not in place. In other words, we need to call above commands in UP events also.
- if (!isKeyDown)
- return "";
-
- // Converts the VKCode to unicode
- int relevantKeyCountInBuffer = ToUnicodeEx(VKCode, lScanCode, bKeyState, sbString, sbString.Capacity, (uint)0, HKL);
-
- string ret = "";
-
- switch (relevantKeyCountInBuffer)
- {
- // Dead keys (^,`...)
- case -1:
- isDead = true;
-
- // We must clear the buffer because ToUnicodeEx messed it up, see below.
- ClearKeyboardBuffer(VKCode, lScanCode, HKL);
- break;
-
- case 0:
- break;
-
- // Single character in buffer
- case 1:
- ret = sbString[0].ToString();
- break;
-
- // Two or more (only two of them is relevant)
- case 2:
- default:
- ret = sbString.ToString().Substring(0, 2);
- break;
- }
-
- // We inject the last dead key back, since ToUnicodeEx removed it.
- // More about this peculiar behavior see e.g:
- // http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_23453780.html
- // http://blogs.msdn.com/michkap/archive/2005/01/19/355870.aspx
- // http://blogs.msdn.com/michkap/archive/2007/10/27/5717859.aspx
- if (lastVKCode != 0 && lastIsDead)
- {
- System.Text.StringBuilder sbTemp = new System.Text.StringBuilder(5);
- ToUnicodeEx(lastVKCode, lastScanCode, lastKeyState, sbTemp, sbTemp.Capacity, (uint)0, HKL);
- lastVKCode = 0;
-
- return ret;
- }
-
- // Save these
- lastScanCode = lScanCode;
- lastVKCode = VKCode;
- lastIsDead = isDead;
- lastKeyState = (byte[])bKeyState.Clone();
-
- return ret;
- }
-
- private static void ClearKeyboardBuffer(uint vk, uint sc, IntPtr hkl)
- {
- System.Text.StringBuilder sb = new System.Text.StringBuilder(10);
-
- int rc;
- do
- {
- byte[] lpKeyStateNull = new Byte[255];
- rc = ToUnicodeEx(vk, sc, lpKeyStateNull, sb, sb.Capacity, 0, hkl);
- } while (rc < 0);
- }
- #endregion
- }
- #endregion
-}
\ No newline at end of file
diff --git a/Pilz.Input/Pilz.Input.csproj b/Pilz.Input/Pilz.Input.csproj
deleted file mode 100644
index f476fc7..0000000
--- a/Pilz.Input/Pilz.Input.csproj
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- net5.0-windows7.0
- true
-
-
-
diff --git a/Pilz.sln b/Pilz.sln
index 746f885..548cbb6 100644
--- a/Pilz.sln
+++ b/Pilz.sln
@@ -31,8 +31,6 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Networking", "Pilz.Net
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pilz.Cryptography", "Pilz.Cryptography\Pilz.Cryptography.csproj", "{3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pilz.Input", "Pilz.Input\Pilz.Input.csproj", "{6F52431D-5D7D-4A6F-AF88-29575F4196B3}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -153,14 +151,6 @@ Global
{3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}.Release|Any CPU.Build.0 = Release|Any CPU
{3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}.Release|x86.ActiveCfg = Release|Any CPU
{3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}.Release|x86.Build.0 = Release|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Debug|x86.ActiveCfg = Debug|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Debug|x86.Build.0 = Debug|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Release|Any CPU.Build.0 = Release|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Release|x86.ActiveCfg = Release|Any CPU
- {6F52431D-5D7D-4A6F-AF88-29575F4196B3}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE