Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 20.02.2024, 21:24
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 45
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию Паттерн запуска логоокна

Здравствуйте, уважаемые любители и профессионалы.
У меня есть задача создать логоокно перед запуском основного окна, в котором бы отображался процесс загрузки основного окна (там длительные по времени процессы). Есть ли у вас какой-то готовый паттерн? Сейчас я делаю вот так (упрощенно)
Код:
constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
  logoForm:=TLogoForm.Create(Application);
  TThread.ForceQueue(nil,
  procedure
  begin
    for var I:byte := 0 to 4 do
   begin
    sleep(2000);
    logoform.p.Position:=logoform.p.Position+10;
   end;
  end );
  logoform.Showmodal;
end;
Проблема в том, что пока не начнется Application.Run в программе, в логоокне не прорисовывается канвас. Уже чего только не перепробовал.
Ответить с цитированием
  #2  
Старый 20.02.2024, 23:05
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Канечна не прорисовывается, ибо прерисовка основана на сообщениях, а до Application.Run обработчик сообщений приложения просто еще не запущен. Тебе надо вручную вызывать Repaint для обновления.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
T232006 (21.02.2024)
  #3  
Старый 21.02.2024, 11:21
T232006 T232006 вне форума
Прохожий
 
Регистрация: 17.11.2022
Сообщения: 45
Версия Delphi: Delphi XE5
Репутация: 10
По умолчанию

Repaint не помог, но если в потоке поставить Application.ProcessMessages, тогда работает. Только обязательно после закрытия этого окна нужно остановить поток, иначе будет происходить хаос.
Еще можно убрать synchronize и тоже будет всё работать

Последний раз редактировалось T232006, 21.02.2024 в 11:31.
Ответить с цитированием
  #4  
Старый 21.02.2024, 22:35
xchgeaxeax xchgeaxeax вне форума
Прохожий
 
Регистрация: 11.05.2023
Сообщения: 15
Версия Delphi: D7, Laz v2.2.6
Репутация: 10
По умолчанию

Проблема в том как у вас организован процесс загрузки данных. Добавьте в процедуру загрузки вызовы Application.ProcessMessages.
Ответить с цитированием
  #5  
Старый 21.02.2024, 23:59
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Если Repaint не помог, значит надо Invalidate вызвать.
Собственно, просто не помню какой из них работает через сообщения, а который делает прямое обновление.

Собственно, проблема понятна из описания почему не обновляется.
Еще пара замечаний по коду.
Форму надо показывать через Show, не через ShowModal.
sleep вообще-то блокирует все нафиг, не помню как он работает внутри потока. Лучше использовать System.Classes.TThread.Sleep

Вообще, я делал такие формы немного подругому.
Во первых, из создание, показ, обновление и удаление делалось в файле проекта. Во вторых, форма показывалась через Show, но была без заголовка и Topmost (что бы пользователь видел ее но не мог закрыть).
В третьих, надо вешать курсор ожидания.
А в остальном - все то же самое.

Вот так все работает:
Код:
type
  TLoadProc = procedure;

procedure LoadProc;
begin
  sleep(1500);
end;

const
  LoadTasks : Array[1..4] Of TLoadProc = (LoadProc, LoadProc, LoadProc, LoadProc);

var
  I : Integer;
begin
  Application.Initialize;

  LogoForm := TLogoForm.Create(Nil);
  LogoForm.ProgressBar1.Min := 0;
  LogoForm.ProgressBar1.Max := High(LoadTasks);
  LogoForm.ProgressBar1.Position := 0;
  Try
    LogoForm.Show;
    for I := Low(LoadTasks) to High(LoadTasks) do
      begin
        LogoForm.Label1.Caption := 'Running load task ' + IntToStr(I);
        LogoForm.ProgressBar1.Position := I;
        LogoForm.Repaint;
        LoadTasks[i];
      end;
  Finally
    LogoForm.Free;
  End;

  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.

понятно, что для простоты я все поместил в файл проекта и сделал просто заглушку для процедуры загрузки. по хорошему, все надо вынести в соотв. модули и здесь только вызвать один метод.

Последний раз редактировалось lmikle, 22.02.2024 в 00:05.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
T232006 (03.03.2024)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:30.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter