На этом шаге мы перечислим макросы, которые используются в картах сообщений, и перечислим особенности удаления
записей из карты сообщений.
В MFC определены 4 типа макросов записей карты сообщений (они перечислены в таблице 1), каждый из которых соответствует определенному типу сообщений.
Тип сообщения | Макрос | Параметры |
---|---|---|
Стандартное сообщение Windows | ON_WM_XXX (где XXX - название сообщения) | Нет |
Командное сообщение | ON_COMMAND | Идентификатор команды, название функции-обработчика |
Команда обновления | ON_UPDATE_COMMAND_UI | Идентификатор команды, название функции-обработчика |
Уведомление от элементов управления | ON_XXX (где XXX - название уведомления) | Идентификатор команды, название функции-обработчика |
Наверняка Вы заметили, что сгенерированный мастером ClassWizard код помещен внутри блока, который начинается с комментария //{{AFX_MSG и заканчивается //}}AFX_MSG. Эти надписи обозначают область, изменяемую мастером ClassWizard. Вы вправе добавлять записи карты сообщений вручную, но только снаружи блока, ограниченного этими комментариями. В противном случае ClassWizard начнет работать неправильно. Модификатор AFX_MSG, предшествующий объявлению функций-обработчиков, тоже используется мастером ClassWizard. Он никак не влияет на компиляцию.
Когда Вы удаляете запись карты сообщений с помощью мастера ClassWizard, он удаляет и объявление соответствующего обработчика. Но сама функция, содержащая написанный Вами код, остается.
Рис.1. Выбор удаляемой функции
Вернемся к способам передачи командных сообщений объектам приложения. Сообщение обрабатывается в наиболее подходящем для этого классе благодаря маршрутизации команд. Каркас MFC-приложения передает команду по стандартной цепочке объектов (определенной для тех классов, которые являются производными от CCmdTarget и имеют карту сообщений) в поисках объекта, в котором есть обработчик этой команды. Каждый объект в цепочке ищет в своей карте сообщений функцию, способную обработать поступившее сообщение.
Такая маршрутизация команд бывает очень полезна. Например, "быстрая" клавиша посылает сообщение ID_SAVE_WINDOW STATE. Ее нажатие показывает, что пользователь хочет сохранить текущие параметры окна. В некоторых оконных объектах иногда присутствует функция-обработчик этого сообщения OnSaveWindowState(), а в других, например во временных диалоговых окнах и окнах справки, она может отсутствовать. При маршрутизации данной команды сначала проверяется карта сообщений активного окна. Если в ней нет функции OnSaveWindowState(), начнется проверка родительского окна. Если же и в нем нет такого обработчика, то выполняется переход к карте сообщений объекта приложения.
Маршрут изменяется в зависимости от контекста. Вы найдете дополнительную информацию по данному вопросу, осуществив поиск по словам "command routing" в справочной системе Visual C++.
Подводя итог сказанному отметим, что каркас MFC-приложения - это небольшая группа взаимосвязанных классов, которые вместе с несколькими глобальными функциями составляют основу любого Windows-приложения. Средствами мастера AppWizard легко создать набор классов, производных от классов каркаса, и собрать на базе него любую нужную Вам программу.
В каркас приложений входит класс CWinApp, инкапсулирующий приложение в целом. В нем определены несколько функций, вызываемых процедурой WinMain() при инициализации, работе и завершении приложения. Класс CFrameWnd инкапсулирует окно-рамку, которое может выполнять роль главного окна приложения, а также содержать меню, панели инструментов и клиентскую область.
В MFC-приложениях сообщения обрабатываются функциями-членами классов приложения. Сообщения связываются со своими обработчиками посредством карты сообщений, которая поддерживается всеми классами, производными от CCmdTarget. Карта сообщений - это таблица, определенная в объявлении класса. Она сопоставляет идентификаторы сообщений и функции этого класса. Для добавления и удаления записей карты сообщений используйте мастер ClassWizard.
Командные сообщения передаются объектам приложения в определенной последовательности до тех пор, пока не находится объект, пособный их обработать. Такая маршрутизация команд позволяет приложению обрабатывать сообщения в наиболее подходящем для этого классе.
Со следующего шага мы начнем знакомиться с архитектурой "документ/вид".