Я просматриваю код в программе, и у них есть следующий код в TTimer
:
procedure TMyMain.CaptureKeyTimerTimer(Sender: TObject);
var
keyloop, KeyResult : Integer;
begin
KeyResult := GetAsyncKeyState(117);
if (KeyResult = -32767) then
Button90Click(Sender);
end;
Я пытаюсь понять, что означает и делает этот код, но это сбивает с толку.
Может ли кто-нибудь объяснить мне код? Что такое GetAsyncKeyState(117)
? Что означает 117
, передаваемый в функцию? Что значит, если оно равно -32767
?
Все сбивает с толку.
117 — это ключ F6
— см. это и это. Состояние (значение KeyResult
) зависит от того, нажата клавиша или нет.
На этот вопрос очень легко ответить, просто посмотрев документацию рассматриваемой функции. Это заставляет меня думать, что вы не знаете о существовании такой документации. Фактически все, что вам нужно сделать, это ввести имя функции в поисковую систему. Настоящий вывод заключается в том, что вам будет полезно освоить этот навык.
«Все запутанно» — для новичка может быть. Почему keyloop
объявлен, но никогда не используется?
@AmigoJack Я новичок. Я не уверен, почему объявлен keyloop
. Это не мой код.
GetAsyncKeyState() принимает на вход Код виртуального ключа , где 117 (шестнадцатеричный 0x75) представляет собой ключ F6 (автору следовало использовать константу VK_F6
в модуле Windows
- держитесь подальше от магических чисел! ).
Согласно документации GetAsyncKeyState()
:
Возвращаемое значение
Тип: КОРОТКИЙ
Если функция завершается успешно, возвращаемое значение указывает, была ли клавиша нажата с момента последнего вызова GetAsyncKeyState и находится ли клавиша в данный момент нажатой или нажатой. Если установлен старший бит, клавиша нажата, а если установлен младший бит, клавиша была нажата после предыдущего вызова GetAsyncKeyState. Однако вам не следует полагаться на последнее поведение; дополнительную информацию см. в Примечаниях.
-32767
в десятичном формате — 0x8001
в шестнадцатеричном и 1000000000000001
в двоичном. Итак, вы можете видеть, что два бита, упомянутые в документе выше, установлены в 1.
Поскольку код проверяет именно это значение, автор хочет знать, когда оба бита установлены одновременно, IOW, когда клавиша F6 перешла из состояния ВВЕРХ в состояние ВНИЗ с момента предыдущего вызова GetAsyncKeyState()
.
Автор мог бы легко использовать событие OnKeyDown
формы для обнаружения нажатия F6, но он, вероятно, сделал это таким образом, чтобы обнаружить нажатие, даже если форма не имеет фокуса клавиатуры. Есть и другие способы сделать это более точно, например, с помощью низкоуровневого перехвата клавиатуры или Raw Input, но их немного сложнее кодировать, чем этот простой таймер.
Спасибо. Это отличное объяснение. Меня все еще немного смущает значение -32767
. Какие еще варианты есть кроме -32767
?
Если вы прочитали процитированную мною документацию, то возможны только 4 случая: 1) оба бита не установлены = 0
, шестнадцатеричный 0x0000
; 2) установлен только младший бит = 1
, шестнадцатеричный 0x0001
; 3) установлен только старший бит = -32768
, шестнадцатеричный 0x8000
; и 4) оба бита установлены = -32767
, шестнадцатеричное 0x8001
. Если вы не понимаете эти значения, вам нужно прочитать о том, как компьютерные двоичные числа работают на битовом уровне, и о взаимосвязи между двоичной, десятичной и шестнадцатеричной системами счисления.
Не используйте Delphi, но, скорее всего, это: Learn.microsoft.com/en-us/windows/win32/api/winuser/…