Image
26.6.2016 0 Comments

C++ pod Windows / Menu, ToolBar, StatusBar / 15. časť

Späť na úvod >> Späť na programovanie >> Späť na seriál

Kým v predchádzajúcej časti som písal, že leto sa nám pomaly končí, teraz už môžem bez pochýb povedať, že leto je nadobro v ťahu. Ale veď ani jeseň nie je zlá. Pre optimistov znamená krásnu vôňu pestro sfarbeného popadaného lístia. Pre pesimistov zase neporiadok na chodníkoch, zapríčinený týmto popadaným a nepríjemne šuštiacim lístím a veľa upršaných dní. Dúfam, že väčšina z vás patrí do tej prvej skupiny, programovanie a vývoj aplikácií si totiž často vyžaduje trocha zidealizovaný pohľad na vec, aby nás z toho načisto neporazilo.

Menu, ToolBar, StatusBar. Náš prehľad tvorby GUI (grafického používateľského rozhrania) zakončíme, keď si povieme o týchto troch neodmysliteľných súčastiach každej aplikácie Win. Čo je Menu, to je azda každému jasné; z pohľadu MFC je to objekt odvodený od triedy CMenu. Táto trieda má v sebe aj podporu viacúrovňových, pop-up  a plávajúcich pop-up menu. ToolBar čiže panel nástrojov je z pohľadu MFC objekt odvodený od triedy CToolbar, ktorá je potomkom triedy CControlBar (spoločnej triedy pre všetky objekty ovládacích prvkov líšt – bars) a tá je potomkom triedy CWnd (z toho vyplýva, že ToolBar a StatusBar sú okná). Presnejšie ToolBar je okno, ktoré umožňuje zobraziť na sebe tlačidlá, kliknutím na ktoré vyvoláme nejakú operáciu. Kliknutie na položku v ToolBare má rovnaký účinok ako výber nejakej položky v menu (generujú sa príkazové správy – podrobnejšie neskôr).  StatusBar alebo stavový riadok slúži na zobrazovanie stavových informácií. Môže to byť ľubovoľný text, napr. help k položkám v menu, súradnice kurzora myši a pod. Je to opäť okno, ale na rozdiel od ToolBaru nepodporuje vstup od používateľa ani negeneruje nijaké správy alebo operácie. Prevažne slúži len na zobrazenie textu, prípadne ikon. Je to objekt odvodený od triedy CStatusBar, ktorá má rovnakých predkov ako trieda CToolBar. V prípade Menu a ToolBaru je ich vytváranie v réžii editora zdrojov. Jediné, čo musíme doprogramovať, je obsluha správ, ktoré môžu vzniknúť pri práci s nimi.

Spracovanie príkazových správ. Príkazové správy sme už v stručnosti opisovali a už viete, že vznikajú ako reakcia na vybratie položky v menu, stlačenie tlačidla v paneli nástrojov a pri stlačení klávesovej skratky (použití akcelerátora). Väčšina takýchto správ pochádza z rámcového okna, ktorému koniec koncov patrí menu aj panel nástrojov. Čo však v takom prípade, keď chceme príkazovú správu obslúžiť v triede pohľadu alebo dokumentu? Aplikačný systém so svojou architektúrou smerovania príkazov (command routing architecture) nám to, samozrejme, umožňuje. Keď zachytí príkazovú správu, jej obslužnú funkciu hľadá v tomto poradí v triedach: Pohľadu -> Dokumentu -> Hlavného rámcového okna SDI -> Aplikácie (platí pre aplikácie SDI, o MDI neskôr). Použitie príkazových správ nám opäť výrazne uľahčuje ClassWizard, ktorý tento proces úplne automatizuje. Jediné, čo musíme urobiť, je napísať kód obslužnej funkcie.

