3.13. Události kontrolních prvků formuláře
Již jsme mluvili o metodě zpracování událostí, která je použita v počítačích Palm Pilot a kompatibilních. Program čeká na akci uživatele (třeba stisknutí tlačítka). Této akci říkáme událost. O této události operační systém PalmOS vytvoří zprávu a tuto zprávu předá našemu programu.
V našem programu je tato zpráva vyzvednuta funkcí EvtGetEvent(). S výjimkou několika zpráv, na které v našem programu reagujeme na jednom místě (třeba výměna formulářů), pak vyzvednutou zprávu předáme funkci aktuálního formuláře.
Také zprávy, které jsou vytvářeny jako reakce na stisknutí tlačítka, přepínače nebo jiného kontrolního prvku formuláře, jsou takto předány funkci aktuálního formuláře. Ve funkci formuláře pak na zprávu můžeme příslušně reagovat.
Události stisknutí tlačítka
Když se uživatel dotkne kontrolního prvku formuláře - třeba tlačítka -, je vytvořena zpráva ctlEnterEvent. Zprávu ctlEnterEvent zpracuje operační systém PalmOS, který invertuje text tlačítka. Naše aplikace může tuto zprávu bezpečně ignorovat.
ctlEnterEvent | |
---|---|
EventType* event; | |
UInt16 event->data.ctlEnter.controlID |
Jednoznačná identifikace kontrolního prvku formuláře (například tlačítka), kterého se uživatel dotkl. |
ControlPtr event->data.ctlEnter.pControl |
Ukazatel na data tohoto kontrolního prvku formuláře. |
Poté, co uživatel tlačítko stiskne, může zvednout pero z displeje buď uvnitř hranic tlačítka, nebo mimo tyto hranice. Zvedne-li uživatel pero z displeje v hranicích tlačítka, znamená to, že je tlačítko stisknuto, a je vytvořena zpráva ctlSelectEvent. Na tuto zprávu budeme většinou v naší aplikaci reagovat.
ctlSelectEvent | |
---|---|
EventType* event; | |
UInt16 event->data.ctlSelect.controlID |
Jednoznačná identifikace kontrolního prvku formuláře (například tlačítka), který uživatel zvolil. |
ControlPtr event->data.ctlSelect.pControl |
Ukazatel na data tohoto kontrolního prvku formuláře. |
Boolean event->data.ctlSelect.on |
Tento prvek má logickou hodnotu true (1), pokud je kontrolní prvek (přepínač, políčko k zaškrtnutí) vybrán (zaškrtnut). |
Pokud naproti tomu uživatel stiskne tlačítko a potom posune pero mimo hranice tohoto tlačítka, nepovažuje to operační systém PalmOS za akci stisknutí tlačítka. V takovém případě předá naší aplikaci zprávu ctlExitEvent.
ctlExitEvent | |
---|---|
EventType* event; | |
UInt16 event->data.ctlExit.controlID |
Jednoznačná identifikace kontrolního prvku formuláře (například tlačítka), kterého se uživatel dotkl a poté přemístil pero na displeji mimo něj. |
ControlPtr event->data.ctlExit.pControl |
Ukazatel na data tohoto kontrolního prvku formuláře. |
Nejdůležitější událostí, kterou generují kontrolní prvky formuláře, je událost ctlSelectEvent. Tuto událost pošle operační systém PalmOS naší aplikaci tehdy, je-li příslušný kontrolní prvek vybrán (tlačítko stisknuto, změněn stav přepínače a podobně).
Ošetření tlačítek
Při stisknutí tlačítka nebo jiného kontrolního prvku formuláře reaguje operační systém PalmOS na tuto událost tak, že vytvoří - a našemu programu předá - postupně tyto dvě zprávy:
- ctlEnterEvent při stisknutí tlačítka
- ctlSelectEvent při zvednutí pera z tlačítka
Nás bude zajímat zpráva ctlSelectEvent. V datové části struktury zprávy je uložena jednoznačná identifikace stisknutého tlačítka (prvek controlID). Podle této hodnoty pozná náš program, které tlačítko bylo právě stisknuto.
Zprávu ctlSelectEvent však operační systém PalmOS generuje, i když se uživatel dotkne přepínače nebo políčka volby textu. Ve funkci formuláře, ve kterém je tlačítko (nebo jiný kontrolní prvek formuláře) umístěno, musíme proto podle hodnoty prvku data.ctlSelect.controlID určit, které tlačítko bylo stisknuto. Pokud budeme stisknutí tohoto tlačítka zpracovávat, musí funkce formuláře vrátit hodnotu true. Příklad je v následujícím rámečku:
static Boolean TypickaFunkceFormulare(EventPtr udalost) { Boolean zpracovano = false; switch(udalost->eType) { ... case ctlSelectEvent: switch(udalost->data.ctlSelect.controlID) { case TlacitkoNapoveda: // ošetření události stisknutí tohoto tlačítka zpracovano = true; break; case TlacitkoDalsi: // ošetření události stisknutí dalšího tlačítka zpracovano = true; break; ... default: break; } break; ... } return zpracovano; } |
Už od počátku musíme důsledně dbát na to, aby funkce formuláře vracela logickou hodnotu true, pouze pokud danou zprávu zpracováváme. Toto pravidlo musíme dodržet i ve větvení podle hodnoty parametru udalost->data.ctlSelect.controlID.
Události opakovacích tlačítek
Opakovací tlačítka se od ostatních kontrolních prvků formuláře liší tím, že při svém stisknutí negenerují zprávu ctlSelectEvent. Namísto toho zasílají - dokud je uživatel drží stisknuté - naší aplikaci zprávu ctlRepeatEvent. Tuto zprávu tedy zasílají opakovaně, a to s frekvencí dvakrát za vteřinu.
ctlRepeatEvent | |
---|---|
EventType* event; | |
UInt16 event->data.ctlRepeat.controlID |
Jednoznačná identifikace kontrolního prvku formuláře (například tlačítka), který uživatel drží stisknutý. |
ControlPtr event->data.ctlRepeat.pControl |
Ukazatel na data tohoto kontrolního prvku formuláře. |
UInt32 event->data.ctlRepeat.time |
Hodnota, kterou měl systémový časovač v okamžiku generování této zprávy ctlRepeatEvent |
Tato tlačítka je možné použít, například chceme-li mít na displeji tlačítko posouvající text o řádek. Bylo by nepohodlné a uživatelsky nepřívětivé, kdybychom nutili uživatele opakovaně tisknout posouvající tlačítko. Mnohem přirozenější je umístit za tímto účelem do formuláře opakovací tlačítko. Z hlediska programátora je jediným rozdílem nutnost reagovat na zprávu ctlRepeatEvent místo ctlSelectEvent.
V našem programu budeme používat jak tlačítka obyčejná (pro vyvolání nápovědy), tak i tlačítka opakovací (ke zvětšování a zmenšování hodnoty výšky).
Pověděli jsme si o zprávách, které operační systém generuje po aktivaci kontrolního prvku formuláře (například stisknutí tlačítka). V příštím dílu uděláme krátkou odbočku, ve které si povíme o tom, jak je možné použít textové konstanty pro nápovědu. Po této odbočce doplníme do našeho postupně vznikajícího programu první funkci - ošetření tlačítka nápovědy.