Delphi - создание скрытой MDI-дочерней формы - PullRequest
5 голосов
/ 21 апреля 2010

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

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

С наилучшими пожеланиями Janne

Ответы [ 3 ]

8 голосов
/ 21 апреля 2010

Чтобы создать невидимые дочерние формы 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() для уменьшения мерцания или подавления любого вывода на экран неверно, неправильно, неправильно. Не делайте этого , прочитайте серию статей Рэймонда Чена на эту тему, чтобы понять, почему это так.

0 голосов
/ 28 февраля 2013

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

 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;
0 голосов
/ 09 сентября 2010

У меня была похожая проблема с мерцанием детей с ДИ. Я использовал комбинацию переопределения 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;

И все отлично работает.

...