Ce este un control owner-draw?
Raspuns
Un control owner-draw este un control pentru care intreaga responsabilitate a desenarii revine "owner-ului".
Mai bine zis, cel care implementeaza un control owner-draw, trebuie sa trateze mesajul WM_DRAWITEM in fereastra parinte si sa deseneze controlul.
In MFC, aceasta se poate face si in clasa controlului, suprascriind functia virtuala DrawItem (exemplu, CButton::DrawItem).
Pentru ca un control sa fie owner-draw trebuie ca sa aiba setat stilul corespunzator (exemplu, BS_OWNERDRAW pentru un buton).
Exemplu
Code: Select all
// OwnerdrawButton.h
// Simple ovner-draw button; just for DEMO purpose
class COwnerdrawButton : public CButton
{
// ...
virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
// ...
private:
void _DrawUpState(CDC* pDC, LPRECT lpRect);
void _DrawDownState(CDC* pDC, LPRECT lpRect);
void _DrawFocusedState(CDC* pDC, LPRECT lpRect);
void _DrawDisabledState(CDC* pDC, LPRECT lpRect);
};
Code: Select all
// OwnerdrawButton.cpp
void COwnerdrawButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
UINT nState = lpDIS->itemState;
if(nState & ODS_SELECTED)
{
// button is pushed
_DrawDownState(pDC, &lpDIS->rcItem);
}
else if(nState & ODS_FOCUS)
{
// button has focus
_DrawFocusedState(pDC, &lpDIS->rcItem);
}
else if(nState & ODS_DISABLED)
{
// button is disabled
_DrawDisabledState(pDC, &lpDIS->rcItem);
}
else
{
// button is in "up" state (none of above)
_DrawUpState(pDC, &lpDIS->rcItem);
}
}
Code: Select all
void COwnerdrawButton::_DrawUpState(CDC* pDC, LPRECT lpRect)
{
pDC->FillSolidRect(lpRect, ::GetSysColor(COLOR_BTNFACE));
pDC->DrawEdge(lpRect, EDGE_ETCHED, BF_RECT);
pDC->DrawText(_T("UP"), lpRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
Code: Select all
void COwnerdrawButton::_DrawDownState(CDC* pDC, LPRECT lpRect)
{
pDC->FillSolidRect(lpRect, RGB(255,255,0));
pDC->DrawEdge(lpRect, EDGE_SUNKEN, BF_RECT);
pDC->DrawText(_T("DOWN"), lpRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
Code: Select all
void COwnerdrawButton::_DrawFocusedState(CDC* pDC, LPRECT lpRect)
{
pDC->FillSolidRect(lpRect, RGB(255,0,0));
pDC->DrawEdge(lpRect, EDGE_RAISED, BF_RECT);
pDC->DrawText(_T("FOCUSED"), lpRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
Code: Select all
void COwnerdrawButton::_DrawDisabledState(CDC* pDC, LPRECT lpRect)
{
pDC->FillSolidRect(lpRect, ::GetSysColor(COLOR_BTNFACE));
pDC->DrawText(_T("DISABLED"), lpRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
}
- Controale precum combobox, listbox si listview pot fi owner-draw-fixed sau owner-draw-variable (exemplu, CBS_OWNERDRAWFIXED sau CBS_OWNERDRAWVARIABLE pentru combobox). Pentru cele owner-draw-variable se trimite mesajul WM_MEASUREITEM ce permte owner-ului sa indice dimensiunile unui item. In MFC, functia virtuala corespunzatoare din clasa controlului este MeasureItem.
- Pentru un combobox sau listbox owner-draw avand stilul CBS_SORT, respectiv LBS_SORT se trimite mesajul WM_COMPAREITEM ce permite owner-ului sa sorteze itemurile. In MFC se poate suprascrie in clasa controlului functia virtuala CompareItem.
- In practica, stilul owner-draw se aplica pentru customizarea controalelor simple (button, combobox, listbox). Pentru controalele mai complexe cum ar fi listview, se prefera custom-draw (se trateaza notificarea NM_CUSTOMDRAW).
- In biblioteca MFC exista clase care contin controale owner-draw. Exemple: CBitmapButton si CCheckListBox.
- In loc de owner-draw se foloseste si termenul self-draw (cand se suprascrie functia virtuala DrawItem din clasa controlului).
- Meniurile pot fi si ele owner-draw.
<< Back to MFC index