Programování klávesnice a myši
Aktivace činnosti
Při
programování klávesnice jde zejména o problém aktivace nějaké činnosti (často
velmi složité) stlačením jediné klávesy nebo kombinace kláves. Takovým
klávesám se říká funkční. (Někdy, v manuálech, též horké. Podle
anglického pojmenování Hot Keys.) Teoreticky může být funkční klávesou
libovolná klávesa, pokud není v rozporu s logikou programu. V užším slova
smyslu jsou za funkční klávesy považovány klávesy F1 až F12. S ohledem na
uživatele je žádoucí dodržovat konvence, které jsou často již několik
desítek let respektované. Druh činnosti je závislý nejen na druhu klávesy,
ale i na okamžité pozici klávesového kurzoru.
Při
programování myši jde o určení místa na obrazovce, na kterou ukazuje
kurzor myši. Při programování myši nutno akceptovat triviální zásadu, že
nemůže existovat činnost vyvolaná myší, která by nebyla aktivizovatelná
též pomocí kláves.
Ve
druhé verzi FoxPro je již důsledně automatizována práce s klávesnicí a
myší. Programátor se při programování styku uživatele s počítačem tímto
problémem obyčejně nezabývá. Zvyšuje se tak produktivita práce, ale co je
podstatnější, přirozeným způsobem se unifikuje používání funkčních
kláves. Přesto existují speciální úlohy, mezi ně patří zejména
instruktážní, demonstrační a simulační programy, u kterých se nelze obejít
bez znalostí programování kláves a myši.
Speciální přepínače
Klávesnice
má několik režimů, které nutno programově řídit. Uživatel má právo mít
předem nastaveny optimální režimy, aby nemusel řešit konfliktní situace.
CapsLock malá nebo velká písmena
InsMode vkládání znaků nebo přepisování
NumLock použití klávesové kostky pro vstup číslic
(důležité pro českou klávesnici)
V
podstatě jde o programové ovládání přepínačů. Při programování se
nezjišťuje z důvodu přepnutí původní nastavení, jak je to nucen dělat uživatel,
ale přímo se nastavuje požadovaný režim. Používají se k tomu funkce
pojmenované podle příslušných kláves. Funkce bez parametru umožní
zjistit nastavení jako logickou hodnotu. Je-li zadán parametr (logický výraz),
pak se režim nastaví podle hodnoty parametru.
CAPSLOCK([<expL>])
Nastavení klávesnice na režim
velkých písmen
=CAPSLOCK(.T.)
INSMODE([<expL>])
Nastavení klávesnice na režim
vkládání znaků
=INSMODE(.T.)
NUMLOCK([<expL>])
Nastavení klávesnice na režim
vstupu číslic z klávesnicové kostky
=INSMODE(.T.)
Aby uživatel viděl nastavené
režimy, je vhodné programovat příkaz:
SET SCOREBOARD ON
Při uvedení ON a nastavení
SET STATUS OFF se informace zobrazí na řádku 0. (Při SET STATUS ON se zapíše
do stavového řádku, ale tato technika se v praxi používá jen výjimečně.)
Při uvedení OFF se informace nezobrazuje.
Vyrovnávací paměť klávesnice
Znaky
z klávesnice nevstupují do programu přímo, ale se ukládají do zvláštní
vyrovnávací paměti (klávesnice). Je to zásobník s nastavitelnou kapacitou,
který vyrovnává rychlost programu a uživatele. Jeho úloha je zvláště důležitá
ve víceuživatelském režimu práce. Kapacita se nastavuje příkazem:
SET TYPEAHEAD TO <expN>
Kde <expN> zadává počet
znaků v zásobníku z intervalu 0 až 128 (implicitně 20). Zadání hodnoty 0
deaktivuje příkaz ON KEY a INKEY().
Čtení znaků ze zásobníku
zajišťuje funkce:
INKEY([[<expN>] [, <expC>]])
která vrací ASCII kód stlačené
klávesy nebo kombinace kláves nebo tlačítka myši. Parametr <expN> určuje
počet sekund, po které funkce čeká na stlačení klávesy. Je-li zadána
nula, není doba čekání omezena. Není-li <expN> zadáno vůbec, vrací
se okamžitá hodnota ze zásobníku. Jako výraz <expC> se uvádí písmeno:
H -
neviditelný kurzor
S -
viditelný kurzor
M -
bude detekováno použití tlačítka myši (lze ji kombinovat s H nebo S).
Nebyla-li stlačena žádná
klávesa, vrací funkce nulu, jinak hodnotu odpovídající stlačené klávese
nebo kombinaci kláves (prvního vloženého znaku ze zásobníku pro vstup z klávesnice).
? INKEY(10, "M")
Tabulka hodnot uložených ve vyrovnávací
paměti klávesnice
│ Klávesa │ Samotná │+SHIFT │ +CTRL │ +ALT │ LABEL │
─────────────────────────────────────────────────────────────
│ F1 │ 28 │ 84 │ 94 │ 104 │ F1 │
│ F2 │ -1 │ 85 │ 95 │ 105 │ F2 │
│ F3 │ -2 │ 86 │ 96 │ 106 │ F3 │
│ F4 │ -3 │ 87 │ 97 │ 107 │ F4 │
│ F5 │ -4 │ 88 │ 98 │ 108 │ F5 │
│ F6 │ -5 │ 89 │ 99 │ 109 │ F6 │
│ F7 │ -6 │ 90 │ 100 │ 110 │ F7 │
│ F8 │ -7 │ 91 │ 101 │ 111 │ F8 │
│ F9 │ -8 │ 92 │ 102 │ 112 │ F9 │
│ F10 │ -9 │ 93 │ 103 │ 113 │ F10 │
│ F11 │ 133 │ 135 │ 137 │ 139 │ F11 │
│ F12 │ 134 │ 136 │ 138 │ 140 │ F12 │
│ 1 │ 49 │ 33 │ - │ 120 │ 1 │
│ 2 │ 50 │ 64 │ 33 │ 121 │ 2 │
│ 3 │ 51 │ 35 │ - │ 122 │ 3 │
│ 4 │ 52 │ 36 │ - │ 123 │ 4 │
│ 5 │ 53 │ 37 │ - │ 124 │ 5 │
│ 6 │ 54 │ 94 │ 30 │ 125 │ 6 │
│ 7 │ 55 │ 38 │ - │ 126 │ 7 │
│ 8 │ 56 │ 42 │ - │ 127 │ 8 │
│ 9 │ 57 │ 40 │ - │ 128 │ 9 │
│ 0 │ 48 │ 41 │ - │ 19 │ 0 │
│ a │ 97 │ 65 │ 1 │ 30 │ a │
│ b │ 98 │ 66 │ 2 │ 48 │ b │
│ c │ 99 │ 67 │ 3 │ 46 │ c │
│ d │ 100 │ 68 │ 4 │ 32 │ d │
│ e │ 101 │ 69 │ 5 │ 18 │ e │
│ f │ 102 │ 70 │ 6 │ 33 │ f │
│ g │ 103 │ 71 │ 7 │ 34 │ g │
│ h │ 104 │ 72 │ 8 │ 35 │ h │
│ i │ 105 │ 73 │ 9 │ 23 │ i │
│ j │ 106 │ 74 │ 10 │ 36 │ j │
│ k │ 107 │ 75 │ 11 │ 37 │ k │
│ l │ 108 │ 76 │ 12 │ 38 │ l │
│ m │ 109 │ 77 │ 13 │ 50 │ m │
│ n │ 110 │ 78 │ 14 │ 49 │ n │
│ o │ 111 │ 79 │ 15 │ 24 │ o │
│ p │ 112 │ 80 │ 16 │ 25 │ p │
│ q │ 113 │ 81 │ 17 │ 16 │ q │
│ r │ 114 │ 82 │ 18 │ 19 │ r │
│ s │ 115 │ 83 │ 19 │ 31 │ s │
│ t │ 116 │ 84 │ 20 │ 20 │ t │
│ u │ 117 │ 85 │ 21 │ 22 │ u │
│ v │ 118 │ 86 │ 22 │ 47 │ v │
│ w │ 119 │ 87 │ 23 │ 17 │ w │
│ x │ 120 │ 88 │ 24 │ 45 │ x │
│ y │ 121 │ 89 │ 25 │ 21 │ y │
│ z │ 122 │ 90 │ 26 │ 44 │ z │
│ Ins │ 22 │ 22 │ - │ - │ INS │
│ Home │ 1 │ 1 │ 29 │ - │ HOME │
│ Del │ 7 │ 7 │ - │ - │ DEL │
│ End │ 6 │ 6 │ 23 │ - │ END │
│ PgUp │ 18 │ 18 │ 31 │ - │ PGUP │
│ PgDn │ 3 │ 3 │ 30 │ - │ PGDN │
│Šipkanahoru│ 5 │ 5 │ - │ - │ UPARROW │
│Šipkavpravo│ 4 │ 4 │ 2 │ - │ RIGHTARROW│
│Šipkavlevo │ 19 │ 19 │ 26 │ - │ LEFTARROW │
│Šipkadolu │ 24 │ 24 │ - │ - │ DNARROW │
│ Escape │ 27 │ 27 │ 27 │ - │ ESC │
│ Enter │ 13 │ 13 │ 10 │ - │ ENTER │
│ Bkspac │ 127 │ 127 │ 127 │ - │ BACKSPACE │
│ Tab │ 9 │ 15 │ 148 │ 165 │ TAB │
│ Mezera │ 32 │ 32 │ 32 │ 32 │ SPACEBAR │
Je-li v programu nutno
zjistit, zda se nachází ve vyrovnávací paměti klávesnice nějaký znak,
použije se funkce:
CHRSAW([<expN>])
Funkce vrací .T., když je
ve vyrovnávací paměti klávesnice znak. Je-li zadán nepovinný parametr a zásobník
je prázdný, čeká na stlačení klávesy <expN> sekund. Jelikož funkce
neodebírá znak z klávesnice, programuje se s oblibou pro zobrazení chybových
zpráv a kontextuálních nápovědí. Zapsání prvního znaku opravy současně
zruší zobrazení zprávy.
Naopak programové vložení
řetězce znaků do vyrovnávací paměti (simulace práce uživatele, nejčastěji
používaná v ukázkových a instruktážních programech) se programuje příkazem:
KEYBOARD <expC> [PLAIN]
Do zásobníku pro vstup z klávesnice
se uloží <expC>. Takto připravený řetězec se uplatní jako vstup až
v okamžiku, kdy FoxPro chce číst data. Klávesová makra zapíšeme do
<expC> jako CHR(i) nebo jméno klávesy (kombinace kláves) uzavřené do
závorek { }. Použití fráze PLAIN zruší pro tento moment působnost klávesových
maker a nastavení z ON KEY LABEL, které by jinak nahradily znaky reprezentované
znaky. Nutno zdůraznit, navzdory tvrzení manuálů, příkaz nezobrazuje ale
zapisuje. Zobrazení je jen druhotné působení zapsaných řetězců, projevující
se v případech, kdy je zobrazení zapsaných znaků programováno.
Například napsání řetězce
ABC samostatně, na novém řádku. Chr(13) = ENTER
KEYBOARD chr(13) + "ABC" + chr(13)
S použitím názvů kláves
(label)
KEYBOARD '{CTRL+LEFTARROW}'
Když klávese K byla přiřazena
funkce, pak napsání textu "Krakonoš" musí být programováno
KEYBOARD "Krakonoš" PLAIN
Aktivace činností pomocí kláves
Nejjednodušším programováním
aktivace činnosti je pomocí příkazu
ON KEY [<příkaz>]
Specifikuje činnost po stlačení
libovolné klávesy. Jakékoliv následné stlačení klávesy po splnění ON
KEY <příkaz> má za následek plnění předepsaného příkazu.
Prakticky se programuje příkaz DO <podprogram>. (Po jeho splnění se řízení
vrací za příkazový řádek, při kterém byla klávesa stlačena, pokud plnění
příkazu nezpůsobilo RETRY). Další vyvolání ON KEY mění předchozí
nastavení. Použití bez parametru ruší nastavení ON KEY. Kód stisknuté klávesy
zůstává ve vyrovnávací pamětí klávesnice. Lze tudíž určit, která klávesa
byla použitá (například funkcí INKEY()).
Aby
příkaz se provedl pouze po stlačení konkrétní klávesy (nebo kombinace kláves),
nutno zadat kód, který není jednoznačně odvoditelný od ASCII hodnoty klávesy
(kód je odvozen od SCAN kódu IBM, zvětšeného o 256). Nejvhodnější je použití
následující tabulky
┌──────────────────────────────────────────────────────
│ KÓDY ODPOVÍDAJÍCÍ KLÁVESY
├──────────────────────────────────────────────────────
│
272 - 281 Alt+Q, W, E, R, T, Y, U, I, O, P
│
286 - 294 Alt+A, S, D, F, G, H, J, K, L
│
300 - 306 Alt+Z, X, C, V, B, N, M
│
│
315 - 324 F1 až F10
│
327 Home
│
328 Šipka
nahoru
│
│
329 Home
│
331
Šipka vlevo
│
333 Šipka
vpravo
│
│
335 End
│ 336
Šipka
dolů
│
337 PgDn
│
│
338 Ins
│
339 Del
│
340 - 349 Shift+F1 až Shift+F10
│
│
350 - 359 Ctrl+F1 až Ctrl+F10
│
360 - 369 Alt+F1 až Alt+F10
│
370 Ctrl+Print Screen
│
│
371 Ctrl+šipka
vlevo
│
372 Ctrl+Šipka
vpravo
│
373 Ctrl+End
│
374 Ctrl+PgDn
│
375 Ctrl+Home
│
376 - 387 Alt+1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =
│
388 Ctrl+PgUp
Pro ovládání výpočtu v
průběhu čtení údajů z klávesnice (například v příkazu READ) konkrétní
klávesou lze použít analogického příkazu:
ON KEY = kód [<příkaz>]
Příkaz se používá spíše
kvůli tradici. V jednom okamžiku lze totiž definovat pouze jednu klávesu a
jednu činnost. To následující příkaz je univerzálnější, pohodlnější
a tudíž v nejnovějších programech velice často se vyskytující:
ON KEY LABEL <název klávesy> [<příkaz>]
Názvy kláves jsou uvedeny v
předchozí tabulce ve sloupci LABEL. Lze přiřadit činnosti více klávesám
najednou. (Stlačení klávesy se zachytí v příkazech READ, BROWSE, EDIT,
CHANGE, uživatelsky definovaných menu a popup, i z příkazového okna.) Po
splnění činnosti předepsané příkazem se řízení vrací za řádek, kde
došlo k přerušení nebo zpět do READ.
Hromadné navrácení
standardních funkcí všem klávesám se provede příkazem
ON KEY
Zkušenosti z ladění programů
Přiřadí-li
se klávesám jiné funkce, než standardní, pak stejnou sérii příkazů ON
KEY LABEL <název klávesy>, bez uvedení příkazu, lze dosáhnout jejich
původního významu.
Při
ladění však může program havarovat v okamžiku, kdy klávesy mají
nestandardní funkci. Někdy se nedá zapsat ani příkaz pro ukončení práce
systému. Není však nutno znovu startovat počítač. Ani při předefinování
funkce klávesy ENTER. Situace se dá řešit napsáním jednořádkového
programu. K editování a odstartování programu stačí myš. Písmena lze brát
z ASCCI tabulky menu SYSTEM. Program obsahuje jediný příkaz: ON KEY. Mnohdy
je rychlejší stisk kláves ALT+F a Q, které způsobí ukončení práce systému.
Zkušený
programátor si vytvoří programový modul typu PRG (proceduru), který
obsahuje příkazy pro zrušení nestandardních funkcí kláves. Ten stejně
použije v programu. V případě havárie segment aktivuje pomocí myši z menu
PROGRAM. Méně vhodné je jako první příkaz série přiřazení nestandardních
funkcí klávesám zapsat příkaz pro rušení všech přiřazení, který je
funkcí kuriózní klávesy. Například ON KEY LABEL | ON KEY. Tento příkaz
nutno z programu, po odladění, odstranit.
Programování tabulkových procesorů.
Pokud
se programuje tabulkový procesor (spreadsheet) pomocí příkazu Browse, pak
ihned po klávese ENTER musí následovat aktualizace mezivýsledků. To vede k
řadě potíží. Proto se doporučuje používat klauzuli VALID, která je součástí
příkazu BROWSE. (Viz specializovanou přednášku k tomuto problému.)
Speciální funkční klávesy
Pro
ovládání funkcí programu je vyhrazeno 12 kláves, označených F1 až F10,
respektive až F12. Jejich funkce lze programově řídit a některé z nich
jsou vázány mezinárodními (zatím nepsanými) konvencemi. F1 je určena pro
nápovědi, F2 by měla být požívána pro funkce spojené s uchováním
informace na vnější médium, F3 pro opačnou funkci (načtení), F10 pro volání
hlavního menu, apod.
Jelikož v některých příkazech
je nutné použít přímo jména klávesy, byla k tomuto účelu vytvořena
funkce
FKLABEL(<expN>)
která vrací jméno funkční
klávesy nebo kombinace kláves odpovídající číselné hodnotě. Číslování
je od nuly, proto např. pro <expN>=4 vrací F5. Je-li SET COMPATIBLE
nastaveno na OFF, je povolený rozsah pro <expN> 0 až 11 (klávesy F1 až
F12). Je-li COMPATIBLE ON, je rozsah 0 až 28 (klávesy F1 až F10 a v kombinacích
s Ctrl nebo Shift). Při <expN> mimo rozsah vrací prázdný řetězec.
Ovládání myši
MCOL([<expC>])
Vrací číslo sloupce aktuální
pozice kurzoru myši. Zadáme-li <expC> jako prázdný řetězec, vrací
sloupec relativně vzhledem k obrazovce. Je-li <expC> jméno okna, pak
relativně vzhledem k oknu. Není-li <expC> zadáno, pak vrací číslo
sloupce v aktuálním výstupním okně, není-li takové okno, pak v celé
obrazovce. Je-li kurzor myši umístěn mimo sloupce pocházející oknem, je vrácena
-1. Tato hodnota je vrácena rovněž tehdy, není-li zaveden ovladač pro myš.
?MCOL("vyst_okno")
MROW([<expC>])
Vrací číslo řádku aktuální
pozice kurzoru myši. Zadáme-li <expC> jako prázdný řetězec, vrací
řádek relativně vzhledem k obrazovce. Je-li <expC> jméno okna, pak
relativně vzhledem k oknu. Není-li <expC> zadáno, pak vrací číslo řádku
v aktuálním výstupním okně, není-li takové okno, pak v celé obrazovce.
Je-li kurzor myši umístěn mimo řádky pocházející oknem, je vrácena -1.
Tato hodnota je vrácena rovněž tehdy, není-li zaveden ovladač pro myš.
? MROW("vyst_okno")
Cvičení
Kontextuální nápovědi
Příklad na přiřazení nápovědí
klávese F1. F1 aktivuje podprogramu 'napoved' pro vstup položek při čtení.
Jde o poněkud starší způsob programování, ale dosud se používá. (Výhodnější
je využití klauzulí valid, message a error).
n= 'Příklad
programování kontextuálních nápovědí'
clear
&& Výmaz obrazovky
set talk off
&& Potlačení mezivýsledků
&&
Konec přípravné části
polozka=" "
&& Příprava vstupu položky
castka=0
&& Příprava vstupu položky
' konec příkladu klávesou ESC' && Zobrazení
povolené funkční klávesy
ON KEY=315 DO napoved
&& Přiřazení nápovědi klávese F1, těsně k příkazu
READ cycle
&& čtení
ON KEY=315
&& Ukončení, zabránit rekurizivitě
PROCEDURE napoved
&& Procedura
do case
case row()=10
&& Funkce procedury je řízena polohou kurzoru
wait "Povolené
položky jsou:1,2a,2b,3,7" nowait wind
&&
Vlastní nápověď je záměrně zjednodušená
case row()=12
&& Funkce procedury je řízena polohou kurzoru
wait "V Kčs na dvě
desetinná místa" nowait wind
&&
Vlastní nápověď je záměrně zjednodušená
endcase