Programování PocketPC naruby (9/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 hlavnímu oknu aplikace.
Dnešním dílem seriálu Programování naruby navážeme na předchozí část věnovanou instalaci a spuštění programu.

Hlavní okno aplikace

Naše úpravy zdrojového kódu začneme změnami, které se budou týkat hlavního okna aplikace. V předchozí podkapitole jsme na obrázcích viděli, že okno zabírá celý displej aplikace; není zobrazené menu ani tlačítko pro vyvolání klávesnice.

Nově vytvořená okna se totiž automaticky roztáhnou přes celý displej a je potřeba je ručně zmenšit o velikost řádku s menu a tlačítkem pro vyvolání klávesnice (26 obrazových bodů).

Programátor také musí ručně umístit na displej prvek Menu bar, který obsahuje položky menu a tlačítko pro vyvolání klávesnice. O vytvoření prvku Menu bar se stará funkce SHCreateMenuBar. V následujícím rámečku je obalující funkce, která vytvoří prvek Menu bar a vrátí ovladač okna prvku:


HWND CreateMyCommandBar(HWND hwnd)
{
    SHMENUBARINFO mbi;

    memset(&mbi, 0, sizeof(SHMENUBARINFO));
    mbi.cbSize     = sizeof(SHMENUBARINFO);
    mbi.hwndParent = hwnd;
    mbi.nToolBarId = NULL;
    mbi.hInstRes   = g_hInstance;

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

    return mbi.hwndMB;
}

Do prvku Menu bar umístíme v pokračování kapitoly položky menu a ovládací ikony.

Při obsluze zprávy WM_CREATE vytvoříme náš Command bar voláním naší obalující funkce a uložíme jeho ovladač do globální proměnné:


LRESULT CALLBACK
MainWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_CREATE:
            g_hwndCB = CreateMyCommandBar(hwnd);
            g_hwndList = CreateListView(hwnd);
            return 0L;
       ...
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

Ve funkci WinMain změníme velikost hlavního okna aplikace tak, aby se uvolnilo místo na displeji. Konstanta MENU_HEIGHT má hodnotu 26 (výška prvku Command bar.


HWND hwndMain = CreateWindowEx(.....

...

RECT rc;
        
GetWindowRect(hwndMain, &rc);
rc.bottom -= MENU_HEIGHT;

if(g_hwndCB) 
{
    MoveWindow(hwndMain, rc.left, rc.top, rc.right, rc.bottom, FALSE);
}

ShowWindow(hwndMain, nCmdShow); 

Posloupnost jednotlivých akcí, pomocí kterých se dole na displeji instaluje viditelný Command bar je tedy následující:

  1. Volání funkce CreateWindowEx ve funkci WinMain.
  2. Zaslání zprávy WM_CREATE hlavnímu oknu aplikace; během zpracování zprávy je vytvořen Command bar.
  3. Byl-li command bar úspěšně vytvořen, změníme ještě ve funkci WinMain velikost hlavního okna tak, aby uvolnilo místo dole na displeji.

Ovládání SIP Software Input Panel

Tam, kde stolní počítače využívají klávesnici, mají počítače s operačním systémem Pocket PC rozšíření SIP (zkratka ze Software Input Panel). SIP je obvykle aktivován tlačítkem v pravém dolním rohu displeje; stejným tlačítkem také vybíráme aktivní vstupní metodu - klávesnici, plošku pro zápis Grafitti apod..

Je-li SIP aktivován, zobrazí své vlastní okno nad oknem stávající aplikace. Poté je hlavnímu oknu zaslána zpráva WM_SIZE, na kterou může programátor ve své aplikaci reagovat přepočítáním velikosti a obsahu okna.

Ještě dvě zprávy jsou pro správné chování SIP v naší aplikaci důležité:

  • WM_ACTIVATE - Tato zpráva je naší aplikaci zaslána, je-li okno aplikace přeneseno do popředí. SIP by v takovém případě měl být přesně v takovém stavu, v jakém byl, když jsme aplikaci opustili.
  • WM_SETTINGCHANGE - Tato zpráva je zasílána při změně globálního nastavení, které by mohlo ovlivnit chování SIP.

Operační systém Pocket PC umožňuje obě dvě zprávy jednoduše ošetřit voláním funkcí SHHandleWMActivate a SHHandleWMSettingChange, podobně jako v následujícím příkladu:


SHACTIVATEINFO g_sai;

...

LRESULT CALLBACK
MainWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_CREATE:
            g_hwndCB = CreateMyCommandBar(hwnd);	
            g_hwndList = CreateListView(hwnd);

            memset(&g_sai, 0, sizeof(SHACTIVATEINFO));
            g_sai.cbSize = sizeof(g_sai);
            return 0L;
   ...
        case WM_ACTIVATE:
            SHHandleWMActivate(hwnd, wParam, lParam, &g_sai, FALSE);
            break;

        case WM_SETTINGCHANGE:
            SHHandleWMSettingChange(hwnd, wParam, lParam, &g_sai);
            break;
   ...

    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

Když už jsme zajistili, že naše aplikace bude korektně spolupracovat se SIP, můžeme nyní SIP ovládat pomocí funkce SHSipPreference. Parametrem funkce mohou být konstanty SIP_UP, SIP_DOWN, SIP_FORCEDOWN a SIP_UNCHANGED.


SHSipPreference(hwnd, SIP_UP);