Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.12.12;
Скачать: CL | DM;

Вниз

Как организавать паузу, чтобы небыло эффекта   Найти похожие ветки 

 
SkyN   (2002-12-02 11:14) [0]

Необходимо подождать 5 минут. Если использую функцию sleep(), то приложение перестает реагировать на сообщения Windows. И получается, что приложение "висит". Как этого избежать?


 
Song ©   (2002-12-02 11:28) [1]

GetTickCount+цикл+TApplicatioin.ProcessMessages


 
id_privin ©   (2002-12-02 12:18) [2]

Лучше TApplicatioin.HandleMessage


 
Андрей Сенченко ©   (2002-12-02 12:52) [3]

Song © (02.12.02 11:28)

А не проще
Timer1.Enabled := true
?

Вопрос именно к Мастеру - я бы реализовал именно таймером.


 
sniknik ©   (2002-12-02 13:05) [4]

Андрей Сенченко © (02.12.02 12:52)
не получится если задержку делать внутри кода. тоже только с эфектом зависания.

поясню

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

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

извини что вместо Song он может по другому думает.


 
Андрей Сенченко ©   (2002-12-02 13:09) [5]

sniknik © (02.12.02 13:05)

>> извини что вместо Song он может по другому думает.
да ничего.

конечно поверка условия. Если я правильно понял вопрос, то нужно по возникновению какого-то условия дать оттяжку в 5 минут, сохранив при этом доступность элементов формы.
Если бы нужно было просто "освободить" форму в затяжном цикле - то тут понятное дело ProcessMessage. Но здесь то четко определен и момент включения таймера и период ожидания.


 
VaS ©   (2002-12-02 13:15) [6]

По-моему так наиболее правильно:


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:58) [7]

MsgWaitForMultipleObjects.

Выдерживает нужную паузу, позволяет во время нее вести обработку сообщений и в то же время не загружать процессор постоянным опросом очереди.

И не нужно никаких таймеров. В том числе, Waitable (а под 9х их и вовсе нет).


 
VaS ©   (2002-12-02 15:12) [8]

Юрий Зотов: Пожалуйста, привидите пример. Действительно интересно.


 
Юрий Зотов ©   (2002-12-02 16:04) [9]

Что-то типа этого. Не сказал бы, что код полностью надежный (остаток паузы надо вычислять аккуратнее, т.к. он может стать отрицательным и произойдет зацикливание), но для примера подойдет.

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 16:36) [10]

Извините, но Вы немного напутали с 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 21:40) [11]

Не напутал, а написал набросок, чтобы только показать идею. Так и сказал - "что-то типа этого". И добавил, что с паузой надо быть аккуратнее.

Вот полностью рабочий код. От первоначального он почти не отличается, а от Вашего отличается, в основном, тем, что не требует никаких окон. Проверил диспетчером задач 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 нужно корректировать - уменьшать на величину уже прошедшей части первоначальной задержки.


 
TTCustomDelphiMaster ©   (2002-12-02 22:17) [12]

По моему не будет работать при значениях GetTickCount близких к $FFFFFFFF


 
Юрий Зотов ©   (2002-12-02 22:54) [13]

Не будет, естественно. Надо ловить возможность перехода через ноль и вносить соответствующую коррекцию.

"Поимку в пустыне Сахара ручного льва предоставляем читателю в качестве самостоятельного упражнения".
(С) Книга "Физики шутят".



Страницы: 1 вся ветка

Текущий архив: 2002.12.12;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.022 c
1-36224
Tankist
2002-12-01 21:19
2002.12.12
Удаление элемента массива


1-36162
Alek_1
2002-11-30 02:06
2002.12.12
ImageList


1-36186
neXt
2002-12-04 09:06
2002.12.12
В чём я не прав?


14-36401
Anatoly Podgoretsky
2002-11-21 07:42
2002.12.12
Именинники 21 ноября


4-36491
Grizli
2002-10-25 09:08
2002.12.12
Перевод фокуса