![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как вывести сообщение об ожидании выполнения операции?
well © (2012-05-23 11:20:00)При нажатии кнопки начинается выполнение длительной операции.
Необходимо пользователю открыть сообщение(либо вывести индикацию) о необходимости ожидания окончания операции.
Пытался сделать с помощью Label перед запуском операции, но надпись не появляется до завершения процесса; То же самое если я устанавливаю Visible метки в True и.т.п. Даже если я между сообщением и операцией ставлю цикл(для задержки), надпись всё равно не появляется.
Как организовать правильно сообщение о необходимости ожидания конца операции?
Dennis I. Komarov (2012-05-24 20:15:00) [1]
> Если надо - то безусловно. Зависит от логики. Если следующее
> действие может быть выполнено только по завершении текущего
> - то не надо. Если может быть выполнено в любой момент -
> то надо.
Конечно зависит, но согласись что с т.з. ГУЯ оно намного приятнее, а запретить следующее действие можно и другой логикой, если надо.
Dennis I. Komarov (2012-05-24 20:11:00) [2]
> Самое неприятное в потоках, что они не могут прямо обращаться
> к процедурам, изменяющим внешний вид, а только через Syncronize,
> который сильно тормозит сам поток.
не их ума дело, а на синхронизе свет клином не сошелся...
Давайте будем жрать! (2012-05-24 07:52:00) [3]
> Вот только перерисовываться будут только они.
Автор именно это и спрашивал. :-)
Германн (2012-05-24 03:36:00) [4]
> Ega23 © (24.05.12 02:50) [15]
>
>
Олежка. Вот только "передёргивать" не надо! Я знаю всю колоду! :)
Ты что предложил в "Ega23 © (2.05.12 16:06) [7]"?
Ega23 (2012-05-24 02:50:00) [5]
> Даже если не надо, то во-первых зачем Application.ProcessMessages?
> Наследники TControl имеют методы немедленной перерисовки
> Repaint & Refresh.
Иметь-то они имеют. Вот только перерисовываться будут только они.
unit Unit20;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm20 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form20: TForm20;
implementation
{$R *.dfm}
procedure TForm20.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 1 to 10 do
begin
Label1.Caption := IntToStr(i);
Label1.Refresh;
// Application.ProcessMessages;
Sleep(500);
end;
end;
end.
Попробуй развернуть окно c Refresh и с PM.
> А во-вторых это всё-таки очень некрасиво в многозадачной среде.
Красивость - мнение субъективное.
Германн (2012-05-24 00:52:00) [6]
> Германн А если во время работы пользователь пронёс мышью
> окно какого-то другого приложения над работающим окном?
> Сообщение об этом окно приложения не сможет получить и будет
> испоганено. ИМХО именно за этим Application.ProcessMessages
Посмотри внимательно код в Ega23 © (23.05.12 16:06) [7]
А потом ещё раз мою вторую фразу. :)
TStas (2012-05-24 00:47:00) [7]Если длительные процесс - это цикл, то запихать с некоторой периодичностью Application.ProcessMessages. Как пишет Юрий Зотов - это оптимальный вариант, но потоки противны в отладке. Я отлаживал поток так: вначале отлаживал его в основном потоке, при этом, конечно, всё висело и сообщения не обрабатывались, а потом, когда косяки были убраны, пихал код в код поток. Самое неприятное в потоках, что они не могут прямо обращаться к процедурам, изменяющим внешний вид, а только через Syncronize, который сильно тормозит сам поток.
>Германн А если во время работы пользователь пронёс мышью окно какого-то другого приложения над работающим окном? Сообщение об этом окно приложения не сможет получить и будет испоганено. ИМХО именно за этим Application.ProcessMessages
Германн (2012-05-24 00:36:00) [8]
> Ega23 © (24.05.12 00:20) [11]
Даже если не надо, то во-первых зачем Application.ProcessMessages? Наследники TControl имеют методы немедленной перерисовки Repaint & Refresh. А во-вторых это всё-таки очень некрасиво в многозадачной среде.
Ega23 (2012-05-24 00:20:00) [9]
> но желательно... (если оно надо)
Если надо - то безусловно. Зависит от логики. Если следующее действие может быть выполнено только по завершении текущего - то не надо. Если может быть выполнено в любой момент - то надо.
Dennis I. Komarov (2012-05-23 23:26:00) [10]
> Ega23 © (23.05.12 22:10) [9]
но желательно... (если оно надо)
предположим у нас какой-нить коннект в теле происходит, прием или еще чего, что не можем разбить PM - приложение мертвое до следующей PM
Ega23 (2012-05-23 22:10:00) [11]
> Не, не согласен. Окно должно обрабатывать сообщения даже
> при долговременных операциях. В поток ее...
Вот совершенно необязательно. А сообщения обрабатывать - передавай Callback для прогресса, в нём и ставь тот самый ProcessMessages
Dennis I. Komarov (2012-05-23 19:28:00) [12]
> Ega23 © (23.05.12 16:06) [7]
Не, не согласен. Окно должно обрабатывать сообщения даже при долговременных операциях. В поток ее...
TAction(Self).Enable:=false;
TAnyThread.Create...
+ добавить логику на запрет создания второго потока, если надо;
+ возвращать данные о процессе выполнения процедуры в ГУЙ;
+ логику досрочного прекращения операции и разбанивания экшина;
Ega23 (2012-05-23 16:06:00) [13]
> Пытался сделать с помощью Label перед запуском операции,
> но надпись не появляется до завершения процесса;
Screen.Cursor := crHourGlass;
try
Label1.Caption := 'Bla-bla-bla 1';
Application.ProcessMessages;
for i := 0 to 100000000 do ....;
finally
Label1.Caption := 'Bla-bla-bla 2';
Screen.Cursor := crDefault;
end;
well (2012-05-23 14:09:00) [14]Спасибо!
Буду пробовать.
Loginov Dmitry (2012-05-23 12:49:00) [15]Неплохой вариант: [3] + [4]
oldman (2012-05-23 12:34:00) [16]FormN.ShowModal
На форме сообщение "Ждите"
На FormN.OnShow твой длительный процесс.
После окончания процесса FormN.Close.
Юрий Зотов (2012-05-23 11:33:00) [17]
> well © (23.05.12 11:20)
Самый лучший вариант - вынести длительную обработку в отдельный поток.
Медвежонок Пятачок (2012-05-23 11:27:00) [18]нужно организовывать не это, а организовать возможность приложению продолжать обрабатывать очередь сообщений.
Давайте будем жрать! (2012-05-23 11:27:00) [19]После изменения лейбла вызывай Label1.Update. Более универсальный вариант — вызывать application.ProcessMessages, но в данном случае это излишне.