Системы, управляемые событиями
Все сообщения о событиях помещаются в очередь в порядке их возникновения.
В системе существует понятие обработчика событий. Обработчик событий Представляет собой объект, т. е. структуру данных, с которой связано несколько подпрограмм – методов. Один из методов вызывается при поступлении сообщения. Обычно он также называется обработчиком событий. Некоторые системы предлагают объектам-обработчикам предоставлять различные методы для обработки различных событий – например, метод onClick будет вызываться, когда придет событие, сигнализирующее о том что кнопка мыши была нажата и отпущена, когда курсор находился над областью, занимаемой объектом на экране.
Рассмотрим объект графического интерфейса, например меню. При нажатии на кнопку мыши в области этого меню вызывается обработчик события Он разбирается, какой из пунктов меню был выбран, и посылает соответствующее командное сообщение объекту, с которым ассоциировано меню Этот объект, в свою очередь, может послать командные сообщения каким-то другим объектам. Например, если была выбрана команда File/Open, меню передаст обработчику основного окна приложения сообщение FILEOPEN, а тот, в свою очередь, может передать команду Open объекту, отвечающему за отрисовку и обработку файлового диалога.
Таким образом, вместо последовательно исполняющейся программы, время от времени вызывающей систему для исполнения той или иной функции, мы получаем набор обработчиков, вызываемых системой в соответствии с желаниями пользователя. Каждый отдельный обработчик представляет собой конечный автомат, иногда даже вырожденный, не имеющий переменной состояния. Код обработчика и по реализации обычно похож на конечный автомат, и состоит из большого оператора switch, выбирающего различные действия в зависимости от типа пришедшего сообщения (пример 7.8).
Пример 7.8. Обработчик оконных событий в OS/2 Presentation Manager.
/* фрагмент примера из поставки IBM Visual Age for C++ 3.0. * Обработчик событий меню предоставляется системой, * а обработку командных событий, порождаемых меню, * вынужден брать на себя разработчик приложения. */ / ° ° ° ° ° ° ° ° ° ° ° °**** Copyright (С) 1992 IBM Corporation ОТКАЗ ОТ ГАРАНТИЙ. Следующий код представляет собой пример кода созданный IBM Corporation. Этот пример кода не является частью ни одного стандарта или продукта IBM и предоставляется вам с единственной целью – помочь в разработке ваших приложений. Код предоставляется "КАК ЕСТЬ", без каких-либо гарантий. IBM не несет ответственности за какие бы то ни было повреждения, возникшие в результате использования вами этого кода, даже если она и могла предполагать возможность таких повреждений. / ° ° ° ° ° ° ° ° ° ° ° °**** * Имя: MainWndProc * Описание: Оконная процедура главного окна клиента. * * Концепции: Обрабатывает сообщения, посылаемые главному окну клиента. Эта процедура обрабатывает основные сообщения, которые должны обрабатывать все клиентские окна, и передает все остальные [функции] UserWndProc, в которой разработчик может обработать любые другие сообщения. * API: He используются * Параметры: hwnd – Идентификатор окна, которому адресовано сообщение * msg – Тип сообщения * mpl – Первый параметр сообщения * тр2 – Второй параметр сообщения. * Возвращаемое значение: определяется типом сообщения */ ° ° ° ° ° ° ° ° ° ° ° °**** MRESULT EXPENTRY MainWndProc(HWND hwnd, USHORT msg, MPARAM mpl, MPARAM mp2) { switch(msg) { case WM_CREATE: return(InitMainWindow(hwnd, mpl, mp2)}; break; case WM_PAINT: << MainPaint(hwnd); break; case WM_COMMAND: MainCommand(mpl, .mp2); break; case WM_INITMENU: Ini tMenu(mpl, mp2); break; case HM_QUERY_KEYS_HELP: return (MRESULT)PANEL_HELPKEYS;/* Вернуть Id панели подсказки ' break; /* * Все необработанные сообщения передаются * пользовательской процедуре окна. * Она отвечает за передачу всех необработанных * сообщений функции WinDefWindowProc(); */ default: return(UserWndProc(hwnd, msg, mpl, mp2)); break; return (MRESULT)O; /* Все оконные процедуры должны по умолчанию возвращать 0 */ } /* Конец MainWndProc() */ / ° ° ° ° ° ° ° ° ° ° ° °**** * Имя: MainCommand * Назначение: Главная процедура окна, обрабатывающая WM_COMMAND * * Концепции: Процедура вызывается, когда сообщение WM_COMMAND * отправляется главному окну. Оператор switch * переключается в зависимости от id меню, которое * породило сообщение и предпринимает действия, * соответствующие этому пункту меню. Все id меню, * не являющиеся частью стандартного набора команд, * передаются пользовательской процедуре обработки * WM_COMMAND. * API: WinPostMsg * * Параметры: mp1 – Первый параметр сообщения тр2 – Второй параметр сообщения * * Возвращает: VOID * \ ° °***+ ° ° ° ° ° ° ° ° ° °^ VOID MainCommand(MPARAM mpl, MPARAM mp2) switch(SHORT1FROMMP(mpl)) I case IDM_EXIT: WinPostMsg(hwndMain, WM_QUIT, NULL, NULL break; case IDM__FILENEW: FileNew(mp2); break; case IDM_FILEOPEN: FileOpen(mp2); break; case IDM_FILESAVE: FileSave(mp2); break; case IDM_FILESAVEAS: FileSaveAs(mp2); break; case IDM_EDITUNDO: EditUndo(mp2); break; case IDM_EDITCUT: EditCut(mp2); break; case IDM_EDITCOPY: EditCopy(mp2); break; case IDM_EDITPASTE: EditPaste(mp2); break; case IDM_EDITCLEAR: EditClear(mp2); break; case IDM_HELPUSINGHELP: HelpUsingHelp(mp2); break; case IDM_HELPGENERAL: HelpGeneral(mp2); break; case IDM_HELPKEYS: HelpKeys(mp2); break; case IDM_HELPINDEX: Helplndex(mp2); break; case IDM_HELPPRODINFO: HelpProdInfo(mp2); break; /* * Здесь вызывается пользовательская процедура * обработки команд, чтобы обработать те id', * которые еще не были обработаны. */ default: UserCammand(mpl, mp2); break;) } /* MainCommand() */