Image
23.6.2016 0 Comments

C++ pod Windows / Dialógy II / 10. časť

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

Po mesiaci sa opäť stretávame. Keďže máme dnes toho prebrať neúrekom, poďme sa radšej hneď venovať naším dialógom.

Mechanizmy DDX a DDV. Ak ste doteraz pracovali s Visual Basicom (VB) alebo C++ Builderom, predávanie dát medzi ovládacími prvkami dialógov a premennými v programe nebol žiaden väčší problém. Jednoducho ste si zadefinovali nejakú premennú a túto premennú ste naplnili dátami pomocou vlastnosti (Property) daného ovládacieho prvku. (napr. vo VB: text=Text1.Text). Vo Visual C++ to takto jednoducho nejde. Visual C++ má zadefinované presné postupy a mechanizmy, ako sa môžu prenášať dáta z/do dialógov. Tieto mechanizmy sa nazývajú DDX (Dialog Data Exchange) a DDV (Dialog Data Validation). Ako iste už tušíte, DDX umožňuje výmenu dát medzi dialógom a premennou (a samozrejme naopak) a DDV overuje, či sa tieto dáta rovnajú zadaným požiadavkám (t.j. napr. či nemajú väčší počet znakov, či sú z určitého rozsahu a pod.) a tiež nastavuje tieto rozsahy. Obidva tieto mechanizmy sú úzko spojené s Class Wizardom (v ňom napríklad priraďujeme ovládacím prvkom premenné) a funkciami UpdateData a DoDataExchange. Ich použite si teraz ukážeme na príklade.

Náš prvý modálny dialóg. Vytvorte novú aplikáciu pomocou MFC AppWizardu. (Tak ako doteraz, zvoľte SDI a ostatné nechajte na default). Nazvime si ju jednoducho Vymena. (Pre istotu si ešte pozrite informáciu o novom projekte, ktorá je na obr. 1 a porovnajte si ju so svojou)

Obr 1. Informácie o projekte Vymena

Tak, teraz keď už máme vygenerovanú kostru novej aplikácie, poďme vytvoriť nový zdroj dialógu. Ako nato? Kliknite na záložku Resource View v paneli Workspace. Zobrazia sa vám všetky zdroje (Resources), ktoré projekt obsahuje. Trošku sa pohrajte a preskúmajte čo všetko tu je. (obr. 2)

Obr. 2 Zdroje projektu Vymena

Nás však teraz najviac zaujímajú dialógy. Na pridanie nového dialógu, kliknite pravým tlačidlom na kartu Dialog a vyberte Insert Dialog. Všimnite si, že ak vyberiete len Insert..., máte na výber o mnoho viac možností. Keď vložíte nový dialóg, mal by vyzerať asi ako na obr 3.

Obr 3   Nový zdroj dialógu

Novému dialógu je automaticky priradené ID: IDD_DIALOG1. Dobre, dialóg už máme, poďme s ním začať pracovať! Najprv pre pohodlnosť, kto chce môže si nastaviť mriežku pre lepšie a presnejšie umiestnenie jednotlivých ovládacích prvkov. V dolnej časti obrazovky kliknite na mriežku (Toggle Grid), ako vidíte na obr. 4.

Obr. 4

Teraz kliknite prvým tlačidlom na dialóg a z menu vyberte Properties. Vyplňte hlavičku dialógu (Caption) tak, ako vidíte na obrázku 5. (záložka General).

Obr. 5 Hlavička dialógu

Základný dialóg máme. Do dialógu teraz pridajte dva popisy (Static Text), dve textové polia (Edit Box) a jedno tlačidlo (Button), usporiadajte a pomenujte ich tak, ako vidíte na obr. 6. Ak neviete, ktorý ovládací prvok reprezentuje tá-ktorá ikona, pomôže vám obr. 7. Názvy (ID) jednotlivých ovládacích prvkov zatiaľ nechajte tak ako sú, zmeňte len hlavičku Caption (postupujte podobne ako pri zmene hlavičky dialógu, čiže kliknite pravým tlačidlom na ovládacom prvku, vyberte Properties a v záložke General dopíšte Caption).

Stlačte teraz kombináciu kláves CTRL+T aby ste videli ako bude dialóg v aplikácií vyzerať. Spokojní? Teraz ešte zmeníme názvy (ID) niektorých prvkov.  Textové pole za popisom s hlavičkou: Zadajte Text nazvite IDC_GETNAME (predtým IDC_EDIT1). Tlačidlo s hlavičkou Skopírovať nazvite IDC_COPY (predtým IDC_BUTTON1) a posledné textové pole nazvite IDC_SHOWNAME (predtým IDC_EDIT2). V prípade tlačidla IDC_COPY kliknite ešte na záložku Styles a zaškrtnite Default button (obr. 8). To znamená, že toto tlačidlo bude „prednastavené“ hneď po vyvolaní dialógu a po stlačení klávesy Enter v dialógu sa aktivuje. 

Tak, vizuálnu časť navrhovania dialógu máme za sebou. Poďme teraz „zakomponovať“ tento dialóg do nášho programu. Chceme, aby sa po kliknutí ľavým tlačidlom do klientského okna aplikácie Vymena zobrazil dialóg IDD_DIALOG1. Potom ak zadáme text do textového poľa IDC_GETNAME a klikneme na tlačidlo IDC_COPY (alebo stlačíme klávesu ENTER – viď. Default button), text z poľa IDC_GETNAME sa objaví v poli IDC_SHOWNAME). Z prostredia Dialog Editoru spusťte Class Wizard (CTRL+W). Ten sa vás opýta, či chcete vytvoriť novú triedu pre tento dialóg (obr. 9a). Nechajte zaškrtnuté Create a new class a kliknite na OK. Potom sa zobrazí ďalší dialóg, ktorý vyplňte podľa obrázka 9b. V jednej z úvodných častí sme si povedali, že všetky triedy odvodené od niektorej z tried MFC sa podľa konvencie začínajú písmenom C, preto sa aj naša trieda nazýva CVymenaDialog. (Jej základná trieda je trieda MFC CDialog). V tomto dialógu si ešte všimnite, že musíme presne určiť, ktorému dialógu bude patriť novo vytváraná trieda (položka Dialog ID).

Keď už máte spustený Class Wizard uistite sa, že v zozname Class name máte triedu CVymenaDialog. Kliknite na záložku Member Variables. Zobrazia sa vám všetky ovládacie prvky, ktoré sú na dialógu IDD_DIALOG1. (obr. 10a). Teraz  postupne pridajte všetkým ovládacím prvkom premenné, podľa tab. 1. Premennú pridáte tak, že sa nastavíte na ten ovládací prvok, ktorému danú premennú pridávate a kliknete na tlačidlo Add Variable. Potom sa zobrazí dialóg ako na obr. 10b.

ID ovládacieho prvku

Členská premenná

Typ

Category

IDC_COPY

m_btnCopy

CButton

Control

IDC_GETNAME

m_editGetName

CString

Value

IDC_SHOWNAME

m_editShowName

CString

Value

Tab. 1 Pomenovanie premenných v dialógu IDD_DIALOG1

Všimnite si, že v prípade premenných m_editGetName m_editShowName môžete voliť aj maximálnu dĺžku reťazca (dole v Class Wizarde).  Pre naše potreby zadajte max. dĺžku reťazca na 25 znakov. Aby sa niečo vôbec stalo, po kliknutí na tlačidlo IDC_COPY, musíme ešte pridať funkciu, ktorá sa zavolá po kliknutí na toto tlačidlo. V Class Wizarde sa teda vráťte na záložku Message Maps a v triede CVymenaDialog vyhľadajte v zozname Object Ids objekt IDC_COPY. Potom mu pridajte správu BN_CLICKED, ktorá sa objaví vpravo v zozname Messages. Jej meno nechajte „prednastavené“, čiže OnCopy (obr. 11).

Zavrite Class Wizard a zmeňte funkciu OnDraw triedy CVymenaView takto:

void CVymenaView::OnDraw(CDC* pDC)
{
      pDC->TextOut(0, 0, "Kliknite tu ľavým tlačidlom na vyvolanie dialógu Vymena");
}

Teraz už užívateľ bude vedieť, čo má s aplikáciou robiť. Aby sa ale dialóg naozaj zobrazil, upravte ešte funkciu OnLButtonDown triedy CVymenaView (to, že ju musíte najprv pridať pomocou Class Wizardu už nepíšem, malo by vám to byť jasné). 

void CVymenaView::OnLButtonDown(UINT nFlags, CPoint point)
{
      CVymenaDialog VymenaDlg;
      VymenaDlg.DoModal();
}

Funkcia DoModal (v našom prípade je to členská funkcia triedy CDialog) spôsobí nahranie zdroju dialógu a jeho následné zobrazenie. Keď táto funkcia zobrazí modálny dialóg, užívateľ nemôže pracovať s aplikáciou až pokým nie je okno tohto dialógu zavreté (presne sme si toto opisovali v predchádzajúcej časti). Aby prekladač spoznal triedu CVymenaDialog, pridajte ešte na začiatok súboru VymenaView.cpp tento riadok:

#include "VymenaDialog.h"

Obr. 6 Dialóg Výmena

Skúste teraz aplikáciu preložiť a spustiť. Po kliknutí ľavým tlačidlom myši do okna sa zobrazí dialóg. Do oboch textových polí síce môžete vpisovať text, ale po stlačení tlačidla s nápisom Skopírovať sa nič nestane (čo je ale celkom logické, keďže sme zatiaľ nepridali žiaden kód do funkcie OnCopy). Teraz to napravíme. V zdrojovom súbore triedy CVymenaDialog vyhľadajte funkciu OnCopy a zmeňte jej telo takto:

void CVymenaDialog::OnCopy()
{
      //skopírujeme dáta z ovládacích prvkov do premenných
UpdateData(TRUE);
      m_editShowName=m_editGetName;
      //skopírujeme dáta z premenných do ovládacích prvkov
      UpdateData(FALSE);
}

Tajomná funkcia UpdateData urobí vlastne celú prácu za nás. Môže vykonávať tri operácie. Môže kopírovať dáta z ovládacieho prvku do premennej, môže kopírovať dáta z premennej do ovládacieho prvku a rovnako môže aj overovať dáta, ktoré užívateľ zadal v ovládacom prvku.  Ak má parameter TRUE, tak vtedy sa kopírujú dáta ovládacieho prvku do premennej a ak má parameter FALSE tak naopak. V knihe Programujeme v jazyce Visual C++, (Mark Andrews, Computer Press, 1997) je použitý zaujímavý trik na zapamätanie, v ktorom smere sa presúvajú dáta. V zdrojovom súbore triedy dialógu autor použil direktívy #define nasledovne:

#define VAR2CTRL   FALSE
#define CTRL2VAR   TRUE

(VAR2CTRL – Variable To Control)

(CTRL2VAR – Control To Variable)

Naša funkcia OnCopy by s týmito direktívami vyzerala takto: (nezabudnite ich ale pridať na začiatok súboru VymenaDialog.cpp)

void CVymenaDialog::OnCopy()
{
      //skopírujeme dáta z ovládacích prvkov do premenných
      UpdateData(CTRL2VAR);
      m_editShowName=m_editGetName;
      //skopírujeme dáta z premenných do ovládacích prvkov
      UpdateData(VAR2CTRL);
}

Obr. 7 Popis ikôn pre ovládacie prvky dialógu

Obr. 8 Nastavenie Default button u tlačidla

Obr. 9a   Vytvorenie novej triedy pre dialóg

Obr. 9b    Vytvorenie novej triedy pre dialóg

Obr. 10a    Pridávanie premenných k ovládacím prvkom

Obr. 10b    Pridávanie premenných k ovládacím prvkom

Teraz, keď spustíte aplikáciu a vyvoláte dialóg, po napísaní textu do horného textového poľa a stlačení klávesy ENTER alebo kliknutí na tlačidlo s textom Skopírovať (čo je vlastne jedno a to isté), text z horného poľa sa zobrazí v dolnom textovom poli (obr. 12.) Ak sa pokúsite napísať text dlhší ako 25 znakov, nebude vám to umožnené. Spôsobí to práve mechanizmus DDV, ktorý kontroluje dĺžku oboch reťazcov v textových poliach.   

FUNKCIA DoDataExchange V PROGRAMOCH. Na začiatku sme písali, že na výmene dát sa zúčastňujú dve funkcie: UpdateData DoDataExchange. Prvú sme si už opísali, teraz sa pozrime na druhú. Je to členská funkcia triedy CWnd a je volaná funkciou UpdateData. Túto funkciu by sme nikdy nemali volať priamo, vždy by sme ju mali najprv zavolať funkciu UpdateData a nechať na nej volanie funkcie DoDataExchange. Tu je kód tejto funkcie ako vyzerá v aplikácií Vymena:

void CVymenaDialog::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CVymenaDialog)
      DDX_Control(pDX, IDC_COPY, m_btnCopy);
      DDX_Text(pDX, IDC_SHOWNAME, m_editShowName);
      DDV_MaxChars(pDX, m_editShowName, 25);
      DDX_Text(pDX, IDC_GETNAME, m_editGetName);
      DDV_MaxChars(pDX, m_editGetName, 25);
      //}}AFX_DATA_MAP
}

Okrem volania výmeny dát (prefix DDX), môžete v tomto výpise nájsť aj volanie s prefixom DDV. Toto volanie nespôsobuje žiaden prenos dát, len nastavuje maximálne, resp. minimálne hodnoty, aké môže premenná priradená ovládaciemu prvku nadobúdať. Keď si pozornejšie prezriete tento kód zistíte, že je tu vlastne to, čo ste pridávali pomocou Class Wizardu. A opäť, ako tomu bolo v prípade pridávania obsluhy správ, kód pridaný Class Wizardom je umiestnený medzi charakteristické komentáre. Vo funkcii DoDataExchange sú to:

//{{AFX_DATA_MAP(CVymenaDialog) – začiatok bloku
//}}AFX_DATA_MAP – koniec bloku

Obr. 11    Pridanie funkcie na obsluhu stlačenia tlačidla

Obr. 12    Koncový dialóg aplikácie Vymena

Na mechanizmoch DDX a DDV sa ešte zúčastňuje aj kód medzi blokmi AFX_DATA_INIT. V našej aplikácií Vymena nájdete tieto komentáre v tele konštruktora dialógu:

            //{{AFX_DATA_INIT(CVymenaDialog)
      m_editShowName = _T("");
      m_editGetName = _T("");
      //}}AFX_DATA_INIT

Kód medzi týmito blokmi pripojuje premenné k ovládacím prvkom. Tieto bloky AFX_DATA_INIT a AFX_DATA_MAP nájdete vždy v zdrojovom súbore triedy dialógu. Tretí a posledný blok týkajúci sa prenosu dát, ktorý pridá do vášho programu Class Wizard je umiestnený v hlavičkovom súbore triedy dialógu. V našom súbore DialogVymena.h vyzerá takto:

            //{{AFX_DATA(CVymenaDialog)
      enum { IDD = IDD_DIALOG1 };
      CButton     m_btnCopy;
      CString     m_editShowName;
      CString     m_editGetName;
      //}}AFX_DATA

Tento blok deklaruje premenné pripojené k ovládacím prvkom.

FAQ

Q: V ktorých súboroch nájdem telá funkcií ako napr. WinMain, Run, OnIdle?

A: Funkcia WinMain je v súbore winmain.cpp, ktorý nájdete pod adresárom VC98\MFC\SRC. Funkcie Run OnIdle sú v súbore appcore.cpp. Ďalšie funkcie, ktoré tvoria jadro aplikačného systému tiež nájdete v tomto adresári.

Tipy na doma. Pohrajte sa trochu s dialógom Vymena. Skúste pridať ďalšie prvky, na ktorých odskúšate funkciu DDX a DDV mechanizmov. Nezadajte nič do poľa max. počet znakov pri textovom poli IDC_GETNAME. Skúste priamo vo funkcii OnCopy previesť vlastnú kontrolu, či je zadaný reťazec kratší alebo rovný ako 15 znakov. Ak nie je, vypíšte o tom užívateľovi správu pomocou funkcie MessageBox.

Nabudúce. Ešte zďaleka problematiku dialógov neuzatvárame. Nabudúce vytvoríme veľký modálny dialóg, ktorý bude obsahovať takmer všetky prvky, ktoré sa na dialóg môžu umiestňovať (okrem spoločných ovládacích prvkov Windows, ich použitie s i ukážeme až o dva mesiace). Teším sa na stretnutie o mesiac.

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 funguje sandbox?

08.12.2016 15:36

Každá aplikácia môže pre operačný systém počítača či mobilného zariadenia predstavovať potenciálnu hrozbu, a to aj v prípade, ak neobsahuje žiadne bloky škodlivého kódu. Murphyho zákony neúprosne defi ...

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 ...

Žiadne komentáre

Vyhľadávanie

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

Najnovšie videá