Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АОПИ. Старое / АОПИ. Глава 2. Конспекты (02_04_19).rtf
Скачиваний:
65
Добавлен:
10.09.2019
Размер:
363.46 Кб
Скачать

Функция открытия объекта ядра «ожидаемый таймер»

BOOL OpenWaitableTimer(

IN DWORD dwDesiredAccess,

IN BOOL bInheritHandle,

IN LPCWSTR lpTimerName

);

Параметры и описание:

(1) dwDesiredAccess — определяет доступ к объекту. 3 варианта: TIMER_ALL_ACCESS (позволяет выполнять все действия по отношению к объекту таймера), TIMER_MODIFY_STATE (поток может использовать только функции SetWaitableTimer и CancelWaitableTimer), SYNCHRONIZE (в потоке можно использовать события функций ожидания).

(2) bInheritHandle — определяет наследование. TRUE — дочерние процессы наследуют дескриптор. FALSE — не наследуют.

(3) lpTimerName — определяет имя таймера.

Возвращаемое значение.

Если функция завершилась успешно, она возвращает TRUE, в противном случае — FALSE.

Отменить таймер можно двумя способами:

1. Функцией CancelWaitableTimer().

2. Функцией SetWaitableTimer().

Пример 1.

Абсолютный таймер, который срабатывает 23 февраля 2019 г. в 20:00, а затем каждую минуту.

#include <iostream>

#include <windows.h>

using namespace std;

void CALLBACK SpecFunc(void *lpArg, unsigned long dwTimerLowValue, unsigned long dwTimerHighValue) {

cout << "Time!\n"; /// Выводим сообщение

MessageBeep(0); /// Свистим

}

int main() {

HANDLE hColTimer; /// Создаем дескриптор объекта

SYSTEMTIME ColTime; /// Создаем структуру «дата и время»

FILETIME ftLocal_ColTime, ftUTC_ColTime;

/// Структура FILETIME содержит 64-разрядное значение (два поля типа DWORD — low и high) — число интервалов в 100 наносекунд с 1 января 1601 года (UTC).

LARGE_INTEGER liUTC_ColTime; /// 64-битное значение

bool bSuccess;

hColTimer = CreateWaitableTimer(NULL, FALSE, NULL); /// Создаем

if (hColTimer != NULL) { /// Если успешно

ColTime.wYear = 2019; /// Год — 2019

ColTime.wMonth = 2; /// Месяц — Февраль

ColTime.wDayOfWeek = 0; /// День недели — неважен

ColTime.wDay = 23; /// День месяца — 23

ColTime.wHour = 20; /// Час — 20

ColTime.wMinute = 0; /// Минуты — 0

ColTime.wSecond = 0; /// Секунды — 0

ColTime.wMilliseconds = 0; /// Миллисекунды — 0

/// Преобразуем системное время в формат времени файла. Системное время основано на всемирном координированном времени (UTC).

SystemTimeToFileTime(&ColTime, &ftLocal_ColTime);

/// Преобразуем время локального файла в время файла на основе всемирного координированного времени (UTC).

LocalFileTimeToFileTime(&ftLocal_ColTime, &ftUTC_ColTime);

liUTC_ColTime.LowPart = ftUTC_ColTime.dwLowDateTime;

liUTC_ColTime.HighPart = ftUTC_ColTime.dwHighDateTime;

bSuccess = SetWaitableTimer(hColTimer, &liUTC_ColTime, 60000, &SpecFunc, NULL, FALSE); /// Активируем таймер

/// 60000 — 60 секунд, SpecFunc — наша функция

If (bSuccess) /// Если успешно, то

/// 5 раз подряд с интервалом в 60 секунд вызываем функцию SpecFunc

for (int MyValue = 1; MyValue <= 5; MyValue += 1)

SleepEx(INFINITE, TRUE); /// Обязательно так

else /// Если ошибка, то

printf("SetWaitableTimer failed with error %d\n", GetLastError());

}

else /// Если ошибка, то

printf("CreateWaitableTimer failed with error %d\n", GetLastError());

CloseHandle(hColTimer); /// Обязательно закрываем дескриптор

cin.get(); cin.get(); /// Ввод символов — пауза перед выходом

return 0;

}

Пример 2.

Относительный таймер, который срабатывает один раз спустя 10 секунд после вызова. Далее ожидается ввод пользователя.

#include <iostream>

#include <windows.h>

using namespace std;

void CALLBACK SpecFunc(void *lpArg, unsigned long dwTimerLowValue, unsigned long dwTimerHighValue) {

cout << "Time!\n"; /// Выводим сообщение

MessageBeep(0); /// Свистим

}

int main() {

HANDLE hColTimer; /// Создаем дескриптор объекта

const unsigned long long quantum = 10 * 1000 * 1000; /// 1 квант

LARGE_INTEGER liUTC_ColTime;

liUTC_ColTime.QuadPart = -10 * quantum; /// минус означает относительное время

bool bSuccess;

hColTimer = CreateWaitableTimer(NULL, TRUE, NULL);

/// Создаем

if (hColTimer != NULL) { /// Если успешно

bSuccess = SetWaitableTimer(hColTimer, &liUTC_ColTime, 0, &SpecFunc, NULL, FALSE); /// Активируем таймер

/// SpecFunc — наша функция