Пользовательские события

При работе с операционной системой пользователь выполняет определенные действия, например, щелкает на кнопке внутри диалогового окна, двигает указатель мыши, нажимает клавишу на клавиатуре и т. д. В ответ на эти события система посылает сигналы, которые могут быть обработаны специальными методами. Иными словами, сигналы — это своего рода извещения системы о том, что пользователь выполнил какое-либо действие или в самой системе возникло некоторое условие. Обработку внешних событий мы рассмотрим в последующих главах, а в этом разделе изучим возможность генерации собственных сигналов и способы обработки их в программе.

В классе, который может генерировать сигнал, следует добавить инструкцию Event. Формат инструкции:

[Public] Event <Имя сигнала>([<Параметры>])

Пример инструкции для сигнала MySignal, принимающего один параметр:

Public Event MySignal(n As Integer)

Сгенерировать сигнал позволяет инструкция RaiseEvent. Формат инструкции:

RaiseEvent <Имя сигнала>([<Параметры>])

Если генерируемый сигнал не содержит параметров, то круглые скобки не указываются. Пример генерации сигнала MySignal с передачей целочисленного параметра и без параметра:

RaiseEvent MySignal(10)
RaiseEvent MySignal

В классе, который обрабатывает событие, необходимо объявить поле с указанием ключевого слова WithEvents и типом класса, генерирующего сигнал. Пример:

Private WithEvents we As MyEvent

Имя переменной становится префиксом для методов обработки сигналов из этого класса. Например, метод, который будет обработчиком сигнала MySignal, должен иметь название we_MySignal и следующий формат:

Private Sub we_MySignal(n As Integer)

End Sub

Обратите внимание на то, что поле с ключевым словом WithEvents может быть указано только в объектном модуле, например, в модулях класса, формы, листа или книги. В пользовательском модуле объявлять такое поле нельзя. После объявления поля, его название добавляется в левый раскрывающийся список в окне модуля. Если выбрать этот пункт, то в правом раскрывающемся списке будут доступные методы-обработчики сигналов.

В качестве примера создадим два класса:

Листинг 10.7. Класс MyEvent

Private count_ As Integer

Public Event MySignal(n As Integer)

Private Sub Class_Initialize()
   count_ = 1
End Sub

Public Sub StartTimer(Count As Integer, Pause As Integer)
   Do While count_ <= Count
      Sleep Pause
      RaiseEvent MySignal(count_)
      count_ = count_ + 1
   Loop
End Sub

Private Sub Sleep(Pause As Integer)
   Dim Start
   Start = Timer
   Do While Timer < Start + Pause
      DoEvents
   Loop
End Sub

Листинг 10.8. Класс MyClass

Private WithEvents we As MyEvent

Private Sub Class_Initialize()
   Set we = New MyEvent
End Sub

Public Sub StartTimer(Count As Integer, Pause As Integer)
   we.StartTimer Count, Pause
End Sub

Private Sub we_MySignal(n As Integer)
   Debug.Print "Событие "; n
End Sub

Исходный код процедуры, предназначенной для запуска событийного цикла, приведен в листинге 10.9. Данная процедура должна находиться в пользовательском модуле, например, в модуле Module1.

Листинг 10.9. Процедура запуска событийного цикла

Sub Тест()       ' Запускаем эту процедуру
   Dim C As New MyClass
   Debug.Print "Начало"
   C.StartTimer Count:=5, Pause:=5
   Debug.Print "Конец"
End Sub

Внутри процедуры Тест() мы создаем экземпляр класса MyClass и вызываем метод StartTimer() для запуска событийного цикла. В метод StartTimer() передается количество сигналов и время задержки между сигналами в секундах. Таким образом, пять раз через пять секунд будет генерироваться сигнал MySignal. При возникновении события вызывается метод we_MySignal() внутри которого мы выводим сообщение и порядковый номер сигнала.

Предыдущая статья Все статьи Следующая статья