Kurz5 - Kapitola4

17. června 2007 v 11:14 | http://www.sweb.cz/kurz_evt/ |  Programování pro WinCE

7.4 Nemodální dialog a ovládání menu

V této části bychom již mohli dokončit kostru programu. Nejprve si ukážeme, jak se vytváří a ovládá nemodální dialog. Zatím co modální dialog již důvěrně znáte (oba předcházející kurzy vytvářely dialogově založené aplikace), nemodální jsme ještě nevyužívali.
Jak se nemodální dialog liší od modálního? Hlavní rozdíl je v tom, že uživateli (ani programátorovi) neumožňuje modální dialog pokračovat v programu, dokud sám není ukončen. Z hlediska programátora můžeme naopak počítat s tím, že nemodální dialog vytvoříme a ten nám hned vrátí řízení programu. My dialog můžeme dále ovlivňovat programově a na konci jej musíme zlikvidovat. Modální dialog se naopak po vytvoření "ujal vlády" a dokud ho uživatel nějakým způsobem neukončil, "kraloval" na obrazovce. Každé volání MessageBoxu je vlastně vytvoření modálního dialogu.
My využijeme nemodální dialog pro signalizaci stavu programu při připojování k poštovnímu serveru.
Začneme tím, že do projektu vložíme nový dialog. Na něm by neměly být žádné tlačítka pro jeho ukončení ("OK" a "Cancel") - odstraňte je tedy z plochy dialogu a na prázdnou plochu umístěte 2 nové prvky. Jeden z nich bude Static Text a druhý Progress. Jejich rozmístění a uspořádání je libovolné. Důležité je pouze zvolit vhodná ID pro použité prvky. Já jsem si vybral a změnil tyto ID pro:
  • Dialog - IDD_STATUSCONN
  • Static Text - IDC_TEXTSTAT
  • Progress - IDC_PROGRESS
