1,931 questions
How to listen for keyboard input and modify it to specific input?
54890279
0
Reputation points
Hi everyone,
I have a barcode scanner that acts as a keyboard input. I need it to only input "def" when I scan "abc,def" in any input field such as webpages, applications, etc.
Below is my attempt.
public struct BarCodes
{
public int VirtKey;
public int ScanCode;
public string KeyName;
public uint Ascll;
public char Chr;
public string BarCode;
public bool IsValid;
public DateTime Time;
}
private struct EventMsg
{
public int message;
public int paramL;
public int paramH;
public int Time;
public int hwnd;
}
delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
BarCodes barCode = new BarCodes();
int hKeyboardHook = 0;
string strBarCode = "";
//install hook
public bool KeyboardStart()
{
if (hKeyboardHook == 0)
{
hookproc = new HookProc(KeyboardHookProc);
IntPtr moduleptr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
hKeyboardHook = SetWindowsHookEx(13, hookproc, moduleptr, 0);
//WH_KEYBOARD_LL=13
//hKeyboardHook = SetWindowsHookEx(13, new HookProc(KeyboardHookProc), Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
}
return (hKeyboardHook != 0);
}
//uninstall hook
public bool KeyboardStop()
{
if (hKeyboardHook != 0)
{
return UnhookWindowsHookEx(hKeyboardHook);
}
return true;
}
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if (nCode == 0)
{
EventMsg msg = (EventMsg)Marshal.PtrToStructure(lParam, typeof(EventMsg));
if (wParam == 0x100)//WM_KEYDOWN=0x100
{
barCode.VirtKey = msg.message & 0xff;
barCode.ScanCode = msg.paramL & 0xff;
StringBuilder strKeyName = new StringBuilder(225);
if (GetKeyNameText(barCode.ScanCode * 65536, strKeyName, 255) > 0)
{
barCode.KeyName = strKeyName.ToString().Trim(new char[] { ' ', '\0' });
}
else
{
barCode.KeyName = "";
}
byte[] kbArray = new byte[256];
uint uKey = 0;
GetKeyboardState(kbArray);
if (ToAscii(barCode.VirtKey, barCode.ScanCode, kbArray, ref uKey, 0))
{
barCode.Ascll = uKey;
barCode.Chr = Convert.ToChar(uKey);
}
TimeSpan ts = DateTime.Now.Subtract(barCode.Time);
if (ts.TotalMilliseconds > 50)
{
strBarCode = barCode.Chr.ToString();
}
else
{
if ((msg.message & 0xff) == 13 && strBarCode.Length > 3)
{
barCode.BarCode = strBarCode;
barCode.IsValid = true;
//methods 1
//it can run on button click event and hook,but can not run on webpages.
//------------------------------------------------
IntPtr foregroundWindow = GetForegroundWindow();
int foregroundWindowProcessId;
GetWindowThreadProcessId(foregroundWindow, out foregroundWindowProcessId);
Process foregroundProcess = Process.GetProcessById(foregroundWindowProcessId);
List<IntPtr> result = new List<IntPtr>();
int ct = 0;
IntPtr prevChild = IntPtr.Zero;
IntPtr currChild = IntPtr.Zero;
while (true && ct < 100)
{
currChild = FindWindowEx(foregroundProcess.MainWindowHandle, prevChild, null, null);
if (currChild == IntPtr.Zero) break;
result.Add(currChild);
prevChild = currChild;
++ct;
}
Point caretPos = Cursor.Position;
IntPtr target = IntPtr.Zero;
target = WindowFromPoint(caretPos);
foreach (IntPtr hWnd in result)
{
if (hWnd == target)
{
Clipboard.SetText(BarcodeSplit(strBarCode) + "\r");
SendMessage(hWnd, WM_PASTE, 0, "");
}
}
private string BarcodeSplit(string str)
{
string[] BarcodeArray = str.Split(',');
if (LimitCode.Contains(BarcodeArray[2]))
{
return BarcodeArray[0];
}
else
{
return BarcodeArray[1];
}
}
//------------------------------------------------
//methods 2
//it can not run on hook
//------------------------------------------------
IntPtr foregroundWindow = GetForegroundWindow();
//set windows focus
SetForegroundWindow(foregroundWindow);
INPUT Input = new INPUT();
Input.type = 1; //keyboard_input
Input.ki.wVk = 0x42; //CAPS_Lock
Input.ki.dwFlags = 0;
SendInput(1, ref Input, Marshal.SizeOf(Input));
//放開Caps Lock
Input = new INPUT();
Input.type = 1;
Input.ki.wVk = 0x42;
Input.ki.dwFlags = 2;//key_up
SendInput(1, ref Input, Marshal.SizeOf(Input));
//------------------------------------------------
//methods 3
//it can not run on hook
//------------------------------------------------
IntPtr foregroundWindow = GetForegroundWindow();
//set windows focus
SetForegroundWindow(foregroundWindow);
SendKeys.Send(barCode.BarCode);
//------------------------------------------------
}
strBarCode += barCode.Chr.ToString();
}
barCode.Time = DateTime.Now;
if (BarCodeEvent != null) BarCodeEvent(barCode);//觸發事件
barCode.IsValid = false;
}
}
//stop keyboard key in
return 1;
}
//Below are relevant quotes.
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
[DllImport("user32", EntryPoint = "GetKeyNameText")]
private static extern int GetKeyNameText(int IParam, StringBuilder lpBuffer, int nSize);
[DllImport("user32", EntryPoint = "GetKeyboardState")]
private static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32", EntryPoint = "ToAscii")]
private static extern bool ToAscii(int VirtualKey, int ScanCode, byte[] lpKeySate, ref uint lpChar, int uFlags);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
// Get a handle to an application window.
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
// Activate an application window.
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, uint wParam, string lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
private const int WM_SETTEXT = 0x000C;
private const int WM_PASTE = 0x0302;
[DllImport("User32.dll")]
public static extern int SendMessageW(IntPtr hWnd, int uMsg, int wParam, int lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr processId);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
internal static extern IntPtr GetFocus();
[DllImport("user32.dll")]
private static extern IntPtr GetAncestor(IntPtr hWnd, uint flags);
private const uint GA_ROOT = 2;
[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
internal static extern int AttachThreadInput(int idAttach, int idAttachTo, bool fAttach);
[DllImport("kernel32.dll")]
internal static extern int GetCurrentThreadId();
[DllImport("user32.dll")]
public static extern bool GetGUIThreadInfo(int idThread, ref GUITHREADINFO lpgui);
[StructLayout(LayoutKind.Sequential)]
public struct GUITHREADINFO
{
public int cbSize;
public uint flags;
public IntPtr hwndActive;
public IntPtr hwndFocus;
public IntPtr hwndCapture;
public IntPtr hwndMenuOwner;
public IntPtr hwndMoveSize;
public IntPtr hwndCaret;
public RECT rcCaret;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", EntryPoint = "ChildWindowFromPointEx")]//指定坐标处窗体句柄
private static extern IntPtr ChildWindowFromPointEx(IntPtr hwnd, Point pt, uint flags);
[DllImport("user32.dll")]
public static extern bool GetCaretPos(out Point lpPoint);
[StructLayout(LayoutKind.Explicit)]
internal struct INPUT
{
[FieldOffset(0)]
internal int type;//0:mouse event;1:keyboard event;2:hardware event
[FieldOffset(4)]
internal MOUSEINPUT mi;
[FieldOffset(4)]
internal KEYBDINPUT ki;
[FieldOffset(4)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
internal int uMsg;
internal short wParamL;
internal short wParamH;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
internal ushort wVk;
internal ushort wScan;
internal uint dwFlags;
internal uint time;
internal IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal int dwFlags;
internal int time;
internal IntPtr dwExtraInfo;
}
How can I modify it to achieve my desired goal?
If there are any missing parameters provided, please let me know.
Developer technologies Windows Forms
Developer technologies C#
11,570 questions
Sign in to answer