针对上一个版本再次改良,上除掉无用代码,新手绝对可以看懂!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection; namespace BookLibraryManagement.CommonTools
{
class BarCodeHook
{
public delegate void BarCodeDelegate(BarCodes barCode);
public event BarCodeDelegate BarCodeEvent; public struct BarCodes
{
public int VirtKey; //虚拟码
public int ScanCode; //扫描码 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;
} [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); delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); BarCodes barCode = new BarCodes();
int hKeyboardHook = 0;
List<char> _barcode = new List<char>(100);
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; //扫描码 if (DateTime.Now.Subtract(barCode.Time).TotalMilliseconds > 100)
{
_barcode.Clear();
}
else
{
if ((msg.message & 0xff) == 13 && _barcode.Count > 0) //回车
{
barCode.BarCode = new String(_barcode.ToArray());
barCode.IsValid = true;
_barcode.Clear();
}
} barCode.Time = DateTime.Now;
if (BarCodeEvent != null) BarCodeEvent(barCode); //触发事件
barCode.IsValid = false;
_barcode.Add(Convert.ToChar(msg.message & 0xff));
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
} private static HookProc hookproc;
// 安装钩子
public bool Start()
{
if (hKeyboardHook == 0)
{
hookproc = new HookProc(KeyboardHookProc);
//WH_KEYBOARD_LL = 13
hKeyboardHook = SetWindowsHookEx(13, hookproc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
}
return (hKeyboardHook != 0);
} // 卸载钩子
public bool Stop()
{
if (hKeyboardHook != 0)
{
return UnhookWindowsHookEx(hKeyboardHook);
}
return true;
}
}
}

无焦点下获取条码枪返回值的Hook(再次改良版)的更多相关文章

  1. 无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)

    1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...

  2. python使用threading获取线程函数返回值的实现方法

    python使用threading获取线程函数返回值的实现方法 这篇文章主要介绍了python使用threading获取线程函数返回值的实现方法,需要的朋友可以参考下 threading用于提供线程相 ...

  3. 统计文件种类数+获取子shell返回值的其它方法

    前言 只是作为一个shell的小小练习和日常统计用,瞎折腾的过程中也是摸到了获取子shell返回值的几种方法: 肯定还有别的方法,跟进程间的通信相关,希望你能提出建议和补充,谢谢~ 完整程序: #! ...

  4. web3调用call()方法获取不到返回值

    一.web3的call()获取不到返回值问题和解决方法 在彩票小合约中,遇到一个问题:合约中 有两个方法 第一个返回一个账户地址,没有使用到当前方法调用者信息: 第二个使用到了当前方法调用者信息 在w ...

  5. 利用SQLServer查询分析器获取存储过程的返回值,检查测试存储过程

    1.存储过程没有返回值的情况(即存储过程语句中没有return之类的语句)用方法 int count = ExecuteNonQuery(..)执行存储过程其返回值只有两种情况(1)如果通过查询分析器 ...

  6. python asyncio 获取协程返回值和使用callback

    1. 获取协程返回值,实质就是future中的task import asyncioimport timeasync def get_html(url): print("start get ...

  7. Python建立多线程任务并获取每个线程返回值

    1.进程和线程 (1)进程是一个执行中的程序.每个进程都拥有自己的地址空间.内存.数据栈以及其他用于跟踪执行的辅助数据.进程也可以派生新的进程来执行其他任务,不过每个新进程都拥有自己的内存和数据栈,所 ...

  8. .NET C#-- 利用BeginInvoke与EndInvoke完成异步委托方法并获取方法执行返回值示例

    //定义委托 delegate string MyDelegate(string name); //定义委托调用函数 public string Hello(string name) { Thread ...

  9. C++11获取线程的返回值

    C++11 std::future and std::promise 在许多时候,我们会有这样的需求--即我们想要得到线程返回的值. 但是在C++11 多线程中我们注意到,std::thread对象会 ...

随机推荐

  1. python 翻转棋(othello)

    利用上一篇的框架,再写了个翻转棋的程序,为了调试minimax算法,花了两天的时间. 几点改进说明: 拆分成四个文件:board.py,player.py,ai.py,othello.py.使得整个结 ...

  2. EJB开发第一期---EJB开发配置

    一.EJB 3.0简介 1.1 什么是EJB Enterprise JavaBeans是一个用于分布式业务应用的标准服务端组件模型.采用Enterprise JavaBeans架构编写的应用是可伸缩的 ...

  3. Hadoop日记Day16---命令行运行MapReduce程序

    一.代码编写 1.1 单词统计 回顾我们以前单词统计的例子,如代码1.1所示. package counter; import java.net.URI; import org.apache.hado ...

  4. Qt控件使用汇总

    QTableWidget: //tab居中显示 QTabWidget::tab-bar { alignment: center; } //tab边框样式,边框颜色,前景色 QTabBar::tab { ...

  5. Selenium-Switch与SelectApi接口详解

    Switch 我们在UI自动化测试时,总会出现新建一个tab页面.弹出一个浏览器级别的弹框或者是出现一个iframe标签,这时我们用WebDriver提供的Api接口就无法处理这些情况了.需要用到Se ...

  6. PowerBI开发 第八篇:查询参数

    在PowerBI Desktop中,用户可以定义一个或多个查询参数(Query Parameter),参数的功能是为了实现PowerBI的参数化编程,使得Data Source的属性.替换值和过滤数据 ...

  7. js 边写边出现刚写的内容

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 【亲测有效】Nodepad++/Sublime Text3中Python脚本运行出现语法错误:IndentationError: unindent does not match any outer indentation level解决策略

    我在开发游戏的时候,发现一个python脚本,本来都运行好好的,然后写了几行代码,而且也都确保每行都对齐了,但是运行的时候,却出现语法错误: IndentationError: unindent do ...

  9. Markdown基本使用方法

    最近开通了博客,看到网上好多推荐markdown的,而且博客园支持markdown,所以决定学习一下. 百度百科对markdown的介绍: Markdown是一种可以使用普通文本编辑器编写的标记语言, ...

  10. Unity3D与C#网站收藏

    siki学院(目前学习ing) http://www.sikiedu.com/ 雨松MOMO研究院 http://www.xuanyusong.com/ 知乎:Unity 开发教程相关回答(初步了解下 ...