Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-36208
^Sanya
2002-12-01 14:52
2002.12.12
TMemo or TRichEdit:


1-36287
Snap
2002-12-01 12:08
2002.12.12
ListBox


1-36238
SkyQuake
2002-11-30 13:56
2002.12.12
Как удалить отображённый в пямяти файл


1-36172
новенькая
2002-12-04 08:08
2002.12.12
помогите


14-36333
Ketmar
2002-11-20 17:47
2002.12.12
test





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский