Programování PocketPC naruby (10/12)

Patříte mezi uživatele PocketPC, kteří by si rádi také něco naprogramovali, řadíte se však k tzv. falešným začátečníkům? Pak právě vám je určen náš seriál věnovaný programování pro kapesní počítače s Windows Mobile. Dnešní díl věnujeme uživatelskému rozhraní.
Dnešním dílem seriálu Programování naruby navážeme na předchozí část věnovanou hlavnímu oknu aplikace a ovládání Software Input Panelu.

Doplnění uživatelského rozhraní

Naše aplikace pro Microsoft Windows na stolním počítači využívala zejména ovládání pomocí klávesnice. Na kapesním počítači musíme koncepci uživatelského rozhraní změnit tak, aby bylo možné všechny základní úkony, ke kterým jsme používali klávesnici, realizovat pomocí doteku perem na displeji. Jedná se o následující akce:

Akce Klávesa
Smazání položky seznamu DELETE
Nová položka seznamu SHIFT + ENTER
Posun položky seznamu nahoru nebo dolů SHIFT + šipka nahoru nebo dolů
Změna ikony mezerník

Už jsme si uvedli, že pro základní úkony při ovládání Pocket PC aplikací potřebujeme umístit na spodní část displeje prvek Menu Bar. Už z názvu prvku Menu Bar je zjevné, že obsahuje položky menu. Pro úsporu místa může být každá položka buď textová, nebo grafická.

U starších verzí Windows CE bylo menu umístěné na horním rámu okna, aby se ušetřilo místo na displeji. K ovládání počítačů Pocket PC je používán převážně stylus a umístění hlavních ovládacích prvků dole na displeji je výhodnější, protože uživatel při ovládání nezakrývá displej.

V prostředí Embedded Visual C++ 3.0 vložíme do souboru prostředků programu nové menu a upravíme jej například podle následujícího obrázku tak, aby obsahovalo jednu textovou položku a pět (viz tabulka výše) položek jako ikony.

Vlastní ikony budeme muset do menu doplnit ručně. Všimněte si, že ačkoliv pro všechny ikony v menu je použit stejný symbol, můžeme u každé z nich doplnit hodnotu Bitmap index. Do projektu doplníme rastrový obrázek výšky 16 bodů, který bude vedle sebe obsahovat všechny ikony, které si přejeme v menu použít. Velikost ikony v menu je 16 x 16 obrazových bodů, celková šířka obrázku je rovna počtu ikon vynásobenému šestnácti. Příklad obrázku, který obsahuje všechny ikony naší aplikace je (příklad je zvětšený, skutečný obrázek je velký 80 x 16 obrazových bodů):

Hodnota Bitmap index pak udává pozici ikony v námi definovaném obrázku (počítáno od nuly). Vlastní propojení obrázku a menu vytvoříme ve zdrojovém kódu programu při inicializaci prvku Menu Bar:


HWND CreateMyCommandBar(HWND hwnd)
{
    SHMENUBARINFO mbi;

    memset(&mbi, 0, sizeof(SHMENUBARINFO));
    mbi.cbSize     = sizeof(SHMENUBARINFO);
    mbi.hwndParent = hwnd;
    mbi.nToolBarId = IDR_MENU; // Index prostředku pro menu
    mbi.hInstRes   = g_hInstance;
    mbi.nBmpId     = IDB_TOOLBAR; // Index prostředku pro náš obrázek s ikonami
    mbi.cBmpImages = 5; // Celkový počet ikon v obrázku

    if(!SHCreateMenuBar(&mbi)) return NULL;

    return mbi.hwndMB;
}

Po doplnění do zdrojového kódu naší aplikace se dočkáme příjemného překvapení: jednak se na spodku displeje zobrazuje menu, ale především -  ty položky menu, které mají stejné identifikátory jako položky menu aplikace pro Windows, jsou funkční. Jednoduchým způsobem můžeme při zpracování zprávy WM_COMMAND doplnit příslušné funkce i k dalším položkám menu.

Dialog nastavení

První, co je třeba udělat, je poskládat dialog nastavení tak, aby se vešel na displej kapesního počítače. Prostředí Embedded Visual C++ nenabízí žádnou možnost, jak zajistit "správnou" velikost dialogového okna pro počítače Pocket PC. V této fázi se pravděpodobně nevyhnete nutnosti vyzkoušet správné rozměry metodou pokus-omyl.

Pokud nyní program přeložíme, bude volání dialogu nastavení fungovat bez chyby. V případě, že se vám ale výsledný efekt nelíbí, máte pravdu. Takhle vypadaly dialogy v předchozích verzích Windows CE.

Nový vzhled, který lépe zapadne do prostředí operačního systému Pocket PC můžeme zajistit jednoduchým voláním funkce SHInitDialog při zpracování zprávy WM_INITDIALOG. Funkce SHInitDialog umožní také skrýt tlačítko (OK) v pravém hormím rohu displeje nebo zobrazit nebo skrýt SIP při otevření dialogu.


BOOL CALLBACK SetupDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    SHINITDLGINFO shidi;

    switch(uMsg)
    {
        case WM_INITDIALOG:
            shidi.dwMask = SHIDIM_FLAGS;
            shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
            shidi.hDlg = hwnd;
            SHInitDialog(&shidi);
            return TRUE;

...
        default:
            break;
    }

    return FALSE;
}

Pokud si nyní prohlédneme dialog nastavení, tak vidíme, že jeho vzhled je zcela standardní a očekávaný: