Delphi - создание скрытой дочерней формы MDI

В моем приложении много форм mdi, и они создаются после успешного входа пользователя в систему. Как я могу лучше всего скрыть этот процесс создания? Это выглядит глупо и занимает больше времени, пока формы mdi рисуются после создания новой формы и так далее.

До сих пор я использовал LockWindowUpdate, который не все скрывает, но я хотел бы использовать заставку, показывающую ход создания, но я не могу использовать LockWindowUpdate.

С наилучшими пожеланиями Янне Полезно Бесполезно


person HeartTune    schedule 21.04.2010    source источник
comment
Не создавайте их при запуске. Создавайте их, когда они вам нужны.   -  person David Heffernan    schedule 12.10.2014


Ответы (3)


Чтобы сделать дочерние формы MDI невидимыми, вы устанавливаете для их свойства Visible значение False, и, кроме того, вы должны отключить принудительное отображение их в VCL во время создания. Это происходит с помощью установщика свойств FormStyle для TCustomForm, который устанавливает Visible в True для дочерних форм MDI.

Если поставить FormStyle в инспекторе объектов, то установщик свойств будет вызываться уже при создании формы, и форма будет отображаться не сразу, а только после завершения построения. Это позволяет сбросить запрос для отображения формы, переопределив метод AfterConstruction() следующим образом:

procedure TMDIChild.AfterConstruction;
begin
  Exclude(FFormState, fsVisible);
  inherited;
end;

Это создаст невидимую дочернюю форму MDI.

Чтобы проверить это, вы можете создать новое приложение MDI в IDE, переопределить метод в классе дочерней формы, как показано выше, и смоделировать длинную инициализацию:

procedure TMainForm.FileNew1Execute(Sender: TObject);
var
  i: integer;
begin
  for i := 1 to 10 do begin
    CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1));
    Update;
    Sleep(500);
  end;
  for i := 0 to MDIChildCount - 1 do
    MDIChildren[i].Visible := True;
end;

Без переопределенного метода AfterConstruction() он будет создавать и показывать дочерний элемент MDI каждые полсекунды. С переопределенным методом он покажет их все после периода занятости в 5 секунд, что даст вам возможность вместо этого отобразить заставку.

Важно:

Использование LockWindowUpdate() для уменьшения мерцания или подавления любого экрана вывод неправильный, неправильный, неправильный. Не делайте этого, прочитайте серию < href="http://blogs.msdn.com/oldnewthing/archive/2007/02/22/1742084.aspx" rel="noreferrer">статьи Рэймонда Чена на эту тему, чтобы понять, почему это так. .

person mghie    schedule 21.04.2010
comment
+1 за очень аккуратный, единственный способ сделать это в Delphi. Обычно для этого мне приходилось прибегать к Win API (ShowWindow). - person Gerry Coll; 22.04.2010
comment
Отлично! Это было именно то, что я искал, и с советами Рэймонда Чена я мог отключить перерисовку для видимого := истинного цикла. Большое Вам спасибо :) - person HeartTune; 22.04.2010

У меня была аналогичная проблема с мерцанием детей MDI. Я использовал комбинацию переопределяющего сообщения AfterConstruction и WM_SETREDRAW из этого совета: Управление размещением окон fsMDIChild в Delphi

SendMessage(Application.MainForm.ClientHandle, WM_SETREDRAW, False, 0);
try
  Child := TChildForm.Create(Self);
  Child.Left := ...;
  Child.Top := ...;
  Child.Show;
finally
  SendMessage(Application.MainForm.ClientHandle, WM_SETREDRAW, True, 0);
  InvalidateRect(Application.MainForm.ClientHandle, nil, True);
end;

И все работает нормально.

person Peter    schedule 09.09.2010

попробуй этот код, у меня работает

 try
  SendMessage(Application.MainForm.ClientHandle,WM_SETREDRAW,0,0);
  FormChild:=TBaseChildForm.Create(application);
  FormChild.Caption:='Form '+IntToStr(n);
  FormChild.Show;
 finally
  SendMessage(Application.MainForm.ClientHandle,WM_SETREDRAW,1,0);
  RedrawWindow(Application.MainForm.ClientHandle, nil, 0, RDW_FRAME or RDW_INVALIDATE or   RDW_ALLCHILDREN or RDW_NOINTERNALPAINT);
 end;
person AsepRoro    schedule 28.02.2013