Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Void callback timerproc(hwnd hwnd, _uint Imsg, _uint itimerid, dword dwtime)




Работа с таймером. Функции создания и удаления таймеров. Синхронные сообщения таймера.

Можно присоединить таймер к своей программе при помощи вызова функции SetTimer. Функция SetTimer содержит интервал в пределах (теоретически) от 1 до 4 294 967 295 миллисекунд, что составляет около 50 дней. Это значение определяет темп, с которым Windows посылает вашей программе сообщения WM_TIMER

WM_TIMER. После вызова функции KillTimer программа никогда не получит случайного сообщения WM_TIMER.

В программах, сделанных для Windows, так не делается. Windows сама обрабатывает аппаратные прерывания и приложения их не получают. Для каждой программы, где в данный момент установлен таймер, Windows обрабатывает таймерное прерывание путем уменьшения на 1 значения счетчика, изначально переданного вызовом функции SetTimer. Когда это значение становится равным 0, Windows помещает сообщение WM_TIMER в очередь сообщений соответствующего приложения и восстанавливает начальное значение счетчика.

Поскольку приложения Windows получают сообщения WM_TIMER из обычной очереди сообщений, то не нужно беспокоится о том, что рограмма во время работы будет "прервана" внезапным сообщением WM_TIMER. В этом смысле таймер похож на клавиатуру и мышь: драйвер обрабатывает асинхронные аппаратные прерывания, а Windows преобразует эти прерывания в регулярные, структурированные, последовательные сообщения.

Таймер в Windows имеет ту же самую разрешающую способность 54.925 миллисекунды, что и встроенный таймер PC. Отсюда следуют два важных вывода:

Приложение Windows при использовании простого таймера не сможет получать сообщения WM_TIMER в темпе, превышающем 18,2 раза в секунду.

Временной интервал, который задается при вызове функции SetTimer всегда округляется вниз до целогочисла кратного частоте срабатываний таймера. Например, интервал в 1000 миллисекунд, разделенный на 54.925 миллисекунды равен 18.207 срабатываниям таймера, которые округляются вниз до 18 срабатываний, что фактически составляет интервал в 989, а не 1000 миллисекунд. Для интервалов, меньших 55 миллисекунд, каждое срабатывание таймера генерирует одно сообщение WM_TIMER.

Аппаратные прерывания таймера так же как и клавиатуры и мыши иногда называется асинхронным прерыванием, поскольку оно происходит случайно по отношению к прерываемой программе. (Фактически, термин "асинхронные" не совсем точен, поскольку прерывания случаются через одинаковые промежутки времени. Но по отношению к другим процессам прерывания остаются асинхронными.)

Хотя Windows тоже обрабатывает асинхронные таймерные прерывания, сообщения WM_TIMER, которыеWindows посылает приложению, не являются асинхронными. Сообщения Windows ставятся в обычную очередьсообщений и обрабатываются как все остальные сообщения. Сообщения от таймера имеют низкий пріоритет, как и WM_PAINT. Если в очереди несколько сообщений WM_ TIMER, то Windows объединяет их в одно сообщение.

Использование таймера: три способа

1. SetTimer(hwnd, 1, iMsecInterval, NULL);

Первый параметр — это описатель того окна, чья оконная процедура будет получать сообщения WM_TIMER. Вторым параметром является идентификатор таймера, значение которого должно быть отличным от нуля. В этом примере он произвольно установлен в 1. Третий параметр — это 32-разрядное беззнаковое целое, которое задает интервал в миллисекундах. Значение 60000 задает генерацию сообщений WM_TIMER один раз в минуту.

Возможно в любое время остановить поток сообщений WM_TIMER (даже во время обработки сообщения WM_TIMER), вызвав функцию:

KillTimer(hwnd, 1);

Вторым параметром здесь является тот же идентификатор таймера, который использовался при вызове функции SetTimer. Вы должны перед завершением вашей программы в ответ на сообщение WM_DESTROY уничтожить все активные таймеры.

Когда ваша оконная процедура получает сообщение WM_TIMER, значение wParam равно значению идентификатора таймера (который равен 1 в приведенном примере), а lParam равно 0. Если вам нужно болем одного таймера, используйте для каждого таймера свой идентификатор.

2. При первом способе установки таймера сообщения WM_TIMER посылаются в обычную оконную процедуру. С помощью второго способа вы можете заставить Windows пересылать сообщение таймера другой функции из вашей программы.

Функция, которая будет получать эти таймерные сообщения, называется функцией "обратного вызова" (call-back). Это функция вашей программы, которую вызывает Windows. Вы сообщаете Windows адрес этой функции, а позже Windows вызывает ее.

Пример

Назовем функцию обратного вызова TimerProc. (Вы можете дать ей любое имя.) Она будет брабатывать только сообщения WM_TIMER.

VOID CALLBACK TimerProc(HWND hwnd, _UINT iMsg, _UINT iTimerID, DWORD dwTime)

{

[обработка сообщений WM_TIMER]

}

Входной параметр hwnd — это описатель окна, задаваемый при вызове функции SetTimer. Windows будет посылать функции TimerProc только сообщения WM_TIMER, следовательно параметр iMsg всегда будет равен WM_TIMER. Значение iTimerID — это идентификатор таймера, а значение dwTime — системное время.

При использовании функции обратного вызова для обработки сообщений WM_TIMER, четвертый параметр функции SetTimer заменяется адресом функции обратного вызова:

SetTimer(hwnd, iTimerID, iMsecInterval,(TIMERPROC) TimerProc);

3. Третий способ установки таймера напоминает второй, за исключением того, что параметр hwnd функции SetTimer устанавливается в NULL, а второй параметр (обычно идентификатор таймера) игнорируется. Функция возвращает ID таймера:

iTimerID = SetTimer(NULL, 0, wMsecInterval,(TIMERPROC) TimerProc);

Возвращаемое функцией SetTimer значение iTimerID будет равно NULL, если таймер недоступен.

Первый параметр функции KillTimer (обычно описатель окна) также должен быть равен NULL. Идентификатор таймера должен быть равен значению, возвращаемому функцией SetTimer.

KillTimer(NULL, iTimerID);

Параметр hwnd, передаваемый в TimerProc, также должен быть равен NULL.

Такой метод установки таймера используется редко. Он удобен, если в программе в разное время делается много вызовов функции SetTimer, и при этом не запоминаются те таймерне идентификаторы, которые уже использовались.

Что написать о синхронних сообщениях тамера не знаю. Может подойдет то, что выделено жырным курсивом? И вообще. Жирным шрифтом в 43 вопросе выделил то, что я бы реально аписал в билете!

Void WINAPI GetLocalTime(

_Out_ LPSYSTEMTIME lpSystemTime

); - извлекает текущее дату и время в структуру:

typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds;} SYSTEMTIME, *PSYSTEMTIME;BOOL WINAPI SetSystemTime(_In_ const SYSTEMTIME *lpSystemTime); - устанавливает дату и время из структуры _SYSTEMTIME.

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...