Príklad. Teraz si na príklade ukážeme vytváranie a programovanie opísaných prvkov. Vytvoríme aplikáciu, ktorá po výbere položky v menu alebo po stlačení príslušného tlačidla panela nástrojov zobrazí dialóg buď na zadanie mena, alebo priezviska. Zadaný text sa potom zobrazí v stavovom riadku. Pridáme funkčnosť aj pre plávajúce  pop-up menu. Pomocou AppWizardu vytvorte nový projekt s názvom GUI. Jeho nastavenia vidíte na obr. 1. (všetko default, ibaže SDI).

Obr. 1  Informácie o novom projekte

Pomocou editora zdrojov vytvorte dva zdroje dialógov (ID nechajte default: IDD_DIALOG1 – zadanie mena a IDD_DIALOG2 – zadanie priezviska). Ovládacie prvky pridajte podľa obr. 2 a 3, na ktorých sú oba dialógy. Všetky ID a vlastnosti okrem Edit Boxov nechajte default. V IDD_DIALOG1 zmeňte ID tohto textového poľa na IDC_MENO a v druhom dialógu na IDC_PRIEZVISKO.

Obr. 2  Dialóg na zadanie mena        

Obr. 3 Dialóg na zadanie priezviska

Obr. 4 Vytvorenie novej triedy pre zdroj dialógu

Obr. 5 Zmenenie mien súborov pre triedy CGUIDialogM a CGUIDialogP 

Teraz spusťte ClassWizard a vytvorte nové triedy postupne pre oba dialógy. Pre IDD_DIALOG1 bude mať trieda názov CGUIDialogM a pre IDD_DIALOG2 to bude trieda s názvom CGUIDialogP. Keďže ide o jednoduché dialógy, do ktorých nejdeme pridávať nejakú super funkčnosť, môžu mať spoločný hlavičkový aj implementačný súbor. Preto v dialógu vytvárania novej triedy pre oba zdroje v textovom poli File Name zvoľte Change... a zadajte: GUIDialogs.h pre hlavičkový a GUIDialogs.cpp pre zdrojový súbor. (obr. 4 a 5). Ak sa vám po pridaní náhodou tieto dve triedy nezobrazia v pohľade ClassView, potom z menu Project vyberte Add to Project, potom Files a nájdite a pridajte súbory  GUIDialogs.h a GUIDialogs.cpp.

Keď už máme pridané dialógy, už nám ostáva len pridať niečo, čo by ich vyvolalo. Začneme s Menu.

Krok 1 – úprava Menu:  V editori zdrojov v „zložke“ Menu dvakrát kliknite na zdroj menu IDR_MAINFRAME. Kliknite na položku menu Help a stlačte kláves Insert. Tým pridáte ďalšiu položku do menu. Dvakrát na ňu kliknite (resp. pravé tlačidlo a Properties) a do poľa Caption napíšte text: &GUI (ampersand má v tomto prípade rovnaký účinok ako pri ovládacích prvkoch dialógov – pozri 11. časť seriálu). Všetky ostatné vlastnosti nechajte default. Pod položku GUI pridajte ďalšiu s Caption: &Dialógy. Zaškrtnite jej vlastnosť Pop-up. Ako pop-up menu k tejto položke vložte dve položky, ktorých Caption je: &Meno a &Priezvisko. Ich vlastnosti nechajte na default, ibaže vo vlastnostiach na záložke General vpíšte do poľa Prompt pre Meno: Zobrazí dialóg so zadaním mena a pre Priezvisko: Zobrazí dialóg so zadaním priezviska (obr. 6). Tento text sa bude zobrazovať v StatusBare ako nápoveď k týmto položkám menu.

Obr. 6 Vlastnosti položky v menu

Na obr. 7 vidíte celú štruktúru položiek menu GUI v editori zdrojov.

Obr. 7  Štruktúra položiek v menu

Nech vás netrápi, že v ID položiek Meno a Priezvisko je namiesto DIALÓGY len DIALGY. V ID totiž nemôžu byť takéto špeciálne znaky (akým je v tomto prípade dĺžeň). Je to síce len kozmetická chybička, ale pri vývoji softvéru v našich podmienkach si na to treba zvyknúť.

