Recent

Author Topic: Problem with using of Keyboard unit  (Read 5946 times)

Tomi

  • Full Member
  • ***
  • Posts: 102
Problem with using of Keyboard unit
« on: November 29, 2015, 06:21:48 pm »
Hello!
I trying using the functions of the Keyboard unit in my program, but something is wrong, because the program not react to keypress, except the 'q' button, after I closing the window.
Here is the whole code:
Code: Pascal  [Select][+][-]
  1. program mygame;
  2. uses wincrt,graph,keyboard;
  3. type players=record
  4.         xplace,yplace: integer;
  5.         itscolor: byte;
  6. end;
  7. var gd,gm: integer;
  8. button: tkeyevent;
  9. i: byte;
  10. player: array[0..1] of players;
  11. BEGIN
  12.         initkeyboard;
  13.         gd:=detect;
  14.         gm:=0;
  15.         initgraph(gd,gm,'');
  16.         player[0].xplace:=5;
  17.         player[0].yplace:=5;
  18.         player[0].itscolor:=5;
  19.         player[1].xplace:=getmaxx-5;
  20.         player[1].yplace:=5;
  21.         player[1].itscolor:=10;
  22.         for i:=0 to 1 do
  23.                 putpixel(player[i].xplace,player[i].yplace,player[i].itscolor);
  24.         repeat
  25.                 button:=getkeyevent;
  26.                 button:=translatekeyevent(button);
  27.                 case ord(button) of
  28.                         87,119: if player[0].yplace-1>0 then player[0].yplace:=player[0].yplace-1; {w or W}
  29.                         83,115: if player[0].yplace+1<getmaxy then player[0].yplace:=player[0].yplace+1; {s or S}
  30.                         65,97: if player[0].xplace-1>0 then player[0].xplace:=player[0].xplace-1; {a or A}
  31.                         68,100: if player[0].xplace-1<getmaxx then player[0].xplace:=player[0].xplace+1; {d or D}
  32.                         75: if player[1].xplace-1>0 then dec(player[1].xplace); {left arrow}
  33.                         77: if player[1].xplace+1<getmaxx then inc(player[1].xplace); {right arrow}
  34.                         72: if player[1].yplace-1>0 then dec(player[1].yplace); {up arrow}
  35.                         80: if player[1].yplace+1<getmaxy then inc(player[1].yplace); {down arrow}
  36.                 end;
  37.                 for i:=0 to 1 do
  38.                         putpixel(player[i].xplace,player[i].yplace,player[i].itscolor);
  39.                 delay(10);
  40.         until getkeyeventchar(button)='q';
  41.         closegraph;
  42.         donekeyboard;
  43. END.
P.S.: can I use the functions of this unit to handle multiple keys simultaneously?

balazsszekely

  • Guest
Re: Problem with using of Keyboard unit
« Reply #1 on: November 29, 2015, 08:05:14 pm »
Hi Tomi,

Did you read the documentation? It's pretty clear about this issue: http://www.freepascal.org/faq.var#win-graph

PS: Something like this:
Code: Pascal  [Select][+][-]
  1. program mygame;
  2.  
  3. {$apptype GUI}
  4. {$mode objfpc}{$H+}
  5.  
  6. uses windows, wincrt, graph;
  7.  
  8. var
  9.   GD, GM: Smallint;
  10.   C: Char;
  11.   OutStr: String;
  12. begin
  13.   GD := Detect;
  14.   GM := 0;
  15.   ShowWindow(GetActiveWindow, 0);
  16.   Initgraph(GD, GM, '');
  17.   repeat
  18.     if KeyPressed then
  19.     begin
  20.       C := ReadKey;
  21.       OutStr := '';
  22.       if GetAsyncKeyState(VK_SHIFT) < 0 then //shift
  23.         OutStr := 'Shift + ';
  24.       OutText(OutStr + c)
  25.     end;
  26.     Sleep(1);
  27.   until C = #27;
  28.   Closegraph;
  29. end.  
  30.  

