На этом шаге мы рассмотрим организацию обработки сообщений Windows.
Windows-программы управляются событиями. Любое действие со стороны пользователя генерирует событие, которое программа получает в виде сообщения Windows. Существует более 100 различных сообщений Windows. Каждое из них представлено стандартной константой. В таблице 1 представлены некоторые наиболее распространенные сообщения Windows.
Идентификатор сообщения | Сообщает окну о том, что… |
---|---|
WM_ACTIVATE | ...это окно активизируется или деактивизируется. |
WM_CHAR | ...для некоторой клавиши были посланы сообщения WM_KEYDOWN или WM_KEYUP. |
WM_CLOSE | ...данное окно должно быть закрыто. |
WM_KEYDOWN | ...на клавиатуре была нажата клавиша. |
WM_KEYUP | ...клавиша на клавиатуре была отпущена. |
WM_LBUTTONDOWN | ...пользователь нажал левую кнопку мыши. |
WM_MOUSEMOVE | ...указатель мыши переместился. |
WM_PAINT | ...необходимо перерисовать клиентскую область данного окна. |
WM_TIMER | ...произошло событие таймера. |
Обработка сообщений, получаемых от Windows, осуществляется путем создания функций-ответов специально для тех сообщений, которые должны обрабатываться. Затем создается таблица откликов, устанавливающая связь между этими функциями и соответствующими им сообщениями. Разберем это на примере обработки нажатия левой клавиши мыши (сообщение WM_LBUTTONDOWN).
Функцию ответа на нажатие левой клавиши мыши и таблицу откликов помещаем в класс окна TWndw в секцию protected.
class TWndw: public TFrameWindow { … protected: void EvLButtonDown ( UINT, TPoint &point ); DECLARE_RESPONSE_TABLE( TWndw ); };
Функция EvLButtonDown() является функцией ответа на соответствующее сообщение WM_LBUTTONDOWN. При определении имени функций-ответов необходимо следовать строгим правилам. Имя функции составляется путем замены в имени сообщения приставки WM_ на Ev и прописных букв на строчные, за исключением первых букв каждого "слова", включенного в имя сообщения. Например, WM_LBUTTONDOWN дает EvLButtonDown, WM_PAINT - EvPaint, WM_RBUTTONDOWN - EvRButtonDown.
Для объявления в классе таблицы откликов используется макрос DECLARE_RESPONSE_TABLE, требующий в качестве единственного параметра имя класса, для которого объявляется таблица. Сама таблица определяется за пределами класса, как правило, сразу за его объявлением:
DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow) EV_WM_LBUTTONDOWN, END_RESPONSE_TABLE;
Таблица начинается с макроса DEFINE_RESPONSE_TABLE. За именем макроса должно следовать число непосредственных базовых классов, производным от которых является данный класс (в нашем случае один базовый класс - TFrameWindow). За именем макроса и числом непосредственных базовых классов указывается имя класса, для которого определяется таблица, а также имена непосредственных базовых классов. Заметим, что все наименования в таблице ответов должны заканчиваться запятой - даже последнее.
Определим теперь функцию ответа на сообщение EvLButtonDown():
void TWndw::EvLButtonDown(UINT, TPoint &point)
{
MessageBox("Нажата левая клавиша","Сообщение",MB_OK);
}
После возникновения события в функцию EvLButtonDown() передаются два параметра: виртуальный ключ-флаг, находящийся в поле UINT, и координаты мыши, находящиеся в объекте TPoint. Функция EvLButtonDown() только выдает сообщение о том, что нажата левая клавиша мыши, при помощи функции MessageBox().
Функция MessageBox() служит для отображения стандартного окна сообщений. Общий вид:
int MessageBox(const char far* text, const char far* caption = 0, uint type = MB_OK);
где text - текст сообщения, caption - заголовок окна, type - стиль окна. Этот параметр может быть комбинацией следующих значений (они записываются через знак логического сложения '|'):
Функция MessageBox() возвращает такие значения:
Ниже приведен текст программы, в которой описана функция обработки нажатия левой кнопки мыши в пределах окна пользователя.
#include <owl\applicat.h> #include <owl\framewin.h> //Класс приложения. class TApp : public TApplication { public : TApp() : TApplication() {} void InitMainWindow(); }; //Класс основного окна. class TWndw : public TFrameWindow { public : TWndw (TWindow *parent, const char far *title): TFrameWindow(parent, title) {} protected : void EvLButtonDown(UINT, TPoint &point); DECLARE_RESPONSE_TABLE(TWndw); }; DEFINE_RESPONSE_TABLE1(TWndw, TFrameWindow) EV_WM_LBUTTONDOWN, END_RESPONSE_TABLE; void TWndw::EvLButtonDown(UINT, TPoint &) { MessageBox("Нажата левая кнопка мыши" ,"Сообщение", MB_OK); } void TApp::InitMainWindow() { TFrameWindow *wndw=new TWndw (0, "Окно"); SetMainWindow (wndw); } int OwlMain(int, char * [ ]) { return TApp().Run(); }
Когда вы запустите эту программу, на экране появится окно. Находясь в окне, нажмите левую кнопку мыши. Появится окно сообщений, сообщающее вам, что нажата левая кнопка мыши. На рисунке 1 показана программа в работе.
Рис.1. Результат работы приложения
На следующем шаге мы рассмотрим задание атрибутов окна.