Sent by a common control to its parent window when an event has occurred or the control requires some information.
Syntax
To send this message, call the SendMessage function as follows. lResult = SendMessage( // returns LRESULT in lResult hWndControl, // (HWND) handle to destination control WM_NOTIFY, // (UINT) message ID wParam, // = (WPARAM)(int) idCtrl; lParam // = (LPARAM)(LPNMHDR) pnmh; );
lResult = SendMessage( // returns LRESULT in lResult hWndControl, // (HWND) handle to destination control WM_NOTIFY, // (UINT) message ID wParam, // = (WPARAM)(int) idCtrl; lParam // = (LPARAM)(LPNMHDR) pnmh; );
Parameters
idCtrl The identifier of the common control sending the message. This identifier is not guaranteed to be unique. An application should use the hwndFrom or idFrom member of the NMHDR structure (passed as the lParam parameter) to identify the control. pnmh A pointer to an NMHDR structure that contains the notification code and additional information. For some notification messages, this parameter points to a larger structure that has the NMHDR structure as its first member.
Return Value
The return value is ignored except for notification messages that specify otherwise.
Remarks
The standard SendMessage syntax shown on this page is somewhat misleading. The destination of the message must be the HWND of the parent of the control. This value can be obtained by using GetParent, as shown in the following example, where m_controlHwnd is the HWND of the control itself. NMHDR nmh; nmh.code = CUSTOM_SELCHANGE; // Message type defined by control. nmh.idFrom = GetDlgCtrlID(m_controlHwnd); nmh.hwndFrom = m_controlHwnd; SendMessage(GetParent(m_controlHwnd), WM_NOTIFY, (WPARAM)m_controlHwnd, (LPARAM)&nmh); Applications handle the message in the window procedure of the parent window, as shown in the following example, which handles the notification message sent by the custom control in the previous example. INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case CUSTOM_SELCHANGE: if (((LPNMHDR)lParam)->idFrom == IDC_CUSTOMLISTBOX1) { ... // Respond to message. return TRUE; } break; ... // More cases on WM_NOTIFY switch. break; } ... // More cases on message switch. } return FALSE; } Some notifications, chiefly those that have been in the API for a long time, are sent as WM_COMMAND messages. For more information, see Control Messages.If the message handler is in a dialog box procedure, you must use the SetWindowLong function with DWL_MSGRESULT to set a return value.For Microsoft Windows 2000 and later systems, the WM_NOTIFY message cannot be sent between processes.Many notifications are available in both ANSI and Unicode formats. The window sending the WM_NOTIFY message uses the WM_NOTIFYFORMAT message to determine which format should be used. See WM_NOTIFYFORMAT for further discussion.
The standard SendMessage syntax shown on this page is somewhat misleading. The destination of the message must be the HWND of the parent of the control. This value can be obtained by using GetParent, as shown in the following example, where m_controlHwnd is the HWND of the control itself.
NMHDR nmh; nmh.code = CUSTOM_SELCHANGE; // Message type defined by control. nmh.idFrom = GetDlgCtrlID(m_controlHwnd); nmh.hwndFrom = m_controlHwnd; SendMessage(GetParent(m_controlHwnd), WM_NOTIFY, (WPARAM)m_controlHwnd, (LPARAM)&nmh);
Applications handle the message in the window procedure of the parent window, as shown in the following example, which handles the notification message sent by the custom control in the previous example.
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case CUSTOM_SELCHANGE: if (((LPNMHDR)lParam)->idFrom == IDC_CUSTOMLISTBOX1) { ... // Respond to message. return TRUE; } break; ... // More cases on WM_NOTIFY switch. break; } ... // More cases on message switch. } return FALSE; }
Some notifications, chiefly those that have been in the API for a long time, are sent as WM_COMMAND messages. For more information, see Control Messages.
If the message handler is in a dialog box procedure, you must use the SetWindowLong function with DWL_MSGRESULT to set a return value.
For Microsoft Windows 2000 and later systems, the WM_NOTIFY message cannot be sent between processes.
Many notifications are available in both ANSI and Unicode formats. The window sending the WM_NOTIFY message uses the WM_NOTIFYFORMAT message to determine which format should be used. See WM_NOTIFYFORMAT for further discussion.
Message Information
Headerwinuser.hMinimum operating systems Windows NT 3.51, Windows 95
See Also
WM_NOTIFYFORMAT
WM_NOTIFY = &H4E
"case: WM_NOTIFY" should be the first case in your "switch (message)" in your message loop.
This may be to ensure that lParam does not get defiled by a different case?
My program was randomly crashing until I moved the WM_NOTIFY case to the front of my message switch.
NMHDR nmh;nmh.code = CUSTOM_SELCHANGE; // Message type defined by control.nmh.idFrom = GetDlgCtrlID(m_controlHwnd);nmh.hwndFrom = m_controlHwnd;SendMessage(GetParent(m_controlHwnd), WM_NOTIFY, (WPARAM)nmh.idFrom, (LPARAM)&nmh);
The documentation says that the WPARAM should be the control id, but the example passes the HWND instead.If the API documentation is correct, the example should be:
NMHDR nmh; nmh.code = CUSTOM_SELCHANGE; // Message type defined by control. nmh.idFrom = GetDlgCtrlID(m_controlHwnd); nmh.hwndFrom = m_controlHwnd; SendMessage(GetParent(m_controlHwnd), WM_NOTIFY, (WPARAM)nmh.idFrom, (LPARAM)&nmh);