TN061: ON_NOTIFY e messaggi WM_NOTIFY

Questa nota tecnica fornisce informazioni di base sul nuovo messaggio WM_NOTIFY e descrive il modo raccomandato (e più comune) di gestione dei messaggi WM_NOTIFY in applicazione MFC.

Messaggi di notifica in Windows 3. x

In Windows 3. x, controlli notificare i genitori di eventi come il clic del mouse, cambia in pittura di sfondo controllo contenuto e selezione inviando un messaggio al padre. Semplice notifiche vengono inviate come messaggi WM_COMMAND speciali, con il codice di notifica (ad esempio BN_CLICKED) e controllano ID confezionato in wParam e lParamhandle del controllo. Si noti che poiché wParam e lParam sono piene, non non c'è nessun modo per passare dati aggiuntivi — questi messaggi possono essere solo semplice notifica. Per esempio, nella notifica BN_CLICKED , non non c'è alcun modo per inviare informazioni circa la posizione del cursore del mouse quando si fa clic sul pulsante.

Quando i controlli in Windows 3. x devono inviare un messaggio di notifica che include dati aggiuntivi, essi usano una varietà di messaggi speciali, tra cui WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEMe così via. Questi messaggi possono essere riflessa indietro al controllo che li ha inviati. Per ulteriori informazioni, vedere TN062: messaggio di riflessione per controlli di Windows.

Messaggi di notifica in Win32

Per i controlli che esisteva in Windows 3.1, l'API Win32 utilizza la maggior parte dei messaggi di notifica che sono stati utilizzati in Windows 3. x. Tuttavia, questi controlli Win32 aggiunge anche un certo numero di controlli sofisticati e complessi, a quelle supportate in Windows 3. x. frequentemente, bisogno di inviare dati supplementari con i loro messaggi di notifica. Piuttosto che aggiungere un nuovo messaggio WM _ * per ogni nuova notifica che ha bisogno di ulteriori dati, i progettisti di API Win32 ha scelto di aggiungere un solo messaggio, WM_NOTIFY, che possono passare qualsiasi quantità di dati aggiuntivi in maniera standardizzata.

WM_NOTIFY messaggi contengono l'ID del controllo l'invio del messaggio in wParam e un puntatore a una struttura nel lParam. Questa struttura è una struttura NMHDR o qualche struttura più grande che ha una struttura NMHDR come il suo primo deputato. Si noti che poiché il membro NMHDR è primo, un puntatore a questa struttura può essere utilizzato come puntatore a un NMHDR o come un puntatore alla struttura più grande a seconda di come lo devi lanciare.

Nella maggior parte dei casi, il puntatore punterà ad una struttura più grande e sarà necessario eseguirne il cast quando lo si utilizza. In solo pochi notifiche, come notifiche di comuni (il cui nome inizia con NM_) e del controllo strumento punta TTN_SHOW e notifiche di TTN_POP , è una struttura NMHDR effettivamente utilizzata.

La struttura NMHDR o membro iniziale contiene l'handle e l'ID del controllo l'invio del messaggio e il codice di notifica (ad esempio TTN_SHOW). Di seguito è riportato il formato della struttura NMHDR:

typedef struct {tag&NMHDR
 nbsp;  HWND hwndFrom;
    UINT idFrom;
    Codice UINT;
} NMHDR

Per un messaggio TTN_SHOW , il membro del codice verrebbe impostato su TTN_SHOW.

La maggior parte delle notifiche passano un puntatore a una struttura più grande che contiene una struttura NMHDR come il suo primo deputato. Per esempio, si consideri la struttura utilizzata dalle LVN_KEYDOWN messaggio di notifica del controllo visualizzazione elenco, che viene inviato quando viene premuto un tasto in un controllo visualizzazione elenco. I punti di puntatore a una struttura LV_KEYDOWN , che è definito come illustrato di seguito:

typedef struct {tagLV_KEYDOW&N
 nbsp;  Hdr NMHDR;   
    WORD wVKey;  
    UINT bandiere;  
} LV_KEYDOWN

Si noti che poiché il membro NMHDR è primo in questa struttura, il puntatore che sei passato nel messaggio di notifica può essere a un puntatore a un NMHDR o un puntatore a un LV_KEYDOWN.

Le notifiche comune a tutti i nuovi controlli di Windows

Alcuni le notifiche sono comuni a tutti i nuovi controlli di Windows. Queste notifiche passano un puntatore a una struttura NMHDR.

Codice di notifica Inviato perché
NM_CLICK Utente fa clic sul pulsante sinistro del mouse nel controllo
NM_DBLCLK Pulsante sinistro doppio clic del mouse utente nel controllo
NM_RCLICK Utente ha fatto clic tasto destro del mouse nel controllo
NM_RDBLCLK Utente fa doppio clic su tasto destro nel controllo
NM_RETURN Utente preme il tasto ENTER mentre il controllo ha lo stato attivo di input
NM_SETFOCUS Controllo è stato dato lo stato attivo input
NM_KILLFOCUS Controllo ha perso lo stato attivo input
NM_OUTOFMEMORY Controllo non ha potuto completare un'operazione perché non c'era abbastanza memoria disponibile

ON_NOTIFY: Gestione di messaggi WM_NOTIFY nelle applicazioni MFC

La funzione CWnd::OnNotify gestisce i messaggi di notifica. L'implementazione predefinita controlla mappa messaggi per i gestori di notifica chiamare. In generale, non prevalere OnNotify. Invece fornire una funzione del gestore e aggiungere una voce di mappa messaggi per tale gestore mappa messaggi della classe della finestra il proprietario.

