Отображение статуса и ProcessMessage

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Ну вот и аргумент за модальное окно на время выполнения задачи.
Модальные окна зло. Их стоит делать разве что на "format c:"

>>Я заранее не знаю, долго ли или быстро будут выполняться операции, мелькать каждый раз модальным окошком с ProgressBar некрасиво.
Поддерживаю. Предлагаю при нужде создавать прогрессбар с статусбаре главного окна
tria
постоялец
Сообщения: 401
Зарегистрирован: 03.04.2006 11:24:10
Контактная информация:

Сообщение tria »

Ну, есть идея - сделать модальное микроокно, расположить над СтатусБаром, чтобы выглядело как ProgressBar в СтатусБаре и не мелькало по центру...
Вроде-бы должно быть проще с точки зрения реализации. Надо попробовать, какой внешний вид получиться.
Аватара пользователя
serbod
постоялец
Сообщения: 449
Зарегистрирован: 16.09.2016 10:03:02
Откуда: Минск
Контактная информация:

Сообщение serbod »

TDatamodule по сути тот же самый TForm, только невидимый, для невизуальных компонентов. Вовсе необязательно его использовать только для компонентов баз данных. Он годится для любых невизуальных компонентов - таймеры, сокеты, ком-порты, итд.. Разные области логики (БД, сеть, ввод-вывод, бизнес-объекты) можно и нужно разделять по разным датамодулям, это облегчает навигацию по коду и упрощает поиск ошибок runtime.

Application.ProcessMessages() очень коварная штука. Если она вызывается где-то в событии таймера или обработчике контрола, то есть большая вероятность получить рекурсию, когда при обработке событий, в результате действий пользователя, таймера или исключений обработчик будет вызываться снова и снова, увеличивая стек. Если ProcessMessages() несколько в разных местах, то разобраться будет очень сложно. Для простых проектов и утилит с коротким временем пользования это не критично, там проблемы не успеют накопиться и в худшем случае будут ошибки при закрытии программы. А в долгоиграющих проектах и круглосуточных сервисах такое неприемлемо.

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

Потоки действительно очень простая и надежная штука, если соблюдать простые правила:
- все переменные потока приватные а лучше локальные (описаны в Execute())
- из кода потока не обращаться к внешним переменным и объектам
- для управления потоком и обмена данными использовать только thread-safe объекты (семафоры, очереди, pipes, messages) и атомарные типы данных (кратные машинному слову).
- избегать использования Synchronize() и FreeOnTerminate

В идеале поток работает как процедура - перед стартом в него передали данные (установили public переменные) и запустили. И по таймеру проверять, если поток Terminated(), значит он завершен и можно прочитать результат или ошибку.
wadman
постоялец
Сообщения: 122
Зарегистрирован: 18.10.2016 14:54:28
Контактная информация:

Сообщение wadman »

zub писал(а):Модальные окна зло. Их стоит делать разве что на "format c:"

Не поддерживаю максимализм на уровне детского сада.
Если какие-то страхи есть перед чем-то, то нужно с ними мужественно бороться, а не проецировать на других.
Ничего, что ответил тем-же? :)

Добавлено спустя 2 минуты 14 секунд:
serbod писал(а):В винде они коряво реализованы, могут прятаться за другие окна и блокировать работу.

В делфи о таком читал, что такая ситуация изредка возникает в терминальных сессиях.
Сам ни разу не сталкивался, даже с "рабочими" примерами.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

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

Тут сборище фанатов модальщины и многопоточности... а мы с tria дартаньяны, да))

Добавлено спустя 1 минуту 5 секунд:
serbod
>>Application.ProcessMessages() очень коварная штука
а ненадо лепить их в код недумая. все должно быть централизовано
wadman
постоялец
Сообщения: 122
Зарегистрирован: 18.10.2016 14:54:28
Контактная информация:

Сообщение wadman »

zub писал(а):Засветить модальное окно просто чтоб заблокировать интерфейс...

Чтобы показать прогрессбар с описанием процесса и кнопкой отмена.
Не встречал каких-либо проблем у кого-либо.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Чтобы показать прогрессбар с описанием процесса и кнопкой отмена.
а зачем модальное та?
wadman
постоялец
Сообщения: 122
Зарегистрирован: 18.10.2016 14:54:28
Контактная информация:

Сообщение wadman »

zub писал(а):а зачем модальное та?

Настоящий программист войдет в рекурсию с последующим стэк оферфлоу: viewtopic.php?f=5&t=41862#p147759
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

