【Delphi】Windows系统下的键盘钩子

这篇博客介绍了如何通过设置Windows键盘钩子(WH_KEYBOARD)来捕获并处理得力扫码枪模拟的键盘输入。作者详细阐述了键盘钩子回调函数KeyHook的实现,包括在接收到回车键时显示输入内容,并在特定字符组合出现时执行特定功能。文章还展示了代码示例,解释了因key_up和key_down导致的输入重复问题,并给出了理想与非理想效果的对比。
摘要由CSDN通过智能技术生成

目的:为了实现得力牌扫码枪的输入,并执行特定功能。
场景描述:此款扫码枪模拟键盘信号,并支持以回车、换行等结尾,这里采用回车结尾进行开发。

思路:使用Windows的钩子回调函数,这里模拟键盘信号所以用WH_KEYBOARD设置键盘钩子,再用键盘钩子回调函数KeyHook来进行具体的定制功能开发。

设置键盘钩子
[SetWindowsHookEx——API文档]https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa

hook: HHOOK; { 定义一个钩子句柄 }
hook := SetWindowsHookEx(WH_KEYBOARD, @KeyHook, 0, GetCurrentThreadID);

键盘钩子回调主体(加上stdcall可以不定义直接使用)
[KeyboardProc——API文档]https://docs.microsoft.com/en-us/windows/win32/winmsg/keyboardproc

function KeyHook(nCode: Integer; wParam: wParam; lParam: lParam)
  : LRESULT; stdcall;
  begin
      //尽情写代码
      Result := CallNextHookEx(hook, nCode, wParam, lParam);
  end;


释放键盘钩子

UnhookWindowsHookEx(hook);

回调函数核心代码

function KeyHook(nCode: Integer; wParam: wParam; lParam: lParam)
  : LRESULT; stdcall;
const
  _KeyUp = $80000000; // 键盘弹起
  _KeyDown = $00000000; // 键盘按下
begin
  // ShowMessage('进入钩子nCode:' + IntToStr(nCode));
  if nCode < 0 then
  begin
    Result := CallNextHookEx(hook, nCode, wParam, lParam);
    exit;
  end
  // HC_ACTION表示钩子中有消息
  else if nCode = HC_ACTION then
  begin
    if (lParam and _KeyUp) = _KeyUp then
    begin
      ShowMessage('键盘弹起');
    end
//    else if (lParam and _KeyDown) = _KeyDown then
//    begin
//      ShowMessage('键盘按下');
//    end
    else if (wParam >= $30) and (wParam <= $39) then // 数字
    begin
      yydsQrParms := yydsQrParms + IntToStr(wParam - $30);
    end
    else if (wParam >= $41) and (wParam <= $5A) then // 字母全部转为小写
    begin
      yydsQrParms := yydsQrParms + Char(wParam + 32);
    end
    else if (wParam = VK_OEM_5) then // VK_OEM_5表示'|'
    begin
      if yydsQrParms = 'yyds' then
      begin
        yydsQrParms := yydsQrParms + '|';
      end
      else
      begin
        ShowMessage('清空前打印:' + yydsQrParms);
        yydsQrParms := '';
      end;
    end
    else if (wParam = VK_RETURN) then // 回车键
    begin
      MessageBox(0, PChar('最终结果:' + yydsQrParms), '', MB_OK);
      yydsQrParms := '';
    end;
  end;
  Result := CallNextHookEx(hook, nCode, wParam, lParam);
end;

个人总结:每一个键盘消息回调函数的nCode都为HC_ACTION(0),然后如果没有判断会有输入两次的情况,是因为key_up和key_down造成的。上述代码以[回车]判断终止进行弹窗。

输入2次,非预期效果如下图:

 

 输入1次,完美效果如下图:

又一个delphi键盘钩子用法及代码,可以截获几乎所有键值,例如:shift ?,ctrl ?,alt ?,F1~F12,shift或者ctrl或者alt F1~F12,单独的 shift、ctrl、alt 键值,特殊键ins、del、caps lock、num lock、小键盘数字 等等,你只要稍作修改,也可以截获 ctrl alt ?等键值,没有截获不到的键值,本程序不使用dll方式,使用常规方式,方便你编译调试修改,支持xp、vista、win7,是最强悍的键盘钩子控件, 在delphi7下通过。   myshiftchar:string;//返回shift状态 例如 ctrl   mypresschar:string;//返回整个键值 例如 ctrl g   dulictrl:string;//返回 ctrl 和 alt 单独状态, =ctrl or =alt   安装方法:   本控件的核心源代码在 unit2   首先 创建调用主窗体,假定是form1,在form1上放一个 memo控件(必须),然后创建一个新单元 如unit2,把我的unit2 单元的源代码全部复制过去,做以下修改,首先确保form1使用 新单元 如unit2,并且unit2也使用form1。   在新单元unit2中 ,找到 函数 function KeyBHkHandle 过程,在其中找到以下两条语句:    // 在这里根据自己的情况修改    form1.Memo1.Lines.Add(mypresschar);   // 在这里根据自己的情况修改    if mypresschar'' then form1.Memo1.Lines.Add(mypresschar);   如果你的调用主窗体就叫form1,则不用修改,否则把这两条语句的form1修改为你的调用主窗体的名字。   在 memo编辑框的onChange事件中编写自己的 键盘消息接受主控制过程,其中 字符串mypresschar 返回总键值,它跟memo编辑框中显示值是一样的 ,例如 g、shift g、ctrl 2、F9、alt F9、 等等,其中 字符串shiftstr 返回 控制键 shift ctrl alt 的状态,例如按下ctrl,则 shiftstr=‘ctrl’ ,否则=''。   最后不要忘记在程序退出时卸载键盘钩子
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值