Win32 API – 4. díl – Reakce menu
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Win32 API – 4. díl – Reakce menuWin32 API – 4. díl – Reakce menu

 

Win32 API – 4. díl – Reakce menu

Google       Google       2. 4. 2006       24 721×

Po krátké přestávce se opět vracím k pokračování seriálu o Win32 API. Posledně jsme se naučili nahrávat ikony a vytvářet menu programu, dnes se naučíme s tímto menu pracovat. Budeme se zaměřovat na zprávu WM_COMMAND.

Vytvoření a nahrání menu je jedna věc, to už umíme, ale samozřejmě potřebujeme s tímto menu pracovat a dnes si právě ukážeme, jak na to. Vrátíme se tedy ke kódu, který jsme vytvořili minule.

Máme vytvořené menu a jak tedy na něj reagovat? Jak říci Windows, že když klepnu na tu nebo tu položku v menu, že se má vykonat ta nebo ta operace? No není to zas tak těžké, jak by se zdálo a jistě zjistíte, že to je vlastně naprosto „Easy“ :-)


Nabídky a zprávy

Když vybereme položku nabídky, Windows obvykle zasílají proceduře okna několik různých zpráv. Ve většině případů program může spoustu těchto zpráv ignorovat a prostě je předat funkci DefWindowProc, jedna z těchto zpráv je zpráva WM_INITMENU, která má následující parametry:

wParam - handle hlavní nabídky
lParam  - 0

Hodnota wParam je handle naší nabídky, dokonce i když se vybíra položka systémové nabídky. Zprávu WM_INITMENU programy Windows obvykle ignorují. Ale tato zpráva existuje, a to z důvodu změny nabídky ještě před tím, než je položka vybrána, ale to může uživatele jen mást, a tak tuto zprávu budeme prozatím také ignorovat.

Další zpráva, kterou bude program dostávat, bude zpráva M_MENUSELECT podle toho, jak uživatel přesouvá kurzor. Program může dostávat mnoho zpráv WM_MENUSELECT podle toho, jak uživatel přesouvá kurzor mezi položkami nabídky. Toto je velice užitečné při vytvoření stavového řádku, který může obsahovat plný popis možností nabídky. Parametry zprávy WM_MENUSELECT jsou:

LOWORD(wParam) - vybraná položka: ID nabídky nebo index rozbalovací nabídky
HIWORD((wParam) - příznaky výběru
lParam - handle nabídky, která obsahuje vybranou položku

Zpráva WM_MENUSELECT je zprávou pohybu po nabídce. Hodnota wParam říká, která nabídka je zrovna vybrána. Příznaky výběru v horním slově wParam mohou být kombinací těchto příznaků:

MF_GRAYED
MF_DISABLE
MF_CHECKED
MF_BITMAP
MF_POPUP
MF_HELP
MF_SYSMENU
MF_MPUSESELECT.

Nejdůležitější zprávou nabídek a pro nás nejpoužívanější je zpráva WM_COMMAND. Tato zpráva říká, že uživatel klepnul na nějakou přístupnou položku nabídky. S touto zprávou se setkáme i při používáni dceřiných prvku, protože z nich vychází. Pokud se stane, že požijeme stejné ID pro nabídky a dceřiné ovládací prvky, můžeme mezi nimi rozlišovat pomocí testování hodnot lParam, která bude u položky nabídky 0.

LOWORD(wParam) - ID nabídky ...... ID ovládacího prvku
HIWORD(wParam) - 0 ....... oznamovací kod
lParam - 0 ....... handle dceřiného okna

Zpráva WM_SYSCOMMAND je podobná zprávě WM_COMMAND až na to, že zpráva WM_SYSCOMMAND signalizuje, že uživatel klepnul na nějakou přístupnou položku ze systémové nabídky:

wParam - ID nabídky
lParam - 0

U této zprávy ale budou hodnoty LOWORD (lParam) a HIWORD (lParam) obsahovat obrazovkové souradnice x,y myši. U zprávy WM_SYSCOMMAND určuje ID nabídky, která položka systémové nabídky byla vybrána. U předdefinovaných položek systémové nabídky by měly být spodní čtyři bity odfiltrovány operací AND s hodnotou 0xFFF0. Výsledná hodnota bude jedna z následujících:

SC_SIZE
SC_MOVE
SC_MINIMIZE
SC_MAXIMIZE
SC_NEXTWINDOW
SC_PREVWINDOW
SC_CLOSE
SC_VSCROLL
SC_HSCROLL
SC_ARRANGE
SC_RESTORE
SC_TASKLIST

Navíc parametr wParam může být SC_MOUSEMENU, nebo SC_KEYMENU.

Když přidáme do systémové nabídky některé položky, spodní slovo wParam bude ID nabídky, kterou jsme zadali. Aby se předešlo kolizi s předdefinovanými ID v nabídce, používají se hodnoty menší než 0xF000. Je to důležité, protože normálně předáváme zprávy WM_SYSCOMMAND dále funkci DefWindowProc. Pokud se toto nedodrží, zablokují se prakticky normální příkazy systémové nabídky.

Poslední zpráva, kterou si popíšeme, je zpráva WM_MENUCHAR, která v podstatě není zpráva nabídky. Windows tuto zprávu odesílají proceduře okna v jednom ze dvou případů:

Pokud uživatel stiskne Alt a znak, který neodpovídá položce nabídky, nebo když je zobrazena rozbalovací nabídka a uživatel stiskne klávesu znaku, který neodpovídá žádné položce v této nabídce. Parametry, které doprovázejí zprávu WM_MENUCHAR jsou tyto:

LOWORD(wParam) - kód znaku (ASCII nebo UNICODE)
HIWORD(wParam) - kód vyberu
lParam - handle nabídky

a kód vyběru je:

0 - žádná nabídka není vybrána
MF_POPUP - rozbalovací nabídka
MF_SYSMENU - systémová nabídka je zobrazena

Programy Windows obvykle předávají zprávy funkci DefWindowProc, která normálně vrací do Windows 0. To způsobí, že Windows pípnou.


Zpráva WM_COMMAND

Pro ovládání nabídky budeme používat zprávu WM_COMMAND. Tak tedy trochu blíže ke kódu. Jelikož jde vlastně o zprávy, budeme se tedy zajímat o proceduru okna.

První věc, co musíme udělat, je získat hale naší nabídky, abychom s ní mohli pracovat, takže si nadefinujeme proměnnou hMenu typu HMENU. Nejlépe na začátek zpracování zpráv si umistíme zprávu WM_COMMAND a jelikož se jedná o blok zpráv, které budou reagovat na různé položky, umístíme zprávy položek do přepínače switch. Na zprávy se reaguje jako na jakékoliv jiné zprávy, procedura okna by tedy mohla vypadat nějak takto:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HMENU hMenu;
        switch(message)
        {
          case WM_COMMAND:
          hMenu=GetMenu(hWnd);
          switch(LOWORD(wParam))
           {
              case IDM_ABOUT:
                   MessageBox(hWnd,TEXT("Já jsem úžasná zpráva"),TEXT("Systém"),
                     MB_OK | MB_ICONINFORMATION);
                   return 0;
           }
           return 0;
          case WM_DESTROY:
          PostQuitMessage(0);
          return 0;
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
}

A to je základ, podle kterého budete jistě schopni doplnit obsluhu i ostatních položek nabídky.

Ošetřili jsme položku „O aplikaci“, kde vytváříme jednoduchý dialog pomocí funkce MessageBox(). To se v praxi samozřejmě dělá pomocí dialogových oken, ale jelikož na ty je ještě brzy, tak se prozatím spokojíme s tímto řešením. Dialogová okna si probereme, až zvládneme dceřiné prvky.

Slíbil jsem, že nakousnu i vykreslení textu do klientské oblasti okna. A taky že ano. Tím otevřu delší sérii kapitol o GDI, o kterém si řekneme více v příštím díle.


Funkce DrawText()

Pro výpis textu na obrazovku se dá použít funkceDrawText().

DrawText(hdc, psText, -1, iFlags);

DrawText nakreslí text do klientské oblasti okna. psText je ukazatel na řetězec znaků. -1 říká, že řetězec je ukončen znakem nula. iFlags jsou bitové příznaky, jak má být text zobrazen. Parametr hdc se nazývá „handle kontextu zařízení“, to je pro nás něco zcela nového, ale budeme to používat hodně často. hdc je důležitou součástí GDI. Téměř každá funkce GDI vyžaduje tento handle jako svůj parametr. V příštím díle se k tomuto vrátíme a blíže vysvětlíme.

Abychom mohli kreslit do klientské oblasti, musíme získat kontext zařízení (hdc). Ten získáme voláním funkce BeginPaint ve zprávě WM_PAINT, poté použijeme kreslicí funkce a zavoláme funkci EndPaint, tím uvolníme kontext. Každý kontext, který jsme vytvořili, bychom měli po jeho použití uvolnit!

Volání BeginPaint vyžaduje manipulátor okna a adresu struktury PAINTSTRUCT, což je struktura, která v sobě uchovává důležité hodnoty pro kreslení. I o ní blíže až příště. Takže obsluha zprávy WM_PAINT by mohla vypadat takto:

case WM_PAINT:
        hDC = BeginPaint(hWnd, &ps);
        DrawText(hDC, TEXT("Sluníčko je milé a roztomilé :-)"), -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
        EndPaint(hWnd, &ps);
return 0;

Tímto voláním se vykreslí text do středu klientské oblasti. Jak a kde je text zobrazen nám určují příznaky, což jsou vlastně číselné konstanty. Říkají, že text má být zobrazen na jeden řádek (DT_SINGLELINE), vystředěn vodorovně a na střed (DT_VCENTER a DT_CENTER). V příštím díle se k tomuto vrátíme.

A teď by procedura okna mohla vypadat takto:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HMENU hMenu;
        HDC hDC;
        PAINTSTRUCT ps;
        RECT rect;
        switch(message)
        {
          case WM_COMMAND:
          hMenu=GetMenu(hWnd);
          switch(LOWORD(wParam))
           {
              case IDM_ABOUT:
                   MessageBox(hWnd,TEXT("Jsem informační zpráva"),TEXT("Systém"),
                   MB_OK|MB_ICONINFORMATION);
                   return 0;
           }
           return 0;
           case WM_PAINT:
                GetClientRect(hWnd, &rect);
                hDC=BeginPaint(hWnd, &ps);
                DrawText(hDC, TEXT("Sluníčko je milé a roztomilé :-)"), -1, &rect,
                 DT_SINGLELINE|DT_CENTER|DT_VCENTER);
                EndPaint(hWnd, &ps);
           return 0;      
         case WM_DESTROY:
          PostQuitMessage(0);
          return 0;
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
}

Pro dnešek vše. V příštím díle si povíme něco o GDI, doladíme detaily okolo textu, odhalíme funkci TextOut() a začneme něco málo kreslit :-)

Zatím :-)

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor programuje v jazycích C++ a Delphi, mezi další koníčky patří kvantová fyzika.

Nové články

Obrázek ke článku Stavebnice umělé inteligence 1

Stavebnice umělé inteligence 1

Článek popisuje první část stavebnice umělé inteligence. Obsahuje lineární a plošnou optimalizaci.  Demo verzi je možné použít pro výuku i zájmovou činnost. Profesionální verze je určena pro vývojáře, kteří chtějí integrovat popsané moduly do svých systémů.

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý