Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Učíme se WinAPI - 3.
winapi_logo
22. ledna 2002, 00.00 | V tomto pokračování si řekneme více o smyčce zpráv aplikace, naučíme se zaregistrovat třídu okna a vytvořit hlavní okno aplikace, které již bude mít znaky běžného okna aplikace ve Windows.
V minulém článku jsme skončili tím, že jsme si řekli o hlavní funkci programu, tedy WinMain a řekli něco o významu jejích parametrů. Abychom dostali ten nejjednodušší kompletní program ve Windows, musíme si říci o 3 základních stavebních kamenech takového programu:
- smyčka zpráv
- registrace třídy okna a vytvoření okna
- procedura okna a zpracování zpráv
Jak hned uvidíte, "všechno souvisí se vším", takže nelze dost dobře vysvětlit a pochopit jeden ze zmíněných bodů bez toho, abychom něco věděli o dalších. Začněme nejlépe tou smyčkou zpráv, která bývá běžně umístěna přímo uvnitř těla funkce WinMain.
Smyčka zprávRozšiřme si do náš kód tak, jak vidíte na následujícím výpisu:
|
To co jsme právě přidali, je ona smyčka zpráv, ve které běží celý náš program. Funkce GetMessage vezme zprávu z fronty zpráv aplikace, a odešle jí k dalšímu zpracování, s jedinou výjimkou, kterou je zpráva WM_QUIT. Při přijetí této zprávy funkce GetMessage vrátí FALSE a smyčka zpráv je tak ukončena a posléze dojde k ukončení celé funkce WinMain, a tedy celé aplikace.
V prvním parametru funkce GetMessage je adresa struktury MSG, obsahující informace o zprávě vyjmuté z fronty zpráv aplikace:
|
Prvek hwnd je handle okna, kterému je zpráva směrována. V této smyčce zpráv se totiž soustřeďují zprávy určené všem oknům naší aplikace. Prvek message je identifikátor zprávy, například minule zmíněný WM_LBUTTONDOWN. Dále následují již zmíněné parametry wParam a lParam, time je pak čas, kdy byla zpráva vložena do fronty a v pt je pozice kurzoru v absolutních souřadnicích obrazovky.
Druhým parametrem funkce GetMessage je handle okna jehož zprávy má tato funkce vyjmout z fronty. V případě použití této funkce ve smyčce zpráv aplikace zde zadáme hodnotu NULL znamenající, že mají být vybírány zprávy všem oknům aplikace. Další dva parametry funkce GetMessage mohou představovat filtr zpráv. Můžeme tak specifikovat, že chceme vybírat pouze zprávy v určitém rozsahu identifikátorů. Ve smyčce zpráv opět zadáme tyto parametry nulové, což znamená, že chceme vybírat všechny zprávy
Ve smyčce zpráv dále vidíte funkci TranslateMessage. Tato funkce "překládá" virtuální kódy zpráv klávesnice a generuje další "znakové" zprávy. Podrobněji se samozřejmě budeme zprávám klávesnice věnovat později, nyní není pro nás podrobné vysvětlení důležité. Následuje funkce DispatchMessage, která zprávu odešle do procedury příslušného okna, o které si řekneme později.
Další základní věcí Win32 programu je registrace třídy okna a vytvoření okna této třídy.
Třídy definují určité vlastnosti, které jsou společné všem oknům, které k této třídě náleží. Některé z těchto vlastností můžeme později u individuálního okna změnit, buď hned při jeho vytvoření nebo později za běhu programu. Existují některé systémové třídy, které nemusíme (a ani nemůžeme) v aplikaci registrovat, a můžeme ihned vytvořit okno patřící k takové systémové třídě. Možná vás již napadlo, že těmito třídami jsou například standardní prvky Windows, jako button, list-box, edit-box apod. Každá třída, jak systémová tak registrovaná aplikací má nějaké jméno ("řetězcová" hodnota), na které se odkazujeme při vytvoření okna patřícího této třídě.
Registrace třídy okna
Jak tedy zaregistrovat třídu okna? K registraci třídy okna použijeme funkci RegisterClassEx, jejímž parametrem je adresa struktury WNDCLASSEX obsahující požadované vlastnosti registrované třídy.
|
Nemělo by nyní asi smyl podrobně rozebírat význam jednotlivých parametrů. Řekneme si o těch základních a ukážeme si nejjednodušší příklad jejich naplnění.
cbSize - je velikost této struktury. Musíme ji naplnit hodnotou sizeof(WNDCLASSEX)
style - můžeme uvést kombinaci stylů třídy. Kompletní seznam možných parametrů naleznete v dokumentaci. Běžně se používá kombinace hodnot CS_VREDRAW (obsah celého okna se překreslí, pokud dojde ke změně výšky okna, tedy k jeho roztažení) a CS_HREDRAW (totéž pouze s tím, že jde o změnu šířky).
lpfnWndProc - adresa procedury okna. O proceduře okna si řekneme později, zatím tolik, že zde jednoduše uvedeme název procedury okna kterou musíme mít v programu vytvořenu.
cbClsExtra - zde můžeme v některých speciálních případech uvést počet bytů, které chceme alokovat spolu s třídou pro použití v některých speciálních případech. Běžně zadáme 0.
cbWndExtra - obdobně můžeme alokovat dalších počet bytů spolu s instancí programu. Používá se opět v některých speciálních případech.
hInstance - handle instance, které nám systém přidělí v 1. parametru (typu HINSTANCE) funkce WinMain.
hIcon - handle ikony příslušné třídy okna, běžně získané pomocí funkce LoadIcon či LoadImage. V tom nejjednodušším případě můžeme použít některou ze systémových ikon, nejlépe tu symbolizující aplikaci. Získáme ji takto: LoadIcon(NULL, IDI_APPLICATION)
hCursor - handle kurzoru, který bude zobrazen, pokud se ukazatel myši přesune do oblasti okna patřícího k této třídě. Systémový kurzor "šipka" získáme takto: LoadCursor(NULL, ICD_ARROW)
hbrBackground - štětec typu HBRUSH definující pozadí, které bude vyplňovat okno této třídy. V nejjednodušším případě můžeme získat handle štětce definováním příslušné systémové barvy, například (HBRUSH)(COLOR_WINDOW+1) nám dá štětec v barvě nastavené jako barva pozadí oken.
lpszMenuName - hlavní menu okna. Můžeme zatím nechat NULL, později si ukážeme, jak používat menu.
lpszClassName - jméno identifikující třídu. Musí být jednoznačné v celém systému.
hIconSm - handle malé ikony (obvykle 16x16) reprezentující třídu. Pokud uvedeme NULL, systém použije "zmenšenou" ikonu specifikovanou v prvku hIcon.
Nyní si dejme vše dohromady a ukažme si registraci třídy. V naší aplikaci si nejprve vytvoříme funkci InitApp typu BOOL, do které budeme postupně přidávat jednotlivé kroky, prováděné při inicializaci aplikace, počínaje nyní registrací třídy. Před tím si nadefinujeme jméno třídy, které budeme potřebovat na více místech, proměnnou pro uložení handle instance, který budeme často v kódu potřebovat, dále handle hlavního okna aplikace:
#define _MainClassName "TohleExistovatNebude"HINSTANCE g_hInstance
HWND g_hwndMain
Ten prefix g_ jsem zvyklý dávat u "globálních" proměnných, které pak na první pohled odliším od těch použitím uvnitř funkcí. Podobně hodnoty definované pomocí "#define", popř. konstanty označuji s podtržítkem na začátku, takže je na první pohled odliším od proměnných. Vlastní "rukopis" si samozřejmě každý vytvoří sám. A nyní již můžeme zaregistrovat třídu
|
Vytvoření okna
Nyní máme zaregistrovanou třídu, takže můžeme vytvořit hlavní (a zatím jediné) okno patřící této třídě. K tomu použijeme funkci CreateWindowEx.
|
Ještě dodám, že proměnnou g_hInstance si nastavíme hned na začátku funkce WinMain na hodnotu 1. parametru této funkce.
Příště si podrobněji vysvětlíme význam jednotlivých parametrů funkce CreateWindowEx, vytvoříme proceduru okna a konečně budeme moci naši první Win API aplikaci spustit.
Obsah seriálu (více o seriálu):
- Učíme se Win API - motivační úvod
- Učíme se WinAPI - Začínáme
- Učíme se WinAPI - 3.
- Učíme se Win API - 4.
- Učíme se Win API - 5.
- Učíme se Win API - 6.
- Učíme se Win API - 7.
- Učíme se Win API - 8
- Učíme se Win API - 9.
- Učíme se Win API - 10.
- Učíme se Win API - 11.
- Učíme se Win API - 12.
- Učíme se Win API - 13.
- Učíme se Win API - 14.
- Učíme se Win API - 15.
- Učíme se Win API - 16.
- Učíme se Win API - 17.
- Učime se Win API - 18.
- Učime se Win API - 19.
- Učime se Win API - 20.
- Učime se Win API - 21.
- Učime se Win API - 22.
- Učime se Win API - 23.
- Učime se Win API - 24.
- Učíme se Win API - 25.
- Učíme se Win API - 26.
- Učíme se Win API - 27.
- Učíme se Win API - 28.
- Učíme se Win API - uživatelsky kreslený ListBox
- Učíme se Win API - uživatelsky kreslený ListBox II
- Dialog výběru složky a naplnění ListBoxu soubory
- Vyhledávání souborů - zjištění obsahu složky
- Pracujeme s ComboBoxem ve WinAPI
- Pracujeme s ComboBoxem II.
- Rozšířený prvek ComboBoxEx
- Ovládací prvek TrackBar
- Ovládací prvek Progress Bar
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007