Основы офисного программирования и язык VBA

       

Построение класса "ВашТаймер"


Поскольку мы уже хорошо знакомы с тем, как строятся классы и как работать с функциями Win32 API, то нам осталось рассказать, как объединить эти две вещи в единое целое. Никаких особых деталей здесь нет. Общая стратегия такова:

  • Необходимо спроектировать интерфейс класса, ориентированный на конечного пользователя. Открытые свойства и методы класса должны позволять пользователю решать все задачи, которые можно решать с помощью скрытых в классе стандартных средств.
  • Встроить в класс стандартные средства, сделав их скрытыми, недоступными для внешнего использования.
  • Реализовать интерфейс класса, используя встроенные средства, возможно расширив их возможности.

Применим эту общую схему для создания класса ВашТаймер. Начнем с проектирования его интерфейса. Естественно, целью класса является предоставление пользователю возможности создавать таймер, посылающий сообщения с заданным интервалом, и удалять его, когда необходимость в нем исчезнет. Пользователь не должен ничего знать о функциях Win32 API, об операторах Declare, преобразовании типов. Кажется естественным с этих позиций в интерфейс класса включить два метода: "СоздатьТаймер" и "УдалитьТаймер" и свойство "ИнтервалТаймера", доступное для чтения и записи. Методы не имеют параметров, что облегчает работу с ними. Чтобы созданный таймер посылал сообщения с заданным интервалом, необходимо предварительно установить подходящее значение свойства, но можно этого и не делать, - в этом случае будет использоваться значение по умолчанию.

Рассматриваемый нами случай упаковки функций Win32 API особый, поскольку одна из этих функций требует вызова Callback функции. Заметьте, функции обратного вызова не должны принадлежать упаковке, - нашему классу. Они не являются стандартными средствами, это функции, создаваемые пользователем. Поэтому они должны находиться вне модуля класса, - в стандартном классе, созданном пользователем, там, где он будет создавать и объекты класса ВашТаймер. Чтобы не возникала соблазна поместить в класс функцию обратного вызова, такая возможность исключается синтаксически.
Обратите, однако, внимание, что созданный класс предъявляет определенные требования к заголовку функции обратного вызова и даже диктует ее имя. Но обо всем по порядку и давайте вначале рассмотрим описание класса ВашТаймер:

Пример 6.12.

(html, txt)

Некоторые комментарии к этому тексту:

  1. О проектировании интерфейса класса мы уже говорили. Его составляют два метода, не имеющие параметров, - СоздатьТаймер и УдалитьТаймер, а также процедуры - свойства Property Get и Property Let ИнтервалТаймера, позволяющие взаимодействовать с закрытым свойством Интервал.
  2. Закрытых свойств и методов больше. Закрытыми являются операторы Declare, описывающие функции Win32 API SetTimer и KillTimer, уже упомянутое свойство Интервал и свойство IdEv, хранящее идентификатор таймера, о котором конечный пользователь может и не знать.
  3. Закрытыми являются конструктор класса по умолчанию и деструктор: Class_Initialize и Class_Terminate. В конструкторе инициализируется свойство Таймер, значение которого устанавливается по умолчанию, равным одной секунде. В деструкторе класса таймер уничтожается, если он не был удален до этого.
  4. При создании таймера устанавливается ссылка на функцию обратного вызова с именем TimerProc. Процедура с таким именем и уже упоминавшимися требованиями к ее заголовку должна быть описана в стандартном модуле класса, созданным конечным пользователем.
  5. В описание класса в качестве комментария вставлена заготовка функции обратного вызова, чтобы облегчить создание этой функции конечному пользователю.




Некоторые комментарии к этому тексту:

  1. О проектировании интерфейса класса мы уже говорили. Его составляют два метода, не имеющие параметров, - СоздатьТаймер и УдалитьТаймер, а также процедуры - свойства Property Get и Property Let ИнтервалТаймера, позволяющие взаимодействовать с закрытым свойством Интервал.
  2. Закрытых свойств и методов больше. Закрытыми являются операторы Declare, описывающие функции Win32 API SetTimer и KillTimer, уже упомянутое свойство Интервал и свойство IdEv, хранящее идентификатор таймера, о котором конечный пользователь может и не знать.
  3. Закрытыми являются конструктор класса по умолчанию и деструктор: Class_Initialize и Class_Terminate. В конструкторе инициализируется свойство Таймер, значение которого устанавливается по умолчанию, равным одной секунде. В деструкторе класса таймер уничтожается, если он не был удален до этого.
  4. При создании таймера устанавливается ссылка на функцию обратного вызова с именем TimerProc. Процедура с таким именем и уже упоминавшимися требованиями к ее заголовку должна быть описана в стандартном модуле класса, созданным конечным пользователем.
  5. В описание класса в качестве комментария вставлена заготовка функции обратного вызова, чтобы облегчить создание этой функции конечному пользователю.



Содержание раздела