2.3. Сообщения и уведомления. ClassWizard.
Основная задача разработчика программ для Windows - связь сообщений с обрабатывающими их функциями . В приложении, не использующем MFC , для этого нужна оконная процедура для каждого зарегистрированного оконного класса. Такая процедура обычно реализуется с помощью оператора switch , получающего идентификатор сообщения. В MFC -приложении сообщения обрабатывают функции-члены классов приложения, созданныx как Вами, так и мастером AppWizard . Чтобы связать сообщение с обработчиком, достаточно карты сообщений .
Карта сообщений - это таблица, объявленная в теле класса, которая связывает системные сообщения с функциями-членами данного класса. Она состоит из записей, назначающих функцию-обработчик для каждого идентификатора сообщения. Карта поддерживает 4 типа сообщений:
Таблица 1. Типы сообщений в MFC
Тип сообщения Описание
Сообщения Windows |
Эти сообщения посылаются операционной системой. Они информируют приложение о создании окна, о его предстоящем уничтожении, о событиях клавиатуры и мыши, об изменениях системных цветов и обо всем остальном, что способно повлиять на выполнение программы. Идентификаторы этих сообщений обычно начинаются с префикса WM_ . Сообщения Windows как правило обрабатываются окном, которому они посланы. Им может быть и главное окно приложения, и диалоговое окно |
Командные сообщения |
Командные сообщения генерируются в ответ на действия пользователя, например на выбор пункта меню, щелчок кнопки панели инструментов или нажатие "быстрой" клавиши. Когда происходит одно из таких событий, приложению отправляется сообщение WM_COM MAND с параметром, зависящим от команды. Данные сообщения передаются каркасом объекту приложения. Такая маршрутизация команд позволяет приложению обработать сообщение в наиболее подходящем для этого классе |
Командные сообщения обновления пользовательского интерфейса |
Данные сообщения генерируются каркасом приложения, таким образом, они присущи только MFC . Они сигнализируют приложению об изменении состояния элементов интерфейса, таких, как пункты меню и кнопки панелей инструментов. Например, перед отображением меню приложению отправляется соответствующее сообщение, что дает ему возможность изменить состояние этого меню - сделать его доступным, недоступным или помеченным |
Уведомления от элементов управления |
Такие сообщения посылают родительскому окну элементы управления и другие дочерние окна. Они обычно представляют собой сообщения WM_COMMAND с параметрами уведомления. Например, поле ввода генерирует для своего родительского окна сообщение WM_COMMAND , содержащее код уведомления EN_CHANGE , когда пользователь предпринимает действия, которые могут изменить текст в этом поле |
Карты сообщений поддерживают все классы, производные от CCmdTarget . Классы, генерируемые мастером AppWizard , создаются вместе с простейшей картой сообщений. С помощью мастера ClassWizard можно добавлять новые классы, содержащие карту сообщений, и манипулировать записями таких карт уже существующих классов.
Создание обработчиков сообщений средствами мастера ClassWizard
Здесь мы рассмотрим вопросы, связанные с добавлением обработчиков сообщений Windows и командных сообщений с помощью мастера ClassWizard . Изучив сгенерированный код, Вы поймете, как в MFC -приложениях создаются карты сообщений.
Добавим обработчик, который будет отображать информационное окно при щелчке в клиентской области окна приложения МуАрр . Клиентской областью называют часть экрана, ограниченную рамкой окна. Все данные приложения обычно отображаются в ней.
- Добавление обработчика сообщения Windows.
- Вернитесь в проект МуАрр .
- Откройте ClassWizard , нажав CTRL+W . Перейдите на вкладку Message Maps .
- В списке Class Name выберите элемент CMyAppView . Это показывает, что Вы хотите обработать сообщение, посланное классу представления, который инкапсулирует клиентскую область главного окна.
- В списке Object IDs щелкните пункт CMyAppView .
- В списке Messages выберите элемент WM_LBUTTONDOWN . Это сообщение будет отправлено приложению, когда Вы щелкнете левой кнопкой мыши в клиентской области окна.

- Щелкните кнопку Add Function . Мастер ClassWizard создаст функцию-заглушку, в которую Вы можете добавить свой код. Все сообщения Windows обрабатываются перегруженными виртуальными функциями базового класса CWnd . Их названия начинаются с " On ", после чего следует название сообщения, у которого обрезан префикс WM_ , а заглавными являются только первые буквы слов. В данном случае функция называется OnLButtonDown() .
- Щелкните кнопку Edit Code . Откроется файл MyAppView.cpp , a курсор будет помещен в начало функции OnLButtonDown() .

