Aplikace ve Win32 API - GUI komponenty
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

Aplikace ve Win32 API - GUI komponentyAplikace ve Win32 API - GUI komponenty

 

Aplikace ve Win32 API - GUI komponenty

Google       Google       28. 9. 2009       14 826×

Obsahem tohoto dílu budou komponenty grafického uživatelského rozhraní. Ať už se bude jednat o komponenty existující nebo o komponenty, které si vytvoříme.

Reklama
Reklama

Každá komponenta má svoje označení, které se nazývá ClassName neboli název třídy komponenty (opět připomínám - neplést s objektovou třídou). Win API má několik předdefinovaných komponent, které mají dané svoje označení - např. tlačítko má označení "BUTTON" (nebo lze použít předdefinovanou konstantu WC_BUTTON ) atd.

Jak jsme si ukázali minule, naše třída CMyWindow je v tomto směru univerzální. Pokud použijeme název existující třídy komponenty, pak pouze přenastaví potřebné parametry. Uloží se ukazatel this a přenastaví WindowProc na zpracování zpráv, které komponentě budou přicházet (provedeme tzv. instanční subclassing):

// pripadne ulozeni this
if (GetWindowLong(GWL_USERDATA) != (LONG)this)
	SetWindowLong(GWL_USERDATA, (LONG)this);

// pripadne prenastaveni WindowProc na nami definovanou
if (GetWindowLong(GWL_WNDPROC) != (LONG)WindowProc) {
	if (m_lpOriginalWindowProc != NULL) assert(0);
	m_lpOriginalWindowProc = (WNDPROC)SetWindowLong(GWL_WNDPROC, (LONG)WindowProc);
}

Pro nově vytvořené komponenty (tj. pro neexistující ClassName) se třída komponenty zaregistruje a nastaví se jí příslušné parametry (mimo jiné také WindowProc).

WNDCLASSEX  sWndClassEx;

sWndClassEx.cbSize		= sizeof(WNDCLASSEX);
sWndClassEx.style		= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
sWndClassEx.lpfnWndProc		= (m_lpWindowProc == NULL) ? (WNDPROC)WindowProc : (WNDPROC)m_lpWindowProc;
sWndClassEx.cbClsExtra		= 0;
sWndClassEx.cbWndExtra		= 0;
sWndClassEx.hInstance		= hInstance;	
sWndClassEx.hIcon		= (m_nBigIcon == 0) ? NULL : LoadIcon(hInstance, MAKEINTRESOURCE(m_nBigIcon));
sWndClassEx.hCursor		= LoadCursor(NULL, IDC_ARROW);
sWndClassEx.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
sWndClassEx.lpszMenuName	= (m_nMenu == 0) ? NULL : MAKEINTRESOURCE(m_nMenu);
sWndClassEx.lpszClassName	= (wcslen(m_wzClassTemplate) < 1) ? MAKEINTRESOURCE(m_nClassTemplate) : m_wzClassTemplate;
sWndClassEx.hIconSm		= (m_nSmallIcon == 0) ? NULL : LoadIcon(hInstance, MAKEINTRESOURCE(m_nSmallIcon));

RegisterClassEx(&sWndClassEx);

Pro zjištění, jestli je daná třída již zaregistrována, se využívá funkce GetClassInfoEx, která uspěje pouze v případě, že požadovaná třída komponent existuje. Registrace okna má tedy následující princip:

if (!GetClassInfoEx(...)) {
	// proved registraci
}

Nejprve převezmeme existující komponentu, např. statický text. Je to velice snadné (vytvoření nové komponenty nebude o nic složitější). Nově vzniklá objektová třída CMyStatic bude dědit od CMyWindow a jako parametr ClassName použijeme označení pro statický text, neboli L"STATIC" (konvence L"", protože používáme Unicode).

CMyStatic::CMyStatic() : CMyWindow(L"STATIC")
{
}

A dále můžeme třídě přidávat různou funkčnost podle potřeby (případně i upravit chování takového prvku). Pro statický text lze třeba využít možnosti zobrazení ikony místo textu.

BOOL CMyStatic::SetIcon(HICON hIcon)
{
	if (hIcon == NULL) return(FALSE);
	if (m_hWnd == NULL) return(FALSE);

	return(SendMessage(STM_SETICON, (WPARAM)hIcon, (LPARAM)0));
}

Vytvoření nové komponenty není o nic složitější. My si vytvoříme dvě komponenty, jednu velice triviální - kontejnerový panel (CMyPanel) - a potom komponentu pro vytvoření dynamického rozdělení okna - splitter (třídy to budou dvě, protože máme vertikální a horizontální).

Kontejnerová komponenta se používá na zobrazení jiných (dalších) prvků. Funkce bude tedy ještě jednodušší než u statického textu, neboť kontejner nebude zobrazovat v podstatě nic, maximálně se bude provádět vymazání pozadí. Celá tvorba našeho kontejneru spočívá pouze ve vytvoření konstruktoru třídy.

CMyPanel::CMyPanel() : CMyWindow(L"MyPanel")
{
}

Případně je možné přetížit metodu OnEraseBkgnd, pokud bude obsah kontejneru celý zakrytý vloženými komponentami, čímž se zbavíme nepříjemného blikání v případě překreslení např. při změně velikosti.

Další komponenta (nebo vlastně dvě) bude o něco složitější. Protože půjde o rozdělení okna, tak musí být jasné, kde k rozdělení okna došlo, tj. kde komponenta bude něco vykreslovat. A dále se obvykle takovéto komponentě přiřazuje jiný než běžný kurzor (šipka). Pro vykreslení obsahu komponenty využijeme funkci OnPaint - zvýrazníme viditelný proužek mezi okny. Jiný kurzor nastavíme již při registraci okna:

