1

既存のアプリケーションと一緒に動作する新しいアプリケーションを開発するように依頼されました。両方のアプリケーションは、バーコードリーダーの入力を待ちます。オペレーターにバーコードを2回スキャンさせたくありません。1回は既存のアプリケーション(16ビット-クリッパー、ソースなし)で、もう1回は新しいアプリケーションです。この問題を解決するために、低レベルのキーボードフック(Delphiで記述)を使用することにしました。2つのアプリケーションがバーコードリーダー入力を必要とし、私のアプリケーションがほとんどの時間焦点を合わせられないので、それは完璧に見えます。

私のアプリケーションがフォーカスされているとき、私の低レベルのキーボードフックはうまく機能しています。たとえば、TEditコントロールを入力してから、バーコードをスキャンした場合:

  • 待機中の文字がTEditコントロール(#02; 90BDIJ#)に表示されます。
  • 低レベルのフックはすべての文字を取得します(#、次に0、次に2など)。

アプリケーションの焦点が合わなくなると、状況はさらに悪化します。メモ帳を開いてからバーコードをスキャンすると、状況はさらに悪化します。

  • 待機中の文字がメモ帳(#02; 90BDIJ#)に表示されます。
  • 低レベルのフックは間違った文字を取得します:"àé;çàbdij"

キーボードの状態が考慮されていないようです。Shiftキー、Ctrlキー、またはAltキーも考慮されていないようです。私のフランス語キーボードでは:

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

誰かが今この問題を解決する方法はありますか?私はそれを間違った方法で行っていますか(代わりに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.
4

2 に答える 2

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);
于 2012-05-07T10:35:38.563 に答える
2

これはローカルキーボードフックです。それがどこでも機能するためには、グローバルフックを作成する必要があります。グローバルキーボード(およびマウス)フックは、別の.dllに実装する必要があります。

アップデート:

訂正されました。どうやらこれはdllに実装する必要はありません。

于 2009-10-19T22:13:01.840 に答える