Questa nota tecnica descrive la riflessione del messaggio, una nuova funzionalità di MFC 4.0. Esso contiene anche indicazioni per la creazione di un controllo semplice riutilizzabile che utilizza la reflection messaggio.
Questa nota tecnica non discutere riflessione messaggio applicato ai controlli ActiveX (precedentemente chiamato controlli OLE). Vedere l'articolo controlli ActiveX: Subclassing un controllo di Windows nel manuale del programmatore di Visual C++.
Che cosa è il riflessione di messaggio?
Controlli di Windows spesso inviano i messaggi di notifica per loro finestre padre. Per esempio, molti controlli inviare un messaggio di notifica del colore di controllo (WM_CTLCOLOR o una delle sue varianti) al loro padre per consentire il genitore per la fornitura di un pennello per lo sfondo del controllo.
In Windows e in MFC precedenti alla versione 4.0, la finestra padre, spesso di una dialogo, è responsabile della gestione di questi messaggi. Questo significa che il codice per la gestione del messaggio deve essere in classe della finestra padre e che deve essere ripetuto in ogni classe che ha bisogno di gestire quel messaggio. Nel caso precedente, ogni finestra di dialogo che voleva controlli con sfondi personalizzati che avrebbe dovuto gestire il messaggio di notifica di controllo colore. Sarebbe molto più facile da riutilizzare codice se una classe di controlli potrebbe essere scritta che potrebbe gestire il proprio colore di sfondo.
In MFC 4.0, il vecchio meccanismo funziona ancora — windows genitore in grado di gestire i messaggi di notifica. Inoltre, tuttavia, MFC 4.0 facilita riutilizzo fornendo una funzionalità denominata "messaggio di riflessione" che permette di questi messaggi di notifica per essere gestita in finestra controllo figlio o la finestra padre o in entrambi. Nell'esempio di colore sfondo controllo ora possibile scrivere una classe di controlli che imposta il proprio colore di sfondo gestendo il messaggio WM_CTLCOLOR riflesso — tutto senza fare affidamento su padre. (Si noti che poiché riflessione messaggio viene implementato da MFC, non da Windows, la classe della finestra padre deve derivare da CWnd di riflessione messaggio al lavoro).
Le versioni precedenti di MFC ha fatto qualcosa di simile alla riflessione messaggio fornendo funzioni virtuali per un paio di messaggi, ad esempio messaggi creati dal proprietario caselle di riepilogo (WM_DRAWITEMe così via). Il nuovo meccanismo di riflessione del messaggio è generalizzata e coerente.
Messaggio riflessione è compatibile con il codice scritto per le versioni di MFC precedenti alla 4.0.
Se si hanno fornito un gestore di un messaggio specifico, o per una serie di messaggi, nella classe della finestra di tuo padre, eseguirà l'override rifletteranno i gestori di messaggi per lo stesso messaggio fornito non chiami la funzione del gestore di classe base nel vostro proprio gestore. Ad esempio, se si gestisce WM_CTLCOLOR nella classe di finestra di dialogo, la gestione sovrascriverà qualsiasi messaggio riflessa gestori.
Se, nella classe finestra padre, si fornisce un gestore per un messaggio WM_NOTIFY specifico o un intervallo di messaggi WM_NOTIFY , il gestore verrà chiamato solo se il controllo figlio l'invio di tali messaggi non dispone di un gestore di messaggi riflessa attraverso ON_NOTIFY_REFLECT(). Se si utilizza ON_NOTIFY_REFLECT_EX() , mappa, il gestore del messaggio può o non può permettere la finestra padre gestire il messaggio. Se il gestore restituisce TRUE, il messaggio verrà gestito dal genitore pure, mentre una chiamata che restituisce che falso non consente il genitore di gestirlo. Si noti che il messaggio riflesso è gestito prima il messaggio di notifica.
Quando viene inviato un messaggio WM_NOTIFY , il controllo è offerto la prima occasione per gestirlo. Se qualsiasi altro messaggio riflesso viene inviato, la finestra padre ha la prima occasione per gestirlo e il controllo verrà visualizzato il messaggio riflesso. A tal fine, bisogno di una funzione del gestore e una voce appropriata nella mappa messaggi della classe del controllo.
La macro mappa messaggi per i messaggi di riflessi è leggermente diversa per le notifiche regolari: essa ha _REFLECT aggiunto al suo nome usuale. Per esempio, per gestire un messaggio WM_NOTIFY nel padre, utilizzare la macro ON_NOTIFY nella mappa dei messaggi del genitore. Per gestire il messaggio riflesso nel controllo figlio, utilizzare la macro ON_NOTIFY_REFLECT nella mappa dei messaggi del controllo figlio. In alcuni casi, i parametri sono diversi, pure. Si noti che il ClassWizard solitamente possono aggiungere le voci della mappa messaggi per te e fornire implementazioni scheletro funzione con parametri corretti.
Vedi TN061: ON_NOTIFY e messaggi WM_NOTIFY per informazioni sul nuovo messaggio WM_NOTIFY.
Le voci della mappa messaggi e prototipi di funzione del gestore per i messaggi di riflessi
Per gestire un messaggio di notifica di controllo riflessa, utilizzare la mappa messaggi macro e prototipi di funzione elencati nella tabella riportata di seguito.
ClassWizard di solito può aggiungere queste voci mappa messaggi per te e fornire implementazioni funzione scheletro. Vedi definire un gestore messaggi per un messaggio riflessa nella guida del programmatore Visual C++ per informazioni su come definire i gestori per riflette i messaggi.
Per convertire il nome della macro riflessa dal nome messaggio, anteporre ON_ e append _REFLECT. Ad esempio, WM_CTLCOLOR diventa ON_WM_CTLCOLOR_REFLECT. (Per vedere quali messaggi possono essere riflesso, fare la conversione opposta alle voci di macro nella tabella sottostante).
Tre eccezioni alla regola di cui sopra sono i seguenti:
In ciascuno dei suddetti casi particolari, è necessario specificare il nome della funzione membro del gestore. Negli altri casi, è necessario utilizzare il nome standard per la funzione del gestore.
I significati dei parametri e valori restituiti delle funzioni sono documentati con su anteposta sotto il nome di funzione o il nome della funzione. Per esempio, CtlColor è documentata nel OnCtlColor. Diversi gestori di messaggi riflessa bisogno meno parametri rispetto i gestori simili in una finestra padre. Appena corrispondono ai nomi nella tabella sottostante con i nomi dei parametri formali nella documentazione.
| Voce della mappa | Prototipo di funzione |
| ON_CONTROL_REFLECT ( wNotifyCode, memberFxn ) | afx_msg voidmemberFxn ( ); |
| ON_NOTIFY_REFLECT ( wNotifyCode, memberFxn ) | afx_msg voidmemberFxn(NMHDR * pNotifyStruct, LRESULT * risultato ); |
| ON_UPDATE_COMMAND_UI_REFLECT ( memberFxn ) | afx_msg voidmemberFxn(CCmdUI * pCmdUI ); |
| ON_WM_CTLCOLOR_REFLECT) | afx_msg HBRUSH CtlColor (CDC * pDC, UINT nCtlColor ); |
| ON_WM_DRAWITEM_REFLECT) | afx_msg void DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct ); |
| ON_WM_MEASUREITEM_REFLECT) | afx_msg void MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct ); |
| ON_WM_DELETEITEM_REFLECT) | afx_msg void DeleteItem (LPDELETEITEMSTRUCT lpDeleteItemStruct ); |
| ON_WM_COMPAREITEM_REFLECT) | afx_msg int CompareItem (LPCOMPAREITEMSTRUCT lpCompareItemStruct ); |
| ON_WM_CHARTOITEM_REFLECT) | afx_msg int CharToItem (UINT , UINT nPer nIndex ); |
| ON_WM_VKEYTOITEM_REFLECT) | afx_msg int VKeyToItem (UINT , UINT nPer nIndex ); |
| ON_WM_HSCROLL_REFLECT) | afx_msg void HScroll (UINT nSBCode, UINT NPO ); |
| ON_WM_VSCROLL_REFLECT) | afx_msg public static void VScroll (UINT nSBCode, UINT NPO ); |
| ON_WM_PARENTNOTIFY_REFLECT) | afx_msg public static void ParentNotify (UINT messaggio, LPARAM lParam ); |
Le macro ON_NOTIFY_REFLECT e ON_CONTROL_REFLECT hanno variazioni che consentono più di un oggetto (ad esempio, il controllo e il relativo elemento padre) per gestire un determinato messaggio.
| Voce della mappa | Prototipo di funzione |
| ON_NOTIFY_REFLECT_EX ( wNotifyCode, memberFxn ) | BOOL afx_msgmemberFxn(NMHDR * pNotifyStruct, LRESULT * risultato ); |
| ON_CONTROL_REFLECT_EX ( wNotifyCode, memberFxn ) | BOOL afx_msgmemberFxn ( ); |
Gestione dei messaggi Reflected: Un esempio di un controllo riutilizzabile
Questo semplice esempio crea un controllo riutilizzabile chiamato CYellowEdit . Il controllo funziona allo stesso modo un controllo regolare edit tranne che consente di visualizzare testo nero su sfondo giallo. Sarebbe facile aggiungere funzioni membro che permetterebbero la CYellowEdit controllo per visualizzare diversi colori.
Per provare questo esempio, effettuare le seguenti operazioni:
È necessario disporre di un'applicazione in cui sviluppare il controllo riutilizzabile. Se non si dispone di un'applicazione esistente, utilizzare, creare un'applicazione basata su finestra di dialogo utilizzando la creazione guidata applicazione.
CYellowEdit basato su CEdit. Lascia selezionata la casella "Aggiungere al componente Gallery".CYellowEdit classe. I primi due saranno COLORREF variabili per mantenere il colore del testo e il colore di sfondo. Il terzo sarà un oggetto CBrush che conterrà il pennello per lo sfondo. L'oggetto CBrush consente di creare una volta, solo riferimento a dopo che il pennello e per distruggere il pennello automaticamente quando il CYellowEdit viene distrutto il controllo.CYellowEdit::CYellowEdit()
{
m_clrText = RGB (0, 0, 0);
m_clrBkgnd = RGB (255, 255, 0);
m_brBkgnd.CreateSolidBrush (m_clrBkgnd);
}
CYellowEdit classe. Si noti che il segno di uguale di fronte il nome nell'elenco dei messaggi che è possibile gestire del messaggio indica che il messaggio viene riflessa. Questo è descritto definire un gestore messaggi per un messaggio riflessa nella guida del programmatore Visual C++.ClassWizard aggiunge la seguente funzione di macro e scheletro mappa messaggi per te:
ON_WM_CTLCOLOR_REFLECT()
/ / Note: altro codice sarà in mezzo....
HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) {
/ / TODO: modificare tutti gli attributi del controller di dominio qui
/ / TODO: restituire un pennello non NULL se la
/ / gestore del genitore non deve essere chiamato
return NULL;
}
pDC-gt;SetTextColor (m_clrText); / / Testo
pDC - > SetBkColor (m_clrBkgnd); / / sfondo testo
return m_brBkgnd; / / sfondo ctl
CYellowEdit controllo nel file di intestazione della tua finestra di dialogo.CYellowEdit controllare classe per altri progetti.&Note tecniche per numero |nbsp; Note tecniche per la categoria