Kurz3 - Kapitola7

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

5.7 Propojení proměnných s prvky dialogu

I když bychom už mohli začít "naplno programovat", věnujeme ještě tento díl částečné přípravě. Vysvětlíme si, jak se předávají data mezi ovládacím prvkem a příslušnou proměnnou. Abychom zbytečně neplýtvali silami, použijeme k tomu druhý dialogový list - "Signals". Zajistíme pouze, aby se zaškrtnutí z horního prvku "RTS" zkopírovalo do "CTS" a "DTR" do "DSR". Přitom si nachystáme větší část programového kódu pro obsluhu tohoto listu.
Nejprve si nahraďte v hlavičkovém souboru TestCOM.h hlavičku třídy CDruhy novou verzí:
////////////////////////////////////////////////////
class CDruhy: public CPropertyPage
{
int m_nDTR;
int m_nRTS;
int m_nCTS;
int m_nDSR;
int m_nRI;
int m_nDCD;
UINT m_nTimer;

public:
CDruhy():CPropertyPage(IDD_DRUHY) {
m_nDTR=m_nRTS=m_nCTS=m_nDSR=m_nDCD=m_nRI=BST_UNCHECKED;
};
protected:
virtual void DoDataExchange(CDataExchange*);
afx_msg BOOL OnSetActive();
afx_msg BOOL OnKillActive();
afx_msg void OnTimer(UINT);
afx_msg void OnDTR();
afx_msg void OnRTS();
DECLARE_MESSAGE_MAP()
};
Třída získala pro každý prvek svoji vlastní členskou proměnnou typu int. V konstruktoru je jejich hodnota nastavena na "nezatrženo". Dále jsme doplnili několik členských funkcí. Jejich kód doplňte do souboru TestCOM.cpp:
/////////////////////////////////////////
/// CDruhy

BEGIN_MESSAGE_MAP (CDruhy,CPropertyPage)
ON_WM_TIMER()
ON_COMMAND(IDC_DTR,OnDTR)
ON_COMMAND(IDC_RTS,OnRTS)
END_MESSAGE_MAP()

BOOL CDruhy::OnSetActive()
{
CWnd *pWnd;

CPropertyPage::OnSetActive();
// Vytvorim si casovac, ktery posle zpravu po 100 msec
if(!(m_nTimer=SetTimer(1,100,NULL))) {
MessageBox(_T("Timer error!"));
return FALSE;
}
// Vystupni bity povolim a nastavim posledni stav
pWnd=GetDlgItem(IDC_DTR); pWnd->EnableWindow();
pWnd=GetDlgItem(IDC_RTS); pWnd->EnableWindow();
OnRTS(); OnDTR();

return TRUE;
}

BOOL CDruhy::OnKillActive()
{
// Casovac neni potreba - bude zobrazena jina stranka
KillTimer(m_nTimer);
return CPropertyPage::OnKillActive();
}

void CDruhy::OnTimer(UINT nTim)
{
// Nastavim zaskrtavaci policka podle promennych
UpdateData(FALSE);
}

void CDruhy::DoDataExchange(CDataExchange* pDX)
{
// Predpis pro vazbu ovladacich prvku a odpovidajicich promennych
DDX_Check(pDX, IDC_DTR, m_nDTR);
DDX_Check(pDX, IDC_RTS, m_nRTS);
DDX_Check(pDX, IDC_RI, m_nRI);
DDX_Check(pDX, IDC_CTS, m_nCTS);
DDX_Check(pDX, IDC_DSR, m_nDSR);
DDX_Check(pDX, IDC_DCD, m_nDCD);
}

void CDruhy::OnDTR()
{
// Promenne nastavim podle stavu ovladacich prvku
UpdateData();
// Hodnotu DTR pouze kopiruji do DSR (pouze prozatimni - test)
m_nDSR=m_nDTR;
}

void CDruhy::OnRTS()
{
// Promenne nastavim podle stavu ovladacich prvku
UpdateData();
// Hodnotu RTS pouze kopiruji do CTS (pouze prozatimni - test)
m_nCTS=m_nRTS;
}
V úvodu je již známá mapa zpráv. Na první pohled se zdá neúplná vzhledem k počtu připravených obslužných funkcí. Ve skutečnosti je mapa zpráv dostatečná, musíme si pouze uvědomit, že naše třída CDruhy je založena na CPropertyPage. Základní třída již zajišťuje obsluhu některých potřebných zpráv. Například funkce OnSetActive je volána v základní třídě při aktivaci okna dialogu - "byla přepnuta naše karta jako aktivní".
Ve funkci OnSetActive je především vytvořen a odstartován časovač, který bude zajišťovat pravidelnou kontrolu stavu modemových signálů. Analogicky je časovač zrušen ve funkci OnKillActive. V obou námi potlačených funkcích musíme uvést do chodu i akce vyžadované základní třídou. Voláme proto odpovídající verze bázových metod.
Nejdůležitějším úkolem tohoto dílu je ve stručnosti vysvětlit, jakým způsobem se v MFC předávají data z dialogu do proměnné a naopak. Děje se tak pomocí mechanismu DDX - Dialog Data eXchange.
Mechanismus je možné aktivovat velmi snadno - potlačením virtuální funkce DoDataExchange. Implementace je jednoduchá. Musíme si pouze vybrat z nabídky DDX_... funkcí a s jejich pomocí vytvořit vazbu mezi prvky a jim odpovídajícími proměnnými. Jako ukázku jsou zde vybrány 4 DDX_ funkce:
FunkcePrvekProměnná
DDX_Texttextové polečíselná nebo řetězcová proměnná
DDX_Checkzaškrtávací políčkoceločíselná proměnná
DDX_Radioskupina přepínačůceločíselná proměnná
DDX_LBIndexseznamceločíselná proměnná
V našem případě např. funkce:
   DDX_Check(pDX, IDC_DTR, m_nDTR);
svazuje zaškrtávací políčko IDC_DTR s proměnnou m_nDTR.
Parametrem funkce DoDataExchange (i funkcí DDX_) je ukazatel na objekt třídy CDataExchange, který mimo jiné sděluje informace o směru toku dat.
Výměnu dat je možné kdykoliv v dialogu spustit zavoláním funkce UpdateData s parametrem FALSE nebo TRUE, který určuje směr přenosu. Standardní argument je zde TRUE a znamená směr "z dialogu do proměnné".
Nyní by již měla být zřejmá činnost funkcí OnDTR, OnRTS a OnTimer. První dvě jsou volány při kliknutí na příslušné políčko. Pomocí UpdateData přenesou aktuální stav do odpovídající proměnné, kterou vzápětí okopírují do proměnné svázané s jiným zvoleným políčkem. Aby se okopírovaný stav dostal na displej, používáme časovač. Ten každých 100 msec pomocí opačně pracující funkce UpdateData aktualizuje prvky v dialogu. Časovač je zvolen pro nezávislou kontrolu stavu portu. Nevíme, kdy se stav signálového bitu změní. Perioda 100 msec je pro oko dostačující - nemyslím, že by uživatel stíhal rychlejší změny...
Poznámka: V krátkosti bych uvedl, že podobným mechanismem je Dialog Data Validation (DDV), který umožňuje kódu používajícím MFC ověřit platnost zadaných údajů - např. zda zadaná číselná hodnota leží v určeném intervalu.
Po přeložení by měla být druhá karta programu schopna zkopírovat údaje z výstupních signálů do 2 vstupních signálů. Můžete si to vyzkoušet.

obr. 58 Přenos dat mezi prvky dialogu
Zatím stále nepracujeme s portem počítače, ale příště už se polepším ;-)

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

  • Přenos dat dialog <-> proměnná zajistí mechanismus DDX.
  • Vazbu mezi prvkem a proměnnou vytvoříme DDX_ funkcí v DoDataExchange.
  • Data lze aktualizovat voláním funkce UpdateData.
 

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.