Сообщения Windows, события и делегаты
Важно понять, что Windows - операционная система с управляемой сообщениями архитектурой. Windows находится в постоянном ожидании того, когда же пользователь подведёт указатель мыши к элементу в прикладном окне приложения и нажмёт на левую клавишу мыши или передвинет ползунок, или нажмёт клавишу клавиатуры и т. д. Windows тотчас генерирует соответствующее сообщение и помещает его в системную очередь сообщений приложения. Каждое сообщение имеет свой идентификатор и с ним может быть связана какая-либо информация (например, координаты указателя мыши в прикладном окне). Имеется более сотни стандартных сообщений Windows.
Для каждого стандартного сообщения (события) есть обработчик сообщения (события) по умолчанию – специальная функция, которая обычно ничего не делает. Но мы можем реализовать свою обработку сообщения, переопределив требуемую функцию–обработчика для этого сообщения.
C# и C++/CLI. Сообщения выполняются в рамках окон, то есть форм, и для связи функций-обработчиков с сообщениями используется механизм событий и делегатов. Посредством делегатов к событиям привязывают требуемые функции-обработчики определённого формата.
Каждая форма или управляющий элемент (который также является формой, но специализированной) имеет фиксированный набор предопределённых событий с предопределёнными делегатами, которые определяют формат функций-обработчиков этих событий.
При желании для простоты можно воспользоваться предопределёнными обработчиками событий. В этом случае не требуется их подписка на события.
Java и J#.Обработка событий основана на делегировании обработчиков с помощью интерфейсов. Вместо делегатов используются предопределённые интерфейсы и включённые в них обработчики.
Итак, реализация обработки событий в языках C# и Java отличаются; она рассмотрена в разделах 9.4.1 и 9.4.2 на примере обработки события от мыши.
9.4.1. Обработка событий мыши на языке C#
Для события MouseDown, возникающего при нажатии на клавишу мыши, используют делегат MouseEventHandler.
Событие определено в классе System.Windows.Forms.Control, из которого порождён класс Form, следующим образом:
public event MouseEventHandler MouseDown;
С событием MouseDown. можно с помощью оператора “+=” связать один или несколько объектов делегата MouseEventHandler события с инкапсулированными в них обработчиками, допустим, обработчик OurMouseDown():
MouseDown += newMouseEventHandler (OurMouseDown);
Разумеется, формат обработчика определяется делегатом MouseEventHandler и должен быть следующим:
voidOurMouseDown (objectsender, MouseEventArgs args);
где
sender - ссылка на объект-источник события,
args - ссылка на объект типа MouseEventArgs, содержащий данные, относящиеся к свершившемуся событию.
Обработчик OurMouseDown() получает аргумент типа MouseEventArgs, содержащий данные, относящиеся к обрабатываемому событию и представленные следующими свойствами класса MouseEventArgs, специфичными для события MouseDown:
- Button, указывающее, какая клавиша нажата;
- Clicks, указывающее, сколько раз была нажата и отпущена клавиша;
- Delta, указывающее, сколько раз было повёрнуто колёсико мыши;
- X, указывающее значение координаты х носика мыши и
- Y, указывающее значение координаты у носика мыши.
Пример 9.4.1 содержит C# программу с событием, происходящим при нажатии на клавишу мыши. При каждом нажатии на клавишу появляется строка на консоли.
Пример 9.4.1. Программа обработки события мыши на C#.
Приложение создаёт прикладное окно и ожидает нажатия клавиши мыши в этом окне (точнее, в области клиента окна). При нажатии на клавишу в консольное окно выдаётся строка с координатами носика курсора мыши.
Рис. 9.4.1. При нажатии на клавишу мыши появилась очередная строка на консоли
Ниже приводятся три варианта реализации этого приложения на языке C#.
///////////////
// C# Вариант 1
using System;
using System.Drawing;
using System.Windows.Forms;
class MainClass : Form // Класс прикладного окна
{
// Использовать предопределённый обработчик OnMouseDown мыши