Модальная форма равна нулю после создания - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь создать экземпляр формы и передать параметр, который должен быть специфичным для этого экземпляра.

type
  TDataForm = class(TForm)
    { Some components}
    { Some procedures }
    constructor Create(AOwner: TComponent; Data: PData; Page: String); reintroduce;
  private
    { Private declarations }
  public
    { Public declarations }
    ViewedData: PData;
  end;

var CharacterScreen: TDataForm;

implementation

CharacterScreen - это переменная для одного из экземпляров sucn.Когда я открываю экземпляр, я делаю это так:

constructor TDataForm.Create(AOwner: TComponent; Data: PData; Page: String);
begin
inherited Create(nil);
ViewedData:=Data;
if Page='Stats'      then CharPageControl.TabIndex:=0;
if Page='Equipment'  then CharPageControl.TabIndex:=1;
if Page='Effects'    then CharPageControl.TabIndex:=2;
if Page='Statistics' then CharPageControl.TabIndex:=3;
ShowModal;
Free;
end;

CharacterScreen:=TDataForm.Create(nil,@Data,'Page 1');

Как бы то ни было, если позже я вызываю какую-то процедуру для формы, я получаю ошибку AV.При просмотре переменной CharacterScreen в пошаговой отладке она описывается как nil.

Так что мой вопрос: как правильно создать экземпляр формы (чтобы позже я мог создать второй экземпляри так далее)?Кроме того, это правильный способ хранения экземпляра переменной ViewedData, который должен быть уникальным для каждого экземпляра формы?

1 Ответ

4 голосов
/ 21 апреля 2019

Проблема в том, что вы вызываете Free из конструктора, поэтому экземпляр будет недоступен при закрытии формы.

Вы можете добавить статический метод в форму и вызывать его из других форм.

рекомендуется удалить глобальную переменную формы, чтобы вызывающий код объявлял локальную переменную (это станет очевидным при создании нескольких экземпляров одной и той же формы). В этом примере я сделал конструктор закрытым, чтобы за пределами этого модуля можно было вызывать только метод execute.

type
  TDataForm = class(TForm)
    { Some components}
    { Some procedures }
  private
    { Private declarations }
    ViewedData: PData;
    constructor Create(AOwner : TComponent);
  public
    { Public declarations }
    class procedure Execute(Data: PData; APage: String);
  end;

implementation

class function TDataForm.Execute(Data: PData; APage: String) :TDataForm;

begin
 Result := TDataForm.Create(nil);
 Result.ViewedData := PData;
 if APage='Характеристики' then Result.CharPageControl.TabIndex:=0 else
 if APage='Экипировка'     then Result.CharPageControl.TabIndex:=1 else
 if APage='Эффекты'        then Result.CharPageControl.TabIndex:=2 else
 if APage='Статистика'     then Result.CharPageControl.TabIndex:=3;
 Result.ShowModal;
end;

constructor TDataForm.Create(AOwner: TComponent);
begin
 inherited Create(nil);
end;

теперь вы называете свою форму так:

var CharacterScreen : TDataForm;

CharacterScreen := TDataForm.Execute(@Data,'Page 1');
try
 // do something with CharacterScreen when it has been closed
finally
 CharacterScreen.Free;   
end;

** ОБНОВЛЕНИЕ **

Теперь, если бы я был вами, я бы сделал что-то вроде этого (псевдокод, я полагаю, вы поймете идею):

Unit character;

type
  TCharacterData = class
  public
   // some public fields
  end;

...

Unit EditCharacter;

type 
  TDataForm = class(TForm)
    procedure OnShow(Sender : TObject);
  public
    class procedure Execute(Data : TCharacterData) : Boolean;  
  end;

implementation;

class function TDataForm.Execute(var Character: TCharacter) : Boolean;

var Frm: TDataForm ;

begin
 Result := False; 
 Frm:= TDataForm.Create(nil);
 try
  Frm.Character := Character;
  Frm.ShowModal;
  Result := Frm.ModalResult = mrOK;
 finally
  Frm.Free;
 end;
end;

procedure TDataForm.OnShow(Sender : TObject);
 begin
  if Character = TWizardCharacter then Frm.CharPageControl.TabIndex:=0 else
  if Character = TBarbarianCharacter then Frm.CharPageControl.TabIndex:=1
   ... //etc
 end;

теперь вызывающий код может выглядеть следующим образом

var Character : TCharacter;
...

Character := TWizardCharacter.Create;

...
// user wants to edit character

procedure EditCharacter;
begin
 if TDataForm.Execute(Character)  then
  begin
   // user has modified character, act accordingly
  end;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...