Правильный способ уничтожить форму и показать другую в Delphi

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

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

  frmStartup.Destroy;

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

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

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

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

РЕДАКТИРОВАТЬ:

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

  Action := caFree;

В метод frmStartup.formClose.

4 ответа

Не создавайте 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.

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

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

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

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

О блоке (К вашему сведению, 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.

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

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

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

На frmMain.FormCreate

frmStartup := TfrmStartup.Create(nil);
try
  frmStartup.ShowModal;
finally
  frmStartup.Free;
end;
Другие вопросы по тегам