Na FreeHostingu Endora běžà desĂtky tisĂc webĹŻ. PĹ™idejte se ještÄ› dnes!
VytvoĹ™it web zdarmaNa FreeHostingu Endora běžà desĂtky tisĂc webĹŻ. PĹ™idejte se ještÄ› dnes!
VytvoĹ™it web zdarmareadln číst ze souborů a z libovolného zařízení DOSu. Je důležité si také uvědomit, že vstup se ukončuje klávesou enter. Existuje ještě varianta read, která ohraničuje vstup trochu jinak. Skoro nikdo ji neumí suverénně používat a většina programátorů se jí vyhýbá. V každé, případě se ale hodí pouze pro načítání ze souborů - ne pro vstup z klávesnice.read/readln všimněme, co se stane, načítáme-li proměnnou číselného typu a uživatel zadá (omylem) něco jiného než číslo. Vyvolá se běhová chyba č.106uses Crt;uses Crt; var c:char; begin repeat repeat {Cykl neustale bezi. V tomto bloku byvaji akce, ktere se maji provadet i kdyz uzivatel vuvec nesaha na klavesnici} until Keypressed; {Pri stisku klavesy vypadne z cyklu} c:=ReadKey; {zjistime, co to vlastne bylo za klavesu} case c of {takze co to bylo?} #13:writeln; #59:writeln(#13#10,'F1'); #60:writeln(#13#10,'F2'); #61:writeln(#13#10,'F3'); else write(c); end; until c=#27; {pri stisku ESC konec} end.Zdroják je myslím dostatečně jednoduchý. Všimněte si, že oproti readln reaguje Readkey na více kláves. Například F-ka, šipky, atd.
uses crt; Function MyKey:word; var c:word; begin c:=word(Readkey); if c=0 then MyKey:=256+word(Readkey) else MyKey:=c; end; var c:word; begin repeat repeat until Keypressed; c:=MyKey; writeln(c); until c=27; {pri stisku ESC konec} end.
writeln(c); zkuste vložit delay(800);while keypressed do readkey;Často budete ve svých programech čekat na stisk libovolné klávesy. (Press any key to continue). Jak to nejlépe napsat?
Procedure AnyKey; begin repeat until Keypressed; while Keypressed do readkey; end;Během experimentování jste asi zjistili, že i když ReadKey umí detekovat více kláves než Readln, tak přesto neodhalí všechny. Neodhalí stisk altů, controlů a dalších.
var klavesy:array[0..127] of booleanvar k:byte; begin k:=Port[$60]; klavesy[k mod 128]:=(k<128);O programování přerušení klávesnice jsem už psal v jiném článku, a to DOS a chráněný režim - 1. díl
unit rezklav; {Rezidentni obsluha klavesnice. Cte polohove kody, ktere pak pomoci tabulek} {prevedu do ASCII znaku. Vse si udelam sam a nebudu zavisly na DOSovych} {ovladacich klavesnice} {Tato unita umi rozlisovat mezi normalnimi sipkami a sipkami na numericke klavesnici. Pro pohodli programatora ale rovnez definuje kody, ktere mezi nimi neodlisuji. napr. Sipka vpravo na numericke klavesnici dava: KEY_NUM_6 = true a KEY_CURSOR_RIGHT = true Seda sipka vpravo dava: KEY_G_CURSOR_RIGHT = true a KEY_CURSOR_RIGHT = true. Vidite, ze KEY_CURSOR_RIGHT zustava spolecne. Jestlize zavolate ZapniObsluhuKlavesnice s parametrem KL_S_BIOSEM, tak dal budou normalne fungovat standardni funkce klavesnice jako ReadKey, KeyPressed a vubec cely BIOS okolo klavesnice. Na druhou stranu se musite starat, aby klavesnice nepipala. Kdyz zavolate ZapniObsluhuKlavesnice(KL_BEZ_BIOSU) tak pipat zarucene nebude, ale prestanou fungovat standardni pascali funkce okolo klavesnice.} {Pri pohledu do zdrojaku zarazi velice bizarni chovani klavesy Pause. Posila velice exotickou sekvenci a hlavne nesignalizuje uvolneni klavesy. Zvlastne se taky taky chova Printscreen. Pri zmacknuti totiz vysle 4-bajtovou sekvenci. Pokud ho ale nepustime, ale drzime dal, tak periodicky vysila jinou, a to 2-bajtovou sekvenci. Periodicke vysilani maji rovnez oba Alty.} {$IFDEF FPC}{$MODE FPC}{$ENDIF} {$Q-} {debugovaci informace musi byt v kazdem pripade povypinana} {$R-} {jinak se to cele zhrouti} {$S-} {$D-} {$F+} {$DEFINE OPATRNOST} {Zda se, ze je mozne ji vypnout...} interface {$IFDEF FPC} uses go32; {$ELSE} uses dos; {$ENDIF} const KL_S_BIOSEM = true; KL_BEZ_BIOSU = false; procedure ZapniObsluhuKlavesnice(rezim:boolean); procedure VypniObsluhuKlavesnice; {$I rezklav.inc} {kody klaves} var kl_kod:word; kl_zmena:boolean; vsechny_klavesy : Array[0..160] of boolean; AltBuf:word; implementation const kbdint = $9; levy_shift = 42; pravy_shift = 54; odpocet:byte=0; var {$IFDEF FPC} oldint9_handler:tseginfo; newint9_handler:tseginfo; backupDS:Word; external name '___v2prt0_ds_alias'; {$ELSE} oldint9_handler:pointer; newint9_handler:pointer; {$ENDIF} paltbuf:array[0..6] of byte; {je to zahada, ale se stringem mi to nefungovalo} obsluha:pointer; bios:boolean; procedure CtiKod;{$IFNDEF FPC}interrupt;{$ENDIF} procedure ZpracujJednotu(alternativa,spolecna,ja:byte); begin if ja<>0 then vsechny_klavesy[ja]:=(kl_kod<128); if kl_kod<128 then vsechny_klavesy[spolecna]:=true else if vsechny_klavesy[alternativa]=false then vsechny_klavesy[spolecna]:=false; end; procedure PrectiAltovyBuffer; var i,j:longint; begin if vsechny_klavesy[KEY_ALT]=false then begin altbuf:=0; j:=1; for i:=paltbuf[0] downto 1 do begin altbuf:=altbuf+paltbuf[i]*j; j:=j*10; end; paltbuf[0]:=0; end; end; var klmod128,op:byte; ab:byte; begin {$IFDEF FPC}kl_kod:=InPortB($60);{$ELSE}kl_kod:=Port[$60];{$ENDIF} if kl_kod=$e1 then if odpocet=0 then odpocet:=7 else else {krkolome osetreni Pause} if kl_kod=$e0 then if odpocet=0 then odpocet:=2 else else if odpocet<3 then begin kl_zmena:=true; klmod128:=kl_kod mod 128; vsechny_klavesy[KEY_PAUSE]:=false; {vopruz z Pause} vsechny_klavesy[KEY_CTRLBREAK]:=false; {stejne se chova CTRL-break} op:=odpocet; odpocet:=0; case op of 2:case klmod128 of 69:vsechny_klavesy[KEY_PAUSE]:=true; {Pause} 70:vsechny_klavesy[KEY_CTRLBREAK]:=true; {CTRL-break} 55:vsechny_klavesy[KEY_PRINT]:=(kl_kod<128); {Printscreen poprve} end; 1:case klmod128 of 71..83:ZpracujJednotu(klmod128,klmod128+Priznak_jednoty,klmod128+Priznak_sedych_sipek); 28:ZpracujJednotu(KEY_G_ENTER,KEY_ENTER,KEY_NUM_ENTER);{sedy Enter} 56:begin ZpracujJednotu(KEY_LALT,KEY_ALT,KEY_PALT); {pravy Alt} PrectiAltovyBuffer; end; 29:ZpracujJednotu(KEY_LCTRL,KEY_CTRL,KEY_PCTRL); {pravy Ctrl} 55:vsechny_klavesy[KEY_PRINT]:=(kl_kod<128); {Printscreen opakovane} 42,70:odpocet:=4; {4-bajtova sekvence E0,neco,E0,neco} else vsechny_klavesy[klmod128]:=(kl_kod<128); end; 0:begin vsechny_klavesy[klmod128]:=(kl_kod<128); case klmod128 of 71..83:ZpracujJednotu(klmod128+Priznak_sedych_sipek,klmod128+Priznak_jednoty,klmod128); 28:ZpracujJednotu(KEY_NUM_ENTER,KEY_ENTER,0); {num Enter} 56:begin ZpracujJednotu(KEY_PALT,KEY_ALT,0); {levy Alt} PrectiAltovyBuffer; end; 29:ZpracujJednotu(KEY_PCTRL,KEY_CTRL,0); {l. Ctrl} 42:ZpracujJednotu(KEY_PSHIFT,KEY_SHIFT,0); {l. Shift} 54:ZpracujJednotu(KEY_LSHIFT,KEY_SHIFT,0); {p. Shift} end; if (kl_kod<128) and (vsechny_klavesy[KEY_ALT]) then begin {drzime Alt a pritom byla}{zmacknuta klavesa na numericke klavesnici?} case kl_kod of 71:ab:=7; 72:ab:=8; 73:ab:=9; 75:ab:=4; 76:ab:=5; 77:ab:=6; 79:ab:=1; 80:ab:=2; 81:ab:=3; 82:ab:=0; 56:ab:=11; {komplikace - periodicke vysilani Altu} else ab:=10; end; if ab<>11 then if ab=10 then paltbuf[0]:=0 else if paltbuf[0]<5 then begin inc(paltbuf[0]); paltbuf[paltbuf[0]]:=ab; end else begin paltbuf[0]:=1; paltbuf[1]:=ab; end; end; end; end; {case odpocet} if kl_kod>127 then kl_kod:=0 else if vsechny_klavesy[KEY_SHIFT] then inc(kl_kod,1000); {musim mit na pameti shifty} end; if odpocet>0 then dec(odpocet); {$IFDEF FPC} if bios=false then OutPortB($20,$20); {$ELSE} if bios=false then Port[$20]:=$20 else begin asm call oldint9_handler end; end; {$ENDIF} end; procedure CtiKod_dummy; begin end; {$IFDEF FPC} procedure int9_handler; assembler; asm cli {$IFDEF OPATRNOST} push ds push es push fs push gs pusha {$ENDIF} mov ax,cs:[backupDS] mov ds,ax mov es,ax mov ax,dosmemselector mov fs,ax call obsluha {$IFDEF OPATRNOST} popa pop gs pop fs pop es pop ds {$ENDIF} jmp cs:[oldint9_handler] sti end; procedure int9_dummy; begin end; procedure int9_nbhandler; assembler;interrupt; asm cli {$IFDEF OPATRNOST} push ds push es push fs push gs pusha {$ENDIF} mov ax,cs:[backupDS] mov ds,ax mov es,ax mov ax,dosmemselector mov fs,ax call obsluha {$IFDEF OPATRNOST} popa pop gs pop fs pop es pop ds {$ENDIF} sti end; procedure int9_nbdummy; begin end; {$ENDIF FPC} procedure ZapniObsluhuKlavesnice(rezim:boolean); begin kl_zmena:=false; bios:=rezim; altbuf:=0; FillChar(paltbuf,sizeof(paltbuf),0); FillChar(vsechny_klavesy,sizeof(vsechny_klavesy),0); obsluha:=@CtiKod; {$IFDEF FPC} lock_data(obsluha, sizeof(obsluha)); lock_data(kl_kod, sizeof(kl_kod)); lock_data(bios, sizeof(bios)); lock_data(kl_zmena, sizeof(kl_zmena)); lock_data(odpocet, sizeof(odpocet)); lock_data(paltbuf, sizeof(paltbuf)); lock_data(altbuf, sizeof(altbuf)); lock_data(vsechny_klavesy,sizeof(vsechny_klavesy)); lock_data(dosmemselector, sizeof(dosmemselector)); lock_code(@CtiKod,longint(@CtiKod_dummy) - longint(@CtiKod)); if bios then begin lock_code(@int9_handler,longint(@int9_dummy)-longint(@int9_handler)); newint9_handler.offset:=@int9_handler; end else begin lock_code(@int9_nbhandler,longint(@int9_nbdummy)-longint(@int9_nbhandler)); newint9_handler.offset:=@int9_nbhandler; end; newint9_handler.segment:=get_cs; get_pm_interrupt(kbdint, oldint9_handler); set_pm_interrupt(kbdint, newint9_handler); {$ELSE} newint9_handler:=@ctikod; GetIntVec(kbdint, oldint9_handler); SetIntVec(kbdint, newint9_handler); {$ENDIF} end; procedure VypniObsluhuKlavesnice; begin {$IFDEF FPC} set_pm_interrupt(kbdint, oldint9_handler); unlock_data(dosmemselector, sizeof(dosmemselector)); unlock_data(kl_kod, sizeof(kl_kod)); unlock_data(bios, sizeof(bios)); unlock_data(kl_zmena, sizeof(kl_zmena)); unlock_data(odpocet, sizeof(odpocet)); unlock_data(paltbuf, sizeof(paltbuf)); unlock_data(altbuf, sizeof(altbuf)); unlock_data(vsechny_klavesy,sizeof(vsechny_klavesy)); unlock_data(obsluha, sizeof(obsluha)); unlock_code(@CtiKod,longint(@CtiKod_dummy) - longint(@CtiKod)); if bios then unlock_code(@int9_handler,longint(@int9_dummy)-longint(@int9_handler)) else unlock_code(@int9_nbhandler,longint(@int9_nbdummy)-longint(@int9_nbhandler)); {$ELSE} SetIntVec(kbdint, oldint9_handler); {$ENDIF} end; end.