![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как организавать паузу, чтобы небыло эффекта
SkyN © (2002-12-02 11:14:00)Необходимо подождать 5 минут. Если использую функцию sleep(), то приложение перестает реагировать на сообщения Windows. И получается, что приложение "висит". Как этого избежать?
Юрий Зотов (2002-12-02 22:54:00) [1]Не будет, естественно. Надо ловить возможность перехода через ноль и вносить соответствующую коррекцию.
"Поимку в пустыне Сахара ручного льва предоставляем читателю в качестве самостоятельного упражнения".
(С) Книга "Физики шутят".
TTCustomDelphiMaster (2002-12-02 22:17:00) [2]По моему не будет работать при значениях GetTickCount близких к $FFFFFFFF
Юрий Зотов (2002-12-02 21:40:00) [3]Не напутал, а написал набросок, чтобы только показать идею. Так и сказал - "что-то типа этого". И добавил, что с паузой надо быть аккуратнее.
Вот полностью рабочий код. От первоначального он почти не отличается, а от Вашего отличается, в основном, тем, что не требует никаких окон. Проверил диспетчером задач W2K - он действительно выдерживает заданную паузу, не загружая CPU и не мешая обработке сообщений.
procedure Delay(Pause: DWORD);
var
H: THandle;
begin
Inc(Pause, GetTickCount);
while (Pause > GetTickCount) and (MsgWaitForMultipleObjects(0, H, False, Pause - GetTickCount, QS_ALLINPUT) <> WAIT_TIMEOUT) do
Application.ProcessMessages;
end;
Я не проверял Ваш код, но, похоже, в нем есть ошибка - если во время паузы придет сообщение, то ее отсчет начнется сначала. Значение dwCount нужно корректировать - уменьшать на величину уже прошедшей части первоначальной задержки.
VaS (2002-12-02 16:36:00) [4]Извините, но Вы немного напутали с time-out interval. Да и с хэндлом тоже.
procedure SleepMsg(AHandle: HWND; dwCount: LongWord);
var
h : THandle;
Msg : tagMSG;
begin
repeat
PeekMessage(Msg, AHandle, 0, 0, PM_REMOVE);
TranslateMessage(Msg);
DispatchMessage(Msg);
until MsgWaitForMultipleObjects(0, h, FALSE, dwCount, QS_ALLEVENTS) = WAIT_TIMEOUT;
end;
Юрий Зотов (2002-12-02 16:04:00) [5]Что-то типа этого. Не сказал бы, что код полностью надежный (остаток паузы надо вычислять аккуратнее, т.к. он может стать отрицательным и произойдет зацикливание), но для примера подойдет.
procedure Delay(Pause: DWORD);
var
H: THandle;
begin
H := GetCurrentProcess;
Inc(Pause, GetTickCount);
while MsgWaitForMultipleObjects(1, H, False, Pause - GetTickCount, QS_ALLINPUT) <> WAIT_TIMEOUT do
Application.ProcessMessages
end;
VaS (2002-12-02 15:12:00) [6]Юрий Зотов: Пожалуйста, привидите пример. Действительно интересно.
Юрий Зотов (2002-12-02 13:58:00) [7]MsgWaitForMultipleObjects.
Выдерживает нужную паузу, позволяет во время нее вести обработку сообщений и в то же время не загружать процессор постоянным опросом очереди.
И не нужно никаких таймеров. В том числе, Waitable (а под 9х их и вовсе нет).
VaS (2002-12-02 13:15:00) [8]По-моему так наиболее правильно:
procedure SleepMsg(AHandle: HWND; dwCount: LongWord);
var
hTimer : THandle;
Period : int64;
Msg : tagMSG;
begin
hTimer:=CreateWaitableTimer(nil, FALSE, "My Timer 1");
if hTimer <> 0 then
begin
Period:=-dwCount*10000;
SetWaitableTimer(hTimer, Period, 0, nil, nil, FALSE);
repeat
PeekMessage(Msg, AHandle, 0, 0, PM_REMOVE);
TranslateMessage(Msg);
DispatchMessage(Msg);
until MsgWaitForMultipleObjects(1, hTimer, FALSE, INFINITE, QS_ALLEVENTS) = WAIT_OBJECT_0;
CancelWaitableTimer(hTimer);
CloseHandle(hTimer);
end;
end;
где AHandle - хэндл окна, сообщения для которого блокируются при Sleep().
Андрей Сенченко (2002-12-02 13:09:00) [9]sniknik © (02.12.02 13:05)
>> извини что вместо Song он может по другому думает.
да ничего.
конечно поверка условия. Если я правильно понял вопрос, то нужно по возникновению какого-то условия дать оттяжку в 5 минут, сохранив при этом доступность элементов формы.
Если бы нужно было просто "освободить" форму в затяжном цикле - то тут понятное дело ProcessMessage. Но здесь то четко определен и момент включения таймера и период ожидания.
sniknik (2002-12-02 13:05:00) [10]Андрей Сенченко © (02.12.02 12:52)
не получится если задержку делать внутри кода. тоже только с эфектом зависания.
поясню
какойто код ....
проверка условия или так сразу задумано надо ждать ... события от таймера?
продолжение кода.
правда если сразу так задумывается то можно процес поделить и делать частями хоть и по таймеру.
извини что вместо Song он может по другому думает.
Андрей Сенченко (2002-12-02 12:52:00) [11]Song © (02.12.02 11:28)
А не проще
Timer1.Enabled := true
?
Вопрос именно к Мастеру - я бы реализовал именно таймером.
id_privin (2002-12-02 12:18:00) [12]Лучше TApplicatioin.HandleMessage
Song (2002-12-02 11:28:00) [13]GetTickCount+цикл+TApplicatioin.ProcessMessages