Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> будильник на API 
:(
    Опции темы
Dmitry_177
Дата 20.10.2006, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



Хочу сделать будильник на API, используя функции CreateWaitableTimer и SystemTimeToFileTime. Т.к. в них нельзя задать определенное время, например в 18:00 чтобы прозвенел, нужно при установке таймера посчитать разницу между 18:00 и системным временем, и поставить этот интервал, чтобы через такой момент времени сработал будильник... Помогите пожалуйста с реализацией

Код

const
 HOUR = 18;

var
 hTimer: THandle;
 sysTime: TSystemTime;
...

hTimer := CreateWaitableTimer(nil, false, nil);
GetLocalTime(sysTime);   // получили системное время
HOUR - sysTime.wHour;   // как получить разницу? Подскажите пожалуйста...

SetWaitableTimer(hTimer, ..., 0, nil, nil, false);

PM MAIL   Вверх
Romikgy
Дата 20.10.2006, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Dmitry_177 @  20.10.2006,  10:27 Найти цитируемый пост)
них нельзя задать определенное время

почему?
Код

BOOL SetWaitableTimer(

    HANDLE hTimer,    // handle to a timer object
    const LARGE_INTEGER *pDueTime,    // when timer will become signaled
    LONG lPeriod,    // periodic timer interval
    PTIMERAPCROUTINE pfnCompletionRoutine,    // pointer to the completion routine
    LPVOID lpArgToCompletionRoutine,    // data passed to the completion routine
    BOOL fResume    // flag for resume state
   );    
 

Parameters

hTimer

Identifies the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle.

pDueTime

Specifies when the state of the timer is to be set to signaled, in 100 nanosecond intervals. 
Use the format described by the FILETIME structure.[U] Positive values indicate absolute time. 
Negative values indicate relative time. [/U]The actual timer accuracy depends on the capability of 
your hardware.




--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Snowy
Дата 20.10.2006, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



Цитата(Dmitry_177 @  20.10.2006,  11:27 Найти цитируемый пост)
Т.к. в них нельзя задать определенное время, например в 18:00
Не "нельзя", а нужно!
Там задаётся время срабатывания, а период - для повтора после этого времени.
PM MAIL   Вверх
Dmitry_177
Дата 20.10.2006, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



а вот так нельзя сделать?
Код

var
 hTimer: THandle;
 sysTime: TSystemTime;
begin
hTimer := CreateWaitableTimer(nil, false, nil);
sysTime.wHour := 18;
sysTime.wMinute := 0;
sysTime.wSecond := 0;
SystemTimeToFileTime(sysTime, fTime);
SetWaitableTimer(hTimer, fTime, 0, nil, nil, false);
end;


только если честно не очень понятно как он должен сработать? толи callback функция должна быть, толи поток создать толи еще что?
PM MAIL   Вверх
Romikgy
Дата 20.10.2006, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Romikgy @  20.10.2006,  12:38 Найти цитируемый пост)
Positive values indicate absolute time. 
Negative values indicate relative time.

имхо если положитнльно значит время абсалютно , если открицательно значит относительно
Цитата(Dmitry_177 @  20.10.2006,  14:10 Найти цитируемый пост)
толи callback функция должна быть

и имхо надо задать не только час срабатывания но и день месяц и т.д.


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Dmitry_177
Дата 20.10.2006, 23:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



А как мне всетаки узнать в какой момент это сработает?

Цитата(Dmitry_177 @  20.10.2006,  15:10 Найти цитируемый пост)
только если честно не очень понятно как он должен сработать? толи callback функция должна быть, толи поток создать толи еще что?

PM MAIL   Вверх
maxim1000
Дата 20.10.2006, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: нет
Всего: 110



Цитата(Dmitry_177 @  20.10.2006,  14:10 Найти цитируемый пост)
только если честно не очень понятно как он должен сработать? толи callback функция должна быть, толи поток создать толи еще что?

т.к. таймер waitable (т.е. ожидаемый), то его надо ожидать smile
советую посмотреть помощь по WaitForSingleObject и её родственникам


--------------------
qqq
PM WWW   Вверх
Snowy
Дата 21.10.2006, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



Книжку Рихтера в руки 2 раза в день и все вопросы сами отвалятся.
Там расписано всё и очень подробно.
PM MAIL   Вверх
Dmitry_177
Дата 21.10.2006, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



Посмотрите пожалуйста код, правильно ли он реализован? Вроде все работает, но правильно ли я закрываю хендл hTimer, а когда закрывать хендл hThread не знаю... Подскажите пожалуйста...

Код

var
 hTimer: THandle;
 hThread: THandle;
 sysTime: TSystemTime;
 fTime: TFileTime;
 idThread: DWORD;