Jednoduchý dialog by měl pak vypadat podobně jako na obrázku.
obr. 80 Nemodální dialog stavu spojení
Pokud jste zvolili jiná ID, nezapomeňte si je dále v programu upravit. Dejte ovšem pozor na to, aby vlastní dialog měl na kartě Properties zatrženou vlastnost Visible. Protože budeme tvořit nemodální dialog, mohli bychom mít problém s jeho zobrazením, pokud si neohlídáme správné parametry. Současně si můžeme vytvořit klasický dialog umístěný uprostřed displeje, takže zatrhněte i vlastnost Center.
K zapojení nového dialogu do programu můžeme přistoupit 2 způsoby. První je obdobný postupu z minulé lekce (vytvořit novou členskou třídu pro dialog a svázat prvky dialogu s vhodnými členskými proměnnými). My však zkusíme jiný postup. Další dialogovou třídu dělat nebudeme, použijeme standardní třídu knihovny MFC CDialog.
Zkusíme si, zda bude vše pracovat tak jak má. Pomocí Class Wizardu si vložte do programu novou členskou funkci pro obsluhu položky menu "Connect". Pak vepište následující tělo funkce:
void CMainFrame::OnConnect() 
{
// Makro pro nastaveni textu u Static polozku stavu v dialogu (budu pouzivat ukazatel pStatic)
#define status(a) pStatic->SetWindowText(a);pStatic->Invalidate();pStatic->UpdateWindow();

// Vytvorim si novy dialog
CDialog* pStatDlg;
pStatDlg= new CDialog();
// Dialog necham zobrazovat jako okno - ne na cele plose
pStatDlg->m_bFullScreen=FALSE;
if(pStatDlg != NULL)
if(!pStatDlg->Create(IDD_STATUSCONN,this)) {
MessageBox(_T("Dialog Error"));
return;
}
// Promenne pro odkazovani na Progress Bar a Static Text
CProgressCtrl* pProgr=(CProgressCtrl *) pStatDlg->GetDlgItem(IDC_PROGRESS);
CWnd* pStatic= pStatDlg->GetDlgItem(IDC_TEXTSTAT);

// Pockam 2 sekundy
Sleep(2000);
// Zobrazim 1. zkusebni stav
status(_T("Connected 50%"));
pProgr->SetPos(50);

// Pockam 2 sekundy
Sleep(2000);
// Zobrazim 2. zkusebni stav
status(_T("Connected 100%"));
pProgr->SetPos(100);
// ...a jeste pockame
Sleep(2000);

// Na zaver cinnosti dialog zrusime
if(IsWindow(pStatDlg->m_hWnd)) pStatDlg->DestroyWindow();
if(pStatDlg) delete(pStatDlg);
}
Uvedený kód pro připojení k serveru je samozřejmě jenom testovací. Můžete si vyzkoušet, jak bude vypadat dialog při zobrazení. Zdrojový kód je sice komentován, ale přidám ještě několik poznámek.
Dialog je vytvořen jako nemodální pomocí funkce Create. Není ovšem proti příkladu uváděnému v Helpu použita funkce ShowWindow. Ta se chovala prapodivně a zaškrtnutí vlastnosti Visible u resource Dialogu by mělo stačit. Výše jsem zmínil, že dialog zobrazíme jako standardní malé okno - ne na celé uživatelské ploše, jak je obvyklé u Pocket PC. K tomu stačí nastavit členskou proměnnou m_bFullScreen třídy CDialog (Tuto proměnnou ale budete marně hledat u starých Windows 2.11).
Různým způsobem jsou aktualizovány oba prvky na dialogu. Zatím co Progress Bar je nastavován členskou funkcí SetPos, prvek CStatic vhodnou členskou funkci nemá. Protože se však programujeme ve Windows, skoro vše na obrazovce máme také Window :-). Můžeme tedy použít členské funkce této základní třídy. Pro nastavení nového textu jsou potřeba 3, a tak jsem si napsal jednoduché makro, abych je nemusel stále opakovat.
Jako druhou věc, kterou bychom mohli dnes připravit, je aktualizace položek v menu. Pomocí Class Wizardu doplňte do třídy CMainFrame dvě členské proměnné typu BOOL. Jedna se bude jmenovat m_bConnected a bude signalizovat připojení k serveru a druhá m_bSelected bude označovat, že jsou vybrané položky pro zrušení. Do konstruktoru CMainFrame doplňte:
  
m_bConnected = FALSE;
m_bSelected = FALSE;
A na konec právě vytvořené členské funkce OnConnect:
   m_bConnected = TRUE;
m_bSelected = TRUE;
Teď využijeme Class Wizard a pomocí několika kliknutí doplníme zbývající položky "Disconnect" a "Delete" v menu o obsluhu zpráv COMMAND a UPDATE_COMMAND_UI:
   
void CMainFrame::OnDisconnect()
{
// Odpojim i zrusim vybrani zprav
m_bConnected = FALSE;
m_bSelected = FALSE;
}

void CMainFrame::OnUpdateDisconnect(CCmdUI* pCmdUI)
{
// Odpojit mohu, pokud jsem pripojen
pCmdUI->Enable(m_bConnected);
}

void CMainFrame::OnDelete()
{
// Zpravy jsou zruseny, zadne tedy nejsou vybrane
m_bSelected = FALSE;
}

void CMainFrame::OnUpdateDelete(CCmdUI* pCmdUI)
{
// Rusit zpravy muzu, kdyz jsou nejake vybrane
pCmdUI->Enable(m_bSelected);
}
V emulátoru Pocket PC sice aktualizace tlačítek nefungovala tak, jak by měla, ale na reálném přístroji by mělo být vše O.K.

Co bychom si měli z této lekce zapamatovat?

  • Nemodální dialog je podobný modálnímu, ale vyžaduje trochu více nastavení a obsluhy.
 

Buď první, kdo ohodnotí tento článek.

Nový komentář

Přihlásit se
  Ještě nemáte vlastní web? Můžete si jej zdarma založit na Blog.cz.