Глобальный хук на определённую клавиатуру - C#
Формулировка задачи:
Пишу сюда, из-за отчаяния. Честно просидел в гугле 3 дня, но не нашел нужного решения.
Задача: Есть считыватель карточек (rfid reader), который вводит 10 цифр и Enter, и определяется как клавиатура.
Из-за этого программу считывания карточек нужно всегда держать активной формой, что очень не удобно.
Нужно заставить программу считывать цифры с второй клавиатуры в фоне, при этом не мешая работе за компьютером.
Сразу говорю, да это возможно(насчет c# не знаю). Нашел такую программу, которая может не только хуки ловить, но и определять на которой клавиатуре было нажатие. Программа называется "HIDmacros".
Лучше задачу сделать полностью на c#, но подскажите если знаете аналоги решения.
Решение задачи: «Глобальный хук на определённую клавиатуру»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace HookDemoApp
{
internal class MyHook
{
bool allhook = false;
List<code> collection = new List<code>();
private struct code
{
public int MyKeyCode, MyParam, MyScanCode;
public void Set(int _MyKeyCode, int _MyParam, int _MyScanCode)
{
MyKeyCode = _MyKeyCode;
MyParam = _MyParam;
MyScanCode = _MyScanCode;
}
}
private const int WH_KEYBOARD_LL = 13;
private LowLevelKeyboardProcDelegate m_callback;
private IntPtr m_hHook;
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("Kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle(IntPtr lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
private IntPtr LowLevelKeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return CallNextHookEx(m_hHook, nCode, wParam, lParam);
}
else
{
var khs = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
bool pro = false;
for (int i = 0; i < collection.Count; i++)
{
if (collection[i].MyKeyCode == khs.VirtualKeyCode && collection[i].MyParam == wParam.ToInt32() && collection[i].MyScanCode == khs.ScanCode)
pro = true;
}
if (pro || allhook)
{
IntPtr val = new IntPtr(1);
return val;
}
else
{
return CallNextHookEx(m_hHook, nCode, wParam, lParam);
}
}
}
[StructLayout(LayoutKind.Sequential)]
private struct KeyboardHookStruct
{
public readonly int VirtualKeyCode;
public readonly int ScanCode;
public readonly int Flags;
public readonly int Time;
public readonly IntPtr ExtraInfo;
}
private delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, IntPtr lParam);
public void SetHookAltTab()
{
code k = new code();
k.Set(9, 260, 15);
collection.Add(k);
m_callback = LowLevelKeyboardHookProc;
m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, m_callback, GetModuleHandle(IntPtr.Zero), 0);
}
public void SetHookAltEsk()
{
code k = new code();
k.Set(27, 260, 1);
collection.Add(k);
m_callback = LowLevelKeyboardHookProc;
m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, m_callback, GetModuleHandle(IntPtr.Zero), 0);
}
public void SetHookAltShiftEsk()
{
code k = new code();
k.Set(162, 256, 29);
collection.Add(k);
m_callback = LowLevelKeyboardHookProc;
m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, m_callback, GetModuleHandle(IntPtr.Zero), 0);
}
public void SetHookAltF4()
{
code k = new code();
k.Set(164, 260, 56);
collection.Add(k);
m_callback = LowLevelKeyboardHookProc;
m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, m_callback, GetModuleHandle(IntPtr.Zero), 0);
}
public void AllHook()
{
allhook = true;
m_callback = LowLevelKeyboardHookProc;
m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, m_callback, GetModuleHandle(IntPtr.Zero), 0);
}
public void UnHook()
{
allhook = false;
collection.Clear();
UnhookWindowsHookEx(m_hHook);
}
}
}