- Замените комментарий, начинающийся с //TODO , таким кодом:
AfxMessageBox("Щелчок левой кнопкой мыши"); Теперь эта функция выглядит следующим образом:
void CMyAppView::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox("Щелчок левой кнопкой мыши");
CScrollView::OnLButtonDown(nFlags, point);
}
- Нажмите клавишу F7 , чтобы собрать проект МуАрр , после чего запустите приложение клавишей F5 . Проверьте работу программы, щелкнув левой кнопкой мыши в клиентской области. Закройте приложение МуАрр .
Теперь добавьте обработчик командного сообщения, посылаемого при выборе пункта Paste в меню Edit .
- Добавление обработчика командного сообщения .
- Открыв проект МуАрр , нажмите клавиши CTRL+W , тем самым Вы вызовите мастер ClassWizard . Перейдите на вкладку Message Maps .
- В списке Class Name щелкните СМуАррАрр . Не забывайте, что командные сообщения могут обрабатываться любым классом приложения. Так как Ваша функция очень маленькая, Вы сделаете ее членом такого класса. Сообщения должны обрабатываться классом, который наиболее тесно с ними связан. Например, лучшее место для размещения обработчиков команд, которые изменяют атрибуты главного окна (отображают и скрывают панель инструментов), - класс CMainFrame .
- В списке Object IDs щелкните элемент ID_EDIT_PASTE . Это идентификатор команды, передаваемый в качестве параметра сообщения WM_COMMAND , которое генерируется при выборе пункта Paste в меню Edit .
- В списке Messages выберите COMMAND . Таким образом Вы указываете, что собираетесь обрабатывать командное сообщение , а не сообщение об обновлении пользовательского интерфейса .
- Щелкните кнопку Add Function . Появится диалоговое окно, предлагающее в качестве названия обработчика OnEditPaste() . Это является результатом того, что Вы определяете новую функцию, а не перегружаете уже существующую виртуальную функцию базового класса. Согласитесь с данным названием, щелкнув кнопку ОК .

- Щелкните кнопку Edit Code . Откроется файл MyAppView.cpp , курсор будет помещен в начало функции OnEditPaste() .
- Замените комментарий, начинающийся с //TODO , таким кодом:
AfxMessageBox("Выбрана команда Paste из меню Edit");
Теперь эта функция выглядит следующим образом:
void CMyAppApp::OnEditPaste()
{
AfxMessageBox("Выбрана команда Paste из меню Edit");
}
- Соберите и запустите приложение МуАрр . Чтобы проверить его работу, выберите в меню Edit пункт Paste . Обратите внимание: пункты меню, обработчики которых не определены, недоступны.
Код карты сообщений
При добавлении функции-обработчика мастер ClassWizard выполняет следующие действия:
- объявляет функцию в заголовочном файле класса;
- создает функцию-заглушку в файле реализации класса;
- добавляет соответствующую запись в карту сообщений.
Посмотрим, что представляют собой тексты объявления функции CMyAppApp::OnEditPaste() и ее карты сообщений.
Как видите, ClassWizard добавил в карту сообщений макрос ON_COMMAND . Его структура очень проста. Первый параметр -это идентификатор сообщения. Второй параметр - название функции-обработчика.
Объявление функции OnLButtonDown() , обрабатывающей сообщение WM_ LBUTTONDOWN , выглядит следующим образом (оно находится в файле MyAppView.h ):
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
Соответствующая ей запись в карте сообщений в файле AppView.cpp такова:
ON_WM_LBUTTONDOWN()
Так как сообщения Windows обрабатываются перегруженными виртуальными функциями базового класса CWnd , нет необходимости передавать название обработчика в качестве параметра. Каркас MFC -приложения автоматически связывает такие сообщения с соответствующей виртуальной функцией. Как правило, сообщения Windows имеют дополнительную информацию, передаваемую в виде параметров. Все эти данные передаются в обработчик каркасом приложения. Внимательно посмотрите на объявление функции CMyApp::OnLButtonDown . Наверняка Вы заметили, что она принимает два параметра (производные от параметров сообщения WM_LBUTTONDOWN ), один из которых содержит координаты текущего положения указателя мыши, а другой - флаг, который "отвечает" за нажатие "виртуальных" клавиш (например CTRL или SHIFT ).
|