WNDCLASSEX  sWndClassEx;

...
sWndClassEx.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(m_nCursor));
....

RegisterClassEx(&sWndClassEx);

Použijeme "svůj" kurzor, abychom měli v naší knihovně na ukázku i nějaké grafické prvky (resource).

Protože budeme dělat vertikální a horizontální rozdělovač, které mají velice podobný kód, tak si vytvoříme společnou třídu, od které budu obě tyto komponentové třídy dědit. Do této třídy dáme společný nebo zobecněný kód, který budou využívat obě třídy. Vertikální a horizontální rozdělovač se liší hlavně přiřazeným kurzorem a způsobem vykreslení rozdělení oblasti. Ostatní vlastnosti se dají snadno zobecnit.

Rozdělovníky mají předdefinovanou dvojí funkčnost: buď při změně velikosti okna drží pevnou pozici, nebo je jejich pozice odvozena procentuálně od velikosti okna. Dále musí řešit problém vykreslení v normálním stavu a při pohybu a také změnu velikosti svojí a svých podoken (řešeno přes virtuální funkce, tj. definice je v základní třídě a implementace je na jednotlivých dceřiných třídách).

Vykreslení v normálním stavu se řeší v reakci na zprávu WM_PAINT (OnPaint). Vykreslení a logika při změně velikosti se řeší v reakci na zprávy od kurzoru:

  • WM_LBUTTONDOWN (OnLButtonDown) - kdy si přes SetCapture "uzamkneme" kurzor jen pro naši aplikaci
  • WM_MOUSEMOVE (OnMouseMove) - reakce na změnu pozice kurzoru, tj. vykreslení předpokládané nové pozice rozdělovníku
  • WM_LBUTTONUP (OnLButtonUp) - potvrzení nové pozice (volání funkcí pro změnu velikostí podoken) a "odemknutí" kurzoru
  • WM_LBUTTONDBLCLK (OnLButtonDblClk) - rychlá maximalizace jednoho z podoken (zakomentováno)

Ukázková aplikace obsahuje použití rozdělovačů a panelů. V tomto jednoduchém příkladě to lze takto použít, ale v aplikaci, která by na panelu něco obsahovala, bychom vytvořili zděděnou třídu od CMyPanel, které bychom dodali potřebnou funkčnost. A to si ukážeme příště, kdy si vytvoříme něco jako jednoduchého průzkumníka, tj. v levém panelu seznam složek a v pravém obsah vybrané složky.

Aplikace z článku ke stažení.

×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 se věnuje programování za peníze :)

Nové články

Obrázek ke článku Blockchain & Bitcoin konference

Blockchain & Bitcoin konference

V pátek 19. 5. 2017 se v pražském konferenčním centru Andel’s konala Blockchain & Bitcoin konference. Řada odborníků a podnikatelů v oboru blockchainu a kryptoměn představila možnosti budoucího směřování tohoto oboru. Speakeři většinou rusky mluvící provenience prezentovali řešení svých firem založená na technologii blockchainu.

Reklama
Reklama
Obrázek ke článku Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Bezpečnostní tým Cisco Talos odhalil celkem 4 kampaně dosud neobjeveného malwaru, který dostal jméno KONNI. Ten se dokázal úspěšně maskovat od roku 2014. Zpočátku se malware zaměřoval pouze na krádeže citlivých dat. Za 3 roky se ale několikrát vyvinul, přičemž jeho současná verze umožňuje útočníkovi z infikovaného počítače nejenom krást data, ale i mapovat stisky na klávesnici, pořizovat screenshoty obrazovky či v zařízení spustit libovolný kód. Pro odvedení pozornosti oběti zasílali útočníci v příloze také obrázek, zprávu a výhružkách severokorejského režimu či kontakty na členy mezinárodních organizací.

Obrázek ke článku Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Trend Micro, celosvětový lídr v oblasti bezpečnostních řešení a VMware, přední světový dodavatel cloudové infrastruktury a řešení pro podnikovou mobilitu, oznámily výsledky výzkumu mezi českými a slovenskými manažery zodpovědnými za ochranu osobních údajů, který zjišťoval, jak jsou připraveni na nové nařízení o ochraně osobních údajů (GDPR). Většina firem v České republice a na Slovensku nad 100 zaměstnanců je již s novým nařízením GDPR obeznámena. Výzkum provedený ve spolupráci s agenturou Ipsos ukázal, že téměř 8 firem z 10 o nařízení ví, přičemž jeho znalost je o něco vyšší na Slovensku (89 %) než v České republice (69 %).

Obrázek ke článku Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Jeden z nejznámějších ransomwarů, Locky, se vrací. Po většinu roku 2016 patřil mezi nejrozšířenější vyděračské softwary. Ke svému šíření využíval emailové kampaně s infikovanými přílohami. Ransomware Locky byl rozesílán prostřednictvím botnetu (internetový robot zasílající spamy) Necurs. Jeho aktivita na konci roku 2016 téměř upadla a spolu s ní i šíření ransomwaru Locky. Před několika týdny se Necurs opět probudil a začal posílat spamy nabízející výhodný nákup akcií. Dne 21. dubna zaznamenal bezpečnostní tým Cisco Talos první velkou kampaň ransomwaru Locky prostřednictvím botnetu Necurs za posledních několik měsíců.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032017 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý