我被要求开发一个新的应用程序,它将与现有应用程序一起工作。两个应用程序都将等待条形码阅读器输入。我不希望我们的操作员扫描条形码两次:一次用于现有应用程序(16位 - 限幅器,无源),一次用于新应用程序。为了解决这个问题,我决定使用一个低级键盘钩子(用Delphi编写)。它看起来很完美,因为2个应用程序需要条形码阅读器输入,而且我的应用程序在大多数时间都不会聚焦。
当我的应用程序集中时,我的低级键盘钩子工作正常。例如,如果我进入TEdit控件然后我扫描条形码:
当我的应用程序不再集中时,事情变得越来越糟:如果我打开记事本然后我扫描条形码:
看起来键盘状态没有考虑在内!看起来我不再考虑Shift,Ctrl或甚至Alt键。在我的法语键盘上:
现在有人如何解决这个问题? 我是以错误的方式做的(我应该使用Windows消息吗?)。提前谢谢。
FWIW这是我的源代码:
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.
答案 0 :(得分:3)
我今天遇到了这个问题,并通过在GetKeyboardState(KeyState)之后添加这些行来解决;
KeyState[VK_CAPITAL] := GetKeyState(VK_CAPITAL);
KeyState[VK_SHIFT] := GetKeyState(VK_SHIFT);
KeyState[VK_CONTROL] := GetKeyState(VK_CONTROL);
KeyState[VK_MENU] := GetKeyState(VK_MENU);
答案 1 :(得分:2)