Продолжаем развитие нашего проекта дальше. Можете опять скопировать файл, как мы это делали в предыдущем шаге.
В описание рамки окна необходимо внести следующие изменения:
class CMainWnd : public CFrameWnd { public: CMainWnd(); afx_msg void OnLButtonDblClk(UINT, CPoint); // виртуальная процедура ответа на левую кнопку afx_msg void OnRButtonDblClk(UINT, CPoint); // виртуальная процедура ответа на правую кнопку afx_msg void OnKeyDown(UINT, UINT, UINT); // виртуальная процедура ответа на клавишу ~CMainWnd(); // деструктор private: CStatic* MyStatic; CButton* MyButton; CEdit* MyEdit; DECLARE_MESSAGE_MAP(); // таблица откликов };
И вписать следующие процедуры после описания класса.
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) // таблица откликов на сообщения ON_WM_LBUTTONDBLCLK() // реакция на нажатие левой кнопки мыши ON_WM_RBUTTONDBLCLK() // реакция на нажатие правой кнопки мышки ON_WM_KEYDOWN() // реакция на нажатие клавиши END_MESSAGE_MAP() void CMainWnd::OnKeyDown(UINT, UINT, UINT) { AfxMessageBox(" Key Button Down "); } void CMainWnd::OnRButtonDblClk(UINT, CPoint) { AfxMessageBox(" Rigth Button Click "); } void CMainWnd::OnLButtonDblClk(UINT, CPoint) { AfxMessageBox(" Left Button Click "); }
Помимо наличия окна и элементов управления неплохо, если программа в виде класса окна сможет реагировать на события. Windows порождает кучу событий, если вы двигаете мышку, нажимаете клавишу или пьете кофе, операционная среда знает все. Свои знания о ситуации она передает с помощью сообщений. На программу сообщения льются непрекращаемым потоком. Нам из этого потока необходимо выбрать нужные и обработать.
Добавление в класс макроса DECLARE_MESSAGE_MAP() говорит о том, что данный класс будет реагировать на события.
Если класс реагирует на события, то необходимо описать таблицу откликов на них. Таблица откликов находится между определениями BEGIN_MESSAGE_MAP(Класс реагирующий, Класс родитель) и END_MESSAGE_MAP(). Зачем при определении таблицы откликов указывать класс, который будет производить реакцию? Но таблиц откликов может быть много для разных классов и как интересно компилятор разберется, кому она принадлежит? Класс родителя необходим для обработки стандартных сообщений, даже если вы их явно не обрабатываете, например, закрыть приложение.
Между этими определениями вы пишете реакцию. В MFC предусмотрена обработка кучи событий, и их описание начинается с ON_WM_message. В нашем случае это стандартные события WINDOWS по реакции на нажатие клавиш и мыши.
Для каждого стандартного события описана виртуальная функция, которая будет вызываться при его возникновении. Имя и параметры этой функции строго определены и ошибаться здесь нельзя. Правило выглядит так: хочешь реакцию на стандартное событие - опиши его в таблице откликов и замени виртуальную процедуру. Afxmsg воспринимайте как аналог virtual.
После описания всех функций необходимо их реально создать, что и делается далее. AfxMessageBox() - это вызов простого диалогового окна с надписью. Результат двойного щелчка мышкой смотрите на картинке ниже.
DECLARE_MESSAGE_MAP();
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) ...... END_MESSAGE_MAP()
afx_msg void OnLButtonDblClk(UINT, CPoint); ......
void CMainWnd::OnKeyDown(UINT, UINT, UINT) { AfxMessageBox(" Key Button Down "); }