Getasynckeystate c коды клавиш

Getasynckeystate c коды клавиш

21.03.2019

(ПолучитьАсинхронноСостояниеКлавиши)

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

Синтаксис

SHORT GetAsyncKeyState (int vKey // код виртуальной клавиши );

Параметры
vKey
Определяет один из 256 возможных кодов виртуальной клавиши.

Windows NT : Вы можете использовать лево - и правосторонние константы, чтобы определять некоторые клавиши. Для дополнительной информации см. раздел Замечания.
Windows 95: Windows 95 не поддерживает лево - и правосторонние константы, доступные в Windows NT .

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения определяет, была ли клавиша нажата начиная с последнего вызова GetAsyncKeyState , и какое из двух состояний, нажатое или отпущенное, занимает в настоящее время клавиша. Если старший значащий бит установлен, клавиша - нажата, а если наименьший значащий бит установлен, клавиша была нажата после предыдущего вызова GetAsyncKeyState . Величина возвращаемого значения нулевая, если окно в другом потоке или процессе в настоящее время имеет фокус клавиатуры.
Windows 95: Windows 95 не поддерживает лево - и правосторонние константы. Если Вы вызываете GetAsyncKeyState на платформе Windows 95 с этими константами, величина возвращаемого значения нулевая.

Замечания
Вы можете использовать константы кода виртуальной клавиши VK_SHIFT , VK_CONTROL и VK_MENU как значения для параметра vKey . Это дает состояние клавиш SHIFT , CTRL или ALT без различия между левой и правой сторонами.
Windows NT : Вы можете использовать следующие константы кода виртуальной клавиши как значения для vKey , чтобы делать различие между левыми и правыми экземплярами этих клавиш:

VK_LSHIFT VK_RSHIFT VK_LCONTROL VK_RCONTROL VK_LMENU VK_RMENU

Эти лево- и правосторонние константы доступны только тогда, когда Вы вызываете функции GetKeyboardState , SetKeyboardState , GetAsyncKeyState , GetKeyState и MapVirtualKey
Windows 95: Windows 95 не поддерживает лево - и правосторонние константы и возвращается 0, когда Вы используете эти константы.
Функция GetAsyncKeyState работает с кнопками мыши. Однако она контролирует состояние физических, а не логических кнопок мыши, которыми физические кнопки отображаются. Например, вызов GetAsyncKeyState (VK_LBUTTON) всегда возвращает состояние левой физической кнопки мыши, которая может отображать левую или правую логическую кнопку мыши. Вы можете установить текущее отображение физических кнопок мыши в логических кнопках мыши системой путем вызова функции

GetSystemMetrics(SM_SWAPBUTTON)

которая возвращает значение ИСТИНА (TRUE ), если кнопки мыши менялись.

Смотри также
GetKeyboardState , GetKeyState , GetSystemMetrics , MapVirtualKey , SetKeyboardState

Размещение и совместимость GetAsyncKeyState

Windows NT Да Win95 Да Win32s Да Импортируемая библиотека user32.lib Заголовочный файл winuser.h Unicode Нет Замечания по платформе Не имеется

01:33

Функция GetAsyncKeyState() в языке C

Помогите разобраться с функцией GetAsyncKeyState()
Мне надо прописать каким-то образом в условии, что кнопка была до этого нажата и в данный момент нажата - тогда делать то. И что кнопка была не нажата и в данный момент нажата - тогда делать сё.
Данная программа открывает бесконечный цикл из первых эн чисел последовательности Фибоначчи и гоняет эту последовательность по кругу до тех пор пока пользователь не нажмёт клавишу 0. Собственно сама клавиша принципиальна, нужна именно она, код её 0x30 .
GetAsyncKeyState() определяет, нажата ли клавиша на момент вызова и была ли нажата клавиша после предыдущего вызова функции.
Некоторое описание функции есть тут help.prognoz.com/ru/mergedProjects/UiLib/interf... но оно не на Си.
Ещё тут есть на дэлфи vwsb.blogspot.ru/2008/10/api-delphi.html
И вот ещё по поиску нашлась книга букс.гугл.ру Программирование игр для Microsoft Windows. Советы профессионала, 2-е издание , про функцию

Но всё равно не пойму как с ней в данном случае работать...

#include
#include
#include
int func1(int N){
if(N == 1) {
printf("0 \n");
}
else if(N == 2){
printf("0 \n");
printf("1 \n");
}
}
int func2(int a, int b, int c, int N) {
int i;
printf("0 \n");
printf("1 \n");
for(i = 0; i < N-2; ++i){
c=a+b;
a=b;
b=c;
printf("%d\n", c);

}
printf("\n");
}

int main() {
setlocale (LC_ALL, "Rus");
int a=0;
int b=1;
int c;
int N;
int i;
printf("Введите N=");
scanf("%d", &N);
while(2 > 1) {
func1(N);
func2(a,b,c,N);
if(тут надо условие с функцией GetAsyncKeyState(0x30) такое, что в результате его выполнения программа шла в тело
ифа тогда и только тогда, когда клавиша 0 была до этого момента нажата и в данный момент нажата) {
break;
}
if(тут надо условие с функцией GetAsyncKeyState(0x30) такое, что в результате выполнения программа шла в тело
ифа тогда и только тогда, когда клавиша 0 была до этого момента не нажата и в данный момент нажата) {
break;
}
}
}

p.s. не знаю почему не отобразились инклуды, подключал эстэдио, локейл и виндоус


2016-10-16 в 10:32

Так а в чем именно проблема?
Студия ошибку выдает или что?
Ссылка на MSDN , описана спецификация функции. Она возвращает значение типа short, которое можно анализировать. В вашем примере предлагают сделать побитовое И с битовой маской 0x8000. Не умеете пользоваться #define?


2016-10-16 в 12:41

А пошли вы все к Ефесянам.

Сохраняй значение GetAsyncKeyState в цикле, пример:

short prev_state = GetAsyncKeyState();
while(...) {
...
short current_state = GetAsyncKeyState();
if(current_state == нажата) {
if(prev_state == нажата) {
...
} else { // не была нажата
...
}
}
...
// в конце итерации сохранить текущее состояние:
prev_state = GetAsyncKeyState();
}


Потому что они в угловых скобках, которые парсер дайри пытается распознать как теги.


2016-10-16 в 22:08

Эллипс - это круг, который можно вписать в квадрат 25х40

Груша Вильямс , p.s. не знаю почему не отобразились инклуды
Есть же кнопка CODE... там всё должно отображаться...

#include


2016-10-16 в 23:22

Я вот собственно и не понимаю как это сделать. Скажем вызвал я функцию GetAsyncKeyState(0x30), она отработала и возвращает значение, пусть это значение в памяти представляется несколькими ячейками-битами, то что она в эти ячейки запишет, если до этого я клавишу 0 не нажимал, а сейчас нажал и как обратиться к этой ячейке и поставить на неё условие проверки? Пишу про одну ячейку потому, что вычитал Если старший значащий бит установлен, клавиша находится в нажатом состоянии, а если самый младший значащий бит установлен, клавиша была нажата после предыдущего вызова . Тогда по логике надо как-то обратиться либо к первой, либо к последней ячейке и проверить что там стоит 0 или 1. А вот как это сделать я действительно не знаю. Скажем запись через амперсанд, которую Вы предложили (если я правильно понял) выглядит так GetAsyncKeyState(0x30) & 0x8000, но что оно значит? Проверка первой/последней ячейки на 0/1 или это только обращение к ячейке, а затем надо проверку делать, например так GetAsyncKeyState(0x30) & 0x8000 == 0 ?
Почитаю про битовые маски, впервые этот термин попался просто. Ещё один вопрос - а что за значение такое short? Мне доводилось лишь использовать short int i в цикле фора при работе с небольшими массивами, причем понимал это как короткое целое число, мол память не заполнять - целое число может принимать 2^32 значения (32 ячейки), а короткое в два раза меньше. То есть short - это по умолчанию и есть short int или что-то иное? В инете не нашел...
А пишу не в студии, а в дэвке - Dev-Cpp 5.11 TDM-GCC 4.9.2 Setup и компилирую этим Compiler Name: TDM-GCC 4.9.2 32-bit Debug и ради интереса этим Compiler Name: TDM-GCC 4.9.2 32-bit Release. Один раз заметил интересную штуку между ними и с того момента все программы смотрю то в одном, то в другом)

