Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Följande tekniska anmärkning har inte uppdaterats sedan den först inkluderades i onlinedokumentationen. Därför kan vissa procedurer och ämnen vara inaktuella eller felaktiga. För den senaste informationen rekommenderar vi att du söker efter det intressanta ämnet i onlinedokumentationsindexet.
Den här tekniska anmärkningen innehåller bakgrundsinformation om det nya WM_NOTIFY-meddelandet och beskriver det rekommenderade (och vanligaste) sättet att hantera WM_NOTIFY meddelanden i ditt MFC-program.
Aviseringsmeddelanden i Windows 3.x
I Windows 3.x meddelar kontroller sina föräldrar om händelser som musklickningar, ändringar i innehåll och val samt kontroll av bakgrundsmålning genom att skicka ett meddelande till den överordnade enheten. Enkla meddelanden skickas som särskilda WM_COMMAND meddelanden, med meddelandekoden (till exempel BN_CLICKED) och kontroll-ID:t packat i wParam och kontrollens handtag i lParam. Observera att eftersom wParam och lParam är fulla finns det inget sätt att skicka ytterligare data – dessa meddelanden kan bara vara enkla meddelanden. I meddelandet BN_CLICKED finns det till exempel inget sätt att skicka information om platsen för musmarkören när knappen klickades.
När kontroller i Windows 3.x behöver skicka ett meddelande som innehåller ytterligare data använder de en mängd olika specialmeddelanden, inklusive WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM och så vidare. Dessa meddelanden kan återspeglas tillbaka till den kontroll som skickade dem. Mer information finns i TN062: Meddelandereflektion för Windows-kontroller.
Aviseringsmeddelanden i Win32
För kontroller som fanns i Windows 3.1 använder Win32-API:et de flesta aviseringsmeddelandena som användes i Windows 3.x. Men Win32 lägger också till ett antal avancerade, komplexa kontroller till dem som stöds i Windows 3.x. Dessa kontroller måste ofta skicka ytterligare data med sina meddelanden. I stället för att lägga till ett nytt WM_* meddelande för varje nytt meddelande som behöver ytterligare data, valde win32-API:ets designers att bara lägga till ett meddelande, WM_NOTIFY, som kan skicka ytterligare data på ett standardiserat sätt.
WM_NOTIFY meddelanden innehåller ID för kontrollen som skickar meddelandet i wParam och en pekare till en struktur i lParam. Den här strukturen är antingen en NMHDR-struktur eller en större struktur som har en NMHDR-struktur som första medlem. Observera att eftersom NMHDR-medlemmen är först kan en pekare till den här strukturen användas som antingen en pekare till en NMHDR eller som en pekare till den större strukturen beroende på hur du kastar den.
I de flesta fall pekar pekaren på en större struktur och du måste kasta den när du använder den. Det är endast i några få meddelanden, såsom vanliga meddelanden (vars namn börjar med NM_) och verktygstipskontrollens TTN_SHOW och TTN_POP meddelanden, som en NMHDR-struktur faktiskt används.
NMHDR-strukturen eller den första medlemmen innehåller handtaget och ID:t för kontrollen som skickar meddelandet och meddelandekoden (till exempel TTN_SHOW). Formatet för NMHDR-strukturen visas nedan:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
För ett meddelande av typen TTN_SHOW skulle "code"-medlemmen anges till TTN_SHOW.
De flesta meddelanden skickar en pekare till en större struktur som innehåller en NMHDR-struktur som första medlem. Tänk till exempel på strukturen som används av listvisningskontrollens LVN_KEYDOWN meddelandemeddelande, som skickas när en nyckel trycks in i en listvykontroll. Pekaren pekar på en LV_KEYDOWN struktur som definieras enligt nedan:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Observera att eftersom NMHDR-medlemmen är först i den här strukturen, kan pekaren du får i meddelandet kastas till antingen en pekare till en NMHDR eller en pekare till en LV_KEYDOWN.
Meddelanden som är gemensamma för alla nya Windows-kontroller
Vissa meddelanden är gemensamma för alla nya Windows-kontroller. Dessa meddelanden skickar en pekare till en NMHDR-struktur .
| Meddelandekod | Skickat eftersom |
|---|---|
| NM_CLICK | Användaren klickade på vänster musknapp i kontrollen |
| NM_DBLCLK | Användaren dubbelklickade på vänster musknapp i kontrollen |
| NM_RCLICK | Användaren klickade på höger musknapp i kontrollen |
| NM_RDBLCLK | Användaren dubbelklickade på höger musknapp i kontrollen |
| NM_RETURN | Användaren tryckte på RETUR-tangenten medan kontrollen har indatafokus |
| NM_SETFOCUS | Kontrollen har fått indatafokus |
| NM_KILLFOCUS | Kontrollen har förlorat indatafokus |
| NM_OUTOFMEMORY | Kontrollen kunde inte slutföra en åtgärd eftersom det inte fanns tillräckligt med minne tillgängligt |
ON_NOTIFY: Hantera WM_NOTIFY-meddelanden i MFC-applikationer
Funktionen CWnd::OnNotify hanterar meddelanden. Dess standardimplementering kontrollerar meddelandekartan för meddelandehanterare som ska anropas. I allmänhet åsidosätter du inte OnNotify. I stället anger du en hanteringsfunktion och lägger till en post för meddelandekarta för den hanteraren i meddelandekartan för ägarfönstrets klass.
ClassWizard kan via egenskapsbladet för ClassWizard skapa posten i meddelandekartan ON_NOTIFY och ge dig en grundfunktion för hanterare. Mer information om hur du använder ClassWizard för att göra detta enklare finns i Mappa meddelanden till funktioner.
Makrot ON_NOTIFY meddelandekarta har följande syntax:
ON_NOTIFY(wNotifyCode, id, memberFxn)
där parametrarna är:
wNotifyCode
Koden för meddelandemeddelandet som ska hanteras, till exempel LVN_KEYDOWN.
ID
Underidentifieraren för kontrollen som meddelandet skickas för.
memberFxn
Medlemsfunktionen som ska anropas när det här meddelandet skickas.
Din medlemsfunktion måste deklareras med följande prototyp:
afx_msg void memberFxn(NMHDR* pNotifyStruct, LRESULT* result);
där parametrarna är:
pNotifyStruct
En pekare till meddelandestrukturen enligt beskrivningen i avsnittet ovan.
resultat
En pekare till den resultatkod som du anger innan du returnerar.
Exempel
Om du vill att medlemsfunktionen OnKeydownList1 ska hantera LVN_KEYDOWN meddelanden från CListCtrl vars ID är IDC_LIST1använder du ClassWizard för att lägga till följande i meddelandekartan:
ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeydownList1)
I exemplet ovan är funktionen som tillhandahålls av ClassWizard:
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
Observera att ClassWizard ger en pekare av rätt typ automatiskt. Du kan komma åt meddelandestrukturen via antingen pNMHDR eller pLVKeyDow.
ON_NOTIFY_RANGE
Om du behöver bearbeta samma WM_NOTIFY meddelande för en uppsättning kontroller kan du använda ON_NOTIFY_RANGE i stället för ON_NOTIFY. Du kan till exempel ha en uppsättning knappar som du vill utföra samma åtgärd för för ett visst meddelande.
När du använder ON_NOTIFY_RANGE anger du ett sammanhängande intervall med underordnade identifierare som du vill hantera meddelandemeddelandet för genom att ange de underordnade identifierarna för början och slutet av intervallet.
ClassWizard hanterar inte ON_NOTIFY_RANGE; för att kunna använda den måste du redigera meddelandekartan själv.
Posten för meddelandekarta och funktionsprototypen för ON_NOTIFY_RANGE är som följer:
ON_NOTIFY_RANGE(wNotifyCode, id, idLast, memberFxn)
där parametrarna är:
wNotifyCode
Koden för meddelandemeddelandet som ska hanteras, till exempel LVN_KEYDOWN.
ID
Den första identifieraren i det sammanhängande intervallet med identifierare.
idLast
Den sista identifieraren i det sammanhängande intervallet med identifierare.
memberFxn
Medlemsfunktionen som ska anropas när det här meddelandet skickas.
Din medlemsfunktion måste deklareras med följande prototyp:
afx_msg void memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);
där parametrarna är:
ID
Barnidentifieraren för kontrollen som skickade meddelandet.
pNotifyStruct
En pekare till meddelandestrukturen enligt beskrivningen ovan.
resultat
En pekare till den resultatkod som du anger innan du returnerar.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Om du vill att fler än ett objekt i meddelandedirigeringen ska hantera ett meddelande kan du använda ON_NOTIFY_EX (eller ON_NOTIFY_EX_RANGE) i stället för ON_NOTIFY (eller ON_NOTIFY_RANGE). Den enda skillnaden mellan EX-versionen och den vanliga versionen är att medlemsfunktionen som anropas för EX-versionen returnerar en BOOL som anger om meddelandebearbetningen ska fortsätta eller inte. Om du returnerar FALSE från den här funktionen kan du bearbeta samma meddelande i mer än ett objekt.
ClassWizard hanterar inte ON_NOTIFY_EX eller ON_NOTIFY_EX_RANGE. Om du vill använda någon av dem måste du redigera meddelandekartan själv.
Meddelandekartans post och funktionsprototyp för ON_NOTIFY_EX och ON_NOTIFY_EX_RANGE är följande. Parametrarnas betydelser är desamma som för icke-EX-versioner .
ON_NOTIFY_EX(nCode, id, memberFxn)
ON_NOTIFY_EX_RANGE(wNotifyCode, id, idLast, memberFxn)
Prototypen för båda ovanstående är densamma:
afx_msg BOOL memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);
I båda fallen så innehåller ID barnidentifieraren för kontrollen som skickade meddelandet.
Funktionen måste returnera TRUE om meddelandemeddelandet har hanterats helt eller FALSKT om andra objekt i kommandodirigeringen ska ha en chans att hantera meddelandet.
Se även
tekniska anteckningar efter nummer
tekniska anteckningar efter kategori