Правильный способ уничтожить форму и показать другую в Delphi - PullRequest
6 голосов
/ 13 февраля 2012

В настоящее время в моей программе есть форма Startup и форма Main. Форма запуска отображается на секунду или две.

Прямо сейчас у меня есть следующий код в таймере:

  frmStartup.Destroy;

  frmMain := TfrmMain.Create(Self);
  frmMain.Show;

Прямо сейчас, я не уверен, что это правильный способ сделать это .. Это работает, но при вызове application.Terminate(); Я получаю сообщение о нарушении прав доступа, заставляя меня поверить, что я что-то не так сделал при уничтожении формы запуска ..

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

Заранее спасибо,

EDIT:

Спасибо за все отзывы, я исправил нарушения доступа, просто добавив код:

  Action := caFree;

В метод frmStartup.formClose.

Ответы [ 4 ]

8 голосов
/ 13 февраля 2012

Не создавайте frmStartup, используя Application.CreateForm. Первая созданная там форма становится главной формой вашего приложения, и если это frmStartup, вы уничтожаете ее за пределами Application знаний.

Вместо этого используйте обычный Form.Create в исходном файле вашего проекта (.dpr):

var
  frmStartup: TfrmStartup;

begin
  Application.Initialize;
  Application.MainFormOnTaskBar := True;
  frmStartup := TfrmStartup.Create(nil);  // No owner assigned here!
  frmStartup.Show;
  frmStartup.Update;

  Application.CreateForm(TfrmMain, frmMain); // Let Application have this for main form
  // Delay here if needed
  frmfrmStartup.Free;
  Application.Run;
end.
4 голосов
/ 14 февраля 2012

Возможно, вы захотите, чтобы ваш Splash Screen отображался как можно раньше, поэтому в идеале это следует делать на этапе инициализации, тогда он должен исчезнуть только тогда, когда MainForm будет готова вступить во владение.

Это именно то, что мы делаем в нашем приложении, где мы снова используем диалоговое окно About в качестве заставки , а затем отпускаем его, когда MainForm крадет фокус.

В dpr как можно выше в пункте использования после необходимых блоков VCL / RTL:

  f_adtDlgAbout in 'f_adtDlgAbout.pas' {frmDlgAbout}, // ASAP to be used as a Splash screen

Единица О (FYI, FormStyle равно fsStayOnTop и Position равно poScreenCenter):

unit f_adtDlgAbout;

[...]

type
  TfrmDlgAbout = class(TForm)

[...]

procedure TfrmDlgAbout.SplashFormDeactivate(Sender: TObject);
begin
  Release;
end;

initialization
  // Use it as a Splash screen
  with TfrmDlgAbout.Create(nil) do begin
    AlphaBlend := True;
    AlphaBlendValue := 208;
    BorderStyle := bsNone;
    btnOK.Visible := False;
    OnDeactivate := SplashFormDeactivate;
    Show;
    Update;
  end;
end.
1 голос
/ 13 февраля 2012

TFrmMain.Create (Self) ???Что такое "Я"?Вы делаете это изнутри frmStartup?Если это так, не .Используйте TFrmMain.Create (NIL).

Используйте frmStartup.Release для выпуска frmStartup, если весь отправленный вами код находится внутри метода frmStartup, вам нужно поместить эту строку в bottom метода.

0 голосов
/ 06 сентября 2013

Установить frmMain в качестве основной формы

On frmMain.FormCreate

frmStartup := TfrmStartup.Create(nil);
try
  frmStartup.ShowModal;
finally
  frmStartup.Free;
end;
...