Subclassing: Pozadí ListBoxu

Je sice hezké, že příklad pracuje jak má, ale jistě Vás napadá jedna otázka: PROČ ??? Podívejme se teď na některé aspekty kódu, který jme vytvořili.

Bod 1
Zpracovávali jsme si zprávu WM_CTLCOLORLISTBOX. Detailní popis tohoto parametru najdete ve Windows Platform SDK Reference, zkráceně se dá říci, že je to zpráva, která je zasílána nadřízenému oknu ListBoxu před tím, než systém ListBox překreslí. Pokud si tuto zprávu zpracujeme dříve, můžeme tak změnit barvu textu a pozadí ListBoxu za pomocí ukazatele na specifický obsah výstupního zařízení (teda to je věta :)))).

Windows obdrží tento parametr přes WindowProc funkci:

LRESULT CALLBACK WindowProc(
  HWND hwnd,       // ukazatel na okno
  UINT uMsg,       // WM_CTLCOLORLISTBOX
  WPARAM wParam,   // ukazatel na  DC (HDC)
  LPARAM lParam    // ukazatel na ListBox (HWND)
);

Parametry:
wParam - ukazatel na obsah zařízení pro ListBox
lParam - ukazatel na ListBox

Návratové hodnoty:
Pokud si aplikace zpracovává tuto zprávu, pak musí vracet ukazatel na brush. Systém pak tento brush použije pro vykreslení pozadí ListBoxu.

Vlastně se dá říci, že nejdůležitější věc je až na konci - Návratové hodnoty, která nám říká, že pokud vrátíme ukazatel na objekt Brush jako hodnotu z "NewWindowProc", tak Windows tento Brush použijí pro vykreslení pozadí ListBoxu.

Když je zpráva WM_CTLCOLORLISTBOX zpracovávána pomocí funkce "NewWindowProc", tak potom jako parametr vrátíme ukazatel na Brush objekt "gBGBrush" místo původní hodnoty. Všechny ostatní zprávy jsou zpracovávány normálně pomocí API CallWindowLong().

Bod 2
Vytvořili jsme si objekt Brush - tento objekt byl vytvářen pomocí API CreatePatternBrush() na události Load formuláře Form1 ještě před tím, než byl spuštěn subclassing. Funkce CreatePatternBrush potřebuje pouze jeden vstupní parametr, kterým je ukazatel na objekt Image. V našem případě jsme použili ukazatel pro Image1.Picture.

Bod 3
Ukončili jsem subclassing a smazali objekt Brush když se uzavírá formulář. Smazání objektu Brush je velice důležité, protože GDI32 si neumí automaticky spravovat zdroje a velice brzo byste měli nedostatek paměti. Zrovna tak je důležité ukončení subclassingu, protože jinak by se formulář nezavřel korektně.

Zpět Další

Autor: The Bozena