т.е. чтобы заблокировать интерфейс.
Я небуду пользоваться вашей программой((
Аватара пользователя
zoltanleo
постоялец
Сообщения: 459
Зарегистрирован: 17.10.2013 10:55:01

Сообщение zoltanleo »

zub писал(а):а зачем модальное та?

вот тоже подумалось. Покажи окошко параллельно выполняющегося потока на статус баре и делов. Захочет юзер посмотреть, чего там делается так долго, поднимет его наверх, если надо - отменит действие.
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

tria я ужо запутался. :lol:
А если вывести "менеджер задач" и от него "плясать".
А ещё проще: составьте себе более правильную структуру проекта. А то она как то стрёмно, судя из описания.
Alex2013
долгожитель
Сообщения: 3230
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

1 С модальными окнами действительно проблем не оберешься если это не диалог в "статической программе" (и то нужна осторожность ).
2 Даже со стандартным ShowMessage и MessageDlg возможны приколы ...

Код: Выделить всё

// Пример.
// Обычная копка делает Show дочернему окну...
// И показывает сообщение...
// Все работало пока понадобилось использовать несколько активных форм ...
procedure TMain_Form.Button11Click(Sender: TObject);
Var DF:Tform; I:Integer;
begin
If CO_Form.Visible then exit;
CO_Form.Show;
// Так было ...
//MessageDlg('Keys: ESC - quit program;'#10' r - auto-initialize tracking; '#10'c - delete all the points; '#10'n - switch the "night" mode on/off ', mtInformation, [mbOK], 0);

// А вот так стало теперь ...
Df:=CreateMessageDialog(
'Keys: ESC - quit program;'#10' r - auto-initialize tracking; '+
 #10'c - delete all the points; '+
 #10'n - switch the "night" mode on/off ', mtInformation, [mbOK]);
df.Show; Application.ProcessMessages;
df.AlphaBlend:=True;
For i:=255*1000 downto 0 do begin
df.AlphaBlendValue:=i div 1000;
Application.ProcessMessages;
end;
df.Free;
// иначе при  двух разных активных дочерних окнах сообщение иногда не закрывается  . 
end;

Есть вариант без лишнего Application.ProcessMessages; в цикле но там я прозрачность через системный вызов дергаю что тоже не хорошо .
Разумеется нормальнее повесить "потухание" на таймер или поток но там у меня их и так многовато крутится ....
Кстати что интересно "потухающие" как бы в основном потоке окно сообщения, никак не мешает работать всему остальному.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

При чем тут прозрачность?
Любые отрисовки по уму должны делаться внутри paintmessage, т.е. очередь сообщений, а значит в однопоточном случае Application.ProcessMessages тут никак не лишний.
Да, в винде и гтке можно порисовать не из события отрисовки, в кт такой фокус уже никак не получится...
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

zub писал(а):Многопоточность в данной постановке принесет только геморой, ибо в гуишном потоке ничего не изменится - ты также будешь сидеть и дисаблить кнопочки и прочие свистелки

Эээ..Вы не знаете как готовить. Там все просто, Да тяжелый старт, нужно обдумывать как нужно взлететь, готовить заранее материал. понимать куда лететь.. но потом полет будет комфортным и приятным.
Нежели Application.ProcessMessages по бездорожью ездить, все кочки собирать.

Добавлено спустя 6 минут 53 секунды:
zub писал(а):ука расскажи какие будут проблемы если я при висе на 10 сек двадцать раз вызову Application.ProcessMessages?
ну во первых нужно вызывать.. Где? в теле процедуры, задачи.
сам Application.ProcessMessages нужен для принудительного выгреба ямы фекалей сообщений. кто туда чего накидал, сколько нужно времени на выполнения каждого события.. а вдруг прилетел WM_Paint.. или еще хуже WM_Size, да их собралось несколько.. вот жди прорисовки всего окна и дочерних компонентов.

Добавлено спустя 7 минут 42 секунды:
tria писал(а):Ну, есть идея - сделать модальное микроокно, расположить над СтатусБаром, чтобы выглядело как ProgressBar в СтатусБаре и не мелькало по центру...

Ээээ.. таких поз даже в кама-с-утра не придумали,
Смотри есть задача по времени не определена, её проще вывести за главный поток, то есть в фон. оттуда периодически можно главному потоку сообщать о состоянии (SendMessage).. можно из главного потока посматривать что там.

Добавлено спустя 12 минут 11 секунд:
serbod писал(а):Модальные окна - зло. В винде они коряво реализованы, могут прятаться за другие окна и блокировать работу.
Верно, пока пользователь не прикроет, все другие окна, будут ждать. Еще веселее будет когда пользователь не увидит или не поймет, что нужно закрыть модальное окно.. этому пользователю скоро на ум придет (событие в его главный мыслительный поток)) мысля что программист - дебил.
Сейчас стандарты не рекомендуют многооконнсть. Вы в мобилках часто кликаете по модалке?

Добавлено спустя 2 минуты 17 секунд:
Это не модно и вредно для здоровия.. этим травились в те времена когда пиксели были большими и все цвета умещались в один байт.

Добавлено спустя 2 минуты 24 секунды:
zub писал(а):Тут сборище фанатов модальщины и многопоточности... а мы с tria дартаньяны, да))

Да. Ставте круглые мониторы с 1024х768 разрешением и там крутите свои модальные окошки.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Эээ..Вы не знаете как готовить. Там все просто, Да тяжелый старт, нужно обдумывать как нужно взлететь,
Нюню. НЕНУЖНА ТУТ МНОГОЗАДАЧНОСТЬ. там где она нужна - наздоровье. Но чтобы прогрессбар порисовать...

>>ну во первых нужно вызывать.. Где? в теле процедуры, задачи.
например тут https://github.com/zamtmn/zcad/blob/mas ... upport.pas
регистрируем обработчики "длинных" задач и вперед

Код: Выделить всё

lpsHandle:=LPS.StartLongProcess(MaxShnyagaCount,'Расчет какойто шняги',nil);
for i:=0 to MaxShnyagaCount do begin
  ShnyagaCalculate(i);
  LPS.ProgressLongProcess(lpsHandle,i);
end;
LPS.EndLongProcess(lpsHandle);

можно зарегать 50 прогресбаров и двигать их, естественно отрисовку делать не на каждом вызове, а на какомто соотношении max и current или при каждом пикселе прогрессбара.
зкадный uzelongprocesssupport не расчитан на централизованый ProcessMessages, но его легко добавить приделав var параметр needProcessMessages в ProgressLongProcess. После вызова всех обработчиков смотрим требуется ли комуто ProcessMessages и если со времени последнего ProcessMessages прошло времени больше установленного - делаем.
Все централизовано и под контролем.
Ответить