TN061. Сообщения ON_NOTIFY и WM_NOTIFY
Примечание
Следующее техническое примечание не было обновлено, поскольку сначала оно было включено в электронную документацию.В результате некоторые процедуры и разделы могут быть устаревшими или неверными.Для получения последних сведений рекомендуется выполнить поиск интересующей темы в алфавитном указателе документации в Интернете.
Это техническом примечании информацию об истории отвечает на новом сообщения WM_NOTIFY и описывает рекомендуемый (и наиболее распространенным) способ обработки сообщения WM_NOTIFY в приложении MFC.
Сообщения уведомления в Windows 3.x
В Windows 3.x, элементы управления " их родительских событий, например щелчки мышью, изменения в содержимом и выделение и фоновое изображение элемента управления, отправляя сообщение на родительский элемент. Простые уведомления отправляются как особые сообщения WM_COMMAND, с кодом уведомления (например, BN_CLICKED) и идентификатор элемента управления упаковыванным в wParam и дескриптором элемента управления в lParam. Обратите внимание, что с момента wParam и lParam полностью, не существует способа передать все дополнительные данные, эти сообщения могут быть только простым уведомления. Например, в уведомлении BN_CLICKED, не существует способа отправлять информацию о расположении курсора мыши, когда кнопка была нажата.
Когда элементам управления в Windows 3.x необходимо отправить сообщение уведомления, которое содержит дополнительные данные, они используют разнообразные специализированные сообщения, включая WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM и т д Эти сообщения могут отражать элементу управления, отправившего их. Дополнительные сведения см. в разделе TN062: Отражение сообщения для элементов управления Windows.
Сообщения уведомления в Win32
Для элементов управления, которые существовали в Windows 3.1, Win32 API большинство сообщений уведомлений, которые использовались в Windows 3.x. Однако Win32 также добавляет несколько изощренного, сложные элементы управления к данным, поддерживаемых в Windows 3.x. Часто, необходимость этих элементов управления отправлял дополнительные данные с их сообщения уведомления. Вместо добавление нового сообщения WM_* для каждого нового уведомления, требуются дополнительные данные, конструкторы Win32 API выбрано добавление только одно сообщение WM_NOTIFY, который может передавать любое количество дополнительных данных в определенной таким.
Сообщения WM_NOTIFY содержит идентификатор элемента управления отправя сообщение в wParam и указатель на структуру в lParam. Эта структура или структура NMHDR или некоторые более крупную структуру, которая имеет структуру NMHDR в качестве первого член. Обратите внимание, что поскольку элемент NMHDR сначала указатель к этой структуре можно использовать в качестве или указатель на интерфейс NMHDR или в качестве указателя на больший структуре зависит от того, как будут приводит его.
В большинстве случаев указатель укажет на больший структуре и необходимо привести ее при использовании его. В лишь несколько уведомлений, такие как общие уведомления (уведомлений, имена которых начинаются с NM_ и TTN_SHOW ) и TTN_POP управления всплывающей подсказки, фактически используется структура NMHDR.
Структура NMHDR или начальный элемент содержит дескриптор и идентификатор элемента управления отправя сообщение и код уведомления (например, TTN_SHOW). Формат структуры NMHDR показан ниже:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
Для сообщений TTN_SHOW является членом code будет установлено значение TTN_SHOW.
Большинство уведомления передают указатель на больший структуру, содержащую структуру NMHDR в качестве первого член. Например, рассмотрим структуру используется сообщением уведомления LVN_KEYDOWN элемента управления "список", которое отправляется, если ключ не в элементе управления списка. Указывает указатель на структуру LV_KEYDOWN, которая определена, как показано ниже:
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Обратите внимание, что поскольку элемент NMHDR является первым в этой структуре, указатель, передаются в сообщение уведомления можно привести к или указатель на указатель на NMHDR или LV_KEYDOWN.
Уведомления общие ко всем элементам управления нового окна
Некоторые общие уведомления ко всем элементам управления нового окна. Эти уведомления передают указатель на структуру NMHDR.
Код уведомлений |
Поскольку при |
---|---|
NM_CLICK |
Пользователь нажимает нажатой в элементе управления |
NM_DBLCLK |
Пользователь щелкнул дважды нажатой в элементе управления |
NM_RCLICK |
Пользователь нажимает правой кнопки мыши в элементе управления |
NM_RDBLCLK |
Дважды пользователь щелкнул правой кнопки мыши в элементе управления |
NM_RETURN |
Пользователь отжал клавиша ВВОД, когда элемент управления имеет фокус ввода |
NM_SETFOCUS |
Давал элементу управления фокус ввода |
NM_KILLFOCUS |
Элемент управления истек фокус ввода |
NM_OUTOFMEMORY |
Элемент управления не удалось выполнить операцию, поскольку не хватает памяти, доступной. |
ON_NOTIFY: Обработка сообщений WM_NOTIFY в приложениях MFC
Сообщения уведомления на CWnd::OnNotify функции. Эта реализация по умолчанию возвращает схему для обработчиков сообщений уведомления для вызова. В общем случае не переопределите OnNotify. Вместо этого необходимо предоставить функцию обработчика и добавить запись сопоставления сообщений для этого обработчика к схеме сообщений класса окна ".
ClassWizard, с помощью страницы свойств ClassWizard, может создать запись сопоставления сообщений ON_NOTIFY и предоставить его с функцией каркасной обработчика. Дополнительные сведения об использовании ClassWizard, чтобы облегчить эту задачу, см. в разделе Сообщения сопоставления в функции.
Макрос сопоставления сообщений ON_NOTIFY имеет следующий синтаксис:
ON_NOTIFY( wNotifyCode, id, memberFxn )
, выделенные курсивом параметры заменяются:
wNotifyCode
Код для сообщения уведомлений, которые необходимо обрабатывать, например LVN_KEYDOWN.id
Идентификатор дочернего элемента управления, для которого отправляется уведомление.memberFxn
Функция-член, вызываемую при это уведомление будет отправлена.
В функции-члена необходимо объявлять с прототипом следующим:
afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
Заметки
, выделенные курсивом параметры:
pNotifyStruct
Указатель на структуру уведомления, как описано в разделе выше.result
Указатель на код результата будут заданы, прежде чем вернуть.
Пример
Чтобы указать, что требуется функции-члена OnKeydownList1 обработка сообщений LVN_KEYDOWN из CListCtrl с идентификатором IDC_LIST1, можно использовать ClassWizard, чтобы добавить следующее к схеме сообщений:
ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 )
В приведенном выше примере, функциональных возможностях ClassWizard выглядит следующим образом:
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
Обратите внимание, что ClassWizard предоставляет указатель правильного типа автоматически. Доступ к структуре уведомления через или pNMHDR или pLVKeyDow.
ON_NOTIFY_RANGE
Если требуется процесс одно и то же сообщение WM_NOTIFY для набора элементов управления, можно использовать ON_NOTIFY_RANGE, а не ON_NOTIFY. Например, можно получить набор кнопок, для которых нужно выполнить те же действия для некоторого сообщения уведомления.
При использовании ON_NOTIFY_RANGE указывается представляет собой непрерывный дочерних диапазон идентификаторов, для которых обрабатывается сообщение уведомления, указав идентификаторы начальное и конечное дочерние диапазона.
ClassWizard не обрабатывает ON_NOTIFY_RANGE; чтобы его использовать, самостоятельно необходимо редактировать схема сообщений.
Запись и прототип функции для сопоставления сообщений ON_NOTIFY_RANGE следующим образом:
ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
, выделенные курсивом параметры заменяются:
wNotifyCode
Код для сообщения уведомлений, которые необходимо обрабатывать, например LVN_KEYDOWN.id
Первый идентификатор в сопредельном диапазон идентификаторов.idLast
Последний идентификатор в сопредельном диапазон идентификаторов.memberFxn
Функция-член, вызываемую при это уведомление будет отправлена.
В функции-члена необходимо объявлять с прототипом следующим:
afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Заметки
, выделенные курсивом параметры:
id
Идентификатор дочернего элемента управления, отправившего уведомление.pNotifyStruct
Указатель на структуру уведомления, как описано выше.result
Указатель на код результата будут заданы, прежде чем вернуть.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Если требуется более одного объекта в маршрутизации для обработки сообщений уведомлений, можно использовать ON_NOTIFY_EX (или ON_NOTIFY_EX_RANGE), а не ON_NOTIFY (или ON_NOTIFY_RANGE). Единственное различие между версией EX и версией, что обычная функция-член вызывается для версии EX возвращает значение bool, которая указывает, должен ли продолжить обработку сообщения. Возвращение ЛОЖЬ из данной функции позволяет процесс одно и то же сообщение в более чем одном объекте.
ClassWizard не обрабатывает ON_NOTIFY_EX или ON_NOTIFY_EX_RANGE; если необходимо использовать указанные из них необходимо самостоятельно необходимо редактировать схема сообщений.
Запись и прототип функции ON_NOTIFY_EX и ON_NOTIFY_EX_RANGE для сопоставления сообщений следующим образом. Значения параметров совпадает для версий не EX.
ON_NOTIFY_EX( nCode, id, memberFxn )
ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast, memberFxn )
Прототип для обоих предыдущего это же:
afx_msg BOOL memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Заметки
В обоих случаях id содержит идентификатор дочернего элемента управления, отправившего уведомление.
Функция должна возвращать значение TRUE, если сообщение уведомления полностью было обработано, или ЛОЖЬ, если другие объекты в маршрутизации команд должны имеют возможность обработки сообщения.