Windows для профессионалов


Ожидаемые таймеры - часть 2


// таймер должен сработать в первый раз 1 января 2002 года в 1:00 PM
// но местному времени

st.wYear = 2002; // год
st.wMonth = 1; // январь
st.wOayOfWeek = 0; // игнорируется
st.wDay = 1, // первое число месяца
st.wHour = 13; // 1 PM
st.wMinute = 0; // 0 минут
st.wSecond = 0, // 0 секунд
st.wMilliseconds = 0; // 0 миллисекунд

SystemTimeToFileTime(&st, &ftLocal);

// преобразуем местное время в UTC-время
LocalFileTimeToFilelime(&ttLocal, &ftUTC);

// преобразуем FILETIME в LARGE_INTEGER из-за различий в выравнивании данных
liUTC.LowPart = ftUTC dwLowDateTime;
liUTC.HighPart = ftUTC dwHighDateTime;

// устанавливаем таймер
SetWaitablcTimer(hTimer, &liUTC, 6 * 60 * 60 * 1000, NULL, NULL, FALSE);

...

Этот фрагмент кода сначала инициализирует структуру SYSTEMTIME, определяя время первого срабатывания таймера (его перехода в свободное состояние). Я уста новил это время как местное. Второй параметр представляется как const LARGE_IN TEGER * и поэтому нс позволяет напрямую использовать структуру SYSTEMTIME. Од нако двоичные форматы структур FILETIME и LARGE_INTEGER идентичны: обе содер жат по два 32-битных значения. Таким образом, мы можем преобразовать структуру SYSTEMTIME в FILETIME. Другая проблема заключается в том, что функция SetWaitable Timer ждет передачи времени в формате UTC (Coordinated Universal Time). Нужное преобразование легко исуществляется вызовом LocalFileTimeToFileTime

Поскольку двоичные форматы структур FILETIMF, и IARGE_INTEGER идентичны, у Вас может появиться искушение передать в SetWaitableTimer адрес структуры FILETIME напрямую;

// устанавливаем таймер
SetWaitableTimer(hTirner, (PLARGE^INTEGER) &ftUTC, 6 * 60 * 60 * 1000, NULL, NULL, FALSE);

В сущности, разбираясь с этой функцией, я так и поступил. По это большая ошиб ка! Хотя двоичные форматы структур FILETIME и LARGE_INTEGER совпадают, вырав нивание этих структур осуществляется по-разному. Адрес любой структуры FILETIME должен начинаться на 32-битной границе, а адрес любой структуры IARGE_INTEGER — на 64-битной.


Начало  Назад  Вперед



Книжный магазин