Image
22.6.2016 0 Comments

C++ pod Windows / Class Wizard a správa tried / 7. časť

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

Mesiac ubehol a my sa opäť stretávame pri seriáli C++ pod Windows, ktorý dospel už k svojej siedmej časti. Takže čo je nové? Už asi všetci viete o novom webe PC REVUE. Ak vás zaujíma programovanie pod Windows a tento seriál, chcel by som vás upozorniť, že na spomenutej stránke v sekcii Programujeme môžete nájsť ďalšie ukážkové príklady a rôzne iné zdroje k tomuto seriálu, ktoré vám, dúfam, pomôžu lepšie sa vyznať vo svete C++.  Tieto ukážkové príklady budú zamerané na práve preberanú tému, napríklad tam budú riešené domáce úlohy a iné okrajové problémy, na ktoré v časopise nezvýši miesto.

V predošlej časti sme dosť podrobne opísali App Wizard a jednotlivé kroky tvorenia aplikácie. Teraz si podrobnejšie rozoberieme ďalší, nemenej dôležitý prvok prostredia Visual C++, a síce Class Wizard. Opäť nájdete aj nejaké ďalšie linky na stránky zaoberajúce sa programovaním. Najprv sa však ešte vrátime k predchádzajúcej časti a sľúbenému „problémiku“, ako upraviť aplikáciu Hi, aby jej výstup bol zhodný s programom First zo štvrtej (nie z tretej!) časti. Týmto sa ospravedlňujem za zámenu častí, ale dúfam, že ste na to prišli sami. Pusťme sa teda do toho.

DOMÁCA ÚLOHA. Pravdepodobne ste tento problém všetci úspešne vyriešili, ak nie, tu je jeho riešenie. Stačilo len zameniť kód vo funkcii OnDraw aplikácie Hi za kód funkcie OnPaint programu First a trošku ho upraviť. A to tak, že namiesto priameho prístupu pomocou objektu triedy CPaintDC (týmto objektom je dc) k jej členským funkciám budeme využívať ukazovateľ pDC, odovzdávaný ako parameter funkcie OnDraw. Tento ukazovateľ však nebude ukazovať na objekt triedy CPaintDC, ale na objekt triedy CDC. Obidve triedy (CDC CPaintDC) sú síce triedami kontextu zariadení, ale objekt odvodený od triedy CDC má všeobecnejší charakter, keďže v hierarchii tried kontextu zariadení stojí najvyššie trieda CDC a trieda CPaintDC je len potomkom triedy CDC. Trieda CPaintDC sa ani veľmi v aplikáciách pre Windows nepoužíva, a ak, tak len v prípade, keď potrebujete prepísať funkciu OnPaint. Zmenený kód (teraz už bez zbytočných komentárov) potom vyzerá takto:

void CHiView::OnDraw(CDC* pDC)
{
CHiDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      // TODO: add draw code for native data here
 
      CRect rectMax;   
      CPen pen(PS_SOLID, 6, RGB(0, 0, 255));  
      GetClientRect(rectMax);
      pDC->SelectObject(&pen);    
      pDC->TextOut(0, 0, "Hello, world!");    
      pDC->Ellipse(rectMax); 
      pDC->SelectStockObject(WHITE_BRUSH);
}

