WinForm 无焦点获取键盘输入
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices; namespace **.Forms
{
/// <summary>
/// 获取键盘输入或者USB扫描枪数据 可以是没有焦点 应为使用的是全局钩子
/// USB扫描枪 是模拟键盘按下
/// 这里主要处理扫描枪的值,手动输入的值不太好处理
/// </summary>
public class BardCodeHook
{
public delegate void BardCodeDeletegate(BarCodes barCode);
public event BardCodeDeletegate BarCodeEvent; //定义成静态,这样不会抛出回收异常
private static HookProc hookproc; public struct BarCodes
{
public int VirtKey;//虚拟吗
public int ScanCode;//扫描码
public string KeyName;//键名
public uint Ascll;//Ascll
public char Chr;//字符 public string OriginalChrs; //原始 字符
public string OriginalAsciis;//原始 ASCII public string OriginalBarCode; //原始数据条码 public bool IsValid;//条码是否有效
public DateTime Time;//扫描时间, public string BarCode;//条码信息 保存最终的条码
} private struct EventMsg
{
public int message;
public int paramL;
public int paramH;
public int Time;
public int hwnd;
} #region DllImport [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);
#endregion delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
BarCodes barCode = new BarCodes();
int hKeyboardHook = ;
StringBuilder sbBarCode = new StringBuilder(); private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
int i_calledNext = -;
if (nCode == )
{
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();
if (GetKeyNameText(barCode.ScanCode * , strKeyName, ) > )
{
barCode.KeyName = strKeyName.ToString().Trim(new char[] { ' ', '\0' });
}
else
{
barCode.KeyName = "";
}
byte[] kbArray = new byte[];
uint uKey = ;
GetKeyboardState(kbArray); if (ToAscii(barCode.VirtKey, barCode.ScanCode, kbArray, ref uKey, ))
{
barCode.Ascll = uKey;
barCode.Chr = Convert.ToChar(uKey); barCode.OriginalChrs += " " + Convert.ToString(barCode.Chr);
barCode.OriginalAsciis += " " + Convert.ToString(barCode.Ascll); barCode.OriginalBarCode += Convert.ToString(barCode.Chr); } TimeSpan ts = DateTime.Now.Subtract(barCode.Time); if (ts.TotalMilliseconds > )
{//时间戳,大于50 毫秒表示手动输入
sbBarCode.Remove(, sbBarCode.Length);
sbBarCode.Append(barCode.Chr.ToString()); barCode.OriginalChrs = " " + Convert.ToString(barCode.Chr);
barCode.OriginalAsciis = " " + Convert.ToString(barCode.Ascll); barCode.OriginalBarCode = Convert.ToString(barCode.Chr); }
else
{
if ((msg.message & 0xff) == && sbBarCode.Length > )
{//回车 barCode.BarCode = barCode.OriginalBarCode; barCode.IsValid = true;
sbBarCode.Remove(, sbBarCode.Length);
} sbBarCode.Append(barCode.Chr.ToString());
} try
{
if (BarCodeEvent != null && barCode.IsValid)
{ //barCode.BarCode = barCode.BarCode.Replace("\b", "").Replace("\0",""); 可以不需要 因为大于50毫秒已经处理
//先进行 WINDOWS事件往下传
i_calledNext = CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
GC.KeepAlive(hookproc); BarCodeEvent(barCode);//触发事件 barCode.BarCode = ""; barCode.OriginalChrs = "";
barCode.OriginalAsciis = "";
barCode.OriginalBarCode = "";
}
}
catch
{
}
finally
{
barCode.IsValid = false; //最后一定要 设置barCode无效
barCode.Time = DateTime.Now;
}
}
}
if (i_calledNext == -)
{
i_calledNext = CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
GC.KeepAlive(hookproc);
}
return i_calledNext;
} /// <summary>
/// 安装钩子
/// </summary>
/// <returns></returns>
public bool Start()
{
if (hKeyboardHook == )
{
hookproc = new HookProc(KeyboardHookProc); //GetModuleHandle 函数 替代 Marshal.GetHINSTANCE
//防止在 framework4.0中 注册钩子不成功
IntPtr modulePtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); //WH_KEYBOARD_LL=13
//全局钩子 WH_KEYBOARD_LL
// hKeyboardHook = SetWindowsHookEx(13, hookproc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0); hKeyboardHook = SetWindowsHookEx(, hookproc, modulePtr, ); //IntPtr intPtr = Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]);
//hKeyboardHook = SetWindowsHookEx(13, hookproc, intPtr, 0); GC.KeepAlive(hookproc);
}
return (hKeyboardHook != );
} /// <summary>
/// 卸载钩子
/// </summary>
/// <returns></returns>
public bool Stop()
{
if (hKeyboardHook != )
{
return UnhookWindowsHookEx(hKeyboardHook);
}
return true;
} }
}
使用方法:
private void Form_Load(object sender, EventArgs e)
{
bardCodeHook.Start();
bardCodeHook.BarCodeEvent += bardCodeHook_BarCodeEvent;
} private void Form_FormClosed(object sender, FormClosedEventArgs e)
{
bardCodeHook.Stop();
bardCodeHook.BarCodeEvent -= bardCodeHook_BarCodeEvent;
}
WinForm 无焦点获取键盘输入的更多相关文章
- 获取键盘输入或者USB扫描枪数据
/// <summary> /// 获取键盘输入或者USB扫描枪数据 可以是没有焦点 应为使用的是全局钩子 /// USB扫描枪 是模拟键盘按下 /// 这里主要处理扫描枪的值,手动输入的 ...
- 在Delphi中使用键盘勾子获取键盘输入(译--5月7日)
http://blog.sina.com.cn/s/blog_502b2e970100949s.html 获取键盘输入以控制无法接受输入焦点的控件考虑一些游戏,显示图片在TPainBox,但是TPai ...
- C# 无焦点获取扫码枪扫码信息
代码网上有的是,多是需要窗体焦点直接show出扫码信息(usb,模拟键盘,hook) 怎样才能真的无焦点获取? 用串口方式 usb转串口 以接收串口通讯消息的方式获取扫码信息
- Go 获取键盘输入,进制转换
#### Go 获取键盘输入,进制转换 最近爱上<<珂矣的心灵独语>> 连续听一下礼拜也不觉得厌: 喜欢她的宁静与安然,喜欢她的坦荡与欢喜,喜欢她的禅意与智慧; ***撑着一苇 ...
- java利用Scanner获取键盘输入
首发地址:我的网易博客 在运行一个java程序的时候,可能我们需要在运行的时候传递一些参数进去...咋办呢... java提供了一个Scanner类,利用这个类,我们可以很方便的获取键盘输入的参数.. ...
- java 获取键盘输入常用的两种方法
java 获取键盘输入常用的两种方法 方法1: 通过 Scanner Scanner input = new Scanner(System.in); String s = input.nextLine ...
- tkinter获取键盘输入
tkinter获取键盘输入
- Java编程中获取键盘输入实现方法及注意事项
Java编程中获取键盘输入实现方法及注意事项 1. 键盘输入一个数组 package com.wen201807.sort; import java.util.Scanner; public clas ...
- Java基础 - 获取键盘输入
package com.demo3; import java.util.Scanner; /* * 使用 Scanner 获取键盘输入供程序使用 * * 使用步骤: * A:导包 * import j ...
随机推荐
- 从内核3.7版本开始,Linux就开始支持VXLAN 到了内核3.12版本,Linux对VXLAN的支持已经完备,支持单播和组播,IPv4和IPv6。
一.关于VXLAN VXLAN 是 Virtual eXtensible LANs 的缩写,它是对 VLAN 的一个扩展,是非常新的一个 tunnel 技术,在Open vSwitch中应用也非常多. ...
- 前端性能测试工具 : dynaTrace Ajax (还没写完)
今天开始写这个工具, #什么是dynaTrace Ajax? 随着 jQuery.Dojo.YUI 等框架的兴起让构建 Web2.0 应用更加容易,但随之带来的定位等应用问题也越来越难,尤其是与性能相 ...
- js监听浏览器剪贴板
function setClipboardText(event){ event.preventDefault(); var node = document.createElement('div'); ...
- 【转载】 linux系统dig和nslookup的安装
原文地址: https://blog.csdn.net/bjbs_270/article/details/7003088 --------------------------------------- ...
- dart里面的时间处理:
原文地址:https://www.cnblogs.com/wyhlightstar/p/11059942.html 1.获取当前时间 var now = new DateTime.now(); pri ...
- 【Java】Spring之控制反转(IoC)(二)
控制反转(IoC) IoC:Inverse of Control(控制反转) 读作“反转控制”,更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来 ...
- matlab学习笔记4--MAT文件的保存和读取
一起来学matlab-matlab学习笔记4 数据导入和导出_1 MAT文件的保存和读取 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用&g ...
- 123457123456#0#----com.DoraGame.ErTongFanPai97--前拼后广--记忆翻牌-doraX
com.DoraGame.ErTongFanPai97--前拼后广--记忆翻牌-doraX
- kafka如果有多个patition,消费消息的时候消息是没有顺序的
创建一个2个分区,3个副本的topic,名字叫first kafka-topics.sh --create --zookeeper datanode1:2181 --partitions 2 --r ...
- -webkit-overflow-scrolling : touch 快速滚动 回弹 效果
现在很多for Mobile的HTML5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼. 要实现这个效果很简单,只需要在元素上加一行css代码即可: -webkit-overflo ...