С previous_state и current_state понравилось, надо попробовать... А слово нажата чем заменить? 0 - нажата, 1 - не нажата или иначе?
В общем поэкспериментировать надо.

Надо запомнить) Я просто воспользовался советом, что в шапке сообщества Можно скопировать полученный там код вместе с подсветкой сюда (для этого его нужно выделить, скопировать исходный код выделенного фрагмента и поместить его в вашу запись с тегом

p.s. я с этой штукой полмесяца уж сижу, лабу сдавать надо, а так и не разобрался как с этим работать всем


2016-10-16 в 23:47

На свете есть всего 10 разновидностей людей. Те, которые понимают бинарный код, и те, кто не понимают

Груша Вильямс , Тогда по логике надо как-то обратиться либо к первой, либо к последней ячейке и проверить что там стоит 0 или 1.
Да, все верно.

выглядит так GetAsyncKeyState(0x30) & 0x8000, но что оно значит?
& - это побитовое И. Переведите оба числа в двоичную систему счисления и выполните операцию И побитово, т.е. для каждого бита отдельно. Получившееся в результате значение и будет результатом операции. В отличие от логического И (&&), где перед сравнением числовые значения приводятся к логическому типу (не ноль в true, ноль в false), а после этого выполняется операция.

например так GetAsyncKeyState(0x30) & 0x8000 == 0
Ну как-то так, да. Надо спецификацию уточнить, с чем именно сравнивать в смысле пробуйте.

битовые маски, впервые этот термин попался просто.
Они используются в операционных системах семейства UNIX, например, для задания прав доступа к файлу. Поскольку язык С изначально был задуман как системный для юникса, в нем такой способ получения результата довольно популярен. Получается очень экономно, на целую кучу вариантов расходуется только один байт.

Ещё один вопрос - а что за значение такое short
Краткое название short int.

целое число может принимать 2^32 значения (32 ячейки)
Чаще всего да, но в стандарте языка размер типа int не указан. Он зависит от компилятора, поэтому для лучшей переносимости программ, когда размер типа критичен (как в этой задаче), рекомендуется использовать более строго заданные типы short и long. Про типы можете почитать, но это для студии только.


2016-10-17 в 00:52

X xxxxx xxxxx xxxxx & 1 00000 00000 00000
Побитовое И - это бинарная операция, действие которой эквивалентно применению логического И к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях операндов. Другими словами, если оба соответствующих бита операндов равны 1, результирующий двоичный разряд равен 1; если же хотя бы один бит из пары равен 0, результирующий двоичный разряд равен 0.
Если я вызвал гетасинк и впервые нажимаю 0, то получаю в соответствии если старший значащий бит установлен, клавиша находится в нажатом состоянии
1 xxxxx xxxxx xxxx0 & 1 00000 00000 00000 = 1 aaaaa aaaaa aaaa0
Если я вызвал второй раз гетасинк и опять нажал на 0, то в соответствии если старший значащий бит установлен, клавиша находится в нажатом состоянии, а если самый младший значащий бит установлен, клавиша была нажата после предыдущего вызова получим
1 xxxxx xxxxx xxxx1 & 1 00000 00000 00000 = 1 bbbbb bbbbb bbbb0.
И непонятно с чем сравнивать... А что самое отвратное, так ещё и старший и младший биты после данных операций одинаковые
То есть после указанных операций мы просто получим два каких то числа 1 aaaaa aaaaa aaaa0 и 1 bbbbb bbbbb bbbb0...


2016-10-17 в 01:51

Просто знаете я на самом деле знаю как цикл останавливать, но случайно так вышло, интуитивно. То есть я до сих пор не понимаю как прога моя работает, но она работает.
Вот код
#include #include #include int func1(int N){ if(N == 1) { printf("0 \n"); } else if(N == 2){ printf("0 \n"); printf("1 \n"); } } int func2(int a, int b, int c, int N) { int i; printf("0 \n"); printf("1 \n"); for(i = 0; i < N-2; ++i){ c=a+b; a=b; b=c; printf("%d\n", c); } printf("\n"); } int main() { setlocale (LC_ALL, "Rus"); int a=0; int b=1; int c; int N; printf("Введите N="); scanf("%d", &N); GetAsyncKeyState(0x30); while(2 > 1) { func1(N); func2(a,b,c,N); if(GetAsyncKeyState(0x30)) { break; } } }
То есть я ввожу что хочу, хоть 10, хоть 100 и цикл идёт бесконечно, а не однократно мол я 0 уже нажимал. Вроде работает и славно. Но писать надо дальше, мне надо потом всё это зациклить, чтоб после остановки нулём программа повторялась.
Делаю так, тут я код поправил малость, запихал весь счёт последовательности в одну функцию, тем самым при вводе 1, избавился от 0 0 1 и получил требуемый 0.
#include #include #include int func1(int a, int b, int c, int N){ int i; if(N == 1){ printf("0 \n\n"); } if(N == 2){ printf("0 \n"); printf("1 \n\n"); } if(N > < N-2; ++i){ c = a + b; a = b; b = c; printf("%d\n", c); } printf("\n"); } } int main() { setlocale (LC_ALL, "Rus"); int a=0; int b=1; int c; int N; int i; for(i = 0; ; i++) { printf("Введите N="); scanf("%d", &N); GetAsyncKeyState(0x30); while(2 > 1) { func1(a, b, c, N); if(GetAsyncKeyState(0x30)){ break; } } } }
Но проблема в том, что перед тем как остановить всё это дело, то есть во время работы бесконечного цикла пользователь может нажимать что попало, и вот это всё потом выводится. Скажем если бы цикл останавливался не нулём, а скажем двойкой, то после остановки двойка автоматически будет вводится, и если потом введём например 5, он будет считать первые 25 чисел. А мне вот эти все автоматически закинутые символы вовсе не нужны, более того в результате непонимания как это всё работает, я не могу даже найти инструкцию в результате которой это всё происходит - то ли сканэф это, то ли гетасинк. Как убрать этот поток тоже не знаю, никогда с таким не сталкивался. Откуда и мысль, что если всё нормально сделать ручками, может нормально и будет...
Вот что на выходе


2016-10-17 в 03:32

Что-то меня подглючило насчёт с чем сравнивать, эта же функция дословно получить асинхронно состояние клавиши, то есть ей без разницы какая клавиша по идее, её возвращаемое значение будет говорить о состоянии - нажата, не нажата, зажата (ну в системе неизвестно какой таймер касания установлен), таким образом три значения ей вполне достаточно, а если она запоминает предыдущее то вроде 4. Таким образом надо как-то написать программу и отловить её значения. Сравнение с ними мне и надо вроде как. И тип short сразу понятен, а зачем тут больше)))