ClassWizard, tramite la finestra delle proprietà ClassWizard o il WizardBar, creare la voce della mappa messaggi ON_NOTIFY e fornirvi una funzione del gestore di scheletro. Per ulteriori informazioni sull'utilizzo di ClassWizard per rendere questo più facile, vedere Messaggi Mapping alle funzioni nel manuale del programmatore di Visual C++.

La macro mappa messaggi ON_NOTIFY ha la seguente sintassi:

ON_NOTIFY ( wNotifyCode, id, memberFxn )

dove i parametri in corsivo vengono sostituiti con:

wNotifyCode

Il codice per il messaggio di notifica venga gestita, come ad esempio LVN_KEYDOWN.

identificazione

L'identificatore del figlio del controllo per il quale viene inviata la notifica.

memberFxn

La funzione membro per essere chiamato quando questa notifica viene inviata.

La funzione membro deve essere dichiarata con il seguente prototipo:

afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * risultato );

dove sono i parametri in corsivo:

pNotifyStruct

Un puntatore alla struttura di notifica, come descritto nella sezione precedente.

risultato

Un puntatore al codice risultato verrà impostata prima di tornare.

Esempio

Per specificare che la funzione membro OnKeydownList1 per gestire i messaggi LVN_KEYDOWN da CListCtrl cui ID è IDC_LIST1 , è necessario utilizzare ClassWizard per aggiungere quanto segue alla mappa:

ON_NOTIFY (LVN_KEYDOWN, IDC_LIST1, OnKeydownList1)

Nell'esempio precedente, la funzione fornita da ClassWizard è:

public static void CMessageReflectionDlg::OnKeydownList1 (&NMHDR * pNMHDR, LRESULT * pResult)
{
   LV_KEYDOWN * pLVKeyDow = (LV_KEYDOWN *) pNMHDR;
   / / TODO: aggiungere il gestore di notifica di controllo
   / / nbsp;  qui il codice
   
   * pResult = 0;
}

Si noti che ClassWizard fornisce un puntatore del tipo corretto automaticamente. È possibile accedere alla struttura di notifica tramite o pNMHDR opLVKeyDow.

ON_NOTIFY_RANGE

Se avete bisogno di elaborare lo stesso messaggio WM_NOTIFY per un insieme di controlli, è possibile utilizzare ON_NOTIFY_RANGE anziché ON_NOTIFY. Per esempio, avete una serie di pulsanti di cui si desidera eseguire la stessa azione per un certo messaggio di notifica.

Quando si utilizza ON_NOTIFY_RANGE, si specifica un intervallo contiguo di identificatori di bambino per il quale gestire il messaggio di notifica specificando l'inizio e che terminano gli identificatori di bambino della gamma.

ClassWizard non gestisce ON_NOTIFY_RANGE; per utilizzarla, è necessario modificare la mappa te stesso.

La voce della mappa messaggi e il prototipo di funzione per ON_NOTIFY_RANGE sono i seguenti:

ON_NOTIFY_RANGE ( wNotifyCode, id, idLast, memberFxn )

dove i parametri in corsivo vengono sostituiti con:

wNotifyCode

Il codice per il messaggio di notifica venga gestita, come ad esempio LVN_KEYDOWN.

identificazione

L'identificatore prima dell'intervallo contiguo di identificatori.

idLast

L'ultimo identificatore nell'intervallo contiguo di identificatori.

memberFxn

La funzione membro per essere chiamato quando questa notifica viene inviata.

La funzione membro deve essere dichiarata con il seguente prototipo:

afx_msgvoidmemberFxn(UINT idNMHDR*pNotifyStruct,LRESULT*risultato);

dove sono i parametri in corsivo:

identificazione

L'identificatore del figlio del controllo che ha inviato la notifica.

pNotifyStruct

Un puntatore alla struttura di notifica, come descritto in precedenza.

risultato

Un puntatore al codice risultato verrà impostata prima di tornare.

ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE

Se si desidera più di un oggetto nella notifica di routing per gestire un messaggio, è possibile utilizzare ON_NOTIFY_EX (o ON_NOTIFY_EX_RANGE) piuttosto che ON_NOTIFY (o ON_NOTIFY_RANGE). L'unica differenza tra la versione EX e la versione normale è che la funzione membro chiamata per la versione EX restituisce un BOOL che indica o meno dovrebbe continuare l'elaborazione del messaggio. Falsificazione di ritorno da questa funzione consente di elaborare lo stesso messaggio a più di un oggetto.

ClassWizard non gestisce ON_NOTIFY_EX o ON_NOTIFY_EX_RANGE; Se si desidera utilizzare una di esse, è necessario modificare la mappa del messaggio te stesso.

La voce della mappa messaggi e il prototipo di funzione per ON_NOTIFY_EX e ON_NOTIFY_EX_RANGE sono i seguenti. I significati dei parametri sono gli stessi per la non-EX versioni.

ON_NOTIFY_EX ( nCode, id, memberFxn )

ON_NOTIFY_EX_RANGE ( wNotifyCode, id, idLast,memberFxn )

Il prototipo per entrambi di cui sopra è la stessa:

afx_msgBOOLmemberFxn(UINT idNMHDR*pNotifyStruct,LRESULT*risultato);

In entrambi i casi, id contiene l'identificatore di bambino del controllo che ha inviato la notifica.

La funzione deve restituire TRUE se il messaggio di notifica è stata completamente gestito o falso se altri oggetti nel comando routing dovrebbe avere la possibilità di gestire il messaggio.

&Note tecniche per numero |nbsp; Note tecniche per la categoria

Index