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