CLASS WIZARD. Domácu úlohu sme teda vybavili, môžeme začať preberať nové veci. Class Wizard sme si už zhruba opisovali v piatej časti, takže už asi približne viete, na čo táto súčasť prostredia Visual C++ slúži. Ešte sme si však neukazovali prácu s týmto nesmierne dôležitým prvkom, čo hneď aj napravíme. Zmeníme aplikáciu Hi (doplníme jej funkčnosť) tak, aby reagovala na niektoré udalosti. Mapu správ sme si už opisovali (bolo to v piatej časti) a dokonca už aj viete pridávať a uberať jednotlivé obslužné funkcie správ. Ale prácnym dopisovaním správ medzi makrá BEGIN_MESSAGE_MAP END_MESSAGE_MAP by sme sa ďaleko nedostali. A tu nám Class Wizard výrazne uľahčí prácu. Toto však nie je jediná práca tohto nástroja. Okrem toho, že nám uľahčuje už spomínané obsluhovanie správ, používa sa na pridávanie členských premenných jednotlivých dialógov a obsluhuje mechanizmy DDV a DDX (dostaneme sa k nim v časti venovanej dialógom), uľahčuje programovanie ActiveX komponentov a pridávanie nových tried. Bez preháňania môžeme povedať, že práve tento nástroj „drží“ aplikáciu pohromade. Jeho základný „look“ (teda vzhľad po prvom spustení) si môžete pozrieť na obr. 1. Spustíte ho buď klávesovou skratkou CTRL+W, alebo z menu View. Celý Class Wizard sa skladá z jedného okna (je to vlastne dialóg), na ktorom je päť záložiek. Prvá, ktorá má názov Message Maps, slúži na spravovanie mapy správ v aplikáciách. Ak sa rozhodnete pridať nejakú správu, najprv vyberte zo zoznamu Project meno projektu, pre ktorý správu pridávate (je to z toho dôvodu, že v jednom Workspace – pracovnom prostredí – môže byť uložených viacero projektov). Potom zo zoznamu Class name vyberte triedu, pre ktorú chcete správu pridať (toto je veľmi dôležité). Niektoré správy sú pre jednotlivé triedy spoločné (tú istú správu môže obsahovať napríklad trieda dokumentu aj trieda pohľadu) alebo líšia sa len málo, a tak si treba dávať pozor, aby ste napríklad správu, ktorá je určená pre pohľad, nepridávali dokumentu. Môžete tak rozbiť celú aplikáciu a potom sa budete čudovať, prečo program nepracuje tak, ako chcete. Platí to hlavne vtedy, ak pridávate obslužné správy napríklad položkám menu. Ak máte už vybratú triedu, potom v ďalšom zozname Object IDs volíte, pre aký objekt chcete pridať obsluhu danej správy. Hneď prvá položka v tomto zozname je názov triedy pohľadu. Ak ho zvolíte, potom sa v ďalšom zozname Messages zobrazia správy, aké môže táto trieda obsluhovať. V zozname Object IDs nájdete napríklad aj názvy jednotlivých položiek menu: ID_APP_ABOUT charakterizuje vybratie položky About... z menu aplikácie. Ak vyberiete nejakú takúto položku, potom sa v zozname Messages zobrazia len dve položky: COMMAND a UPDATE_COMMAND_UI. Nebudeme sa tým však teraz zdržiavať, k obsluhe ovládacích prvkov a menu sa ešte dostaneme. Ak ste si už vybrali ID objektu, pre ktorý chcete pridať obsluhu správy, potom v zozname Messages vyberte názov správy. Tým sa sprístupní tlačidlo Add Function. Kliknite naň. Ak pridávate funkciu na správu nejakého ovládacieho prvku alebo menu, objaví sa dialóg, v ktorom môžete meniť názov obslužnej funkcie tejto správy (odporúčam ponechať implicitný). Ak volíte funkciu na obsluhu správy, ktorá je dostupná v danej triede (napr. v triede CHiView funkcia OnLButtonDown), túto možnosť nemáte a Class Wizard priradí danej funkcii štandardný názov (tieto názvy funkcií ste mohli vidieť v tabuľke 2 v piatej časti seriálu). Potom sa v  zozname Member functions zobrazí názov tejto obslužnej funkcie, ako aj názov správy, ktorú obsluhuje. Teraz už stačí len kliknúť na tlačidlo Edit Code a pridať potrebný kód do obslužnej funkcie.  Ak vás zaujíma, čo sú to za funkcie, ktoré sú nad správami v zozname Messages (správu chápeme, keď sa začína prefixom WM), tak to sú virtuálne funkcie, ktoré je niekedy potrebné preťažiť (override). (Niekedy, ako napr. pri funkcii OnDraw, je to nevyhnutné. Preto už pri prvom spustení Class Wizardu môžete vidieť v zozname Member functions nejaké funkcie, aj keď ste vy ešte žiadne nepridali, urobil to za vás aplikačný systém.)

Obr. 1 Class Wizard

