Answer the question
In order to leave comments, you need to log in
How to implement global KeyPress in C#?
For quite a long time I used the AutoHotKey program to automate a fairly large number of actions, and although the functionality of the program is sufficient, it is still not unlimited. In the end, I realized that this program is not the only solution and it's time to move on.
As a result, I started learning C# and now I'm trying to transfer one project to this platform, but I don't know how to work with WinApi, and more specifically, how to count keystrokes from the keyboard outside the form. Could you suggest how this is implemented?
Answer the question
In order to leave comments, you need to log in
If you need hotkeys, then use RegisterHotKey / UnregisterHotKey
If you need to catch KeyDown KeyPress KeyUp events, then use SetWindowsHookEx with the WH_KEYBOARD_LL / UnhookWindowsHookEx parameter
private bool hooked = false;
private IntPtr hHook;
private HookProc managedDelegate = InternalCallback;
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
public event KeyPressEventHandler KeyPress;
public void StartHook()
{
IntPtr delegt = Marshal.GetFunctionPointerForDelegate(managedDelegate);
hHook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, delegt, getMainModuleHandle(), 0);
if (hHook == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
}
public virtual void Unhook()
{
if (!UnhookWindowsHookEx(hHook)) throw new Win32Exception(Marshal.GetLastWin32Error());
}
protected int InternalCallback(int code, IntPtr wParam, IntPtr lParam)
{
if (code >= 0)
{
bool handled = false;
KeyboardHookStruct keyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
if (KeyDown != null && ((int)wParam == WM_KEYDOWN || (int)wParam == WM_SYSKEYDOWN))
{
Keys keyData = (Keys)keyboardHookStruct.VirtualKeyCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyDown.Invoke(null, e);
handled = e.Handled;
}
if (KeyPress != null && (int)wParam == WM_KEYDOWN)
{
//Перекодирование сканкодов в Ascii
}
if (KeyUp != null && ((int)wParam == WM_KEYUP || (int)wParam == WM_SYSKEYUP))
{
Keys keyData = (Keys)keyboardHookStruct.VirtualKeyCode;
KeyEventArgs e = new KeyEventArgs(keyData);
KeyUp.Invoke(null, e);
handled = handled || e.Handled;
}
if (handled) return 1;
}
return CallNextHookEx(hHook, code, wParam, lParam);
}
private IntPtr getMainModuleHandle()
{
IntPtr hMod;
using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
{
hMod = GetModuleHandle(module.ModuleName);
}
return hMod;
}
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(HookType hook, IntPtr callback,
IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
internal static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam,
IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
private const int
WM_KEYDOWN = 0x100,
WM_KEYUP = 0x101,
WM_SYSKEYDOWN = 0x104,
WM_SYSKEYUP = 0x105;
[StructLayout(LayoutKind.Sequential)]
private struct KeyboardHookStruct
{
/// <summary>
/// Specifies a virtual-key code. The code must be a value in the range 1 to 254.
/// </summary>
public int VirtualKeyCode;
/// <summary>
/// Specifies a hardware scan code for the key.
/// </summary>
public int ScanCode;
/// <summary>
/// Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
/// </summary>
public int Flags;
/// <summary>
/// Specifies the Time stamp for this message.
/// </summary>
public int Time;
/// <summary>
/// Specifies extra information associated with the message.
/// </summary>
public int ExtraInfo;
}
internal enum HookType : int
{
///
WH_JOURNALRECORD = 0,
///
WH_JOURNALPLAYBACK = 1,
///
WH_KEYBOARD = 2,
///
WH_GETMESSAGE = 3,
///
WH_CALLWNDPROC = 4,
///
WH_CBT = 5,
///
WH_SYSMSGFILTER = 6,
///
WH_MOUSE = 7,
///
WH_HARDWARE = 8,
///
WH_DEBUG = 9,
///
WH_SHELL = 10,
///
WH_FOREGROUNDIDLE = 11,
///
WH_CALLWNDPROCRET = 12,
///
WH_KEYBOARD_LL = 13,
///
WH_MOUSE_LL = 14
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question