Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

2006 г.

WinApi
Лекция из курса «Основы офисного программирования и язык VBA»

Биллиг Владимир Арнольдович
Интернет-Университет Информационных Технологий, INTUIT.ru

Назад Оглавление Вперёд

Функции Win32 API для работы с таймером

Кроме функций перечисления, требующих в процессе своей работы вызов Callback функций, другим известным примером является функция SetTimer, создающая таймер. Во многих приложениях возникает необходимость синхронизировать его работу в соответствии с регулярно поступающими сообщениями от таймера. Общая схема такова: таймер посылает сообщения приложению с заданным интервалом, в ответ приложение выполняет определенную работу, вызывая ту или иную функцию (Callback функцию). Класс таких диспетчерских приложений, регулярно обрабатывающих вновь поступившие заявки, весьма велик. При работе в приложении Access для этих целей введен специальный элемент управления - Timer. В приложениях Word или Excel такого элемента нет, но всегда можно воспользоваться соответствующими функциями Win32 API, чтобы создать один или несколько собственных таймеров и организовать работу приложения, реагирующего на их сообщения. Заметьте, несмотря на то, что физический таймер один, логических таймеров, посылающих приложению свои сообщения, может быть несколько.

Функция SetTimer

Эта функция создает таймер, посылающий сообщения с заданным интервалом. Ее описание, которое можно найти на Platform SDK, имеет вид:

UINT SetTimer(
   HWND hWnd,		// handle to window for timer messages
   UINT nIDEvent,	        // timer identifier
   UINT uElapse,		// time-out value
   TIMERPROC lpTimerFunc	// pointer to timer procedure
);
 

Ее параметры:

  • hwnd - Описатель окна, которому будут посылаться сообщения таймера. В VBA программах таймер не связывается с окном и значение этого параметр задается как NULL.
  • nIDEvent - Задает идентификатор таймера. Его значение игнорируется, когда таймер не связан с окном, что имеет место в рассматриваемом нами случае.
  • uElapse - Задает интервал, с которым таймер будет посылать свои сообщения. Интервал задается в миллисекундах, так что значение 1000 соответствует одной секунде.
  • lpTimerFunc - Указатель на Callback функцию, которая будет вызываться всякий раз, когда обрабатывается сообщение WM_Timer, поступающее от таймера.

Если функция успешно завершает свою работу и создает таймер, то в качестве результата она возвращает уникальный идентификатор этого таймера, идентифицирующий его. Этот идентификатор запоминается и используется для уничтожения таймера при вызове Win32 API функции KillTimer. В случае неуспеха возвращается значение 0.

Заметьте, функция SetTimer только создает таймер. В отличие от функций перечисления вызов Callback функции не происходит в ее теле. Вызов осуществляется более сложным путем. Созданный таймер посылает сообщения с заданным интервалом, сообщения, как обычно, поступают в очередь сообщений и в обработчике сообщения WM_Timer автоматически вызывается функция обратного вызова. Поскольку при обработке сообщений очереди могут происходить разные задержки, то вызываемая функция не всегда будет вызываться с заданным интервалом, - возможны задержки.

Оператор Declare, задающий VBA описание этой функции имеет соответственно вид:

Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, _
   ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Функция обратного вызова TimerProc

Функция TimerProc является Callback функцией, определенной приложением и вызываемой при обработке сообщений, поступающих от таймера. Ее определение имеет вид:

VOID CALLBACK TimerProc(
   HWND hwnd,	// handle of window for timer messages
   UINT uMsg,	// WM_TIMER message
   UINT idEvent,	// timer identifier
   DWORD dwTime	// current system time
);

Ее параметры:

  • hwnd - Описатель окна.
  • uMsg - Указывает WM_Timer сообщение.
  • idEvent - Идентификатор таймера.
  • dwTime - Задает текущее системное время, возвращаемое функцией GetTickCount.

Заметьте, имя TimerProc является лишь держателем места. В конкретной ситуации необходимо будет определить одну или несколько Callback функций с подходящими именами. Поскольку вызов каждой из этих функций производится автоматически, то нет необходимости заботиться о корректной передаче аргументов в момент вызова. Необходимо лишь позаботиться о корректной трансляции приведенного определения, взятого из справочной системы Platform SDK, к виду, воспринимаемому в программах на VBA. Вот как выглядит возможное определение:

Public Sub TimerProc(ByVal HandleW As Long, ByVal msg As Long, _
   ByVal idEvent As Long, ByVal TimeSys As Long)

Обратите внимание, мы транслировали функцию в процедуру, поскольку Callback функция TimerProc не возвращает значения. Все типы данных преобразованы в тип Long, в том числе UINT и DWORD. В данной ситуации нет причин для беспокойства о возможной некорректности передаваемых значений, поскольку их передачу обеспечивает сама система.

Функция 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 таймер удаляется. Кнопки можно нажимать многократно. Все процедуры обработки помещены в модуль Таймер. Вот его текст:

Пример 6: html, txt

Комментариев, приведенных в тексте, полагаем достаточно для понимания всех деталей. Приведем еще результаты печати, периодически появляющиеся в окне отладки. Следует только сказать, что дважды были поочередно нажаты кнопки Start и Finish:

Создан Таймер: Идентификатор =32578 
Hi					1 
Hi					2 
Hi					3 
Удален Таймер: Идентификатор =32578 
Создан Таймер: Идентификатор =32573 
Hi					1 
Hi					2 
Hi					3 
Hi					4 
Удален Таймер: Идентификатор =32573 

Заметьте, в нашей реализации кнопки нужно нажимать поочередно, поскольку хранится только последнее значение идентификатора таймера, так что если подряд нажать несколько раз кнопку Start, то будет создано несколько таймеров, но при последующих нескольких нажатиях кнопки Finish будет удален только один, последний созданный таймер и печать в окне отладки будет продолжаться.

Назад Оглавление Вперёд

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в 21 локации

От 104 рублей в месяц

Безлимитный трафик. Защита от ДДоС.

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...