低级别的键盘挂钩问题:当应用程序未聚焦时,键盘状态丢失(Delphi) [英] Low-level keyboard hook issue : Keyboard state losed when application is not focused (Delphi)

查看:118
本文介绍了低级别的键盘挂钩问题:当应用程序未聚焦时,键盘状态丢失(Delphi)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已要求我开发一个新应用程序,该应用程序可与现有应用程序一起使用.两个应用程序都将等待条形码读取器的输入.我不希望我们的操作员扫描条形码两次:一次扫描现有的应用程序(16位-剪切器,无源),一次扫描新的应用程序.为了解决此问题,我决定使用低级键盘挂钩(用Delphi编写).看起来很完美,因为2个应用程序将需要条形码读取器输入,并且我的应用程序通常不会被关注.

I've been asked to develop a new application that will work along side the existing one. Both application will wait for a barcode reader input. I don't want our operator to scan a barcode twice: once for the existing application (16bit - clipper, no sources) and once for the new application. To solves this issue I've decided to use a low-level keyboard hook (written in Delphi). It looks perfect since 2 applications will need the barcode reader input and that my application will not be focused the most of the time.

当我的应用程序集中精力时,我的低级键盘挂钩可以正常工作.例如,如果我输入一个TEdit控件,然后扫描我的条形码:

My low-level keyboard hook is well working when my application is focused. For example, if I enter into a TEdit control and then if I scan my barcode :

  • 等待的字符将是显示在TEdit控件中(#02; 90BDIJ#).
  • 低级挂钩将获取所有字符(#,然后是0,然后是2,依此类推上).

当我的应用程序不再集中时,情况变得越来越糟:如果我打开记事本,然后再扫描条形码:

Things are getting worse when my application is no more focused : if I open notepad and then if I scan my barcode :

  • 等待的字符将是显示在记事本(#02; 90BDIJ#)中.
  • 低级挂钩会出现错误字符:àé;çàbdij"

似乎未考虑键盘状态!似乎不再考虑Shift,Ctrl甚至Alt键.在法语键盘上:

It looks like the Keyboard state is no taken in account ! It looks like the Shift, Ctrl or even Alt keys are no more taken in account.On my french keyboard :

  • '#'= CTRL = ALT +"
  • '0'= SHIFT +à
  • '2'= SHIFT +é
  • ...

现在有人可以解决这个问题吗?我做错了吗(我应该改用Windows消息吗?).预先谢谢你.

Does anyone now how to solve this problem ? Am I doing it the wrong way (should I use windows messages instead ?). Thank you in advance.

FWIW这是我的源代码:

FWIW Here is my source code :

unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Math;

const
  LLKHF_UP             =  $0080;

type
  tagKBDLLHOOKSTRUCT =  packed record
    vkCode :            DWORD;
    scanCode :          DWORD;
    flags :             DWORD;
    time :              DWORD;
    dwExtraInfo :       Integer;
  end;
  KBDLLHOOKSTRUCT      =  tagKBDLLHOOKSTRUCT;
  PKBDLLHOOKSTRUCT     =  ^KBDLLHOOKSTRUCT;

var
  hkHook : HHook;
  function LowLevelKeyboardProc(Code, wParam, lParam: Integer): Integer; stdcall;
  procedure HookIt;
  procedure UnHookIt;

implementation

uses Unit1;

procedure HookIt;
begin
  hkHook := SetWindowsHookEx(WH_KEYBOARD_LL,@LowLevelKeyboardProc,hInstance,0);
end;

procedure UnHookIt;
begin
  UnHookWindowsHookEx(hkHook);
end;

function LowLevelKeyboardProc(Code, wParam, lParam: Integer): Integer;
var
  KeyState : TKeyboardState;
  NewChar: array[0..1] of Char;
  Hook : PKBDLLHOOKSTRUCT;
  bControlKeyDown : Boolean;
begin
  Try
    Hook := Pointer(lParam);
    Case Code Of
      HC_ACTION:
        begin
            If (Hook^.flags And LLKHF_UP) <> 0 Then
            begin
              FillChar(NewChar,2,#0);
              GetKeyboardState(KeyState);
              If ToAscii(Hook^.vkCode,Hook^.scanCode,KeyState,NewChar,0) = 1 Then
                    Form1.ListBox1.Items.Add(NewChar[0]);
            end;
        end;boar
      end;
  Finally
     Result := CallNextHookEx(hkHook,Code,wParam,lParam);
  end;
end;

end.

推荐答案

这是本地键盘挂钩.您需要创建一个全局挂钩,以便它可以在任何地方使用.全局键盘(和鼠标)钩子需要在单独的.dll中实现.

This is a local keyboard hook. You need to create a global hook for it to work everywhere. Global keyboard (and mouse) hooks need to be implemented in a separate .dll.

更新:

我已改正.显然,这不需要在dll中实现.

I have been corrected. Apparently this does not need to be implemented in a dll.

这篇关于低级别的键盘挂钩问题:当应用程序未聚焦时,键盘状态丢失(Delphi)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