TN061: ON_NOTIFY a WM_NOTIFY – zprávy
Poznámka
Následující technická poznámka se od prvního zahrnutí do online dokumentace neaktualizovala. V důsledku toho můžou být některé postupy a témata zastaralé nebo nesprávné. Nejnovější informace doporučujeme vyhledat v online indexu dokumentace, které vás zajímá.
Tato technická poznámka obsahuje základní informace o nové zprávě WM_NOTIFY a popisuje doporučený (a nejběžnější) způsob zpracování WM_NOTIFY zpráv v aplikaci MFC.
Zprávy oznámení ve Windows 3.x
Ve Windows 3.x ovládací prvky upozorňují rodiče na události, jako jsou kliknutí myší, změny obsahu a výběru, a ovládání obrazu na pozadí odesláním zprávy nadřazené sadě. Jednoduchá oznámení se odesílají jako speciální WM_COMMAND zprávy s kódem oznámení (například BN_CLICKED) a ID ovládacího prvku zabalené do wParam a popisovače ovládacího prvku v lParam. Všimněte si, že vzhledem k tomu , že jsou wParam a lParam plné, neexistuje způsob, jak předat žádná další data – tyto zprávy mohou být pouze jednoduché oznámení. Například v oznámení BN_CLICKED neexistuje způsob, jak odeslat informace o umístění kurzoru myši při kliknutí na tlačítko.
Když ovládací prvky ve Windows 3.x potřebují odeslat zprávu s oznámením, která obsahuje další data, používají různé speciální zprávy, včetně WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM atd. Tyto zprávy se dají promítnout zpět do ovládacího prvku, který je poslal. Další informace naleznete v tématu TN062: Message Reflexe ion for Windows Controls.
Zprávy s oznámením ve Win32
U ovládacích prvků, které existovaly ve Windows 3.1, používá rozhraní API Win32 většinu zpráv oznámení, které byly použity ve Windows 3.x. Win32 ale také přidává k těm podporovaným ve Windows 3.x řadu sofistikovaných a složitých ovládacích prvků. Tyto ovládací prvky často potřebují odesílat další data se zprávami s oznámeními. Místo přidání nové WM_* zprávy pro každé nové oznámení, které potřebuje další data, se návrháři rozhraní API Win32 rozhodli přidat pouze jednu zprávu, WM_NOTIFY, která může předávat libovolné množství dalších dat standardizovaným způsobem.
WM_NOTIFY zprávy obsahují ID ovládacího prvku odesílajícího zprávu v wParam a ukazatel na strukturu v lParam. Tato struktura je buď struktura NMHDR , nebo některá větší struktura, která má strukturu NMHDR jako svůj první člen. Všimněte si, že vzhledem k tomu , že je nejprve člen NMHDR , lze ukazatel na tuto strukturu použít buď jako ukazatel na NMHDR , nebo jako ukazatel na větší strukturu v závislosti na tom, jak ji přetypujete.
Ve většině případů ukazatel ukáže na větší strukturu a při použití ho budete muset přetypovat. V několika oznámeních, jako jsou běžná oznámení (jejichž názvy začínají NM_) a ovládací prvek popisku nástroje TTN_SHOW a TTN_POP oznámení, je ve skutečnosti použitá struktura NMHDR .
Struktura NMHDR nebo počáteční člen obsahuje popisovač a ID ovládacího prvku, který odesílá zprávu a kód oznámení (například TTN_SHOW). Formát struktury NMHDR je znázorněn níže:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
U TTN_SHOW zprávy by byl člen kódu nastavený na TTN_SHOW.
Většina oznámení předává ukazatel na větší strukturu, která jako první člen obsahuje strukturu NMHDR . Představte si například strukturu, kterou ovládací prvek zobrazení seznamu používá LVN_KEYDOWN zpráva s oznámením, která se odešle při stisknutí klávesy v ovládacím prvku zobrazení seznamu. Ukazatel odkazuje na LV_KEYDOWN strukturu, která je definována takto:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Všimněte si, že vzhledem k tomu , že člen NMHDR je v této struktuře první, může být ukazatel, který jste předali v oznamovací zprávě, přetypovat na ukazatel na NMHDR nebo ukazatel na LV_KEYDOWN.
Oznámení společná pro všechny nové ovládací prvky Windows
Některá oznámení jsou společná pro všechny nové ovládací prvky Windows. Tato oznámení předávají ukazatel na strukturu NMHDR .
Kód oznámení | Odesláno z důvodu |
---|---|
NM_CLICK | Uživatel klikl na levé tlačítko myši v ovládacím prvku. |
NM_DBLCLK | Uživatel poklikáním na levé tlačítko myši v ovládacím prvku |
NM_RCLICK | Uživatel v ovládacím prvku klikl pravým tlačítkem myši. |
NM_RDBLCLK | Uživatel poklikáním pravým tlačítkem myši v ovládacím prvku |
NM_RETURN | Uživatel stiskl klávesu ENTER, zatímco ovládací prvek má fokus vstupu. |
NM_SETFOCUS | Ovládací prvek dostal vstupní fokus. |
NM_KILLFOCUS | Ovládací prvek ztratil fokus vstupu. |
NM_OUTOFMEMORY | Ovládací prvek nemohl dokončit operaci, protože není k dispozici dostatek paměti. |
ON_NOTIFY: Zpracování zpráv WM_NOTIFY v aplikacích MFC
Funkce CWnd::OnNotify
zpracovává zprávy s oznámeními. Jeho výchozí implementace zkontroluje mapování zpráv, aby obslužné rutiny oznámení volání. Obecně platí, že nepřepíšete OnNotify
. Místo toho zadáte funkci obslužné rutiny a přidáte položku mapy zpráv pro tuto obslužnou rutinu do mapy zpráv třídy okna vlastníka.
ClassWizard, prostřednictvím seznamu vlastností ClassWizard, může vytvořit ON_NOTIFY položku mapy zpráv a poskytnout vám funkci kostru obslužné rutiny. Další informace o použití TřídyWizard, aby to bylo jednodušší, naleznete v tématu Mapování zpráv na funkce.
Makro mapy zpráv ON_NOTIFY má následující syntaxi:
ON_NOTIFY(wNotifyCode, id, memberFxn)
kde parametry jsou:
wNotifyCode
Kód zprávy s oznámením, který se má zpracovat, například LVN_KEYDOWN.
id
Podřízený identifikátor ovládacího prvku, pro který je oznámení odesláno.
memberFxn
Členová funkce, která se má volat při odeslání tohoto oznámení.
Členová funkce musí být deklarována pomocí následujícího prototypu:
afx_msg void memberFxn(NMHDR* pNotifyStruct, LRESULT* result);
kde parametry jsou:
pNotify – struktura
Ukazatel na strukturu oznámení, jak je popsáno v části výše.
Výsledek
Ukazatel na kód výsledku, který nastavíte před vrácením.
Příklad
Chcete-li určit, že chcete, aby členská funkce OnKeydownList1
zpracovávala LVN_KEYDOWN zprávy z CListCtrl
ID je IDC_LIST1
, byste pomocí TřídyWizard přidali následující položky do mapy zpráv:
ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeydownList1)
Ve výše uvedeném příkladu je funkce poskytovaná classWizard:
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
Všimněte si, že ClassWizard poskytuje ukazatel správného typu automaticky. Ke struktuře oznámení můžete přistupovat prostřednictvím pNMHDR nebo pLVKeyDow.
ON_NOTIFY_RANGE
Pokud potřebujete zpracovat stejnou zprávu WM_NOTIFY pro sadu ovládacích prvků, můžete místo ON_NOTIFY použít ON_NOTIFY_RANGE. Můžete mít například sadu tlačítek, pro které chcete provést stejnou akci pro určitou zprávu s oznámením.
Pokud používáte ON_NOTIFY_RANGE, zadáte souvislou oblast podřízených identifikátorů, pro které se má zpráva s oznámením zpracovat zadáním počátečního a koncového podřízeného identifikátoru rozsahu.
TřídaWizard nezpracuje ON_NOTIFY_RANGE; pokud ho chcete použít, musíte mapu zpráv upravit sami.
Položka mapy zpráv a prototyp funkce pro ON_NOTIFY_RANGE jsou následující:
ON_NOTIFY_RANGE(wNotifyCode, id, idLast, memberFxn)
kde parametry jsou:
wNotifyCode
Kód zprávy s oznámením, který se má zpracovat, například LVN_KEYDOWN.
id
První identifikátor v souvislé oblasti identifikátorů.
IdLast
Poslední identifikátor v souvislé oblasti identifikátorů.
memberFxn
Členová funkce, která se má volat při odeslání tohoto oznámení.
Členová funkce musí být deklarována pomocí následujícího prototypu:
afx_msg void memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);
kde parametry jsou:
id
Podřízený identifikátor ovládacího prvku, který oznámení odeslal.
pNotify – struktura
Ukazatel na strukturu oznámení, jak je popsáno výše.
Výsledek
Ukazatel na kód výsledku, který nastavíte před vrácením.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Pokud chcete, aby zprávu zpracovával více než jeden objekt směrování oznámení, můžete místo ON_NOTIFY (nebo ON_NOTIFY_RANGE) použít ON_NOTIFY_EX (nebo ON_NOTIFY_EX_RANGE). Jediným rozdílem mezi verzí EX a běžnou verzí je, že členová funkce volaná pro verzi EX vrací boOL , která označuje, zda má zpracování zpráv pokračovat nebo ne. Vrácení NEPRAVDA z této funkce umožňuje zpracovat stejnou zprávu ve více než jednom objektu.
TřídaWizard nezpracuje ON_NOTIFY_EX ani ON_NOTIFY_EX_RANGE; pokud chcete některou z nich použít, musíte mapu zpráv upravit sami.
Položka mapy zpráv a prototyp funkce pro ON_NOTIFY_EX a ON_NOTIFY_EX_RANGE jsou následující. Významy parametrů jsou stejné jako u jiných verzí než EX .
ON_NOTIFY_EX(nCode, id, memberFxn)
ON_NOTIFY_EX_RANGE(wNotifyCode, id, idLast, memberFxn)
Prototyp obou výše uvedených možností je stejný:
afx_msg BOOL memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);
V obou případech obsahuje ID podřízený identifikátor ovládacího prvku, který oznámení odeslal.
Funkce musí vrátit hodnotu TRUE , pokud byla zpráva oznámení zcela zpracována nebo NEPRAVDA , pokud by jiné objekty ve směrování příkazů měly mít šanci zprávu zpracovat.
Viz také
Technické poznámky podle čísel
Technické poznámky podle kategorií