PRÍKLAD. Ak ste tomu neporozumeli, nasledujúci príklad vám v tom pomôže. Zmeníme aplikáciu Hi tak, aby robila to isté, čo aplikácia First z piatej časti, ale jednotlivé správy a ich obslužné funkcie budeme pridávať pomocou Class Wizardu. Budeme teda používať tú aplikáciu Hi, ktorá je riešením domácej úlohy z predošlej časti (pozri predošlý text). Zatiaľ máme na obrazovke modrý kruh a v ľavom hornom rohu nápis: Hello, world! Teraz chceme, aby program obsluhoval stlačenie ľavého tlačidla myši, a síce tak, že po jeho stlačení sa do klientskeho okna aplikácie zobrazí správa „Tu som“ presne na tom istom mieste, kde sa nachádza kurzor. Postup si opíšeme v krokoch.

1.   Ak už máte otvorený projekt Hi, spusťte Class Wizard, ak ho nemáte otvorený, otvorte ho cez File-Open a spusťte Class Wizard.

2.   Pridajte obslužnú funkciu správe WM_LBUTTONDOWN triede CHiView. V zozname Class Name zvoľte CHiView, v zozname Object IDs vyberte CHiView a v zozname Messages vyberte WM_LBUTTONDOWN. Kliknite na Add Function. Po týchto operáciách by malo okno Class Wizardu vyzerať, ako ho vidíte na obr. 2. Pod zoznamom Member functions môžete vidieť nápis Description:, kde sa vám zobrazí stručný opis pridávanej funkcie na obsluhu danej správy (vlastne je to opis tej správy).

3.   Teraz kliknite na tlačidlo Edit Code a Class Wizard otvorí okno editora a nastaví vás na členskú funkciu OnLButtonDown triedy CHiView. Kód tejto funkcie teraz vyzerá takto:

void CHiView::OnLButtonDown(UINT nFlags, CPoint point)
{
         // TODO: Add your message handler code here and/or call default
  
      CView::OnLButtonDown(nFlags, point);
}

Ako vidíte, opäť nás aplikačný systém upozorňuje, že tu môžeme pridávať náš vlastný kód, notoricky známym komentárom //TODO. Takto vygenerovaná funkcia OnLButtonDown však ešte nič nerobí, preto ju zmeňte takto:

void CHiView::OnLButtonDown(UINT nFlags, CPoint point)
{
      CClientDC dc(this);
      dc.TextOut(point.x, point.y, "Tu som");
}

Príklad skompilujte, zlinkujte a spusťte. Robí presne to, čo program First z piatej časti seriálu.

ČO VLASTNE UROBIL CLASS WIZARD? Asi sa teraz pýtate, čo také prevratné vlastne ten Class Wizard urobil? Bolo by dobré spomenúť si, čo ste museli robiť, aby ste dosiahli takúto funkčnosť s programom First. Museli ste editovať hlavičkový súbor first.h a manuálne tam dopísať prototyp obslužnej funkcie. Museli ste editovať aj zdrojový súbor first.cpp, kde ste správu pridali medzi makrá BEGIN_MESSAGE_MAPEND_MESSAGE_MAP. Keď používate Class Wizard, toto nepríjemné kódovanie už nemusíte robiť, vykoná tak za vás práve Class Wizard (to je prekvapko, nie?) Aby ste videli, čo urobil, otvorte hlavičkový súbor triedy CHiView, uvidíte tam tento kód:

Obr. 2  Okno Class Wizardu po pridaní obsluhy správy WM_LBUTTONDOWN

// Generated message map functions
protected:
      //{{AFX_MSG//{{AFX_MSG(CHiView)
      afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()

Class Wizard pridal prototyp funkcie na obsluhu správy WM_LBUTTONDOWN, medzi pre neho charakteristické komentáre //{{AFX_MSG(CHiView) a //{{AFX_MSG. Rovnako aj v zdrojovom súbore triedy CHiView môžete vidieť kód pridaný Class Wizardom:

BEGIN_MESSAGE_MAP(CHiView, CView)
      //{{AFX_MSG_MAP(CHiView)
      ON_WM_LBUTTONDOWN()
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

Tu je rozpísaná celá mapa správ aplikácie Hi. A opäť text umiestnený medzi komentáre //{{AFX_MSG_MAP(CHiView) a //}}AFX_MSG_MAP je pridaný Class Wizardom. Tak teraz už viete, čo tajomné urobil Class Wizard. Ešte jedna poznámka. Dávajte si veľký pozor a dobre si rozmyslite, či budete niekedy editovať kód, ktorý vytvoril Class Wizard. Takmer s istotou totiž niečo pokazíte a tým celú aplikáciu rozbijete. Na editáciu kódu vytvoreného Class Wizardom je vždy dobrý len on sám. Ak teda niekedy chcete vymazať obsluhu nejakej správy a následne aj funkciu, ktorú ste pridali pomocou Class Wizardu, použite napríklad tlačidlo Delete Function, ktoré je dostupné na jeho okne pod záložkou Message Maps, a nepokúšajte sa manuálne odstrániť túto funkciu z hlavičkového súboru a následne aj správu prislúchajúcu tejto funkcii z mapy správ!!! Čomu sa však nevyhnete a na čo vás upozorní aj sám Class Wizard pri mazaní niektorej správy a jej obslužnej funkcie, je odstránenie tela tejto funkcie. Keby ste teraz napríklad chceli kompletne odstrániť reakciu na stlačenie ľavého tlačidla myši z programu Hi, spustili by ste Class Wizard, v zozname Member functions by ste vybrali funkciu OnLButtonDown a klikli na tlačidlo Delete Function, zobrazil by sa dialóg ako na obr. 3, ktorý vás upozorňuje, že treba manuálne vymazať „implementačný“ kód  funkcie CHiView::OnLButtonDown (teda ten, ktorý je umiestený v zdrojovom *.cpp súbore triedy CHiView, jednoducho povedané, jej telo). Ak zvolíte pokračovať, Class Wizard vymaže z hlavičkového a zdrojového súboru kód, ktorý tam pridal (pozri vyššie), ale ponechá tam celú funkciu OnLButtonDown. Túto funkciu musíte sami vymazať a až teraz je obsluha správy WM_LBUTTONDOWN odstránená z programu Hi.

Obr 3. Použitie makra TRACE na sledovanie súradníc kurzora

MAKRÁ TRACE. Aby sme však trochu rozšírili aj vaše vedomosti o ladení aplikácie, ukážeme si aj použitie makra TRACE. Ak ho chcete používať, musíte mať zapnuté sledovanie (tracing). Je zapnuté implicitne už pri inštalácii Visual C++. Ak ho však máte vypnuté, pomocou utility TRACER ho jednoducho zapnete (Enable Tracing). Na čo je to dobré? Ak spustíte aplikáciu cez debugger (čiže nie klávesovou skratkou CTRL+F5, ale len klávesom F5), pomocou makra TRACE budete môcť sledovať určité výstupy programu. Ako príklad si znova uvedieme zlepšenie aplikácie Hi.

Poznámka: Celý projekt musí byť v tzv. Debug móde. Ak je niečo ešte stále vo vývoji (to znamená, že ešte meníte kód), je dobré, ak sa celý projekt nachádza v móde Debug. Okrem iného môžete používať práve tieto „sledovacie“ makrá TRACE a ladenie zdrojového kódu. Tento „režim“ zmeníte cez menu: Build -> Set Active Configuration... V budúcnosti sa ešte k problému nastavenia projektu vrátime.

POUŽITIE MAKRA TRACE. V terajšej verzii aplikácie Hi, ak klikneme ľavým tlačidlom myši do jej okna, zobrazí sa na súradniciach kurzora text: Tu som. My sa teraz pokúsime zistiť hodnoty týchto súradníc a tieto hodnoty nebudeme vypisovať do okna aplikácie, ale do výstupného okna (output window), ktoré je prístupné v záložke Debug vo Visual C++. Makro TRACE má rovnakú syntax ako volanie funkcie printf v klasickom programovaní pod DOS. Odporúčam zopakovať.

Ak si ešte pamätáte, súradnice kurzora sú prístupné ako point.x a point.y. Dopíšte teda nasledujúci riadok do členskej funkcie OnLButtonDown, triedy CHiView:

TRACE("Poloha kurzora je: %d %d\n", point.x, point.y);

Teraz spusťte aplikáciu Hi z prostredia Visual C++ klávesom F5 a párkrát kliknite do jej okna (klientskeho), aby sa zobrazil text Tu som. Ak kliknete na záložku Debug (na spodnej časti obrazovky, pozri obr. 4), mali by ste dostať podobný výstup.

TIPY NA WWW. V tipoch na WWW nájdete linky na dva freewarové produkty, pomocou ktorých je možné vyvíjať aplikácie s jazykmi C/C++. A nezabudol som ani na tvorcov hier.

http://www.maxcode.com/ – zdrojové kódy a linky na jazyky C/C++/VisualC++, Pascal, QuickBasic...

http://www.gamedev.net/gamedev.asp – absolútne vynikajúca stránka, ak vás zaujíma tvorenie hier. Nájdete tam tutorialy na tvorenie pod DirectX, OpenGL, programovanie „fyziky“ v hrách...

http://www.bloodshed.net/ – stránka, na ktorej nájdete vynikajúci freeware na tvorenie   Windows aplikácií. Má vlastné IDE a z tejto stránky sa k nemu dajú stiahnuť rôzne prídavné knižnice, helpy...

http://www.cs.virginia.edu/~lcc-win32 – stránka, na ktorú ma upozornil jeden čitateľ. Obsahuje ANSI-C kompilátor (vraj zatiaľ nepodporuje C++).

http://www.vcworld.f2s.com/ – stránka venovaná Visual C++. Zdrojaky a tutorialy.

TIPY NA DOMA.

1.   Preskúmajte Class Wizard a pomocou neho pridajte do aplikácie Hi obsluhu pravého tlačidla myši, aby sa po jeho stlačení na mieste, kde je kurzor, zobrazil text: Tu nie som.

2.   Vráťte aplikáciu Hi do pôvodného stavu (t. j. odstráňte obsluhu správ WM_RBUTTONDOWN a WM_LBUTTONDOWN).

3.   Vymyslite si vlastné zadania, a nech ich je čo najviac!

V helpe si vyhľadajte informácie o makre TRACE a vymyslite si iné zadanie/aplikáciu, ktorej výstupy by ste mohli sledovať pomocou tohto makra.

NABUDÚCE. V ďalšej časti na chvíľu opustíme „praktický“ výklad a zájdeme viac do teórie. Opíšeme si totiž dosť zložitú, ale dôležitú tému: mapovacie režimy. Do nášho programu Hi pridáme napríklad rolovanie (áno, to sú tie rolovacie „pásky“ na pravom a dolnom konci okna skoro každej aplikácie). Riešenie domácich úloh z tejto časti by ste už teraz mali pravdepodobne nájsť na stránke PC REVUE. Stretneme sa teda v marci! Dovidenia.

Zobrazit Galériu

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

Mohlo by Vás zaujímať

Ako na to

Ako zbaviť fotky hmly

08.12.2016 11:59

Hmla alebo dym sú často veľmi kreatívne nástroje. No všetkého veľa škodí. Fotka potom stráca kontrast a v podstate na nej nič nevidieť. Hmlu môžete neraz následnými úpravami odstrániť alebo zredukovať ...

Ako na to

Užitočné SW nástroje

08.12.2016 11:53

AllDup v4.0.3 Určenie: program na vyhľadávanie a odstraňovanie duplicitných súborov Vlastnosti: duplicitné súbory sa vyhľadávajú len na zvolených diskových jednotkách alebo len v rámci vybraných ...

Ako na to

Fotografovanie s bleskom

08.12.2016 11:47

Ak máte moderný fotoaparát so vstavaným alebo externým bleskom, zdá sa vám téma článku triviálna. Jednoducho nastavíte vhodný režim, vyberiete najlepšiu kompozíciu záberu, exponujete a o zvyšok sa už ...

Žiadne komentáre

Vyhľadávanie

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

Najnovšie videá