2016-10-17 в 04:31

Как написать программу чтобы отловить её значения не пришло в голову. Надо же вроде таймер тогда как-то ставить, включать сканэф, а затем с каким-то таймингом выводить в цикле. В общем совсем не понятно как это сделать, хотя интересно. Нашел в сети её возвращаемые значения.
Возвращаемые значения:
0 - клавиша не нажата и не была нажата при предыдущем вызове этой функции.
1 - не нажата, но была нажата в прошлый вызов.
-32767 - нажата, но не была нажата в прошлый вызов.
-32768 - нажата, и была нажата в прошлый вызов.
Написал
#include #include #include int func1(int a, int b, int c, int N){ int i; if(N == 1){ printf("0 \n\n"); } if(N == 2){ printf("0 \n"); printf("1 \n\n"); } if(N > 2){ printf("0 \n"); printf("1 \n"); for(i = 0; i < N-2; ++i){ c = a + b; a = b; b = c; printf("%d\n", c); } printf("\n"); } } int main() { setlocale (LC_ALL, "Rus"); int a=0; int b=1; int c; int N; int i; for(i = 0; ; i++) { printf("Введите N="); scanf("%d", &N); while(2 > 1) { func1(a, b, c, N); if(GetAsyncKeyState(0x30) == -32767){ break; } if(GetAsyncKeyState(0x30) == -32768){ break; } } } }
И всё та же ерундень! Почему она пишет то, что нажал, если функция должна срабатывать лишь на состояние клавиши, что в её аргументе. И до сканэфа там далеко, перед ним же принтэф отрабатывается, а цикл тормозится до инструкции принтэф. Как-нибудь можно убирать весь этот поток нажимаемых клавиш в попытках остановить цикл, почитстить как-нибудь его или сразу как-то прописать, что вот это вся информация нам не нужна?


