crt.pp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. Borland Pascal 7 Compatible CRT Unit - win32 implentation
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit crt;
  13. interface
  14. {$i crth.inc}
  15. procedure Window32(X1,Y1,X2,Y2: DWord);
  16. procedure GotoXY32(X,Y: DWord);
  17. function WhereX32: DWord;
  18. function WhereY32: DWord;
  19. implementation
  20. uses
  21. windows;
  22. var
  23. SaveCursorSize: Longint;
  24. {
  25. definition of textrec is in textrec.inc
  26. }
  27. {$i textrec.inc}
  28. {****************************************************************************
  29. Low level Routines
  30. ****************************************************************************}
  31. procedure TurnMouseOff;
  32. var Mode: DWORD;
  33. begin
  34. if GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), @Mode) then begin { Turn the mouse-cursor off }
  35. Mode := Mode AND cardinal(NOT enable_processed_input)
  36. AND cardinal(NOT enable_mouse_input);
  37. SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), Mode);
  38. end; { if }
  39. end; { proc. TurnMouseOff }
  40. function GetScreenHeight : DWord;
  41. var
  42. ConsoleInfo: TConsoleScreenBufferinfo;
  43. begin
  44. if (not GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ConsoleInfo)) then begin
  45. {$ifdef SYSTEMDEBUG}
  46. Writeln(stderr,'GetScreenHeight failed GetLastError returns ',GetLastError);
  47. Halt(1);
  48. {$endif SYSTEMDEBUG}
  49. // ts: this is really silly assumption; imho better: issue a halt
  50. GetScreenHeight:=25;
  51. end else
  52. GetScreenHeight := ConsoleInfo.dwSize.Y;
  53. end; { func. GetScreenHeight }
  54. function GetScreenWidth : DWord;
  55. var
  56. ConsoleInfo: TConsoleScreenBufferInfo;
  57. begin
  58. if (not GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ConsoleInfo)) then begin
  59. {$ifdef SYSTEMDEBUG}
  60. Writeln(stderr,'GetScreenWidth failed GetLastError returns ',GetLastError);
  61. Halt(1);
  62. {$endif SYSTEMDEBUG}
  63. // ts: this is really silly assumption; imho better: issue a halt
  64. GetScreenWidth:=80;
  65. end else
  66. GetScreenWidth := ConsoleInfo.dwSize.X;
  67. end; { func. GetScreenWidth }
  68. procedure GetScreenCursor(var x : DWord; var y : DWord);
  69. var
  70. ConsoleInfo : TConsoleScreenBufferInfo;
  71. begin
  72. FillChar(ConsoleInfo, SizeOf(ConsoleInfo), 0);
  73. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ConsoleInfo);
  74. X := ConsoleInfo.dwCursorPosition.X + 1;
  75. Y := ConsoleInfo.dwCursorPosition.Y + 1;
  76. end;
  77. procedure SetScreenCursor(x,y : DWord);
  78. var
  79. CurInfo: TCoord;
  80. begin
  81. FillChar(Curinfo, SizeOf(Curinfo), 0);
  82. CurInfo.X := X - 1;
  83. CurInfo.Y := Y - 1;
  84. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), CurInfo);
  85. end;
  86. {****************************************************************************
  87. Public Crt Functions
  88. ****************************************************************************}
  89. procedure TextMode (Mode: word);
  90. begin
  91. {$WARNING TextMode not implemented yet!!}
  92. end;
  93. Procedure TextColor(Color: Byte);
  94. { Switch foregroundcolor }
  95. Begin
  96. TextAttr:=(Color and $8f) or (TextAttr and $70);
  97. End;
  98. Procedure TextBackground(Color: Byte);
  99. { Switch backgroundcolor }
  100. Begin
  101. TextAttr:=((Color shl 4) and ($f0 and not Blink)) or (TextAttr and ($0f OR Blink) );
  102. End;
  103. Procedure HighVideo;
  104. { Set highlighted output. }
  105. Begin
  106. TextColor(TextAttr Or $08);
  107. End;
  108. Procedure LowVideo;
  109. { Set normal output }
  110. Begin
  111. TextColor(TextAttr And $77);
  112. End;
  113. Procedure NormVideo;
  114. { Set normal back and foregroundcolors. }
  115. Begin
  116. TextColor(7);
  117. TextBackGround(0);
  118. End;
  119. Procedure GotoXY(X: Byte; Y: Byte);
  120. begin
  121. GotoXY32(X,Y);
  122. end;
  123. Procedure GotoXY32(X: DWord; Y: DWord);
  124. { Go to coordinates X,Y in the current window. }
  125. Begin
  126. If (X > 0) and (X <= (WindMaxX - WindMinX + 1)) and
  127. (Y > 0) and (Y <= (WindMaxY - WindMinY + 1)) Then Begin
  128. Inc(X, WindMinX - 1);
  129. Inc(Y, WindMinY - 1);
  130. SetScreenCursor(x,y);
  131. End;
  132. End;
  133. Procedure Window(X1, Y1, X2, Y2: Byte);
  134. begin
  135. Window32(X1,Y1,X2,Y2);
  136. end;
  137. Procedure Window32(X1, Y1, X2, Y2: DWord);
  138. {
  139. Set screen window to the specified coordinates.
  140. }
  141. Begin
  142. if (X1 > X2) or (X2 > GetScreenWidth) or
  143. (Y1 > Y2) or (Y2 > GetScreenHeight) then
  144. exit;
  145. WindMinY := Y1;
  146. WindMaxY := Y2;
  147. WindMinX := X1;
  148. WindMaxX := X2;
  149. WindMin:=((Y1-1) Shl 8)+(X1-1);
  150. WindMax:=((Y2-1) Shl 8)+(X2-1);
  151. GotoXY(1, 1);
  152. End;
  153. procedure ClrScr;
  154. var
  155. DestCoor: TCoord;
  156. numChars, x : DWord;
  157. begin
  158. DestCoor.X := WindMinX - 1;
  159. DestCoor.Y := WindMinY - 1;
  160. numChars := (WindMaxX - WindMinX + 1);
  161. repeat
  162. FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), TextAttr,
  163. numChars, DestCoor, x);
  164. FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), #32,
  165. numChars, DestCoor, x);
  166. inc(DestCoor.Y);
  167. until DWord(DestCoor.Y)=WindMaxY;
  168. GotoXY(1, 1);
  169. end; { proc. ClrScr }
  170. procedure ClrEol;
  171. {
  172. Clear from current position to end of line.
  173. }
  174. var
  175. Temp: DWord;
  176. CharInfo: Char;
  177. Coord: TCoord;
  178. X,Y: DWord;
  179. begin
  180. GetScreenCursor(x, y);
  181. CharInfo := #32;
  182. Coord.X := X - 1;
  183. Coord.Y := Y - 1;
  184. FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), CharInfo, WindMaxX - X + 1,
  185. Coord, @Temp);
  186. FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), TextAttr, WindMaxX - X + 1,
  187. Coord, @Temp);
  188. end;
  189. Function WhereX: Byte;
  190. begin
  191. WhereX:=WhereX32 mod 256;
  192. end;
  193. Function WhereX32: DWord;
  194. {
  195. Return current X-position of cursor.
  196. }
  197. var
  198. x,y : DWord;
  199. Begin
  200. GetScreenCursor(x, y);
  201. WhereX32:= x - WindMinX +1;
  202. End;
  203. Function WhereY: Byte;
  204. begin
  205. WhereY:=WhereY32 mod 256;
  206. end;
  207. Function WhereY32: DWord;
  208. {
  209. Return current Y-position of cursor.
  210. }
  211. var
  212. x, y : DWord;
  213. Begin
  214. GetScreenCursor(x, y);
  215. WhereY32:= y - WindMinY + 1;
  216. End;
  217. {*************************************************************************
  218. KeyBoard
  219. *************************************************************************}
  220. var
  221. ScanCode : char;
  222. SpecialKey : boolean;
  223. DoingNumChars: Boolean;
  224. DoingNumCode: Byte;
  225. Function RemapScanCode (ScanCode: byte; CtrlKeyState: byte; keycode:longint): byte;
  226. { Several remappings of scancodes are necessary to comply with what
  227. we get with MSDOS. Special Windows keys, as Alt-Tab, Ctrl-Esc etc.
  228. are excluded }
  229. var
  230. AltKey, CtrlKey, ShiftKey: boolean;
  231. const
  232. {
  233. Keypad key scancodes:
  234. Ctrl Norm
  235. $77 $47 - Home
  236. $8D $48 - Up arrow
  237. $84 $49 - PgUp
  238. $8E $4A - -
  239. $73 $4B - Left Arrow
  240. $8F $4C - 5
  241. $74 $4D - Right arrow
  242. $4E $4E - +
  243. $75 $4F - End
  244. $91 $50 - Down arrow
  245. $76 $51 - PgDn
  246. $92 $52 - Ins
  247. $93 $53 - Del
  248. }
  249. CtrlKeypadKeys: array[$47..$53] of byte =
  250. ($77, $8D, $84, $8E, $73, $8F, $74, $4E, $75, $91, $76, $92, $93);
  251. begin
  252. AltKey := ((CtrlKeyState AND
  253. (RIGHT_ALT_PRESSED OR LEFT_ALT_PRESSED)) > 0);
  254. CtrlKey := ((CtrlKeyState AND
  255. (RIGHT_CTRL_PRESSED OR LEFT_CTRL_PRESSED)) > 0);
  256. ShiftKey := ((CtrlKeyState AND SHIFT_PRESSED) > 0);
  257. if AltKey then
  258. begin
  259. case ScanCode of
  260. // Digits, -, =
  261. $02..$0D: inc(ScanCode, $76);
  262. // Function keys
  263. $3B..$44: inc(Scancode, $2D);
  264. $57..$58: inc(Scancode, $34);
  265. // Extended cursor block keys
  266. $47..$49, $4B, $4D, $4F..$53:
  267. inc(Scancode, $50);
  268. // Other keys
  269. $1C: Scancode := $A6; // Enter
  270. $35: Scancode := $A4; // / (keypad and normal!)
  271. end
  272. end
  273. else if CtrlKey then
  274. case Scancode of
  275. // Tab key
  276. $0F: Scancode := $94;
  277. // Function keys
  278. $3B..$44: inc(Scancode, $23);
  279. $57..$58: inc(Scancode, $32);
  280. // Keypad keys
  281. $35: Scancode := $95; // \
  282. $37: Scancode := $96; // *
  283. $47..$53: Scancode := CtrlKeypadKeys[Scancode];
  284. end
  285. else if ShiftKey then
  286. case Scancode of
  287. // Function keys
  288. $3B..$44: inc(Scancode, $19);
  289. $57..$58: inc(Scancode, $30);
  290. end
  291. else
  292. case Scancode of
  293. // Function keys
  294. $57..$58: inc(Scancode, $2E); // F11 and F12
  295. end;
  296. RemapScanCode := ScanCode;
  297. end;
  298. function KeyPressed : boolean;
  299. var
  300. nevents,nread : dword;
  301. buf : TINPUTRECORD;
  302. AltKey: Boolean;
  303. c : longint;
  304. begin
  305. KeyPressed := FALSE;
  306. if ScanCode <> #0 then
  307. KeyPressed := TRUE
  308. else
  309. begin
  310. GetNumberOfConsoleInputEvents(TextRec(input).Handle,nevents);
  311. while nevents>0 do
  312. begin
  313. ReadConsoleInputA(TextRec(input).Handle,buf,1,nread);
  314. if buf.EventType = KEY_EVENT then
  315. if buf.Event.KeyEvent.bKeyDown then
  316. begin
  317. { Alt key is VK_MENU }
  318. { Capslock key is VK_CAPITAL }
  319. AltKey := ((Buf.Event.KeyEvent.dwControlKeyState AND
  320. (RIGHT_ALT_PRESSED OR LEFT_ALT_PRESSED)) > 0);
  321. if not(Buf.Event.KeyEvent.wVirtualKeyCode in [VK_SHIFT, VK_MENU, VK_CONTROL,
  322. VK_CAPITAL, VK_NUMLOCK,
  323. VK_SCROLL]) then
  324. begin
  325. keypressed:=true;
  326. if (ord(buf.Event.KeyEvent.AsciiChar) = 0) or
  327. (buf.Event.KeyEvent.dwControlKeyState and (LEFT_ALT_PRESSED or ENHANCED_KEY) > 0) then
  328. begin
  329. SpecialKey := TRUE;
  330. ScanCode := Chr(RemapScanCode(Buf.Event.KeyEvent.wVirtualScanCode, Buf.Event.KeyEvent.dwControlKeyState,
  331. Buf.Event.KeyEvent.wVirtualKeyCode));
  332. end
  333. else
  334. begin
  335. { Map shift-tab }
  336. if (buf.Event.KeyEvent.AsciiChar=#9) and
  337. (buf.Event.KeyEvent.dwControlKeyState and SHIFT_PRESSED > 0) then
  338. begin
  339. SpecialKey := TRUE;
  340. ScanCode := #15;
  341. end
  342. else
  343. begin
  344. SpecialKey := FALSE;
  345. ScanCode := Chr(Ord(buf.Event.KeyEvent.AsciiChar));
  346. end;
  347. end;
  348. if AltKey then
  349. begin
  350. case Buf.Event.KeyEvent.wVirtualScanCode of
  351. 71 : c:=7;
  352. 72 : c:=8;
  353. 73 : c:=9;
  354. 75 : c:=4;
  355. 76 : c:=5;
  356. 77 : c:=6;
  357. 79 : c:=1;
  358. 80 : c:=2;
  359. 81 : c:=3;
  360. 82 : c:=0;
  361. else
  362. break;
  363. end;
  364. DoingNumChars := true;
  365. DoingNumCode := Byte((DoingNumCode * 10) + c);
  366. Keypressed := false;
  367. Specialkey := false;
  368. ScanCode := #0;
  369. end
  370. else
  371. break;
  372. end;
  373. end
  374. else
  375. begin
  376. if (Buf.Event.KeyEvent.wVirtualKeyCode in [VK_MENU]) then
  377. if DoingNumChars then
  378. if DoingNumCode > 0 then
  379. begin
  380. ScanCode := Chr(DoingNumCode);
  381. Keypressed := true;
  382. DoingNumChars := false;
  383. DoingNumCode := 0;
  384. break
  385. end; { if }
  386. end;
  387. { if we got a key then we can exit }
  388. if keypressed then
  389. exit;
  390. GetNumberOfConsoleInputEvents(TextRec(input).Handle,nevents);
  391. end;
  392. end;
  393. end;
  394. function ReadKey: char;
  395. begin
  396. while (not KeyPressed) do
  397. Sleep(1);
  398. if SpecialKey then begin
  399. ReadKey := #0;
  400. SpecialKey := FALSE;
  401. end else begin
  402. ReadKey := ScanCode;
  403. ScanCode := #0;
  404. end;
  405. end;
  406. {*************************************************************************
  407. Delay
  408. *************************************************************************}
  409. procedure Delay(MS: Word);
  410. begin
  411. Sleep(ms);
  412. end; { proc. Delay }
  413. procedure sound(hz : word);
  414. begin
  415. MessageBeep(0); { lame ;-) }
  416. end;
  417. procedure nosound;
  418. begin
  419. end;
  420. {****************************************************************************
  421. HighLevel Crt Functions
  422. ****************************************************************************}
  423. procedure removeline(y : DWord);
  424. var
  425. ClipRect: TSmallRect;
  426. SrcRect: TSmallRect;
  427. DestCoor: TCoord;
  428. CharInfo: TCharInfo;
  429. begin
  430. CharInfo.UnicodeChar := #32;
  431. CharInfo.Attributes := TextAttr;
  432. Y := (WindMinY - 1) + (Y - 1) + 1;
  433. SrcRect.Top := Y;
  434. SrcRect.Left := WindMinX - 1;
  435. SrcRect.Right := WindMaxX - 1;
  436. SrcRect.Bottom := WindMaxY - 1;
  437. DestCoor.X := WindMinX - 1;
  438. DestCoor.Y := Y - 1;
  439. ClipRect := SrcRect;
  440. cliprect.top := destcoor.y;
  441. ScrollConsoleScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE), SrcRect, ClipRect,
  442. DestCoor, CharInfo);
  443. end; { proc. RemoveLine }
  444. procedure delline;
  445. begin
  446. removeline(wherey);
  447. end; { proc. DelLine }
  448. procedure insline;
  449. var
  450. ClipRect: TSmallRect;
  451. SrcRect: TSmallRect;
  452. DestCoor: TCoord;
  453. CharInfo: TCharInfo;
  454. X,Y: DWord;
  455. begin
  456. GetScreenCursor(X, Y);
  457. CharInfo.UnicodeChar := #32;
  458. CharInfo.Attributes := TextAttr;
  459. SrcRect.Top := Y - 1;
  460. SrcRect.Left := WindMinX - 1;
  461. SrcRect.Right := WindMaxX - 1;
  462. SrcRect.Bottom := WindMaxY - 1 + 1;
  463. DestCoor.X := WindMinX - 1;
  464. DestCoor.Y := Y;
  465. ClipRect := SrcRect;
  466. ClipRect.Bottom := WindMaxY - 1;
  467. ScrollConsoleScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE), SrcRect, ClipRect,
  468. DestCoor, CharInfo);
  469. end; { proc. InsLine }
  470. {****************************************************************************
  471. Extra Crt Functions
  472. ****************************************************************************}
  473. procedure cursoron;
  474. var CursorInfo: TConsoleCursorInfo;
  475. begin
  476. GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  477. CursorInfo.dwSize := SaveCursorSize;
  478. CursorInfo.bVisible := true;
  479. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  480. end;
  481. procedure cursoroff;
  482. var CursorInfo: TConsoleCursorInfo;
  483. begin
  484. GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  485. CursorInfo.bVisible := false;
  486. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  487. end;
  488. procedure cursorbig;
  489. var CursorInfo: TConsoleCursorInfo;
  490. begin
  491. GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  492. CursorInfo.dwSize := 93;
  493. CursorInfo.bVisible := true;
  494. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  495. end;
  496. {*****************************************************************************
  497. Read and Write routines
  498. *****************************************************************************}
  499. var
  500. CurrX, CurrY : DWord;
  501. procedure WriteChar(c : char);
  502. var
  503. WritePos: Coord; { Upper-left cell to write from }
  504. numWritten : DWord;
  505. WinAttr : word;
  506. begin
  507. Case C of
  508. #10 : begin
  509. Inc(CurrY);
  510. end;
  511. #13 : begin
  512. CurrX := WindMinX;
  513. end; { if }
  514. #08 : begin
  515. if CurrX > WindMinX then Dec(CurrX);
  516. end; { ^H }
  517. #07 : begin
  518. //MessagBeep(0);
  519. end; { ^G }
  520. else begin
  521. WritePos.X := currX - 1;
  522. WritePos.Y := currY - 1;
  523. WriteConsoleOutputCharacter(GetStdhandle(STD_OUTPUT_HANDLE),
  524. @c, 1, writePos, numWritten);
  525. WinAttr:=TextAttr;
  526. WriteConsoleOutputAttribute(GetStdhandle(STD_OUTPUT_HANDLE),
  527. @WinAttr, 1, writePos, numWritten);
  528. Inc(CurrX);
  529. end; { else }
  530. end; { case }
  531. if CurrX > WindMaxX then begin
  532. CurrX := WindMinX;
  533. Inc(CurrY);
  534. end; { if }
  535. While CurrY > WindMaxY do begin
  536. RemoveLine(1);
  537. Dec(CurrY);
  538. end; { while }
  539. end;
  540. Function CrtWrite(var f : textrec) : integer;
  541. var
  542. i : longint;
  543. begin
  544. GetScreenCursor(CurrX, CurrY);
  545. for i:=0 to f.bufpos-1 do
  546. WriteChar(f.buffer[i]);
  547. SetScreenCursor(CurrX, CurrY);
  548. f.bufpos:=0;
  549. CrtWrite:=0;
  550. end;
  551. Function CrtRead(Var F: TextRec): Integer;
  552. procedure BackSpace;
  553. begin
  554. if (f.bufpos>0) and (f.bufpos=f.bufend) then begin
  555. WriteChar(#8);
  556. WriteChar(' ');
  557. WriteChar(#8);
  558. dec(f.bufpos);
  559. dec(f.bufend);
  560. end;
  561. end;
  562. var
  563. ch : Char;
  564. Begin
  565. GetScreenCursor(CurrX,CurrY);
  566. f.bufpos:=0;
  567. f.bufend:=0;
  568. repeat
  569. if f.bufpos>f.bufend then
  570. f.bufend:=f.bufpos;
  571. SetScreenCursor(CurrX,CurrY);
  572. ch:=readkey;
  573. case ch of
  574. #0 : case readkey of
  575. #71 : while f.bufpos>0 do begin
  576. dec(f.bufpos);
  577. WriteChar(#8);
  578. end;
  579. #75 : if f.bufpos>0 then begin
  580. dec(f.bufpos);
  581. WriteChar(#8);
  582. end;
  583. #77 : if f.bufpos<f.bufend then begin
  584. WriteChar(f.bufptr^[f.bufpos]);
  585. inc(f.bufpos);
  586. end;
  587. #79 : while f.bufpos<f.bufend do begin
  588. WriteChar(f.bufptr^[f.bufpos]);
  589. inc(f.bufpos);
  590. end;
  591. #28: begin // numpad enter
  592. WriteChar(#13);
  593. WriteChar(#10);
  594. f.bufptr^[f.bufend]:=#13;
  595. f.bufptr^[f.bufend+1]:=#10;
  596. inc(f.bufend,2);
  597. break;
  598. end;
  599. #53: begin
  600. ch:='/';
  601. if f.bufpos<f.bufsize-2 then begin
  602. f.buffer[f.bufpos]:=ch;
  603. inc(f.bufpos);
  604. WriteChar(ch);
  605. end;
  606. end;
  607. end;
  608. ^S,
  609. #8 : BackSpace;
  610. ^Y,
  611. #27 : begin
  612. while f.bufpos<f.bufend do begin
  613. WriteChar(f.bufptr^[f.bufpos]);
  614. inc(f.bufpos);
  615. end;
  616. while f.bufend>0 do
  617. BackSpace;
  618. end;
  619. #13 : begin
  620. WriteChar(#13);
  621. WriteChar(#10);
  622. f.bufptr^[f.bufend]:=#13;
  623. f.bufptr^[f.bufend+1]:=#10;
  624. inc(f.bufend,2);
  625. break;
  626. end;
  627. #26 : if CheckEOF then begin
  628. f.bufptr^[f.bufend]:=#26;
  629. inc(f.bufend);
  630. break;
  631. end;
  632. else begin
  633. if f.bufpos<f.bufsize-2 then begin
  634. f.buffer[f.bufpos]:=ch;
  635. inc(f.bufpos);
  636. WriteChar(ch);
  637. end;
  638. end;
  639. end;
  640. until false;
  641. f.bufpos:=0;
  642. SetScreenCursor(CurrX, CurrY);
  643. CrtRead:=0;
  644. End;
  645. Function CrtReturn(Var F:TextRec):Integer;
  646. Begin
  647. CrtReturn:=0;
  648. end;
  649. Function CrtClose(Var F: TextRec): Integer;
  650. Begin
  651. F.Mode:=fmClosed;
  652. CrtClose:=0;
  653. End;
  654. Function CrtOpen(Var F: TextRec): Integer;
  655. Begin
  656. If F.Mode=fmOutput Then begin
  657. TextRec(F).InOutFunc:=@CrtWrite;
  658. TextRec(F).FlushFunc:=@CrtWrite;
  659. end Else begin
  660. F.Mode:=fmInput;
  661. TextRec(F).InOutFunc:=@CrtRead;
  662. TextRec(F).FlushFunc:=@CrtReturn;
  663. end;
  664. TextRec(F).CloseFunc:=@CrtClose;
  665. CrtOpen:=0;
  666. End;
  667. procedure AssignCrt(var F: Text);
  668. begin
  669. Assign(F,'');
  670. TextRec(F).OpenFunc:=@CrtOpen;
  671. end;
  672. var
  673. CursorInfo : TConsoleCursorInfo;
  674. ConsoleInfo : TConsoleScreenBufferinfo;
  675. // ts
  676. begin
  677. { Initialize the output handles }
  678. LastMode := 3;
  679. SetActiveWindow(0);
  680. {--------------------- Get the cursor size and such -----------------------}
  681. FillChar(CursorInfo, SizeOf(CursorInfo), 00);
  682. GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), CursorInfo);
  683. SaveCursorSize := CursorInfo.dwSize;
  684. {------------------ Get the current cursor position and attr --------------}
  685. FillChar(ConsoleInfo, SizeOf(ConsoleInfo), 0);
  686. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ConsoleInfo);
  687. TextAttr := ConsoleInfo.wAttributes;
  688. { Not required, the dos crt does also not touch the mouse }
  689. {TurnMouseOff;}
  690. WindMinX := (ConsoleInfo.srWindow.Left) + 1;
  691. WindMinY := (ConsoleInfo.srWindow.Top) + 1;
  692. WindMaxX := (ConsoleInfo.srWindow.Right) + 1;
  693. WindMaxY := (ConsoleInfo.srWindow.Bottom) + 1;
  694. DoingNumChars := false;
  695. DoingNumCode := 0;
  696. { Redirect the standard output }
  697. AssignCrt(Output);
  698. Rewrite(Output);
  699. TextRec(Output).Handle:= GetStdHandle(STD_OUTPUT_HANDLE);
  700. AssignCrt(Input);
  701. Reset(Input);
  702. TextRec(Input).Handle:= GetStdHandle(STD_INPUT_HANDLE);
  703. end. { unit Crt }
  704. {
  705. $Log$
  706. Revision 1.25 2005-05-14 15:01:49 hajny
  707. * TextMode parameter type changed to word for TP/BP compatibility
  708. Revision 1.24 2005/02/14 17:13:32 peter
  709. * truncate log
  710. Revision 1.23 2005/01/03 18:16:12 peter
  711. fix clrscr with windowsize<>screensize
  712. fix cursorbig
  713. }