На этом шаге мы рассмотрим организацию обработки сообщений Windows.
Windows-программы управляются событиями. Любое действие со стороны пользователя
генерирует событие, которое программа получает в виде сообщения Windows. Существует более 100 различных сообщений Windows.
Каждое из них представлено стандартной константой. В таблице 1 представлены некоторые наиболее распространенные сообщения 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 - стиль окна. Этот параметр может быть комбинацией следующих значений
(они записываются через знак логического сложения '|'):
- MB_ABORTRETRYIGNORE - в окно вставляются кнопки Прервать (Abort), Повторить (Retry), Пропустить (Ignore);
- MB_APPLMODAL - пользователь должен закрыть это окно перед тем, как продолжить работу с окном, его породившим; однако он может переходить в другие окна и работать с ними;
- MB_DEFBUTTON1 - кнопкой по умолчанию является первая кнопка;
- MB_DEFBUTTON2 - кнопкой по умолчанию является вторая кнопка;
- MB_DEFBUTTON3 - кнопкой по умолчанию является третья кнопка;
- MB_ICONASTERISK - вставляется пиктограмма
;
- MB_ICONEXCLAMATION - вставляется пиктограмма
;
- MB_ICONHAND - вставляется пиктограмма
;
- MB_ICONINFORMATION - то же, что и MB_ICONASTERISK;
- MB_ICONQUESTION - вставляется пиктограмма
;
- MB_ICONSTOP - то же, что и MB_ICONHAND;
- MB_OK - в окно вставляется кнопка OK;
- MB_OKCANCEL - в окно вставляются кнопки OK и Отмена (Cancel);
- MB_RETRYCANCEL - в окно вставляются кнопки Повторить (Retry) и Отмена (Cancel);
- MB_SYSTEMMODAL - все программы приостанавливают свою работу, пока пользователь не закроет это окно;
- MB_TASKMODAL - приостанавливается работа во всех окнах данной программы до тех пор, пока пользователь не закроет это окно;
- MB_YESNO - в окно вставляются кнопки Да (Yes) и Нет (No);
- MB_YESNOCANCEL - в окно вставляются кнопки Да (Yes), Нет (No), Отмена (Cancel).
Функция MessageBox() возвращает такие значения:
- IDABORT - была нажата кнопка Abort;
- IDCANCEL - была нажата кнопка Cancel;
- IDIGNORE - была нажата кнопка Ignore;
- IDNO - была нажата кнопка No;
- IDOK - была нажата кнопка OK;
- IDRETRY - была нажата кнопка Retry;
- IDYES - была нажата кнопка Yes.
Ниже приведен текст программы, в которой описана функция обработки нажатия левой кнопки мыши в пределах окна пользователя.
#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. Результат работы приложения
На следующем шаге мы рассмотрим задание атрибутов окна.