wincrt.pp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. This is unit implements some of the crt functionality
  6. for the gui win32 graph unit implementation
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit wincrt;
  14. interface
  15. function readkey : char;
  16. function keypressed : boolean;
  17. procedure delay(ms : word);
  18. { dummy }
  19. procedure textmode(mode : integer);
  20. { plays the windows standard sound }
  21. { hz is ignored (at least on win95 }
  22. procedure sound(hz : word);
  23. { dummy }
  24. procedure nosound;
  25. var
  26. directvideo : boolean;
  27. { dummy }
  28. lastmode : word;
  29. implementation
  30. uses
  31. windows,graph;
  32. const
  33. keybuffersize = 32;
  34. var
  35. keyboardhandling : TCriticalSection;
  36. keybuffer : array[1..keybuffersize] of char;
  37. nextfree,nexttoread : longint;
  38. procedure inccyclic(var i : longint);
  39. begin
  40. inc(i);
  41. if i>keybuffersize then
  42. i:=1;
  43. end;
  44. procedure addchar(c : char);
  45. begin
  46. EnterCriticalSection(keyboardhandling);
  47. keybuffer[nextfree]:=c;
  48. inccyclic(nextfree);
  49. { skip old chars }
  50. if nexttoread=nextfree then
  51. begin
  52. // special keys are started by #0
  53. // so we've to remove two chars
  54. if keybuffer[nexttoread]=#0 then
  55. inccyclic(nexttoread);
  56. inccyclic(nexttoread);
  57. end;
  58. LeaveCriticalSection(keyboardhandling);
  59. end;
  60. function readkey : char;
  61. begin
  62. while true do
  63. begin
  64. EnterCriticalSection(keyboardhandling);
  65. if nexttoread<>nextfree then
  66. begin
  67. readkey:=keybuffer[nexttoread];
  68. inccyclic(nexttoread);
  69. LeaveCriticalSection(keyboardhandling);
  70. exit;
  71. end;
  72. LeaveCriticalSection(keyboardhandling);
  73. { give other threads a chance }
  74. Windows.Sleep(10);
  75. end;
  76. end;
  77. function keypressed : boolean;
  78. begin
  79. EnterCriticalSection(keyboardhandling);
  80. keypressed:=nexttoread<>nextfree;
  81. LeaveCriticalSection(keyboardhandling);
  82. end;
  83. procedure delay(ms : word);
  84. begin
  85. Sleep(ms);
  86. end;
  87. procedure textmode(mode : integer);
  88. begin
  89. end;
  90. procedure sound(hz : word);
  91. begin
  92. Windows.Beep(hz,500);
  93. end;
  94. procedure nosound;
  95. begin
  96. end;
  97. procedure addextchar(c : char);
  98. begin
  99. addchar(#0);
  100. addchar(c);
  101. end;
  102. const
  103. altkey : boolean = false;
  104. ctrlkey : boolean = false;
  105. shiftkey : boolean = false;
  106. function msghandler(Window: HWnd; AMessage:UInt; WParam : WParam; LParam: LParam): Longint; stdcall;
  107. begin
  108. case amessage of
  109. WM_CHAR:
  110. begin
  111. addchar(chr(wparam));
  112. end;
  113. WM_KEYDOWN:
  114. begin
  115. case wparam of
  116. VK_LEFT:
  117. addextchar(#75);
  118. VK_RIGHT:
  119. addextchar(#77);
  120. VK_DOWN:
  121. addextchar(#80);
  122. VK_UP:
  123. addextchar(#72);
  124. VK_INSERT:
  125. addextchar(#82);
  126. VK_DELETE:
  127. addextchar(#83);
  128. VK_END:
  129. addextchar(#79);
  130. VK_HOME:
  131. addextchar(#71);
  132. VK_PRIOR:
  133. addextchar(#73);
  134. VK_NEXT:
  135. addextchar(#81);
  136. VK_F1..VK_F10:
  137. begin
  138. if ctrlkey then
  139. addextchar(chr(wparam+24))
  140. else if altkey then
  141. addextchar(chr(wparam+34))
  142. else
  143. addextchar(chr(wparam-11));
  144. end;
  145. VK_CONTROL:
  146. ctrlkey:=true;
  147. VK_MENU:
  148. altkey:=true;
  149. VK_SHIFT:
  150. shiftkey:=true;
  151. end;
  152. end;
  153. WM_KEYUP:
  154. begin
  155. case wparam of
  156. VK_CONTROL:
  157. ctrlkey:=false;
  158. VK_MENU:
  159. altkey:=false;
  160. VK_SHIFT:
  161. shiftkey:=false;
  162. end;
  163. end;
  164. end;
  165. msghandler:=0;
  166. end;
  167. var
  168. oldexitproc : pointer;
  169. procedure myexitproc;
  170. begin
  171. exitproc:=oldexitproc;
  172. charmessagehandler:=nil;
  173. DeleteCriticalSection(keyboardhandling);
  174. end;
  175. begin
  176. charmessagehandler:=@msghandler;
  177. nextfree:=1;
  178. nexttoread:=1;
  179. InitializeCriticalSection(keyboardhandling);
  180. oldexitproc:=exitproc;
  181. exitproc:=@myexitproc;
  182. lastmode:=0;
  183. end.