regards,
GetMem
« Last Edit: November 29, 2015, 08:25:59 pm by GetMem »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Problem with using of Keyboard unit
« Reply #2 on: November 29, 2015, 08:26:18 pm »
I trying using the functions of the Keyboard unit in my program, but something is wrong, because the program not react to keypress, except the 'q' button, after I closing the window.
It does react, but your way of getting the button is wrong. I modify your program a bit because wincrt and graph don't exist on linux, thankfully the API compatible PTC backend alternative is available. So, here's your working program (I put writeln output every cycle so you know that it's really detected):
Code: Pascal  [Select][+][-]
  1. program mygame;
  2. uses ptccrt,ptcgraph,keyboard;
  3. type players=record
  4.         xplace,yplace: integer;
  5.         itscolor: byte;
  6. end;
  7. var gd,gm: integer;
  8. button: tkeyevent;
  9. i: byte;
  10. player: array[0..1] of players;
  11. BEGIN
  12.         initkeyboard;
  13.         detectgraph(gd,gm);
  14.         initgraph(gd,gm,'');
  15.         if GraphResult<>grok then
  16.          halt;
  17.         SetColor(White);
  18.         Bar(0,0,getmaxx,getmaxy);
  19.         player[0].xplace:=5;
  20.         player[0].yplace:=5;
  21.         player[0].itscolor:=Red;
  22.         player[1].xplace:=getmaxx-5;
  23.         player[1].yplace:=5;
  24.         player[1].itscolor:=Blue;
  25.         for i:=0 to 1 do begin
  26.                 putpixel(player[i].xplace,player[i].yplace,player[i].itscolor);
  27.                 writeln('pixel put at (',player[i].xplace,',',player[i].yplace,') with color ',player[i].itscolor);
  28.               end;
  29.         repeat
  30.                 button:=getkeyevent;
  31.                 button:=translatekeyevent(button);
  32.                 case GetKeyEventFlags(button) of
  33.                   kbASCII: case GetKeyEventChar(button) of
  34.                     'w','W': if player[0].yplace-1>0 then player[0].yplace:=player[0].yplace-1; {w or W}
  35.                     's','S': if player[0].yplace+1<getmaxy then player[0].yplace:=player[0].yplace+1; {s or S}
  36.                     'a','A': if player[0].xplace-1>0 then player[0].xplace:=player[0].xplace-1; {a or A}
  37.                     'd','D': if player[0].xplace-1<getmaxx then player[0].xplace:=player[0].xplace+1; {d or D}
  38.                   end;
  39.                   kbFnKey: case GetKeyEventCode(button) of
  40.                     kbdLeft: if player[1].xplace-1>0 then dec(player[1].xplace); {left arrow}
  41.                     kbdRight: if player[1].xplace+1<getmaxx then inc(player[1].xplace); {right arrow}
  42.                     kbdUp: if player[1].yplace-1>0 then dec(player[1].yplace); {up arrow}
  43.                     KbdDown: if player[1].yplace+1<getmaxy then inc(player[1].yplace); {down arrow}
  44.                   end;
  45.                 end;
  46.                 for i:=0 to 1 do begin
  47.                         putpixel(player[i].xplace,player[i].yplace,player[i].itscolor);
  48.                 writeln('pixel put at (',player[i].xplace,',',player[i].yplace,') with color ',player[i].itscolor);
  49.               end;
  50.                 delay(10);
  51.         until getkeyeventchar(button)='q';
  52.         closegraph;
  53.         donekeyboard;
  54. END.
  55.  

Tomi

  • Full Member
  • ***
  • Posts: 102
Re: Problem with using of Keyboard unit
« Reply #3 on: November 30, 2015, 04:36:39 pm »
Thank you for your answers, guys, but it's still not works... :(
Maybe the mistake from my keyboard, because it is not USB but PS/2...

balazsszekely

  • Guest
Re: Problem with using of Keyboard unit
« Reply #4 on: November 30, 2015, 04:41:26 pm »
Can you please specify the exact Lazarus/FPC version? What is your OS(32 or 64)?

Tomi

  • Full Member
  • ***
  • Posts: 102
Re: Problem with using of Keyboard unit
« Reply #5 on: November 30, 2015, 04:50:01 pm »
Can you please specify the exact Lazarus/FPC version? What is your OS(32 or 64)?

The FPC version is: FPC\2.6.4\bin\i386-win32
My OS: Windows 7 Ultimate (64 bit)

balazsszekely

  • Guest
Re: Problem with using of Keyboard unit
« Reply #6 on: November 30, 2015, 04:56:22 pm »
Quote
The FPC version is: FPC\2.6.4\bin\i386-win32
My OS: Windows 7 Ultimate (64 bit)
I have the exact same configuration and it's working fine. So must be something at your side. Try to disable AV software, run your program with elevated privileges(right click, run as administrator). I don't think it's related to PS/2 keyboard.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Problem with using of Keyboard unit
« Reply #7 on: November 30, 2015, 06:21:09 pm »
Thank you for your answers, guys, but it's still not works... :(
Maybe the mistake from my keyboard, because it is not USB but PS/2...
It would never be a problem. Programs don't read keystrokes from the port directly, but from interrupt request, which doesn't care what the connector is.

Tomi

  • Full Member
  • ***
  • Posts: 102
Re: Problem with using of Keyboard unit
« Reply #8 on: November 30, 2015, 07:50:25 pm »
It seems that I found a bug: I rewrote this official example program to graphic mode, but the FreePascal does nothing, only write out the "Press keys, press "q" to end." text. Here is the code:
Code: Pascal  [Select][+][-]
  1. program example1;
  2.  
  3. { This program demonstrates the GetKeyEvent function }
  4.  
  5. uses graph,keyboard;
  6.  
  7. Var
  8.   K : TKeyEvent;
  9.   gd,gm: integer;
  10.  
  11. begin
  12.   InitKeyBoard;
  13.   gd:=detect;
  14.   gm:=0;
  15.   initgraph(gd,gm,'');
  16.   outtextxy(50,1,'Press keys, press "q" to end.');
  17.   Repeat
  18.     K:=GetKeyEvent;
  19.     K:=TranslateKeyEvent(K);
  20.     outtextxy(1,1,'Got key event with ');
  21.     Case GetKeyEventFlags(K) of
  22.       kbASCII    : outtextxy(1,10,'ASCII key');
  23.       kbUniCode  : outtextxy(1,10,'Unicode key');
  24.       kbFnKey    : outtextxy(1,10,'Function key');
  25.       kbPhys     : outtextxy(1,10,'Physical key');
  26.       kbReleased : outtextxy(1,10,'Released key event');
  27.     end;
  28.     outtextxy(1,20,KeyEventToString(K));
  29.   Until (GetKeyEventChar(K)='q');
  30.   closegraph;
  31.   DoneKeyBoard;
  32. end.
  33.  
So, it seems it works only in text mode. :o
« Last Edit: November 30, 2015, 07:53:16 pm by Tomi »

 

TinyPortal © 2005-2018