Keď už máme vizuálne veci za sebou, musíme ešte pridať nejaký kód na „spojazdnenie“ nových položiek menu. Pravým tlačidlom kliknite na Meno a z plávajúceho pop-up menu (áno, to je to plávajúce menu spomenuté na začiatku, ktoré si aj my neskôr naprogramujeme) vyberte ClassWizard. Pridajte tejto položke Menu obsluhu príkazovej správy, ktorá je reakciou na kliknutie alebo „odenterovanie“ tejto položky (na COMMAND a Add Function). Túto funkčnosť pridajte do triedy CMainFrame (skúste si doma pridať obsluhu týchto príkazových správ aj do triedy pohľadu, odskúšajte funkčnosť a potom ich pridajte aj do triedy Dokumentu. Funguje to rovnako? Je v tom nejaký rozdiel? Skúste nad tým porozmýšľať, viac informácií v časti spracovanie príkazových správ). Názvy obslužných funkcií nechajte ponúkané. Ich kód zmeňte, ako vidíte tu:

void CMainFrame::OnGuiDialgyMeno()
{
      CGUIDialogM dlgM;
     
      dlgM.DoModal();
}
 
void CMainFrame::OnGuiDialgyPriezvisko()
{
      CGUIDialogP dlgP;
     
      dlgP.DoModal();
}

Samozrejme, ešte nezabudnite pridať na začiatok súboru MainFrm.cpp túto include direktívu:

#include "GUIDialogs.h"

Projekt preložte a spustite. Vyskúšajte funkčnosť nových položiek menu (vrátane spomínanej nápovede v stavovom riadku).

Krok 2 – úprava ToolBaru: Znova sa vráťte do editora zdrojov a v „zložke“ Toolbar dvakrát kliknite na zdroj IDR_MAINFRAME. Tým spustíte editor. V ňom na konci bitmapy panela nástrojov vidíte prázdne políčko. Trochu ho myšou posuňte doprava, aby bolo opticky oddelené od predchádzajúcich. Pomocou editora doň vpíšte M (po kliknutí na toto tlačidlo toolbaru sa zobrazí dialóg na zadanie Mena). Vedľa tohto tlačidla sa objavilo ďalšie prázdne a doň vpíšte P.

Obr. 8 ToolTip pri tlačidlách panela nástrojov

Ak dvakrát kliknete na niektoré tlačidlo panela nástrojov (ešte stále sa, samozrejme, nachádzame v editori), zobrazia sa jeho vlastnosti. Do políčka ID vpíšte rovnaké ID ako v prípade položiek menu (pre tlačidlo M bude ID: ID_GUI_DIALGY_MENO a pre tlačidlo P bude ID: ID_GUI_DIALGY_PRIEZVISKO). Ako som v úvode spomínal, aplikačný systém smeruje príkazové správy z menu a panela nástrojov rovnakým spôsobom (smerom), a preto môžeme použiť rovnaké obslužné funkcie, čo v tomto prípade zabezpečíme rovnakým ID. Tým, že sme zvolili rovnaké ID, aj nápoveď v stavovom riadku bude rovnaká a už ju nemusíme zbytočne prepisovať.  Pre panel nástrojov existuje ešte takzvaná ToolTip nápoveď (ak sa myšou zastavíte nad niektorým tlačidlom ToolBaru, zobrazí sa zvyčajne žltý pravouholník s textom, ktorý objasňuje funkciu tlačidla). Túto „funkčnosť“ pridáte jednoducho tak, že vo vlastnostiach tlačidla do poľa Prompt pridáte za nápoveď, ktorá sa zobrazuje v stavovom riadku, znak nového riadka \n a za ním text ToolTipu (obr. 8). V našom príklade pre tlačidlo M pridajte ToolTip: Dialóg meno a pre tlačidlo P zase Dialóg priezvisko. Kontrolná otázka: Myslíte si, že sa zmenil Prompt aj vo vlastnostiach položiek Menu? Skúste najprv odpovedať a až potom sa pozrieť.

