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