TN062: Reflexe zprávy pro ovládací prvky Windows
[!POZNÁMKA]
Následující technická poznámka nebyla aktualizována, protože byla poprvé zahrnuta v dokumentaci online.V důsledku toho některé postupy a témata mohou být nesprávné nebo zastaralé.Pro nejnovější informace je vhodné vyhledat téma zájmu v dokumentaci online index.
Tato technická Poznámka popisuje zprávy odraz, nové funkce aplikace MFC 4.0.Obsahuje také pokyny pro vytváření jednoduchých opakovaně použitelný ovládací prvek, který používá reflexi zprávy.
Tato technická Poznámka nezabývá reflexe zprávu, která se vztahuje na ovládací prvky ActiveX (dříve nazývané ovládací prvky OLE).Přečtěte si článek ovládací prvky ActiveX: Subclassing ovládací prvky pro Windows.
Co je zpráva reflexe?
Ovládací prvky systému Windows často odesílat zprávy oznámení jejich nadřazeného okna.Například mnoho ovládacích prvků odesílat oznámení ovládací prvek barvy (WM_CTLCOLOR nebo jednu z jeho variant) k jejich rodiče o povolení dodávat stopy pro malování pozadí ovládacího prvku nadřazeného.
V systému Windows a před verzí 4.0 MFC nadřazené okno, často dialogové okno, je odpovědný za zpracování těchto zpráv.To znamená, že kód pro zpracování zprávy musí být v nadřazené okno třídy a že má zkopírovat do každé třídy, který potřebuje ke zpracování této zprávy.Ve výše uvedeném případě by musel každé dialogové okno Ovládací prvky s vlastní pozadí chtěli zpracovat oznámení barva ovládacího prvku.Je mnohem jednodušší, pokud lze zapsat třídu ovládacího prvku, který bude zpracovávat barvu pozadí opětovného použití kódu.
V MFC 4.0 staré mechanismus stále pracuje – nadřazené windows může zpracovávat zprávy s oznámením.Kromě toho však MFC 4.0 usnadňuje opakované použití tím, že poskytuje funkci nazvanou "zpráva reflexe", který umožňuje tyto oznamovací zprávy ke zpracování v podřízené okno Ovládací prvek nebo nadřazené okno nebo v obou.V příkladu barva pozadí ovládacího prvku nyní můžete napsat třídu ovládacího prvku, který nastaví barvu pozadí zpracováním zrcadlené WM_CTLCOLOR zpráva – vše bez spoléhání se na nadřazené. (Všimněte si, že vzhledem k tomu, že zpráva reflexe je implementováno knihovnou MFC, systémem Windows, nadřazené okno třídy nesmí být odvozen od CWnd pro zprávu reflexi práce.)
Starší verze knihovny MFC něco podobné reflexi zprávy tím, že virtuální funkce několik zpráv, například zprávy pro seznamy nakreslena vlastníka (WM_DRAWITEMa tak dále).Nový mechanismus odraz zpráva je generalizovaná a konzistentní.
Zpráva reflexe je zpětně kompatibilní s kódem napsaným pro verze knihovny MFC před 4.0.
Pokud jste zadali obslužnou rutinu pro konkrétní zprávu nebo pro rozsah zprávy nadřazené okno třídy přepíše projeví pokud nemůžete volat základní třídy obslužné rutiny vlastní rutiny obslužné rutiny zpráv pro stejnou zprávu.Například, pokud je zpracování WM_CTLCOLOR ve vaší třídy dialogového okna, vaše zpracování přepíše jakékoli zrcadlenou zprávu obslužné rutiny.
Pokud ve své nadřazené okno třídy poskytovat obslužnou rutinu pro konkrétní WM_NOTIFY zpráva nebo oblast WM_NOTIFY zprávy, vaše obslužná rutina bude volat, pouze v případě, že podřízený ovládací prvek odesílání těchto zpráv nemá popisovač zrcadlených zprávy prostřednictvím ON_NOTIFY_REFLECT().Použijete-li ON_NOTIFY_REFLECT_EX() na mapě zpráva vaše obslužné rutiny zpráv může nebo nemusí umožnit nadřazené okno pro zpracování zprávy.Pokud obslužná rutina vrátí FALSE, zpráva bude zpracována nadřazené také při volání, které vrátí TRUE neumožňuje zpracování nadřazeného.Všimněte si, že zrcadlené zprávy je zpracována před oznámení.
Když WM_NOTIFY zprávy, ovládací prvek je k dispozici první možnost zpracování.Pokud všechny zrcadlené zprávy odeslána, první šanci jej má nadřazené okno a ovládací prvek dostane zrcadlené zprávy.Chcete-li tak učinit, musíte obslužnou rutinu a příslušnou položku v mapě zpráva třídy ovládacího prvku.
Makro mapu zpráv pro zrcadlené zprávy je mírně odlišné než pravidelná oznámení: má _REFLECT připojen k jeho obvyklý název.Například pro zpracování WM_NOTIFY zpráva v nadřazené, použijte makro ON_NOTIFY v nadřazené mapě zpráva.Zpracování zrcadlené zprávy v podřízeném ovládacím prvku, použijte ON_NOTIFY_REFLECT makro v podřízeném ovládacím prvku mapu zpráv.V některých případech parametry se liší, stejně.Poznámka: ClassWizard může obvykle můžete přidat položky mapování zpráv a poskytují implementaci funkce kostry s správné parametry.
Viz TN061: ON_NOTIFY a zprávy WM_NOTIFY informace o nové WM_NOTIFY zprávy.
Mapu zpráv položky a prototypy funkce obslužné rutiny pro zrcadlené zprávy
Zpracování oznámení zrcadlené ovládací prvek, použijte mapu zpráv makra a prototypy funkce uvedené v následující tabulce.
ClassWizard lze obvykle přidat tyto položky mapu zpráv a poskytují funkce kostry implementací.Viz Definování popisovače zpráv zprávy se projeví informace o tom, jak definovat obslužné rutiny pro zrcadlené zprávy.
Převést z názvu zprávy na název makra zrcadlené, předřazení ON_ a připojit _REFLECT.Například WM_CTLCOLOR se stane ON_WM_CTLCOLOR_REFLECT. (Chcete-li zobrazit zprávy, které mohou odrážet, to opačný Převod makra položky v tabulce níže.)
Tři výjimky z výše uvedeného pravidla jsou následující:
Makro pro WM_COMMAND oznámení je ON_CONTROL_REFLECT.
Makro pro WM_NOTIFY odrazů je ON_NOTIFY_REFLECT.
Makro pro ON_UPDATE_COMMAND_UI je odrazy ON_UPDATE_COMMAND_UI_REFLECT.
Ve všech výše uvedených zvláštních případech je nutné zadat název funkce obslužné rutiny člen.V ostatních případech je nutné použít standardní název obslužné rutiny.
Význam parametrů a vrácené hodnoty funkce jsou popsány v části název funkce nebo název funkce s na před.Například CtlColor je popsána v OnCtlColor.Několik zrcadlenou zprávu obslužné rutiny nutné parametry méně než podobné obslužné rutiny v nadřazené okno.Pouze odpovídat názvům v níže uvedené tabulce s názvy formálních parametrů v dokumentaci.
Položku mapy |
Prototyp funkce |
---|---|
ON_CONTROL_REFLECT( wNotifyCode, memberFxn ) |
afx_msg void memberFxn ( ); |
ON_NOTIFY_REFLECT( wNotifyCode, memberFxn ) |
afx_msg void memberFxn ( NMHDR * pNotifyStruct, LRESULT* result ); |
ON_UPDATE_COMMAND_UI_REFLECT (memberFxn) |
afx_msg void memberFxn ( CCmdUI* pCmdUI ); |
(ON_WM_CTLCOLOR_REFLECT) |
afx_msg HBRUSH CtlColor ( CDC* pDC, UINT nCtlColor ); |
(ON_WM_DRAWITEM_REFLECT) |
afx_msg zrušit DrawItem (LPDRAWITEMSTRUCTlpDrawItemStruct), |
(ON_WM_MEASUREITEM_REFLECT) |
afx_msg zrušit MeasureItem (LPMEASUREITEMSTRUCTlpMeasureItemStruct), |
(ON_WM_DELETEITEM_REFLECT) |
afx_msg zrušit DeleteItem (LPDELETEITEMSTRUCTlpDeleteItemStruct), |
(ON_WM_COMPAREITEM_REFLECT) |
afx_msg int CompareItem (LPCOMPAREITEMSTRUCTlpCompareItemStruct), |
(ON_WM_CHARTOITEM_REFLECT) |
afx_msg int CharToItem ( UINT nKey, UINT nIndex ); |
(ON_WM_VKEYTOITEM_REFLECT) |
afx_msg int VKeyToItem ( UINT nKey, UINT nIndex ); |
(ON_WM_HSCROLL_REFLECT) |
afx_msg void HScroll ( UINT nSBCode, UINT nPos ); |
(ON_WM_VSCROLL_REFLECT) |
afx_msg void VScroll ( UINT nSBCode, UINT nPos ); |
(ON_WM_PARENTNOTIFY_REFLECT) |
afx_msg void ParentNotify ( UINT message, LPARAM lParam ); |
ON_NOTIFY_REFLECT a ON_CONTROL_REFLECT makra mají varianty, které umožňují více než jeden objekt (například ovládací prvek a jeho nadřazeným) ke zpracování dané zprávy.
Položku mapy |
Prototyp funkce |
---|---|
ON_NOTIFY_REFLECT_EX( wNotifyCode, memberFxn ) |
afx_msg BOOL memberFxn ( NMHDR * pNotifyStruct, LRESULT* result ); |
ON_CONTROL_REFLECT_EX( wNotifyCode, memberFxn ) |
afx_msg BOOL memberFxn ( ); |
Zpracování zpráv Reflected: Příklad opakovaně použitelný ovládací prvek.
Tento jednoduchý příklad vytvoří opakovaně použitelný ovládací prvek nazvaný CYellowEdit.Ovládací prvek funguje stejně jako ovládací prvek pro běžné úpravy s výjimkou, že se zobrazí černý text na žlutém pozadí.Je snadné přidání členské funkce, které by umožnilo CYellowEdit prvek, který zobrazí různé barvy.
Zkuste příklad, který vytvoří opakovaně použitelný ovládací prvek.
Nové dialogové okno vytvořte v existující aplikaci.Další informace naleznete dialogové okno editor téma.
Musíte mít aplikaci, ve které chcete vytvořit opakovaně použitelný ovládací prvek.Pokud nemáte existující aplikace použít, vytvořte dialogovou aplikaci pomocí AppWizard.
Projekt načten do aplikace Visual C++ pomocí ClassWizard k vytvoření nové třídy nazývá CYellowEdit podle CEdit.
Přidat tři členské proměnné v CYellowEdit třídy.Budou první dva COLORREF proměnné pro uložení barvu textu a barvu pozadí.Třetí bude CBrush objekt, který bude obsahovat stopy pro malování na pozadí.CBrush Objekt umožňuje jednou, pouze na po nich stopy a zničit stopy automaticky při CYellowEdit řízení je zničen.
Napsáním konstruktoru inicializujte proměnné členů:
CYellowEdit::CYellowEdit() { m_clrText = RGB( 0, 0, 0 ); m_clrBkgnd = RGB( 255, 255, 0 ); m_brBkgnd.CreateSolidBrush( m_clrBkgnd ); }
Pomocí ClassWizard, přidejte obslužnou rutinu pro zrcadlené WM_CTLCOLOR zprávy v CYellowEdit třídy.Poznámka: rovnítko, název zprávy v seznamu zpráv, které lze zpracovávat označuje, že zpráva je zohledněna.To je popsáno v Definování popisovače zpráv zprávy se projeví.
ClassWizard přidá následující funkce makro a kostru mapu zpráv:
ON_WM_CTLCOLOR_REFLECT() // Note: other code will be in between.... HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here // TODO: Return a non-NULL brush if the // parent's handler should not be called return NULL; }
Tělo funkce nahraďte následující kód.Tento kód určuje barvu textu, barvu pozadí textu a barvy pozadí pro zbývající část ovládacího prvku.
pDC->SetTextColor( m_clrText ); // text pDC->SetBkColor( m_clrBkgnd ); // text bkgnd return m_brBkgnd; // ctl bkgnd
Vytvoření ovládacího prvku pro úpravy v dialogovém vyberte a připojte jej k členské proměnné dvojitým kliknutím na ovládací prvek pro úpravy, podržte stisknutou klávesu control.V dialogovém okně Přidat členskou proměnnou dokončit název proměnné a zvolte "Řízení" pro kategorii, pak "CYellowEdit" pro typ proměnné.Nezapomeňte nastavit pořadí v dialogovém okně.Také je nutné zahrnout hlavičku souboru pro CYellowEdit ovládací prvek v záhlaví souboru v dialogovém.
Sestavte a spusťte aplikaci.Ovládací prvek pro úpravy budou mít pozadí žluté.