Возвращаемые значения GetAsyncKeyState не соответствуют описанию - PullRequest
2 голосов
/ 26 октября 2011

Я исследовал GetAsyncKeyState , увидев его в примере кода о том, как заставить вымышленный персонаж перемещаться по экрану с помощью клавиш WASD.

Я прочитал это на странице MSDN:

Возвращаемое значение

Тип: КОРОТКИЙ

Если функция завершается успешно, возвращаемое значение указывает, является ли ключ был нажат с момента последнего вызова GetAsyncKeyState, и был ли клавиша в настоящее время вверх или вниз.

Если установлен старший значащий бит, клавиша нажата, и если установлен младший значащий бит, ключ был нажимается после предыдущего вызова GetAsyncKeyState.

У меня проблемы с пониманием структуры возвращаемого значения:

Он говорит, что типом является short, поэтому, я полагаю, что через него вы можете представить ноль, в двоичном виде, как 0000000000000000, или в шестнадцатеричном, как 0x0000 (поскольку, насколько я знаю, одна шестнадцатеричная цифра представляет четыре двоичные цифры).

В описании сказано, что старший значащий бит должен быть установлен при нажатии клавиши. Это заставляет меня думать, что если бы указанный бит был установлен, число выглядело бы так:

1000000000000000

Чтобы лучше использовать его в моей программе, я сократил его, переведя в шестнадцатеричный формат, в результате чего:

0x8000

Поскольку 8 в шестнадцатеричном виде должно соответствовать 1000 в двоичном.

Когда я увидел, что указанный механизм не работает в моей программе (выполнение GetAsyncKeyState(chr) == 0x8000 всегда будет приводить к ложному значению, независимо от того, была нажата клавиша или нет), я еще раз взглянул на исходный пример, в котором я видел функцию, использованную в первый. Там возвращаемое значение сравнивалось с числом -32767, которое при быстром переводе в гекс с помощью калькулятора Windows приводит к значению 0xFFFFFFFFFFFF8001. Теперь, не берите в голову последнюю шестнадцатеричную цифру (1), потому что это бит, используемый для проверки, активен ли младший значащий бит, но я не хочу этого в моем случае.

Вот что я не могу понять:

  1. Почему, если одна шестнадцатеричная цифра представляет четыре двоичные цифры, а выходное значение функции является коротким (два байта), то здесь число представляется шестнадцатью шестнадцатеричными цифрами? Разве это не те восемь байтов?
  2. В описании возвращаемого значения сказано, что старший значащий бит будет установлен в 1 при нажатии клавиши, и это заставило меня поверить, что число будет выглядеть как 1000000000000000, а не 0000000000001000. Что мне здесь не хватает?

Ответы [ 2 ]

3 голосов
/ 26 октября 2011
GetAsyncKeyState(chr) == 0x8000

Это неверная проверка.Используйте:

!!(GetAsyncKeyState(chr) & 0x8000)

, чтобы увидеть, установлен ли самый старший бит.

Значение 0xFFFFFFFFFFFF8001 не соответствует фактическому возвращенному значению из GetAsyncKeyState.Windows-калькулятор не знает размер значения, возвращаемого из GetAsyncKeyState, поэтому он предполагает, что вы работаете с 64-разрядным числом.Вы можете переопределить его в настройках.

3 голосов
/ 26 октября 2011

1 - возвращаемое значение SHORT, что составляет 16 бит = 2 байта.

2 - старший значащий бит - 15-й, поскольку значение подписывается, если вы преобразуете его в 32-битное INT, 16-битное 1000 0000 значение станет 1111 1111 1000 0000 (в 64-битном мире преобразование будет быть 1000 0000 -> 1111 1111 1111 1111 - 1111 1111 1000 0000). Если вы хотите просто проверить старший значащий бит целочисленного значения со знаком, просто сравните его с нулем:

if(GetAsyncKeyState(...) < 0)
{
  // Hey, MSB is set here!
}
...