Форум: "Основная";
Текущий архив: 2002.12.12;
Скачать: [xml.tar.bz2];
ВнизКак организавать паузу, чтобы небыло эффекта Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.005 c