Шаг 3 - События рамки окна

Создание проекта

Продолжаем развитие нашего проекта дальше. Можете опять скопировать файл, как мы это делали в предыдущем шаге.

Создаем код

В описание рамки окна необходимо внести следующие изменения:

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() - это вызов простого диалогового окна с надписью. Результат двойного щелчка мышкой смотрите на картинке ниже.

3_1.gif (2825 b)

Шпаргалка

  1. Указать классу, что он реагирует на события:
    DECLARE_MESSAGE_MAP();
  2. Создать таблицу откликов на события:
    BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
    ......
    END_MESSAGE_MAP()
  3. Описать процедуры, соответствующие таблице, в классе, реагирующем на события:
    afx_msg void OnLButtonDblClk(UINT, CPoint);
    ......
  4. Создать реализацию событий:
    void CMainWnd::OnKeyDown(UINT, UINT, UINT)
    {
    	AfxMessageBox(" Key Button Down ");
    }
    
  5. Дальше Вам известно. Результат превосходит все ожидания. Только не забудьте, что реакция мышки на двойной щелчок.

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.