Главная страница
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.024 c
1-36216
Tankist
2002-12-01 15:33
2002.12.12
Размер массива


7-36435
ArtSoft
2002-10-13 23:13
2002.12.12
HDD


14-36361
Шишкин Илья
2002-11-20 20:34
2002.12.12
А как сделать так, чтобы мой IP не было видно в форуме?


1-36249
Илайдж
2002-12-02 09:53
2002.12.12
Файл открыт или закрыт - проверка.


14-36418
Malder
2002-10-23 19:03
2002.12.12
Master Of Orion rus