procedure WaitThread; stdcall;
begin
 WaitForSingleObject(hTimer, INFINITE);
 ShowMessage('Time!!!!!!!');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 hTimer := CreateWaitableTimer(nil, false, nil);
   try
     GetLocalTime(sysTime);
     sysTime.wHour := 18;
     sysTime.wMinute := 0;
     sysTime.wSecond := 0;
     SystemTimeToFileTime(sysTime, fTime);
     LocalFileTimeToFileTime(fTime, fTime);
     SetWaitableTimer(hTimer, TLargeInteger(fTime), 0, nil, nil, false);

     hThread := CreateThread(nil, 0, @WaitThread, nil, 0, idThread);

     ShowMessage('Time installed!');
   finally
     CloseHandle(hTimer);
   end;
end;

PM MAIL   Вверх
maxim1000
Дата 21.10.2006, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: нет
Всего: 110



когда основной поток доходит до CloseHandle, ожидающий поток всё ещё работает (точнее, ожидает)
HANDLE закрывать надо когда его уже никто не использует
в разных случаях могут получаться довольно сложные ситуации, но в данном всё просто: достаточно закрыть его в конце WaitThread


--------------------
qqq
PM WWW   Вверх
Dmitry_177
Дата 22.10.2006, 04:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



А вот так правильно будет? оба хендла (hTimer и hThread) закрываю в функции WaitThread после WaitForSingleObject. А если выключить программу (нажав на крестик) до срабатывания таймера, удалятся эти хендлы или их лучше в событии разрушения формы их удалять?

Код

var
 hTimer: THandle;
 hThread: THandle;
 idThread: DWORD;

function WaitThread(Param: Pointer): DWORD; stdcall;
begin
 WaitForSingleObject(hTimer, INFINITE);
 CloseHandle(hTimer);    -> Правильно ли тут будет удалять хендл hTimer?
 CloseHandle(hThread);  -> Правильно ли тут будет удалять хендл hThread?
 MessageBox(0, 'Time!!!!!!!', 'Time', MB_OK);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 sysTime: TSystemTime;
 fTime: TFileTime;
begin
 hTimer := CreateWaitableTimer(nil, false, nil);
 GetLocalTime(sysTime);
 sysTime.wHour := 18;
 sysTime.wMinute := 0;
 sysTime.wSecond := 0;
 SystemTimeToFileTime(sysTime, fTime);
 LocalFileTimeToFileTime(fTime, fTime);
 SetWaitableTimer(hTimer, TLargeInteger(fTime), 0, nil, nil, false);

 hThread := CreateThread(nil, 0, @WaitThread, nil, 0, idThread);

 MessageBox(0, 'Time installed!', 'Time', MB_OK);
end;

PM MAIL   Вверх
maxim1000
Дата 22.10.2006, 10:52 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: нет
Всего: 110



Цитата(MSDN)
The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

т.е. (ИМХО) дескриптор потока можно закрывать сразу после CreateThread, если он не нужен
да и вообще, дескриптор нигде больше не будет использоваться, его закрывают
в случае таких объектов, как таймер, событие, к которым доступ производится только по дескрипторам, после удаления всех дескрипторов они удаляются
а поток имеет ещё одного "пользователя" - собственно, сам поток, который выполняется
поэтому даже если все дескрипторы позакрывать, он будет выполняться, пока не закончится его основная функция



--------------------
qqq
PM WWW   Вверх
Dmitry_177
Дата 22.10.2006, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



Спасибо, вы очень добры.. Если будет такая ситуация, ставим мы будильник на 18:00, а время будет уже больше 18:00, часов (19, 20, 21, 22, 23 например).. так вот день в sysTime, будет сегодняшний, а сработать таймер должен завтра, т.к. сегодня 18 часов уже было... Вот как прибавить к дате один день, с учетом того, что если день будет последним в текущем месяце, то 1-ый день будет следующего месяца, так же и с годом, если последний день года, т.е. 31 декабря...
PM MAIL   Вверх
Romikgy
Дата 22.10.2006, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 13
Всего: 146



Цитата(Dmitry_177 @  22.10.2006,  16:16 Найти цитируемый пост)
ставим мы будильник на 18:00, а время будет уже больше 18:00, часов (19, 20, 21, 22, 23 например).

для работы переодически есть параметр
Код

lPeriod
Specifies the period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. 
If lPeriod is greater than zero, the timer is periodic. A periodic timer automatically reactivates 
each time the period elapses, until the timer is canceled using the CancelWaitableTimer 
function or reset using SetWaitableTimer. If lPeriod is less than zero, the function fails.


Цитата(Dmitry_177 @  22.10.2006,  16:16 Найти цитируемый пост)
Вот как прибавить к дате один день,

там время представленно в  in 100 nanosecond intervals т.е. добавь кол-во интервалов в сутках к дате сейчас и получишь слудующий день


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Dmitry_177
Дата 22.10.2006, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



А так правильно будет?

Код

GetLocalTime(sysTime);
if sysTime.wHour > 18 then
 sysTime.wDay := sysTime.wDay + 1;
sysTime.wHour := 18;
sysTime.wMinute := 0;
sysTime.wSecond := 0;

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0794 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.