Krok 3 – úprava StatusBaru: Dostali sme sa do predposlednej fázy úpravy projektu GUI. V nej spojíme dialógy pre zadanie mena a priezviska so stavovým riadkom, na ktorom zobrazíme text zadaný v týchto dialógoch. Stavový riadok je definovaný v súbore MainFrm.cpp v statickom poli indicators. V našom prípade definíciu predstavuje kód:

static UINT indicators[] =
{
      ID_SEPARATOR,           // status line indicator
      ID_INDICATOR_CAPS,
      ID_INDICATOR_NUM,
      ID_INDICATOR_SCRL,
};

Indikátory CAPS, NUM a SCRL sa aktivujú, keď stlačíme príslušný kláves (ak ste sa s tým ešte nestretli, spusťte aplikáciu GUI a vyskúšajte si to). Pre naše potreby nám budú stačiť len dve „prázdne“ miesta v stavovom riadku, pričom v prvom (má index 0 a je vľavo) sa bude zobrazovať text z dialógu Meno a v druhom text z dialógu Priezvisko. Zmeňte preto definíciu stavového riadka takto:

static UINT indicators[] =
{
      ID_SEPARATOR,
      ID_SEPARATOR,
};

Pomocou ClassWizardu pridajte textovým poliam v dialógoch premenné, ako vidíte v tab. 1.

ID ovládacieho prvku

Členská premenná

Typ

Max. dĺžka

IDC_MENO

m_strMeno

CString

10

IDC_PRIEZVISKO

m_strPriezvisko

CString

15

Tab. 1 Členské premenné dialógov

Teraz už len pridajte tento riadok do funkcie OnGuiDialgyMeno:

m_wndStatusBar.SetPaneText(0, dlgM.m_strMeno);

a do funkcie OnGuiDialgyPriezvisko:

m_wndStatusBar.SetPaneText(1, dlgP.m_strPriezvisko);

Samozrejme, že tento kód musíte pridať až za volanie funkcie DoModal. Premenná m_wndStatusBar je deklarovaná v hlavičkovom súbore triedy CMainFrame ako premenná typu stavový riadok (CStatusBar  m_wndStatusBar). To je všetko, po spustení aplikácie sa bude zobrazovať v ľavej časti StatusBaru meno a v pravej priezvisko. Ako však uvidíte, tieto dva panely StatusBaru nie sú veľmi esteticky usporiadané. Ľavý je akýsi vypuklý a väčší ako pravý. To hneď napravíme. Pridajte tieto dva riadky do súboru MainFrm.cpp niekde ku koncu funkcie OnCreate:

m_wndStatusBar.SetPaneInfo(0, 0, 0, 300);
m_wndStatusBar.SetPaneInfo(1, 0, 0, 300);

Tým sme nastavili rovnaký vzhľad a rozmery pre oba panely stavového riadka (viac o funkciách stavového riadka sa dočítate v helpe).

Krok 4 – pridanie plávajúceho pop-up menu: Ako som písal na začiatku, trieda CMenu má v sebe obsiahnutú podporu aj pre takýto typ menu (štandardne sa toto menu používa, ak kliknete pravým tlačidlom myši do klientskej oblasti okna). Pomocou editora zdrojov vložte nový zdroj menu do projektu (postupujte rovnako ako pri vkladaní nového dialógu). Nový zdroj nazvite IDR_MYMENU. Jeho položky vyplňte podľa obr. 9. Keďže aj tu platí rovnaké smerovanie príkazových správ ako v klasickom menu a ToolBare, ID položiek Meno a Priezvisko zvoľte rovnaké ako v predchádzajúcom prípade. „Oddeľovač“ (Separator, horizontálna čiara) vložíte do menu tak, že pri vkladaní novej položky menu zaškrtnete vlastnosť Separator na karte General (do poľa Caption nemusíte nič vpisovať). Pre položku About... napíšte jej ID: ID_APP_ABOUT, čo je opäť rovnaké ako v prípade klasického menu pre položku Help -> About GUI... Teraz pomocou ClassWizardu pridajte zdroj IDR_MYMENU do už existujúcej triedy CMainFrame a pridajte obsluhu správy WM_CONTEXMENU takisto do triedy CMainFrame. Kód jej obslužnej funkcie zmeňte takto:

