Вопросы программирования на Free Pascal, использования компилятора и утилит.
Модератор: Модераторы
Romtek
постоялец
Сообщения: 190 Зарегистрирован: 22.05.2005 12:29:35
Откуда: Рамат Ган
Контактная информация:
Сообщение
Romtek » 15.06.2005 13:12:29
В программе "виртуальное пианино" я, допустим, буду нажимать разные клавиши одновременно (аккорды) и хочу получить их скан-коды + нажата ли или отжата клавиша.
readkey не подходит однозначно. Я так понимаю, надо использовать АПИ-функцию
GetKeyboardState , но не знаю как организовать цикл обработки сообщений. Это консольное приложение.
Код: Выделить всё
while GetMessage(AMessage, 0, 0, 0) Do Begin TranslateMessage(AMessage); DispatchMessage(AMessage); End;не подходит.
FPC 2.0.0, i386-Win32
Romtek
постоялец
Сообщения: 190 Зарегистрирован: 22.05.2005 12:29:35
Откуда: Рамат Ган
Контактная информация:
Сообщение
Romtek » 15.06.2005 14:36:48
Ответ найден.
Вот исходник на Си.
Код: Выделить всё
#include <stdio.h> #include <windows.h> int main(int argc, char* argv[]) { HANDLE hStdin; DWORD cNumRead, fdwMode, fdwSaveOldMode, i; INPUT_RECORD irInBuf[128]; hStdin = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(hStdin, &fdwSaveOldMode) ; fdwMode = ENABLE_MOUSE_INPUT; SetConsoleMode(hStdin, fdwMode) ; while (1) { ReadConsoleInput( hStdin, irInBuf, 128, &cNumRead); for (i = 0; i < cNumRead; i++) { if (irInBuf[i].EventType==KEY_EVENT) { if (irInBuf[i].Event.KeyEvent.bKeyDown) printf (" %c key pressed\n", irInBuf[i].Event.KeyEvent.uChar.AsciiChar); else printf (" %c key released\n", irInBuf[i].Event.KeyEvent.uChar.AsciiChar); } } } return 0; }Думаю его нетрудно перевести на Паскаль (возможно, я так и сделаю).
Romtek
постоялец
Сообщения: 190 Зарегистрирован: 22.05.2005 12:29:35
Откуда: Рамат Ган
Контактная информация:
Сообщение
Romtek » 15.06.2005 16:03:07
А это уже на Паскале:
Код: Выделить всё
program con_events; uses Windows; var hStdin: THandle; cNumRead, fdwMode, fdwSaveOldMode, i: DWORD; irInBuf: array [0..127] of INPUT_RECORD; begin hStdin:= GetStdHandle (STD_INPUT_HANDLE); GetConsoleMode (hStdin, fdwSaveOldMode); SetConsoleMode (hStdin,fdwMode); while true do begin ReadConsoleInput (hStdin, irInBuf[0], 128, cNumRead); for i := 0 to Pred (cNumRead) do if irInBuf[i].EventType = KEY_EVENT then begin if irInBuf[i].Event.KeyEvent.wVirtualKeyCode= vk_Escape then exit; if irInBuf[i].Event.KeyEvent.bKeyDown then writeln (irInBuf[i].Event.KeyEvent.AsciiChar, ' key pressed') else writeln (irInBuf[i].Event.KeyEvent.AsciiChar, ' key released'); end; end; end.
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 15.06.2005 20:23:52
Пианино не получится:
в аккорде qwer невозможно звучание звуков t,a,s,d,f,z,x,c,v и др
аппаратные возможности клавиатуры не совпадают с возможностями синтезатора
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 15.06.2005 20:30:22
Вот небольшая переделка:
Код: Выделить всё
program con_events; uses Windows; var hStdin: THandle; cNumRead, fdwMode, fdwSaveOldMode, i,j: DWORD; irInBuf: array [0..127] of INPUT_RECORD; S:string; C:char; begin hStdin:= GetStdHandle (STD_INPUT_HANDLE); GetConsoleMode (hStdin, fdwSaveOldMode); SetConsoleMode (hStdin,fdwMode); while true do begin ReadConsoleInput (hStdin, irInBuf[0], 128, cNumRead); for i := 0 to Pred (cNumRead) do if irInBuf[i].EventType = KEY_EVENT then begin if irInBuf[i].Event.KeyEvent.wVirtualKeyCode= vk_Escape then exit; C:=irInBuf[i].Event.KeyEvent.AsciiChar; if C in [#32..#255] then begin if irInBuf[i].Event.KeyEvent.bKeyDown then if Pos(C,S)=0 then S:=S+C else else begin j:=Pos(C,S); if j>0 then delete(S,j,1); end; write(S,' '); for j:=0 to Length(S) do Write(#8); end; end; end; end.<span style='color:red'>
Настоятельно рекомендую: </span> выделять код тегом [ code ].
Uniser
новенький
Сообщения: 46 Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава
Сообщение
Uniser » 15.06.2005 20:46:45
А я только подумал, Както мой код не смотрится