当集成到项目中时,简单的delphi捕获键不起作用

时间:2013-10-24 18:11:20

标签: delphi delphi-xe2 delphi-2010

这个简单的捕获键可以作为独立的VCL项目正常工作

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, DBCtrls, DBCGrids, Db, DBTables, ExtCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Timer1: TTimer;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
    FLastMsg: TMsg;

  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  capturedWord:string;
implementation

{$R *.DFM}

function GetCharFromVirtualKey(Key: Word): string;
 var
    keyboardState: TKeyboardState;
    asciiResult: Integer;
 begin
    GetKeyboardState(keyboardState) ;

    SetLength(Result, 2) ;
    asciiResult := ToAscii(key, MapVirtualKey(key, 0), keyboardState, @Result[1], 0) ;
    case asciiResult of
      0: Result := '';
      1: SetLength(Result, 1) ;
      2:;
      else
        Result := '';
    end;
 end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i,j:integer;
begin

  if ((GetAsyncKeyState(13) and 1) = 1) or ((GetAsyncKeyState(32) and 1) = 1) then begin;
      capturedWord:='';
      exit;
  end;
  For i:=32 to 128 do begin;
    if ((GetAsyncKeyState(i) and 1) = 1) then begin;
      capturedWord:=capturedWord + GetCharFromVirtualKey(i);
      capturedWord:=LowerCase(capturedWord);
       label1.Caption:=      (capturedWord);

      end;
    end;
  end;

end.

但是当我将它集成到我的项目中时,它会捕获中文或无意义的密钥!

知道为什么吗?

enter image description here

1 个答案:

答案 0 :(得分:1)

你的方法没有意义。

WM_TIMER条消息的优先级较低。如果消息队列包含更高优先级的消息,则WM_Timer消息将无法通过。

自Windows 1以来,无需轮询获取密钥 它只会获得输入片段。

不要轮询密钥
最好放弃计时器方法并在表单中使用OnKeyPress 如果你想捕获所有键OnKeyDown是要走的路。

procedure TForm1.FormCreate(Sender: TObject);
begin
  Self.KeyPreview:= true;  (*-- all keypresses get send to the form as well.*)
end;

//Takes dead keys into account
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
//                                             ^^^^^^^^^^^^^^
//                                             virtual key code.
begin
  case Key of 
    32: if Shift = ssShift then .....
end;

//Just shows the char pressed.
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  case Key of .....
end;

有关详情,请参阅在线帮助。

此外,对键进行轮询是一种糟糕的方法,无论如何它会杀死笔记本电脑上的电池,因为它会阻止系统进入睡眠状态。如果您等待键*事件,您的系统可以进入睡眠状态,保留电池。