void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point)
{
      CMenu MyMenu;
     
      MyMenu.LoadMenu(IDR_MYMENU);
     
      MyMenu.GetSubMenu(0)->TrackPopupMenu(TPM_CENTERALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);  
}

Opis parametrov nosnej funkcie TrackPopupMenu nájdete v helpe. Výsledné menu vidíte na obr. 10.

Obr. 9  Položky plávajúceho menu   

Obr. 10    Plávajúce pop-up menu

Tipy na doma. Prepíšte aplikáciu GUI tak, aby dialógy na zadanie mena aj priezviska boli nemodálne. Keď ich takto zmeníte, doprogramujte aj zaškrtnutie tej položky menu, ktorej dialóg bol vyvolaný. Zaškrtnutie sa robí namapovaním správy UPDATE_COMMAND_UI  pri položkách menu. V tele tejto funkcie sa potom zaškrtnutie robí pomocou funkcie CCmdUI::SetCheck (podrobnejšie v helpe). Existujú aj ďalšie funkcie, napríklad CCmdUI::Enable, ktorá dokáže sprístupniť, resp. zneprístupniť položku v menu.  Pozrite sa na tieto funkcie, v praxi sa dosť často využívajú. Už nezostal  priestor na opísanie akcelerátorov (klávesových skratiek). Pozrite sa na prácu s nimi, je jednoduché ich používať a aj programovať (vo väčšine prípadov si vystačíte s editorom zdrojov). Naprogramujte akcelerátory do našej aplikácie pre nami pridané položky menu. Opäť platí použitie rovnakých ID. Upravte StatusBar tak, aby mal tri položky. V prvej (index 0) sa bude zobrazovať help k položkám menu a tlačidlám ToolBaru, v druhej text z dialógu meno a v tretej text z dialógu priezvisko. Tým opravíte prepisovanie textu dialógu meno nápoveďou a inými informáciami, ktoré aplikácia zobrazuje štandardne v prvej položke.

Nabudúce. Sľubovanú prácu s triedou dokumentu si odložíme do budúcej časti. Dovidenia v novembri.

Zobrazit Galériu

Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

Ako na to

Tipy a triky: Ako na snímku obrazovky na akomkoľvek počítači s Windows?

02.12.2016 00:13

Ak snímky obrazovky robíte často apotrebujete napríklad funkcie na posun stránok alebo snímanie zobrazenia pri vyššom rozlíšení displeja, zrejme používate nejakú špecializovanú aplikáciu. Väčšina použ ...

Ako na to 1

Tipy a triky: Ako aplikácii prednastaviť spúšťanie s administrátorskými právami?

30.11.2016 00:10

Väčšina aspoň trochu skúsenejších používateľov vie, že aj keď máte na operačnom systéme Windows vytvorený administrátorský účet, aplikácie pre bezpečnosť nefungujú vždy splnými administrátorskými práv ...

Ako na to 2

Tipy a triky: Ako vypnúť uzamykaciu obrazovku vo Windows 10?

29.11.2016 00:10

Rozčuľuje vás, že pred každým prihlásením doúčtu vášho počítača musíte prejsť uzamykacou obrazovkou? Windows 10 na tejto obrazovke ukazuje čas,dátum anejakú zaujímavú fotografiu zrôznych kútov sveta. ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá