Wraz z nadejściem IE3, Windows dają daleko posuniętą możliwość dostosowywania wyglądu kontrolek. Ta nowa technologia została nazwana Custom Draw //w nagłówku typedef struct tagNMCUSTOMDRAWINFO { NMHDR hdr; DWORD dwDrawStage; HDC hdc; RECT rc; DWORD dwItemSpec; UINT uItemState; LPARAM lItemlParam; } NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW; typedef struct tagNMTVCUSTOMDRAW { NMCUSTOMDRAW nmcd; COLORREF clrText; COLORREF clrTextBk; int iLevel; // IE 4 only } NMTVCUSTOMDRAW, *LPNMTVCUSTOMDRAW; // stałe Custom Draw #define NM_CUSTOMDRAW (NM_FIRST - 12) #define CDDS_ITEM 0x10000 #define CDDS_PREPAINT 0x1 #define CDDS_ITEMPREPAINT CDDS_ITEM | CDDS_PREPAINT #define CDRF_DODEFAULT 0x0 #define CDRF_NEWFONT 0x2 #define CDRF_NOTIFYITEMDRAW 0x20 #define CDIS_SELECTED 0x0001 TFont *NewFont; // mapujemy komunikat WM_NOTIFY void __fastcall WMNotify(TMessage &Msg); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_NOTIFY, TMessage, WMNotify) END_MESSAGE_MAP(TForm) //------------------------------------------------------ //------------------------------------------------------ //w źródle __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { // tworzymy nowy font, który przypiszemy // konkretnym węzłom TTreeView NewFont = new TFont(); NewFont->Size = 10; NewFont->Name = "Comic Sans MS"; } void __fastcall TForm1::WMNotify(TMessage &Msg) { // wskaźnik do struktury NM_TREEVIEW LPNM_TREEVIEW lpnm = (NM_TREEVIEW *)Msg.LParam; // sprawdza, czy komunikat to Custom Draw if (lpnm->hdr.code == NM_CUSTOMDRAW) { // sprawdza, czy komunikat pochodzi z TreeView1 if (lpnm->hdr.hwndFrom == TreeView1->Handle) { // wskaźnik do struktury NMTVCUSTDRAW LPNMTVCUSTOMDRAW lptvcd = (NMTVCUSTOMDRAW *)Msg.LParam; // sprawdza fazę rysowania switch (lptvcd->nmcd.dwDrawStage) { // przed rysowaniem... case CDDS_PREPAINT: { // mówi Windowsowi, że chcemy // powiadomienia o rysowaniu każdej pozycji Msg.Result = CDRF_NOTIFYITEMDRAW; break; } // powiadomienie o rysowaniu pozycji case CDDS_ITEMPREPAINT: { // zmienia font pierwszej pozycji w TreeView1 ULONG HItem = (ULONG)TreeView1->Items->Item[0]->ItemId; if (lptvcd->nmcd.dwItemSpec == HItem) { SelectObject(lptvcd->nmcd.hdc, NewFont->Handle); } // określa stan pozycji TreeView1 UINT State = lptvcd->nmcd.uItemState; // zmienia kolor tła jeżeli zaznaczona pozycja // jeżeli nie, to kolor TreeView1 if (State & CDIS_SELECTED) lptvcd->clrTextBk = ColorToRGB(clHighlight); else lptvcd->clrTextBk = ColorToRGB(TreeView1->Color); // mówi Windowsowi, że zmienił atrybut Msg.Result = CDRF_NEWFONT; break; } //w innym przypadku standardowe rysowanie default: Msg.Result = CDRF_DODEFAULT; } } } // jeżeli komunikat nie jest Custom Draw // to pozwala formie obsłużyć go else TForm::Dispatch(&Msg); } // czyścimy... void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { delete NewFont; } Custom Draw może być używane z większością kontrolek. Niektóre są trudniejsze do zaimplementowania, ale na pewno o wiele łatwiej jest to zrobić niż poprzez styl owner-drawn. Inną kwestią jest to, że Custom Draw nie powoduje denerwującego migotania, co można zaobserwować przy wielu kontrolkach owner-drawn. Nie trzeba więc używać podwójnego buforowania.
|