![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не срабатывает SetWaitableTimer. [D7, XP]
Б © (2010-04-15 12:18:00)Здрасти!
Почему не срабатывает SetWaitableTimer?
Будильник должен включиться ровно через 1 минуту после запуска.
Var
HTIMER : LongWord;
TimeSys : TSystemTime;
TimeFile: TFileTime;
Procedure TimerAPCProc(lpArgToCompletionRoutine: Pointer; dwTimerLowValue, dwTimerHighValue: DWORD); stdcall;
begin
MessageBox(0, 'Wake Up!', '!', MB_OK or MB_ICONERROR);
End;
Procedure XRunTimer(Hour, Minute: word);
begin
HTIMER:= CreateWaitableTimer(nil, False, nil);
If (HTIMER = 0) then
begin
MessageBox(0, 'No create timer!', '!', MB_OK or MB_ICONERROR);
Exit;
end;
GetLocalTime(TimeSys); // Текущая дата и время.
TimeSys.wMinute:= TimeSys.wMinute + 1; // Должен сработать через 1 минуту.
(*
With TimeSys do
begin
wHour := Hour;
wMinute:= Minute;
end;
*)
Win32Check(SystemTimeToFileTime(TimeSys, TimeFile));
Win32Check(SetWaitableTimer(HTIMER, INT64(TimeFile), 0, @TimerAPCProc, nil, False));
End;
procedure TForm1.FormCreate(Sender: TObject);
begin
XRunTimer(StrToInt(Edit1.Text), StrToInt(Edit2.Text));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseHandle(HTIMER);
end;
Anatoly Podgoretsky (2010-04-16 18:56:00) [21]> Б (16.04.2010 17:48:25) [25]
GetTime убери
Б (2010-04-16 17:48:00) [22]Остался 1 вопрос.
На вход функции запуска будильника принимается одна переменная типа TDateTime.
Как правильно передать ей дату и время?
WakeUp.RunTimer(Now + GetTime); // Для примера текущая дата и время.
Б (2010-04-16 11:23:00) [23]Тем более, с MsgWaitForMultipleObjectsEx
можно сделать поддержку нескольких таймеров и сделать
подобие планировщика задач.
Б (2010-04-16 11:08:00) [24]
> Сергей М. © (16.04.10 10:13) [21]
Если указать не INFINITE, а к примеру 10, то функция по идее должна
возвратить управление, выйти в начало Repeat, где произойдёт обработка мессаг окна
и попробовать снова.
Но происходит RaiseLastOSError.
> Leonid Troyanovsky © (16.04.10 10:18) [22]
Не, лучше вернуть к прежнему способу с APC-proc.
Почитал тут: http://www.compress.ru/Archive/CP/2001/9/38/index.htm
, чтобы GUI реагировал на нажатия и окно перерисовывалось нужно использовать как ни крути MsgWaitForMultipleObjectsEx.
Leonid Troyanovsky (2010-04-16 10:18:00) [25]
> Б (16.04.10 09:40) [20]
http://rsdn.ru/forum/delphi/500558.1.aspx
--
Regards, LVT.
Сергей М. (2010-04-16 10:13:00) [26]
> программа виснет
Конечно она виснет)
Ты же заставил ее "висеть" вызвав ф-цию ожидания, не реагирующую на оконные сообщения)
Б (2010-04-16 09:40:00) [27]
> Leonid Troyanovsky © (15.04.10 21:42) [19]
Да, лучше использовать WaitForSingleObject, т.к. объект ожидания 1.
Переделал так, но всё программа виснет:
If SetWaitableTimer(HTIMER, TimeFile, 0, nil, nil, True) then
begin
If (GetLastError = ERROR_NOT_SUPPORTED) then
begin
MessageBox(0, 'Resume - no supported!', '!', MB_OK or MB_ICONERROR);
end;
Repeat
Application.ProcessMessages;
If Application.Terminated then Break;
If (WaitForSingleObject(HTIMER, INFINITE) = WAIT_OBJECT_0) then
begin
Audio.Play(WakeUp.FAudID);
MessageBox(0, PCHAR('Wake Up! - ' + TimeToStr(Time)), '!', MB_OK or MB_ICONINFORMATION);
Break;
end else
begin
RaiseLastOSError;
Break;
end;
Until False;
Leonid Troyanovsky (2010-04-15 21:42:00) [28]
> Б (15.04.10 20:49) [18]
> Тогда где ставить обработчик срабатывания будильника?
http://msdn.microsoft.com/en-us/library/ms687008
> Программа не хочет закрываться крестиком.
[15]
Application.ProcessMessages;
if Application.Terminated then
Exit;
--
Regards, LVT.
Б (2010-04-15 20:49:00) [29]
> Кста, для WaitableTimer TimerAPCProc не обязательна.
Тогда где ставить обработчик срабатывания будильника?
Б (2010-04-15 19:56:00) [30]Программа не хочет закрываться крестиком.
Б (2010-04-15 19:38:00) [31]Заменил QS_ALLPOSTMESSAGE на QS_ALLINPUT и всё заработало наконец-то. ;)
Leonid Troyanovsky (2010-04-15 19:20:00) [32]
> Б (15.04.10 18:56) [14]
> Как правильно её вызывать?
http://rsdn.ru/forum/delphi/500558.1.aspx
Ex оставлено в качестве домашнего задания.
Кста, для WaitableTimer TimerAPCProc не обязательна.
--
Regards, LVT.
Б (2010-04-15 18:56:00) [33]Замутно всё как-то...
Вроде бы сделал, обработку мессаг от зависания.
Как правильно её вызывать?
If SetWaitableTimer(HTIMER, TimeFile, 0, @TimerAPCProc, nil, True) then
begin
If (GetLastError = ERROR_NOT_SUPPORTED) then
begin
MessageBox(0, 'Resume - no supported!', '!', MB_OK or MB_ICONERROR);
end;
Repeat
Case MsgWaitForMultipleObjectsEx(1, HTIMER, INFINITE, QS_ALLPOSTMESSAGE, 0) of
WAIT_OBJECT_0 : Break; // Finish.
WAIT_OBJECT_0 + 1: Application.ProcessMessages; // Process messages.
else // Error.
RaiseLastOSError;
end;
Until False;
SleepEx(INFINITE, True);
end else
RaiseLastOSError;
Сергей М. (2010-04-15 17:55:00) [34]Кури MsgWaitForMultipleObjectsEx()
Б (2010-04-15 17:34:00) [35]Как теперь избавиться от зависания?
Создание потока? Application.ProcessMessages?
Б (2010-04-15 17:16:00) [36]Ура!
Проверил, врубается из ждущего режима и проигрывает добавленную .mp3-ху. ;)
Б (2010-04-15 16:50:00) [37]> Гы
Или ждущий режим?
Или параметр fResume не для того?
Игорь Шевченко (2010-04-15 16:45:00) [38]
> которая могла бы включаться даже из состояние спящего режима.
Гы
Б (2010-04-15 16:19:00) [39]
> Anatoly Podgoretsky © (15.04.10 13:13) [5]
> > Б (15.04.2010 12:35:02) [2]
>
> За RaiseLastOSError тебе сисадмины будут ноги целовать,
> а за твое самоувереное морду бить.
Пока обойдусь без фетишистов.
> Вариант (15.04.10 13:15) [7]
> Используй обычный таймер в главном потоке - это тебе будет проще, чем другие варианты, которые конечно тоже существуют.
Цель всего этого дела, создать программу на подобии будильника,
которая могла бы включаться даже из состояние спящего режима.
> Leonid Troyanovsky © (15.04.10 13:14) [6]
Поток виснет от этого.
Вариант (2010-04-15 13:15:00) [40]
> Б (15.04.10 13:00) [4]
> Только я не понял, почему мой пример не работает без SleepEx
Потому, что TimerAPCProc - это APCProc.
> С ним приложение зависает.
> Как этого избежать?
Используй обычный таймер в главном потоке - это тебе будет проще, чем другие варианты, которые конечно тоже существуют.