Author Topic: Как открыть новую форму в Delphi  (Read 10860 times)

0 Members and 1 Guest are viewing this topic.

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Как открыть новую форму в Delphi
« on: July 03, 2007, 23:54:16 »
Изначально открывается форма с вводом логина, пароля и пути к БД. Нужно при нажатии на кнопочку открыть новую форму и закрыть эту убрав из памяти. Получется только следующим образом:
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  Form2.ShowModal;
  Form1.Close;
end;
но здесь я полагаю форма из памяти не убирается.

Пробовал  так:
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  Form2.ShowModal;
  Form1.Free;
end;
но потом при закрытии Form2 вылазит ошибка, наверное из-за того что не найдена форма вызвавшая процедуру Form2.ShowModal т.е. Form1.
Как победить грамотно?

Offline demiurg

  • Hero Member
  • *****
  • Posts: 1014
  • Karma: +0/-0
    • http://larin.tomsk.ru
Как открыть новую форму в Delphi
« Reply #1 on: July 04, 2007, 03:05:17 »
Quote from: CRonaldo
Изначально открывается форма с вводом логина, пароля и пути к БД. Нужно при нажатии на кнопочку открыть новую форму и закрыть эту убрав из памяти. Получется только следующим образом:
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  Form2.ShowModal;
  Form1.Close;
end;
но здесь я полагаю форма из памяти не убирается.

Пробовал  так:
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  Form2.ShowModal;
  Form1.Free;
end;
но потом при закрытии Form2 вылазит ошибка, наверное из-за того что не найдена форма вызвавшая процедуру Form2.ShowModal т.е. Form1.
Как победить грамотно?
Очень похоже на попытку удаления гланд через анус.
Из написанного не понятно из какой формы какая вызывается и какую форму следует разрушить.
Во-первых, нужно убедиться что форма не создается автоматически при старте приложения.
Во-вторых, очень сильно рекомендую забыть о глобальных переменных Form1 и Form2 -- это зло.
В-третьих, самый простой способ вызова и разрушения формы
Code: [Select]
program Project1;
uses
  Forms,
  Controls,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.RES}

begin
  Application.Initialize;
  with TForm2.Create(Application) do
    try
      if ShowModal = mrOK then
      //   делаем полезную работу, например
        begin
          Application.CreateForm(TForm1, Form1);
          Application.Run;
        end
      else
        // делаем работу при других ModalResult, например
        Application.Terminate
    finally
      Free
   end;
end.
На форме Form2 нужно при нажатии кнопки OK выполнить необходимую работу, например, проверить правильность имени и пароля, путей и т.д. и вернуть ModalResult := mrOK, для для кнопки отмена можно сразу установить ModalResult в mrCancel.
Можно так же создать обработчик OnClose
Code: [Select]
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   Action := caFree
end;
В указанном случае форма будет разрушаться после вызова Close;
« Last Edit: July 04, 2007, 11:33:15 by demiurg »

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Как открыть новую форму в Delphi
« Reply #2 on: July 04, 2007, 21:10:11 »
Code: [Select]
program Project1;
uses
  Forms,
  Controls,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.RES}

begin
  Application.Initialize;
  with TForm2.Create(Application) do
    try
      if ShowModal = mrOK then
      //   делаем полезную работу, например
        begin
          Application.CreateForm(TForm1, Form1);
          Application.Run;
        end
      else
        // делаем работу при других ModalResult, например
        Application.Terminate
    finally
      Free
   end;
end.

Спасибо! Вроде работает. Если первая форма создаётся и открывается здесь:
with TForm2.Create(Application) do
тогда всё понятно  Хотя где это ещё может быть!
Кстати, что ты имел ввиду когда говорил забыть о глобальных переменных Form1 и Form2?
« Last Edit: July 04, 2007, 21:10:47 by CRonaldo »

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Как открыть новую форму в Delphi
« Reply #3 on: July 06, 2007, 13:54:20 »
А что происходит если на созданную форму сделать ещё Create? Она просто обновиться и лишней памяти не займет?

Offline demiurg

  • Hero Member
  • *****
  • Posts: 1014
  • Karma: +0/-0
    • http://larin.tomsk.ru
Как открыть новую форму в Delphi
« Reply #4 on: July 06, 2007, 16:32:52 »
Quote from: CRonaldo
Спасибо! Вроде работает. Если первая форма создаётся и открывается здесь:
with TForm2.Create(Application) do
тогда всё понятно  Хотя где это ещё может быть!
Кстати, что ты имел ввиду когда говорил забыть о глобальных переменных Form1 и Form2?
Это значит, что не следует из использовать, или хотя бы использовать только в тех случаях, когда без этого невозможно обойтись, но полагаться на существование конкретного экземпляра класса в методах этого класса неверно и опасно, вот например, кусок Вашего кода
Code: [Select]
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  .....
  Form1.Free;
end;
Правильнее делать
Code: [Select]
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  ...
  Free;
end;
или
Code: [Select]
procedure TForm1.ButtonOKClick(Sender: TObject);
begin
  ....
  Self.Free;
end;
если требуется уточнение "контекста" вызова метода.
Quote from: CRonaldo
А что происходит если на созданную форму сделать ещё Create? Она просто обновиться и лишней памяти не займет?
Вам нужно срочно читать буквари по ООП и по работе с указателями.
Когда Вы делаете Form1 := TForm1.Create(.....) еще раз, создается еще один экземпляр класса TForm1 при этом старый указатель в Form1 "затирается", но "старый" экземпляр класса никуда не денется, memory leak конечно не будет, так как этот объект в принципе доступен через Application и владелец его разрушит перед собственным разрушением, но если сделать
Code: [Select]
Form1 := TForm1.Create(nil);
Form1 := TForm1.Create(nil);
то "утечка памяти" гарантирована.
« Last Edit: July 06, 2007, 16:34:56 by demiurg »

Offline CRonaldo

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Как открыть новую форму в Delphi
« Reply #5 on: July 06, 2007, 19:18:15 »
Спасиба!
Quote from: demiurg
Вам нужно срочно читать буквари по ООП и по работе с указателями.
Литературы в электронном виде много. Многие читал, только сейчас каша в голове. Практически получается, что делаю программу и учусь (самоучка), при этом понимаю, что скорее всего придется частично её переделывать потом. Но дело в том, что к концу года нужно её сделать, а БД и прога думаю достаточно большая даже не для начинающего программиста, хотя я вообще даже не программист .