TN061: messaggi di WM_NOTIFY e di ON_NOTIFY
[!NOTA]
La seguente nota tecnica non è stata aggiornata dalla prima volta che viene inclusa nella documentazione online.Di conseguenza, alcune procedure e argomenti potrebbero non essere aggiornati o errati.Per le informazioni più recenti, è consigliabile cercare l'argomento di interesseindice della documentazione online.
Questa nota tecnica vengono fornite informazioni di base sul nuovo messaggio di WM_NOTIFY e viene descritto (e la più comune) la modalità consigliata per gestire i messaggi di WM_NOTIFY nell'applicazione MFC.
Messaggi di notifica in windows 3.x
In windows 3.x, i controlli notifica ai relativi elementi padre degli eventi quali i clic del mouse, modifiche nel contenuto e selezione e disegno dello sfondo del controllo inviando un messaggio al padre.Le notifiche semplici vengono inviate come messaggi di WM_COMMAND speciale, con il codice di notifica ad esempio BN_CLICKED) e l'ID del controllo compresso in wParam e la manopola di comando in lParam.Si noti che su wParam e lParam è completo, non esiste alcun modo per passare dati aggiuntivi — questi messaggi possono essere solo notifica semplice.Ad esempio, nella notifica di BN_CLICKED , non è possibile inviare le informazioni sulla posizione del cursore del mouse quando il pulsante è stato fatto clic.
Quando i controlli in windows 3.x necessario inviare un messaggio di notifica che include dati aggiuntivi, utilizzano diversi messaggi per uno scopo specifico, inclusi WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM, e così via.Questi messaggi possono essere applicate al controllo che li ha inviati.Per ulteriori informazioni, vedere TN062: reflection di messaggio per i controlli Windows.
Messaggi di notifica in Win32
Per i controlli presenti in Windows 3.1, gli utilizzi dell'API Win32 più messaggi di notifica utilizzati in windows 3.x.Tuttavia, in Win32 aggiunge una serie di controlli specializzati e complessi a quelli supportati in windows 3.x.Spesso, necessità di questi controlli di inviare dati aggiuntivi con i messaggi di notifica.Anziché aggiungendo un nuovo messaggio di WM_* per ogni nuova notifica che necessita di dati aggiuntivi, le finestre di progettazione dell'API Win32 scelto per aggiungere un messaggio, WM_NOTIFY, che possono passare qualsiasi quantità di dati aggiuntivi in modo standardizzato.
I messaggi diWM_NOTIFY contengono l'ID del controllo che invia il messaggio in wParam e un puntatore a una struttura in lParam.Questa struttura rappresenta una struttura di NMHDR o da più grande struttura con una struttura di NMHDR come primo membro.Si noti che poiché il membro di NMHDR inizialmente, un puntatore a questa struttura può essere utilizzato come puntatore a NMHDR o puntatore a più grande struttura a seconda di come si esegue il cast.
Nella maggior parte dei casi, il puntatore farà riferimento a una maggiore struttura e sarà necessario eseguirne il cast quando la si utilizza.Solo in determinate notifiche, ad esempio le notifiche comuni di notifiche (i cui nomi iniziano con NM_) e di TTN_SHOW e di TTN_POP del controllo di descrizione comandi, è una struttura di NMHDR effettivamente utilizzata.
La struttura di NMHDR o il membro iniziale contiene l'handle e l'ID del controllo che invia il messaggio e il codice di notifica ad esempio TTN_SHOW).Il formato della struttura di NMHDR è indicato di seguito:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
Per un messaggio di TTN_SHOW , il membro di code verrebbe impostato su TTN_SHOW.
La maggior parte delle notifiche passare un puntatore a una maggiore struttura che contiene una struttura di NMHDR come primo membro.Ad esempio, si consideri la struttura utilizzata dal messaggio di notifica di LVN_KEYDOWN del controllo visualizzazione elenco, che viene inviato a una chiave viene introdotto un controllo visualizzazione elenco.I punti del puntatore a una struttura di LV_KEYDOWN , definita come illustrato di seguito:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Si noti che poiché il membro di NMHDR inizialmente in questa struttura, il puntatore che viene passato nel messaggio di notifica è possibile eseguirne il cast a un puntatore a NMHDR o a un puntatore a LV_KEYDOWN.
Notifiche comuni a tutti i nuovi controlli Windows
Le notifiche sono comuni a tutti i nuovi controlli Windows.Tali notifiche passare un puntatore a una struttura di NMHDR .
Codice di notifica |
Inviato perché |
---|---|
NM_CLICK |
L'utente ha fatto clic sul pulsante sinistro del mouse nel controllo |
NM_DBLCLK |
L'utente ha fatto doppio clic sul pulsante sinistro del mouse nel controllo |
NM_RCLICK |
L'utente ha fatto clic con il pulsante destro del mouse nel controllo |
NM_RDBLCLK |
L'utente ha fatto doppio clic sul pulsante destro del mouse nel controllo |
NM_RETURN |
L'utente ha premuto il tasto INVIO quando il controllo ha lo stato attivo per l'input |
NM_SETFOCUS |
Il controllo è stato lo stato attivo per l'input specificato |
NM_KILLFOCUS |
Il controllo non è più lo stato attivo per l'input |
NM_OUTOFMEMORY |
Il controllo non può completare un'operazione perché non cera abbastanza memoria disponibile |
ON_NOTIFY: Messaggi di gestione WM_NOTIFY nelle applicazioni MFC
I messaggi di notifica di handle di CWnd::OnNotify di funzione.L'implementazione predefinita controlla la mappa messaggi per i gestori di notifica venga chiamato.Non eseguire l'override in genere OnNotify.Al contrario, svolgete una funzione di gestione e aggiungere una voce della mappa messaggi per tale gestore alla mappa messaggi della classe della finestra proprietaria.
ClassWizard, in una finestra delle proprietà di ClassWizard, possibile creare la voce della mappa messaggi di ON_NOTIFY e fornire con una funzione di gestione di base.Per ulteriori informazioni sull'utilizzo di ClassWizard per semplificare questa procedura, vedere Messaggi del mapping delle funzioni.
La macro della mappa messaggi di ON_NOTIFY con la seguente sintassi:
ON_NOTIFY( wNotifyCode, id, memberFxn )
dove i parametri visualizzati in corsivo vengono sostituiti con:
wNotifyCode
Il codice del messaggio di notifica vengono gestiti, come LVN_KEYDOWN.id
L'identificatore figlio del controllo per il quale la notifica viene inviato.memberFxn
La funzione membro da chiamare quando questa notifica viene inviata.
La funzione membro deve essere dichiarata con il prototipo indicato di seguito:
afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
Note
dove i parametri visualizzati in corsivo sono:
pNotifyStruct
Un puntatore a una struttura di notifica, come descritto nella sezione precedente.result
Un puntatore al codice di risultato verrà impostata prima del completamento di.
Esempio
Per specificare che la funzione membro OnKeydownList1 per gestire i messaggi di LVN_KEYDOWN da CListCtrl il cui ID è IDC_LIST1, si utilizzava ClassWizard per aggiungere quanto segue alla mappa messaggi:
ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 )
Nell'esempio precedente, la funzione fornita da ClassWizard è:
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
Si noti che ClassWizard fornisce un puntatore di tipo corretto automaticamente.È possibile accedere alla struttura di notifica con pNMHDR o pLVKeyDow.
ON_NOTIFY_RANGE
Se è necessario elaborare lo stesso messaggio di WM_NOTIFY per un insieme di controlli, è possibile utilizzare ON_NOTIFY_RANGE anziché ON_NOTIFY.Ad esempio, è possibile eseguire un set esempio di pulsanti per il quale si desidera eseguire la stessa azione per un determinato messaggio di notifica.
Quando si utilizza ON_NOTIFY_RANGE, specificare un intervallo contiguo di identificatori figlio per il quale è necessario gestire il messaggio di notifica specifica l'inizio e identificatori figlio finali dell'intervallo.
ClassWizard non gestisce ON_NOTIFY_RANGE; per utilizzarlo, è necessario modificare la mappa messaggi manualmente.
Il prototipo di funzione e la voce della mappa messaggi per ON_NOTIFY_RANGE è la seguente:
ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
dove i parametri visualizzati in corsivo vengono sostituiti con:
wNotifyCode
Il codice del messaggio di notifica vengono gestiti, come LVN_KEYDOWN.id
Il primo identificatore nell'intervallo contiguo degli identificatori.idLast
L'ultimo identificatore nell'intervallo contiguo degli identificatori.memberFxn
La funzione membro da chiamare quando questa notifica viene inviata.
La funzione membro deve essere dichiarata con il prototipo indicato di seguito:
afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Note
dove i parametri visualizzati in corsivo sono:
id
L'identificatore figlio del controllo che ha inviato la notifica.pNotifyStruct
Un puntatore a una struttura di notifica, come descritto in precedenza.result
Un puntatore al codice di risultato verrà impostata prima del completamento di.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Se si desidera maggiore di un oggetto nel routing di notifica per gestire un messaggio, è possibile utilizzare ON_NOTIFY_EX (o ON_NOTIFY_EX_RANGE) anziché ON_NOTIFY (o ON_NOTIFY_RANGE).L'unica differenza tra la versione di EX e la versione normale è che la funzione membro chiamata per la versione di EX restituisce BOOL che indica se un l'elaborazione dei messaggi deve continuare.Restituire FALSE da questa funzione consente di elaborare lo stesso messaggio in più di un oggetto.
ClassWizard non gestisce ON_NOTIFY_EX o ON_NOTIFY_EX_RANGE; se si desidera utilizzare uno di essi, è necessario modificare la mappa messaggi manualmente.
Il prototipo di funzione e la voce della mappa messaggi per ON_NOTIFY_EX e ON_NOTIFY_EX_RANGE sono indicati di seguito.I significati di parametri sono gli stessi delle versioni non diEX .
ON_NOTIFY_EX( nCode, id, memberFxn )
ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast, memberFxn )
Il prototipo per entrambi il di sopra è lo stesso:
afx_msg BOOL memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Note
In entrambi i casi, id utilizzato l'identificatore figlio del controllo che ha inviato la notifica.
La funzione deve restituire TRUE se il messaggio di notifica è stato completamente gestito o FALSE se altri oggetti nel routing dei comandi hanno la possibilità di gestire il messaggio.