3.22. Databáze nastavení
Programy spuštěné na počítačích Palm Pilot a kompatibilních vzbuzují v uživateli dojem multitaskingu. Při přepnutí hardwarovým tlačítkem do jiné aplikace nebo do správce aplikací však náš program regulérně skončí (je mu zaslána zpráva appStopEvent). Pokud se uživatel do programu "vrátí" (znovu jej spustí), tak očekává, že vše nalezne v takovém stavu, v jakém aplikaci opustil. Podle pořadí důležitosti je to:
- Program si pamatuje uživatelské nastavení
- Stejný formulář
- Stejné hodnoty přepínačů a políček k zaškrtnutí, stejný text v políčkách
- Kursor je ve stejném políčku na stejném místě, jako když uživatel aplikaci ukončil.
Jednoduchým prostředkem, který pro toto ukládání dat poskytuje operační systém PalmOS, je databáze nastavení (Preferences). Aplikace mohou při skončení uložit svůj stav (ve kterém formuláři se uživatel nachází, obsahy políček a logické stavy přepínačů) do databáze nastavení a při opětovném spuštění jej z této databáze přečíst. Popsaným mechanismem vzbuzují aplikace pro PalmOS dojem, že běží "současně".
Zápis do databáze nastavení
void PrefSetAppPreferences(UInt32 tvurce, UInt16 typ, Int16 verze, void* data, UInt16 velikost, Boolean uložit) Uloží stav aplikace do databáze nastavení. | |
Vstupní parametry |
|
Každý záznam v databázi nastavení je jednoznačně popsán třemi konstantami, které předáváme při uložení dat: identifikací aplikace, která jej uložila (parametr tvurce), verzí aplikace, která jej uložila (parametr verze), a svým typem (parametr typ), který volí uživatel. Parametr typ od sebe odlišuje jednotlivé záznamy, které ukládá do databáze nastavení stejná aplikace. Většina aplikací ukládá do databáze nastavení pouze jeden záznam s hodnotou typ rovnou nule.
Poslední parametr (uložit) informuje operační systém o tom, zda si přejeme zálohovat toto nastavení při synchronizaci nebo ne.
Ačkoliv aplikace mohou zapisovat i číst data v databázi nastavení kdykoliv, bývá zvykem přečíst nastavení na začátku aplikace a uložit jej před skončením. Tento příklad je popsán v následujícím rámečku:
#define VERZE 1 // Definice typu ukládaných dat typedef struct { // prvky struktury obsahující nastavení programu } Nastaveni; // Globální proměnná obsahující nastavení programu Nastaveni globalni; ... void KonecAplikace() { PrefSetAppPreferences('NECO', 0, VERZE, &globalni, sizeof(Nastaveni), true); } |
Při vytváření nové verze programu můžeme zjistit, že potřebujeme ukládat do databáze nastavení jiná data. V takovém případě nesmíme zapomenout v každé další verzi programu zvolit jinou hodnotu parametru verze. Pokud bychom omylem načetli jinou datovou strukturu, mohl by se program začít chovat nepředvídatelně.
Čtení z databáze nastavení
Podobně jednoduché jako ukládání dat do databáze nastavení je i jejich čtení na začátku programu. Hodnoty z databáze nastavení většinou čteme při spuštění programu ve funkci ZacatekProgramu(). Podle přečtených hodnot pak zvolíme počáteční formulář, nastavíme globální proměnné a tak podobně.
Int16 PrefGetAppPreferences(UInt32 tvurce, UInt16 typ, void* data, UInt16* delka, Boolean uložené) Vyzvedne data z databáze nastavení. | |
Vstupní parametry |
|
Výstupní parametry |
|
Vrácená hodnota |
|
Pokud funkci PrefGetAppPreferences() předáme v parametru data hodnotu NULL, uloží funkce do parametru *delka délku bloku dat, který je uložen v databázi nastavení. I v tomto případě funkce vrátí číslo verze aplikace, která data uložila. Typické použití funkce je následující:
#define VERZE 1 // Definice typu ukládaných dat typedef struct { // prvky struktury obsahující nastavení programu } Nastaveni; // Globální proměnná obsahující nastavení programu Nastaveni globalni; ... Err ZacatekAplikace() { UInt16 delka = sizeof(Nastaveni); Int16 verze = PrefGetAppPreferences('NECO', 0, &globalni, &delka, true); if(verze != VERZE || delka != sizeof(Nastaveni)) { MemSet(&globalni, sizeof(Nastaveni), 0); // Jde o první spuštění této verze aplikace // a musíme nastavit počáteční hodnoty // nastavení... } FrmGotoForm(prvniFormular); return 0; } |
Pokud uživatel instaluje na počítači Palm Pilot novou verzi aplikace, tak nastavení staré verze není vymazáno. Programátor se v takovém případě musí rozhodnout, jak naloží s původním nastavením. V některých případech je možné původní nastavení ignorovat. Jindy je nutné testovat verzi uloženého nastavení a v případě starší verze ji načíst do pomocné proměnné jako v následujícím příkladu:
typedef struct { // prvky struktury obsahující nastavení programu } Nastaveni; typedef struct { // prvky struktury obsahující nastavení původní verze programu } NastaveniVerze1; // Globální proměnná obsahující nastavení programu Nastaveni globalni; ... Err ZacatekAplikace() { UInt16 delka = 0; // Vyzvedneme číslo verze aplikace, která ukládala data // a délku bloku dat Int16 verze = PrefGetAppPreferences('NECO', 0, NULL, &delka, true); NastaveniVerze1 pomocne; if(verze == 1 && delka == sizeof(NastaveniVerze1)) { // Data uložila aplikace verze 1 delka = sizeof(NastaveniVerze1); PrefGetAppPreferences('NECO', 0, &pomocne, &delka, true); // Zkopírujeme data, která si odpovídají, po jednotlivých // prvcích struktury a zbylá inicializujeme ručně. MemSet(&globalni, sizeof(Nastaveni), 0); globalni.promenna1 = pomocne.promenna1; globalni.promenna2 = pomocne.promenna2; ... } else if(verze == 2 || delka != sizeof(Nastaveni)) { // Data uložila aplikace verze 2 delka = sizeof(Nastaveni); PrefGetAppPreferences('NECO', 0, &globalni, &delka, true); } else { MemSet(&globalni, sizeof(Nastaveni), 0); // Jde o první spuštění této verze aplikace // a musíme nastavit počáteční hodnoty // nastavení... } FrmGotoForm(prvniFormular); return 0; } |
Databázi nastavení můžeme také použít přímo k uložení dat jednotlivých formulářů. V takovém případě přečteme data z databáze nastavení při obsluze události frmOpenEvent. Podle přečtených dat můžeme inicializovat ovládací prvky formuláře. Uložit data do databáze nastavení můžeme pak při obsluze události frmCloseEvent nebo při obsluze události stisknutí tlačítka pro uložení dat (ve větvi ctlSelectEvent). Data jednotlivých formulářů můžeme od sebe odlišit právě parametrem typ označujícím odlišný typ záznamu pro každý formulář.
Starší verze PalmOS
V poznámce k funkcím PrefGetAppPreferences() a PrefSetAppPreferences() je uvedeno, že tyto funkce jsou součástí operačního systému PalmOS od verze 2.0. Pokud překládáme program pro starší verzi operačního systému PalmOS, musíme místo nich použít funkce PrefGetAppPreferencesV10() a PrefSetAppPreferencesV10(), které mají poněkud odlišné parametry a které zde nebudeme popisovat.
Dokončení naší aplikace
Posledním krokem při psaní naší aplikace bude zachování jejího stavu (pohlaví dítěte a hodnoty výšky matky a otce) při opětovném spuštění aplikace. S databází nastavení pracujeme pomocí vhodných obalujících funkcí UlozStavProgramu() a VyzvedniStavProgramu(). Z důvodu úspory paměti ukládáme data do databáze nastavení v kompaktní podobě (zabírající jen 32 bitů).
Zdrojový text poslední verze naší aplikace si můžete stáhnout zde.
Konec třetí kapitoly.