Спасибо, всё написал. Но так и не понял как функция GetAsyncKeyState работает.
Вот пишут, что она делает две операции.
1) Старший бит возвращаемого значения установлен в 1, если указанная клавиша была нажата в момент вызова функции. Если этот бит равен 0, клавиша не была нажата.
2) Младший бит возвращаемого значения установлен в 1, если указанная клавиша была нажата с момента последнего вызова функции GetAsyncKeyState.

Проверяю её работу на этой программке
#include #include #include int func1(int a, int b, int c, int N){ int i; if(N == 1){ printf("0 \n\n"); } if(N == 2){ printf("0 \n"); printf("1 \n\n"); } if(N > 2){ printf("0 \n"); printf("1 \n"); for(i = 0; i < N-2; ++i){ c = a + b; a = b; b = c; printf("%d\n", c); } printf("\n"); } } int main() { setlocale (LC_ALL, "Rus"); int a=0; int b=1; int c; int N; int i; for(i = 0; ; i++) { printf("Введите N="); scanf("%d", &N); while(2 > 1) { func1(a, b, c, N); if(GetAsyncKeyState(0x30)){ //0x30 - код нуля break; } } } }
Функция GetAsyncKeyState вызывается нажатием клавиш как понимаю.
Допустим вначале нажал 1 (0 xxxxx xxxxx xxxx0), затем 0 (1 xxxxx xxxxx xxxx1) и 5 (0 xxxxx xxxxx xxxx0), то есть на экране "Введите N=205" и фактически произошло три вызова функции GetAsyncKeyState. Нажимаю Enter, получаю бесконечный цикл, таким образом в условие if не заходим, таким образом значение 0 xxxxx xxxxx xxxx0 = 0 00000 00000 00000 = 0 (т.е. x=0). Так как надо зайти в if чтобы остановить цикл, вызываю в четвёртый раз функцию GetAsyncKeyState, нажимая на 0 (1 xxxxx xxxxx xxxx1), и цикл останавливается, так как очевидно, что число 1 xxxxx xxxxx xxxx1 отлично от 0 00000 00000 00000 = 0 нуля.
Если же по новой перезапустить программу и сразу ввести 10, то есть вначале нажал 1 (0 xxxxx xxxxx xxxx0), затем 0 (1 xxxxx xxxxx xxxx1), то сразу уходим в цикл.
Таким образом фактически получаем, что функция GetAsyncKeyState может возвращать только три числа - 0 xxxxx xxxxx xxxx0, 1 xxxxx xxxxx xxxx1 и если сразу бы ввели 0, то получили бы 1 xxxxx xxxxx xxxx0. Применяя битовые операции к этим возвращаемым значениям и сравнивая с тем или иным числом мы и будем задавать условия.
Например для бесконечного вывода и остановки можно использовать "побитовое и" GetAsyncKeyState(0x30) & 0x8000 !=0. Но если поставить это условие if(GetAsyncKeyState(0x30) & 0x8000) и ввести 10 (1 xxxxx xxxxx xxxx1 & 1 00000 00000 00000 = 1 00000 00000 00000 = 32768), то программа не идёт в if. Что здесь не так?




© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows