这个简单的捕获键可以作为独立的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.
但是当我将它集成到我的项目中时,它会捕获中文或无意义的密钥!
知道为什么吗?
答案 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;
有关详情,请参阅在线帮助。
此外,对键进行轮询是一种糟糕的方法,无论如何它会杀死笔记本电脑上的电池,因为它会阻止系统进入睡眠状态。如果您等待键*事件,您的系统可以进入睡眠状态,保留电池。