Hlavní
Hlavní strana
Seznam článků
Nejčtenější články
Progres e-mailem
Visual C++ FAQ

Seriály
COM
ISAPI

banner2.gif (2546 bytes)

Nenechte si ujít
Neobdélníková okna
Tisk bez Preview
MFC a DLL
Logo v MDI ploše
Kouzla s kombo-boxem
Výjimky v C++

banner.gif (3305 bytes)

Kouzla s kombo-boxem díl 2. Jan Odvárko
19.10.1999
[Hlavní stránka]  |  [Rubrika]  |  [Download]

1.2 Změna barev
Častým požadavkem je změna barev ovládacích prvků (pozadí, text, ...). Pro vyřešení tohoto problému máme dvě možnosti. Barvu může nastavovat rodič ovládacího prvku (nejčastěji dialog), nebo ovládací prvek sám. Druhá možnost je vhodná tam, kde chceme vytvořit speciální prvek uživatelského rozhraní a nechceme opakovat kód změny barvy v každém použitém dialogu. Na následujícím příkladě je demonstrována první varianta.

2.2 Ať se snaží rodič
V dialogu, jež obsahuje daný ovládací prvek musíme reagovat na zprávu WM_CTLCOLOR, kterou svému rodiči zasílají všechny ovládací prvky. Pomocí této zprávy dává prvek svému rodiči k dispozici svůj obrazový kontext (device context), který tak může měnit jeho atributy - např. barvy. Hlavička metody, která bude obsluhovat tuto zprávu je následující.

HBRUSH OnCtlColor( CDC* pDC, CWnd* pWnd,
	UINT nCtlColor );

pDC           Ukazatel na obrazový kontext dětského okna.
pWnd         Ukazatel na okno, které zasílá zprávu (jež se dotazuje na barvu).
nCtlColor   Typ dětského okna.

Návratovou hodnotou této metody je štětec, který se použije pro vyplnění pozadí okna. Pozorného čtenáře jistě napadne, že změnou tohoto štětce lze měnit barvu pozadí dialogu..

V následující tabulce si ještě uveďme, jakých hodnot může poslední parametr - nCtlColor nabývat.

CTLCOLOR_BTN   
CTLCOLOR_DLG   
CTLCOLOR_EDIT  
CTLCOLOR_LISTBOX   
CTLCOLOR_MSGBOX   
CTLCOLOR_SCROLLBAR   
CTLCOLOR_STATIC   
Button control
Dialog box
Edit control
List-box ontrol
Message box
Scroll-bar control
Static control

Pokud tedy budeme chtít změnit barvu textu ve všech editačních řádcích, včetně editačních řádků kombo-boxů, bude implementace této metody následující.

HBRUSH CColorComboDlg::OnCtlColor(CDC* pDC, CWnd* pWnd,
	UINT nCtlColor) 
{
  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd,
	nCtlColor);
  
  switch (nCtlColor)
  {
  case CTLCOLOR_EDIT:
    pDC->SetTextColor(RGB(25500));
    break;
  }
  
  return hbr;
}

jo_15101999_magiccombo2_obr1.gif (2309 bytes)

3.2 Já sám
Pokud nechceme měnit barvu u všech ovládacích prvků stejného typu, nebo potřebujeme vytvořit takový prvek, který si bude barvy měnit sám (nemusíme pak opakovat kód v dialogu, kde je použitý) použijeme druhý způsob, který souvisí s mechanismem Message Reflection.

Ve Windows obvykle zasílají dětská okna svým rodičům notifikační zprávy. Od verze MFC 4.0 je však implementován speciální mechanismus message reflection, který umožňuje zpracovat tuto zprávu přímo v dětském okně. Ukažme si použití tohoto mechanismu nejdříve na změně barev v editačním řádku.

3.2.1 Příklad změny barev v editačním řádku
Pomocí ClassWizardu si vygenerujeme třídu PRO_ColorEdit, která bude reprezentovat náš obarvený editační řádek. Tato třída bude dědit ze třídy CEdit. Ve třídě založíme dvě členské proměnné, které budou definovat barvu textu (m_clrText) a barvu pozadí  (m_brBkgnd), typ těchto proměnných je vidět na následující částečné ukázce zdrojového kódu.

class PRO_ColorEdit : public CEdit
{
// ...

// Attributes
public:
  COLORREF m_clrText;
  CBrush m_brBkgnd;

// ...
};

V konstruktoru naší třídy obě proměnné inicializujeme...

PRO_ColorEdit::PRO_ColorEdit()
{
  m_clrText = RGB(02550);
  m_brBkgnd.CreateSolidBrush(RGB(0255255));
}

Opět pomocí ClassWizardu vygenerujeme reakci na notifikační (odraženou) zprávu =WM_CTLCOLOR. Pozor neplést se zprávou WM_CTLCOLOR, která je zasílána rodiči! V této metodě pak můžeme jednoduchým způsobem nastavit atributy obrazového kontextu editačního řádku. Podívejme se opět na následující ukázku.

HBRUSH PRO_ColorEdit::CtlColor(CDC* pDC, UINT nCtlColor) 
{
  pDC->SetTextColor(m_clrText);
  pDC->SetBkMode(TRANSPARENT);
  return m_brBkgnd;
}

Do připravené dialogové šablony vložíme kombo-box a pomocí ClassWizardu (opět) na tento ovládací prvek "namapujeme" členskou proměnnou m_oComboBox. Tato proměnná bude náležet do kategorie Control a její typ bude PRO_ColorEdit.

3.2.1 Příklad změny barev v combo-boxu
Nyní si ukážeme změnu barev v kombíčku. Zde je situace poněkud složitější, protože kombo (combo-box) je prvek složený s editačního řádku (edit) a seznamu (list-box). Musíme tedy tuto architekturu brát v úvahu. Podobně jako v předchozí kapitole vygenerujeme třídu PRO_ColorComboBox, která bude reprezentovat obarvené kombíčko. Tato třída bude opět obsahovat dvě členské proměnné, které definují barvy a jsou inicializované v konstruktoru.

Vygenerujeme reakci na zprávu WM_CTLCOLOR (ne notifikaci). Pozor, zde nevyužíváme mechanismu message reflection, protože kombo-box (jako rodič) obdrží tuto standardní zprávu od svých dětských oken - editačního řádku a list-boxu. Obarvený tedy bude jak list-box, tak i editační řádek kombo-boxu.

Následující kód ukazuje implementaci naší metody.

HBRUSH PRO_ColorComboBox::OnCtlColor( CDC* pDC,
  CWnd* pWnd, UINT nCtlColor ) 
{
  HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd,
	nCtlColor);
  
  switch (nCtlColor)
  {
  case CTLCOLOR_EDIT:
  case CTLCOLOR_LISTBOX:
    pDC->SetTextColor(m_clrText);
    pDC->SetBkMode(TRANSPARENT);
    break;
  }

  return m_brBkgnd;
}

Do připravené dialogové šablony můžeme nyní vložit ovládací prvek kombo a "namapovat" proměnnou např. m_oColorCombo, která naleží do kategorie Control a je typu PRO_ColorComboBox. Naše barevné kombo má však v tuti chvíli ještě jeden drobný nedostatek. Pokud spustíte testovací aplikaci uvidíte následující detail.

jo_15101999_magiccombo2_obr2.gif (1498 bytes)

Vnitřní okraj kombíčka zůstal neobarvený (bílý). To je způsobeno tím, že editační řádek nezabírá celou vnitřní plochu komba a část je viditelná (okraj). Musíme, nyní již s použitím mechanismu message reflection obarvit ještě pozadí kombo-boxu. Princip je stejný jako v předchozí kapitole, takže vygenerujeme reakci na notifikační zprávu =WM_CTLCOLOR. Implementace této metody bude následující.

HBRUSH PRO_ColorComboBox::CtlColor(CDC* pDC,
	UINT nCtlColor) 
{
  return m_brBkgnd;
}

Nyní je již všechno jak má být.

jo_15101999_magiccombo2_obr3.gif (2259 bytes)

 


Podobné články: Jak obarvit dialog?,

<<Předchozí
Kouzla s kombo-boxem díl 1.
Článek je zařazen do seriálu Následující>>
Kouzla s kombo-boxem díl 3.

Kdo Otázka nebo připomínka

Prohlížení příspěvků nebo nový příspěvek

O firmě... Kontakt Ostatní