Одновременное нажатие нескольких клавиш

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Сообщение 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.
Аватара пользователя
Romtek
постоялец
 
Сообщения: 190
Зарегистрирован: 22.05.2005 12:29:35
Откуда: Рамат Ган

Сообщение 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

А я только подумал, Както мой код не смотрится :)
Uniser
новенький
 
Сообщения: 46
Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru