Image
26.6.2016 0 Comments

C++ pod Windows / Dialógy – dokončenie / 14. časť

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

Leto sa nám pomaly končí, pre školopovinných sa začína škola, pre „prácopovinných“ sa skončil čas dovoleniek a zase je tu ten známy kolotoč. Ráno do školy/práce, poobede zo školy a večer/v noci z práce domov. V sobotu ešte stihnúť, na čo nebol čas cez pracovný týždeň, v nedeľu poobede sa pripraviť na pondelok a večer s frflaním, že opäť sme si nenašli čas „na seba“, zaspávať. Dúfam, že aj napriek tejto časovej „kompresii“ si predsa len nájdete chvíľku pre seba a v pokoji si prečítate obľúbený časopis (PC REVUE) a nezabudnete ani na svoj obľúbený seriál .

Nemodálne dialógy. Ak si ešte spomeniete, v deviatej časti sme si vysvetlili základný rozdiel medzi modálnymi a nemodálnymi dialógmi. Nemodálne dialógy na rozdiel od modálnych umožňujú používateľovi ďalej pracovať v aplikácii a „nezastavia“ tak jej beh. Toto je pohľad používateľa. Čo sa týka pohľadu programátora, ten bude zrejme o niečo kritickejší. Nemodálne dialógy sa totiž trochu ťažšie programujú. Môžu, samozrejme, obsahovať všetky tie ovládacie prvky ako modálne dialógy, ale nemodálne dialógy sa ťažšie vytvárajú, rušia a celá komunikácia medzi nimi a aplikáciou je trochu odlišná. Prvý rozdiel, ktorý nám bije do očí hneď na začiatku, je použitie funkcie Create namiesto funkcie DoModal. Medzi týmito dvoma funkciami je jeden podstatný rozdiel. Kým funkcia DoModal sa skončí zavretím dialógu (keď ukončíme dialóg, je jedno či OK, Cancel alebo ALT + F4), funkcia Create sa skončí hneď, pričom dialóg zostane stále na obrazovke a je nám ponechaný takpovediac napospas. My sa  musíme postarať o jeho zrušenie. A teraz si pravdepodobne položíte takéto otázky: Veď za ten čas, čo bol dialóg aktívny, sa mohli „podmienky“ v aplikácii zmeniť, a komu a ako my pošleme správu, že rušíme dialóg? Ako sa vôbec aplikácia dozvie, že sme klikli na nejaké tlačidlo dialógu? Kto v skutočnosti vlastní dialóg? Je to pohľad? Odpovede na ne sú v ukážkovom príklade.

Príklad 1. Namiesto ďalšej teórie si ukážeme „programovanie“ nejakého nemodálneho dialógu. Spusťte AppWizard, vytvorte nový projekt s menom Nemodalny. Všetky jeho nastavenia nechajte default, ale zvoľte aplikáciu SDI. Tento náš nemodálny dialóg bude robiť presne to isté, čo dialóg z projektu Vymena z desiatej časti (prenášať dáta medzi dvoma EditBoxami). Ak máte vytvorenú novú kostru aplikácie, pridajte nový dialóg do zdrojov (ID nechajte default: IDD_DIALOG1). Podľa desiatej časti pridajte aj všetky ovládacie prvky (t. j. dva popisy, dva EditBoxy, jedno „kopírovacie“ tlačidlo). Ich ID tiež vyplňte podľa desiatej časti. Okrem týchto ovládacích prvkov nechajte na dialógu aj tlačidlá OK a Cancel, aby sme si na nich ukázali ďalší rozdiel medzi modálnymi a nemodálnymi dialógmi. (Poznámka: Dúfam, že ste si uvedomili: ak nastavujete tlačidlo IDC_COPY ako default button, musíte túto vlastnosť odznačiť na tlačidle IDOK). Kompletný „screen“ dialógu aplikácie Nemodalny vidíte na obr. 1.

Obr. 1  Nemodálny dialóg Vymena

 

Teraz vytvorte novú triedu pre dialóg. Nazvite ju CNemodDialog. Pomocou Class Wizardu pridajte ovládacím prvkom premenné (ako v 10. časti – IDC_GETNAME>m_editGetName>CString, IDC_SHOWNAME>m_editShowName>CString IDC_COPY>m_btnCopy>CButton). Tlačidlu m_btnCopy pridajte obsluhu správy BN_CLICKED (do triedy dialógu). Pridajte do nej tento kód:

void CNemodDialog::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);
}

Do triedy pohľadu tejto aplikácie pridajte obsluhu správy WM_LBUTTONDOWN a zmeňte kód funkcie OnDraw (hádam ho už ani nemusím písať, prípadne pozrite projekt Subor ďalej). Tak a odteraz to začne byť zaujímavé. Začneme pridávať prvky potrebné na zobrazenie dialógu Vymena ako nemodálneho dialógu. Najprv musíme napísať konštruktor takéhoto dialógu. Pridajte preto nasledujúci kód do zdrojového súboru triedy dialógu (pôvodný konštruktor nemusíte mazať):

CNemodDialog::CNemodDialog(CView* pView)
{
      m_editGetName = _T("");
      m_editShowName = _T("");
     
      m_pView=pView;
}

Práve parameter konštruktora prekladaču hovorí, či ide o modálny alebo o nemodálny konštruktor (presnejšie, či konštruktor „konštruuje“ modálny alebo nemodálny dialóg). Ak je jeho parametrom ukazovateľ na pohľad (CView a od neho odvodené), pôjde o nemodálny konštruktor, ak je jeho parametrom ukazovateľ na „okno“ (CWnd a od neho odvodené), pôjde o modálny konštruktor. Do hlavičkového súboru tejto triedy pridajte tieto deklarácie:

private:
      CView* m_pView;
 
public:
      CNemodDialog(CView* pView);

Pre nemodálne dialógy musíte prepísať štandardné funkcie CDialog::OnOKCDialog::OnCancel. Keby ste tak neurobili, po zavretí dialógu (kliknutie na OK, Cancel, stlačenie ESC, Enter alebo ALT+F4 v dialógu) by sa vyvolali tieto štandardné funkcie triedy CDialog, ktoré ďalej volajú funkciu EndDialog. Táto funkcia je však určená len pre modálne dialógy a pre nemodálne sa nemôže použiť. Pre ne je určená funkcia DestroyWindow (veď si skúste neprepísať tieto funkcie a uvidíte sami, čo sa stane). Namapujte preto do triedy dialógu na tlačidlá OK a Cancel správu BN_CLICKED a kód obslužných funkcií zmeňte takto:

void CNemodDialog::OnOK()
{
      DestroyWindow();
     
      // NESMIE sa volať
      //CDialog::OnOK();
}
 
void CNemodDialog::OnCancel()
{
      DestroyWindow();
     
      // NESMIE sa volať
      //CDialog::OnCancel();
}

Tieto funkcie umožnia korektné zavretie dialógu. Presuňme sa teraz do súborov triedy pohľadu, z ktorých budeme dialóg vyvolávať. Pridajte jednu deklaráciu do hlavičkového súboru triedy pohľadu, aby sme mohli k dialógu pristupovať:

private:
      CNemodDialog* m_pNdlg;

Aby ste nemuseli zbytočne includovať hlavičkový súbor triedy dialógu, pridajte nasledujúci riadok na začiatok hlavičkového súboru triedy pohľadu:

class CNemodDialog;

V zdrojovom súbore triedy pohľadu sa však už includovaniu tohto súboru nevyhneme:

#include "NemodDialog.h"

Zmeňte konštruktor a deštruktor pohľadu:

CNemodalnyView::CNemodalnyView()
{
      // vytvoríme objekt dialógu
      m_pNdlg=new CNemodDialog(this);
}
 
CNemodalnyView::~CNemodalnyView()
{
      // zruší okno dialógu
      delete m_pNdlg;
}

A nakoniec pridajte nasledujúci kód do funkcie OnLButtonDown:

void CNemodalnyView::OnLButtonDown(UINT nFlags, CPoint point)
{
      // zistíme, či už náhodou
      // dialóg nebol vytvorený
      if (m_pNdlg->GetSafeHwnd()==0)
      {
            // ak nie, zobrazí okno dialógu
            m_pNdlg->Create(IDD_DIALOG1);
      }
}

To je všetko. Vyskúšajte si túto aplikáciu. Ak ste nastavili dialógu vlastnosť Visible, potom po stlačení ľavého tlačidla myši sa zobrazí nemodálny dialóg Vymena. O tom, že skutočne ide o nemodálny dialóg, sa môžete presvedčiť tak, že po vyvolaní dialógu vám bude umožnené ďalej pracovať s aplikáciou.

Spoločné dialógy Windows. Spoločné dialógy Windows sú založené na podobnom princípe ako spoločné ovládacie prvky Windows. Ich kód je uložený v súbore commdlg.dll (pre spoločné ovládacie prvky to bol súbor commctl.dll (pre Windows ME, pre NT comctl32.dll pre ovládacie prvky a comdlg32.dll pre dialógy)). Všetky spoločné dialógy Windows nájdete v tab. 1 spolu s krátkym opisom a miestom „výskytu“ v niektorej aplikácii (obsahuje cestu v menu).

Trieda MFC

Opis

Miesto výskytu

CfileDialog

Otvoriť/uložiť súbor

Word -> Súbor -> Otvoriť

CFontDialog

Umožňuje zmenu fontu

Word -> Formát -> Písmo (len prvá karta: Písmo)

CColorDialog

Výber/vytvorenie farby

Skicár (Maľovanie) -> Farby -> Upraviť farby

CPageSetupDialog

Nastavenie stránky

Notepad -> Súbor -> Nastavenie strany

CPrintDialog

Dialóg tlače (nastavenie tlačiarne a tlač)

WordPad -> Súbor -> Tlaèi

CFindReplaceDialog

Vyhľadá a príp. zamení hľadaný reťazec

VisualC++ -> Edit -> Replace

COleDialog

Obsahuje OLE dialógy , napr. Vložiť inak (Excel) alebo Vložiť objekt (Word, Excel) a ďalšie

 

Tab. 1 Spoločné dialógy Windows

Je dobré si uvedomiť, že tieto dialógy len zhromažďujú informácie od používateľa, ale nič s nimi ďalej nerobia. Napríklad dialóg otvorenia súboru síce zistí, aký súbor sa má otvoriť, ale neotvorí ho. Rovnako dialóg tlače zistí informácie o tlačiarni, ale samotný dokument nevytlačí. Prácu s asi najrozšírenejším FileDialogom si ukážeme na príklade, použitie ostatných spoločných dialógov je podobné.

Príklad 2. Cieľom tohto ukážkového príkladu nebude nič zložité: po stlačení ľavého tlačidla myši v okne aplikácie vyvolať dialóg Otvoriť súbor a potom pomocou MessageBoxu vypísať meno vybraného súboru. Spusťte AppWizard a vytvorte nový projekt s názvom Subor. Všetky hodnoty nechajte štandardne nastavené, iba zvoľte aplikáciu SDI. V súbore SuborView.cpp potom zmeňte kód funkcie OnDraw:

void CSuborView::OnDraw(CDC* pDC)
{
      pDC->TextOut(0, 0, "Kliknite sem na vyvolanie dialógu: Otvoriť súbor");
}

Do tejto triedy (CSuborView) pridajte aj obsluhu správy WM_LBUTTONDOWN. Jej obslužnú funkciu zmeňte takto:

void CSuborView::OnLButtonDown(UINT nFlags, CPoint point)
{
      // konštrukcia objektu dialógu
      CFileDialog Fdlg(TRUE, NULL, "*.cpp");
 
      if (Fdlg.DoModal()==IDOK)
      {
            MessageBox(Fdlg.GetPathName(), "Vybrali ste súbor:", MB_OK);
      }
}

To je všetko. Teraz po stlačení ľavého tlačidla myši v okne aplikácie sa zobrazí dialóg Otvoriť súbor (prvý parameter konštruktora – TRUE: Otvoriť súbor, FALSE: Uložiť ako). Ak vyberiete nejaký súbor, dialóg sa zavrie a zobrazí sa informačný dialóg podobný tomu na obr. 2.

Obr. 2 Meno vybraného súboru

Tipy na doma. Skúste rozšíriť aplikáciu Nemodalny tak, aby sa po kliknutí ľavým tlačidlom do okna aplikácie vyvolala nemodálna verzia dialógu Vymena a po kliknutí pravým tlačidlom zase modálna verzia (nápoveď: ak ide o modálny dialóg, tak m_pView=NULL). Po zavretí dialógu vypíšte kopírovaný text do okna aplikácie. Pokúste sa zistiť, či po zavretí okna nemodálneho dialógu sa tiež zruší jeho objekt (ale skúste sa, prosím, nepozrieť najprv do helpu ) . Rozšírte aplikáciu tak, aby sa zakaždým, keď kliknete ľavým tlačidlom do okna, vyvolala ďalšia kópia nemodálneho dialógu Vymena.

Naprogramujte si aj iné spoločné dialógy Windows. Napríklad pri dialógu výber farby sa pokúste zistiť, akú farbu si používateľ v dialógu vybral.

FAQ

Q: Ako sa dajú preniesť dáta medzi dvoma dialógmi?

A: Dáta medzi dvoma dialógmi sa dajú vymeniť napríklad využitím nejakej pomocnej premennej, ktorú zadefinujeme v triede, z ktorej vyvolávame tieto dialógy [štandardne je to trieda pohľadu, skutočným vlastníkom dialógov je však hlavné rámcové okno aplikácie (obsahuje titulkový pruh a pruh menu, toolbar atď., podrobnejšie v ďalšej časti seriálu)].

Príklad: Máme dva dialógy, kde jeden sa aktivuje po stlačení ľavého tlačidla a druhý po stlačení pravého tlačidla myši. My chceme, aby si vymenili pomocou premennej globalna dáta zo svojich textových polí (edit boxov). Zadeklarujeme preto premennú globalna ako verejnú členskú premennú triedy pohľadu typu CString. Obslužné funkcie správ WM_RBUTTONDOWNWM_LBUTTONDOWN potom zmeníme takto:

void CViacDokView::OnLButtonDown(UINT nFlags, CPoint point)
{
      CDialog1 dlg1;
 
      dlg1.DoModal();
 
      globalna=dlg1.m_strDlg;
}
 
void CViacDokView::OnRButtonDown(UINT nFlags, CPoint point)
{
      CDialog1 dlg1;
      CDialog2 dlg2;
     
      dlg2.m_strDlg2=globalna;
     
      dlg2.DoModal();
}

Nabudúce. O mesiac začneme pracovať aj s triedou dokumentu a vytvoríme si menu. Prajem pekné prežitie septembra.

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á