![]() |
| ||
|
|
Новости |
Поиск |
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;
Б (2010-04-20 15:09:00) [1]
> Anatoly Podgoretsky © (20.04.10 14:50) [44]
> При нажатии SpeedButton3, никакой MessageBox не вызывается.
Есть 2 кнопки OK и Cancel.
OK - это SpeedButton2. (Запускаем будильник)
Cancel - это SpeedButton3. (Посылаем сообщение об остановке будильника,
WakeUp.RunTimer завершиться и вызовится MsgBox)
> Что только не придумает русский программист, только бы не
> покупать будильник.
;)
Anatoly Podgoretsky (2010-04-20 14:52:00) [2]> Б (20.04.2010 14:29:42) [42]
Что только не придумает русский программист, только бы не покупать будильник.
Anatoly Podgoretsky (2010-04-20 14:50:00) [3]> Б (20.04.2010 14:01:38) [38]
При нажатии SpeedButton3, никакой MessageBox не вызывается.
Б (2010-04-20 14:35:00) [4]
> Leonid Troyanovsky © (20.04.10 14:24) [41]
А ну правильно... там WM_CLOSE.
> В-третьих, ссылку, как надо я приводил 2 раза.
Тогда я не понимал, зачем вызывался PostMessage c WM_NULL.
Сейчас уже вроде вник. ;)
Б (2010-04-20 14:29:00) [5]Кстати, на днях у меня сломалась мобила.
Поэтому пришлось воспользоваться этим будильником. ;)
Leonid Troyanovsky (2010-04-20 14:24:00) [6]
> Б (20.04.10 14:01) [38]
> WM_QUIT: // Press close [x].
> begin
> PostQuitMessage(0);
> Exit;
Во-первых, WM_QUIT - это вовсе не "Press close [x]".
Во-вторых, PostQuitMessage посылает WM_QUIT.
В-третьих, ссылку, как надо я приводил 2 раза.
ТщательнЕй, надо, тщательнЕй.
--
Regards, LVT.
Б (2010-04-20 14:12:00) [7]Решил.
Надо было при ловле WM_NULL возвращать ещё и Result = True.
Б (2010-04-20 14:02:00) [8]Поправка: Не WM_WAIT_STOP, а WM_NULL.
Б (2010-04-20 14:01:00) [9]Начал делать через PostMessage.
Const
WM_WAIT_STOP = WM_NULL + 1;
. . . . .
WAIT_OBJECT_0 + 1: // Process messages.
begin
If PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
Case Msg.Message of
WM_QUIT: // Press close [x].
begin
PostQuitMessage(0);
Exit;
end;
WM_WAIT_STOP: Exit;
else begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end
end;
end;
. . . . .
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
If WakeUp.RunTimer(DateTimePicker1.Time, OpenDialog1.FileName) then
begin
MessageBox(0, PCHAR(' Дождались! ;)'), '!', MB_OK or MB_ICONINFORMATION)
// RaiseLastOSError;
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
PostMessage(Handle, WM_WAIT_STOP, 0, 0);
end;
При нажатии SpeedButton3, будильник не вызывается,
но и не показывается MessageBox, говорящий о завершении ожидания.
Почему?
Leonid Troyanovsky (2010-04-20 13:56:00) [10]
> Сергей М. © (20.04.10 13:10) [35]
> ожидающему потоку любое сообщение
Про "послать потоку" ИШ ссылался недавно:
http://transl-gunsmoker.blogspot.com/2010/04/blog-post_05.html
Ну, а про уничтожение
http://msdn.microsoft.com/en-us/library/ms687069(VS.85).aspx ;)
--
Regards, LVT.
Вариант (2010-04-20 13:37:00) [11]
> Сергей М. © (20.04.10 13:10) [35]
> Из другого потока уничтожить объект синхронизации
Не факт. Я бы не стал на это рассчитывать. Поведение функции ожидания события (Msg)WaitForXXX при CloseHandle (если это имелось ввиду под уничтожением) может быть не определенным в общем случае.
Сергей М. (2010-04-20 13:10:00) [12]Из другого потока уничтожить объект синхронизации или послать ожидающему потоку любое сообщение, например, WM_NULL
Leonid Troyanovsky (2010-04-20 13:10:00) [13]
> Б (20.04.10 12:21) [33]
> Как прервать вызов MsgWaitForMultipleObjectsEx?
PostMessage, QueueUserAPC.
--
Regards, LVT.
Б (2010-04-20 12:21:00) [14]Остался последний вопрос:
Как прервать вызов MsgWaitForMultipleObjectsEx?
Б (2010-04-17 21:34:00) [15]Удалено модератором
Б (2010-04-17 13:05:00) [16]
> Leonid Troyanovsky © (17.04.10 10:40) [30]
SetTimer не будет срабатывать из ждущего режима, теряется весь смысл будильника.
В Caption выдаётся установленная дата и время.
Но будильник не срабатывает. В чём дело?
DateTimePicker1.Time:= DateTimePicker2.Time;
Caption:= DateTimeToStr(DateTimePicker1.Date);
WakeUp.RunTimer(DateTimePicker1.Date);
Leonid Troyanovsky (2010-04-17 10:40:00) [17]
> Б (16.04.10 11:08) [23]
> Не, лучше вернуть к прежнему способу с APC-proc.
Для гуевого приложения лучше вернуться к SetTimer.
--
Regards, LVT.
Б (2010-04-16 23:09:00) [18]
> Игорь Шевченко © (16.04.10 23:00) [28]
Неожиданный ответ для вас. ;D
Вот так конвектирую время:
Var
TimeFile: Int64;
TimeSys : TSystemTime;
begin
DateTimeToSystemTime(WakeUpTime, TimeSys);
Win32Check(SystemTimeToFileTime(TimeSys, TFILETIME(TimeFile)));
Игорь Шевченко (2010-04-16 23:00:00) [19]
> Почему не работает?:
не хочет
Б (2010-04-16 22:44:00) [20]Забыл, что Now возвращает текущую дату и время, а не одну дату.
Почему не работает?:
// DateTimePicker'ы - настраиваются пользователем.
// У DateTimePicker2.Kind = dtkTime.
WakeUp.RunTimer(DateTimePicker1.Date + DateTimePicker2.Time);