我正在尝试确定按钮的OnKeyDown中按下的键(FMX,XE3),但我目前发现自己无法区分小键盘键和常规键......
根据我按下的键,我可以使用Key或KeyChar找出已按下的键。例如,按 F1 发送112和#0所以我可以使用VkCode,按 A 发送0和'a'所以我可以使用'a'。 KeyChar在许多情况下都是#0显然是有意义的,但是如果KeyChar存在,我无法理解为什么Key被设置为0。
function GetCharFromVirtualKey(Key: Word): string;
var Buffer: array[0..255] of Char;
ScanCode: Cardinal;
begin
if Key = VK_PAUSE
then ScanCode := $45 shl 16
else ScanCode := MapVirtualKey(Key, 0) shl 16;
if Key in [33..46, 91..93, 108, 111, 144, 163, 165]
then ScanCode := ScanCode + $1000000;
GetKeyNameText(ScanCode, Buffer, SizeOf(Buffer));
result := Buffer;
end;
procedure TMyForm.Edit1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
var test: string;
begin
if (KeyChar <> #0) then Key := VkKeyScan(KeyChar) and 255;
test := GetCharFromVirtualKey(Key);
// do whatever I want to to with Key and test
end;
我遇到的具体问题是按下常规'1'键和我的小键盘'1'键会发送KeyChar ='1'和Key = 0,所以我无法区分这两者。我能做些什么吗?
答案 0 :(得分:5)
'如果KeyChar存在,我无法理解为什么Key设置为0' - 简短回答,因为这就是FMX.Platform.Win.pas的编码方式:
WM_CHAR:
begin
ch := WideChar(wParam);
key := 0;
LForm.KeyDown(key, ch, KeyDataToShiftState(lParam));
LForm.KeyUp(key, ch, KeyDataToShiftState(lParam));
Result := 0;
end;
至于你的问题,调用GetKeyState
应该可以解决问题:
procedure TMyForm.Edit1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
Shift: TShiftState);
begin
case KeyChar of
'0'..'9':
if GetKeyState(VK_NUMPAD0 + Ord(KeyChar) - Ord('0')) < 0 then
ShowMessage('Number pad ' + KeyChar + ' pressed')
else
ShowMessage('Normal ' + KeyChar + ' pressed');
end;
end;