- •Создание динамических структур данных
- •Встроенный динамический класс Collection
- •Создание собственных динамических классов
- •Обертывание коллекции vba
- •Несколько слов об api, Win32, dll
- •Вызов функций и оператор Declare
- •Две кодировки ansi и Unicode
- •Два языка: c и vb. Различия при вызове функций
- •Соответствие между простыми типами данных
- •Структуры языка c и тип, определенный пользователем, в языке vba
- •Об описателях языка c и объектах Windows
- •Void функции языка c
- •Вызов аргументов по ссылке ByRef и по значению ByVal
- •Строковые аргументы при вызове функций Win32 api
- •Примеры работы с Win32 api функциями
- •Работа с окнами
- •Характеристики окружения
- •Вызов функций Win32 api, работающих в Unicode кодировке
- •Обработка ошибок, возникающих при вызове функций Win32 api
- •Функции api и вызов Callback функций
- •Функции высших порядков и конструкция AddressOf
- •Функции перечисления Win32 api
- •Функция EnumWindows
- •Еще один пример работы с функцией EnumWindows
- •Функции Win32 api для работы с таймером
- •Функция SetTimer
- •Функция обратного вызова TimerProc
- •Функция KillTimer
- •Пример создания, работы и удаления таймера
- •Классы как обертка вызовов функций Win32 api
- •Построение класса "ВашТаймер"
- •Использование класса ВашТаймер
- •Операторы
- •Операторы и строки
- •Оператор комментария
- •Присваивание
- •Оператор Let
- •Оператор lSet
- •Оператор rSet
- •Оператор Set
- •Управляющие операторы
- •Условный оператор If Then Else End If
- •Оператор выбора Select Case
- •Цикл For Next
- •Цикл Do...Loop
- •Цикл While...Wend
- •Цикл For Each...Next
- •Работа с каталогами, папками и файлами
- •Изменение текущего диска: оператор ChDrive
- •Изменение текущего каталога (папки): оператор ChDir
- •Создание каталога (папки): оператор MkDir
- •Переименование каталогов (папок) и файлов: оператор Name
- •Удаление каталога (папки): оператор RmDir
- •Установка атрибутов файла: оператор SetAttr
- •Копирование файлов: оператор FileCopy
- •Удаление файлов: оператор Kill
- •Прочие операторы
- •Операции с одним объектом. Оператор With
- •Операции
- •Работа с числовыми данными
- •Математические функции
- •Работа со строками
- •Сравнение строк
- •Сравнение с образцом
- •Основные операции над строками
- •Новые функции для работы со строками
- •Функция InStrRev - поиск последнего вхождения подстроки
- •Функция Replace - замена всех вхождений подстроки
- •Удаление подстроки
- •Разбор строки. Функции Split, Join и Filter
- •Преобразование строки в массив. Функция Split
- •Сборка элементов массива в строку. Функция Join
- •Фильтрация элементов массива. Функция Filter
- •Несколько модификаций встроенных функций
- •Замена, основанная на шаблоне. Функция WildReplace
- •Замена разных символов строки. Функция CharSetReplace
- •Фильтрация, основанная на шаблоне. Функция WildFilter
- •Разбор строки, допускающей разные разделители ее элементов. Функция WildSplit
- •Работа с датами и временем
- •Присваивание значений
- •Встроенные функции для работы с датами
- •Определение текущей даты или времени.
- •Вычисления над датами
- •Функция Timer и хронометраж вычислений
- •Некоторые встроенные функции
- •Функции проверки типов данных
- •Преобразование типов данных
- •Форматирование данных. Функции группы Format
- •Функция Format.
- •Другие функции форматирования
- •Описание и создание процедур
- •Классификация процедур
- •Синтаксис процедур и функций
- •Функции с побочным эффектом
- •Создание процедуры
- •Создание процедур обработки событий
- •Вызовы процедур и функций Вызовы процедур Sub
- •Вызовы функций
- •Использование именованных аргументов
- •Аргументы, являющиеся массивами
- •Конструкция ParamArray
- •Задача о медиане
- •Пользовательские функции, принимающие сложный объект Range
- •Рекурсивные процедуры
- •Деревья поиска
- •Класс TreeNode
- •Класс BinTree
- •Работа со словарем
- •Отладка
- •Написание надежных программ
- •Искусство отладки
- •Средства отладки
- •Панель отладки и команды меню
- •Окна наблюдения
- •Окно локальных переменных - Locals
- •Окно проверки - Immediate
- •Окно контрольных выражений - Watch
Функция KillTimer
Поскольку одновременно могут существовать несколько таймеров, также как и при необходимости заменить один таймер другим, - по разным причинам возникает необходимость удаления уже не нужных таймеров. Для этого и используется функция Win32 API KillTimer. Вот ее стандартное описание:
BOOL KillTimer(
HWND hWnd, // handle to window that installed timer
UINT nIDEvent, // timer identifier
);
Ее параметры:
-
hwnd - Описатель окна, ассоциированного с таймером, совпадающий по значению с соответствующим параметром функции SetTimer. Напомним, в VBA программах таймер не связывается с окном и значение этого параметр задается как NULL.
-
nIDEvent - Задает идентификатор таймера, который должен быть удален. В нашем случае, когда первый параметр равен NULL, его значение задается идентификатором, возвращенным в качестве результата по окончании работы функции SetTimer.
Если функция успешно завершает свою работу и удаляет таймер, то в качестве результата она возвращает ненулевое значение. В случае неуспеха возвращается значение 0.
Пример создания, работы и удаления таймера
В свое время в книге по языку Visual C++ , демонстрируя работу с таймером и соответствующими функциями Win32 API, мы разработали проект "Жизнь". В этом проекте моделируется известная компьютерная игра, где можно задать начальную конфигурацию "жизни". Затем эта конфигурация начинает жить, изменяя свое состояние по заданным правилам. Изменение состояния происходит в качестве ответной реакции на сообщения таймера. Другим подобным примером, по существу вариацией на эту же тему, является создание экранных заставок. Сейчас мы решили обойтись более простым примером, демонстрирующим суть проблемы, но не имеющим эффектной формы. В нашем тестовом примере есть две командные кнопки Start и Finish. В ответ на нажатие первой кнопки создается таймер, соответствующая ему Callback функция ведет подсчет числа ее вызов и уведомляет об этом, печатая значение счетчика в окне отладки. При нажатии кнопки Finish таймер удаляется. Кнопки можно нажимать многократно. Все процедуры обработки помещены в модуль Таймер. Вот его текст:
'Функции работы с таймером
Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, _
ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
'Глобальная информация
Public Counter As Long 'Счетчик числа вызовов Callback функции
Public IdEv As Long
Public Sub HowManyProc(ByVal HandleW As Long, ByVal msg As Long, _
ByVal idEvent As Long, ByVal TimeSys As Long)
'Функция обратного вызова. Вызывается при обработке сообщения WM_Timer,
'посылаемого таймером, созданным процедурой SetTimer
Counter = Counter + 1
Debug.Print "Hi", Counter
End Sub
Public Sub Start()
'Создает таймер, вызывая Win32 Api функцию SetTimer
Counter = 0
IdEv = SetTimer(0&, 0&, 10000, AddressOf HowManyProc)
If IdEv = 0 Then
MsgBox ("Не удалось создать таймер!")
Else
Debug.Print "Создан Таймер: Идентификатор = ", IdEv
End If
End Sub
Public Sub Finish()
'Удаляет таймер
If IdEv > 0 Then
Call KillTimer(0&, IdEv)
Debug.Print "Удален Таймер: Идентификатор = ", IdEv
IdEv = 0
End If
End Sub
Пример 6.11. (html, txt)
Комментариев, приведенных в тексте, полагаем достаточно для понимания всех деталей. Приведем еще результаты печати, периодически появляющиеся в окне отладки. Следует только сказать, что дважды были поочередно нажаты кнопки Start и Finish:
Создан Таймер: Идентификатор =32578
Hi 1
Hi 2
Hi 3
Удален Таймер: Идентификатор =32578
Создан Таймер: Идентификатор =32573
Hi 1
Hi 2
Hi 3
Hi 4
Удален Таймер: Идентификатор =32573
Заметьте, в нашей реализации кнопки нужно нажимать поочередно, поскольку хранится только последнее значение идентификатора таймера, так что если подряд нажать несколько раз кнопку Start, то будет создано несколько таймеров, но при последующих нескольких нажатиях кнопки Finish будет удален только один, последний созданный таймер и печать в окне отладки будет продолжаться.