Hello,
I believe I have found a bug with the OnCreate routine.
Given the following example:
type
TForm1 = class(TWebForm)
WebHTMLDiv1: TWebHTMLDiv;
WebHTMLDiv2: TWebHTMLDiv;
WebHTMLDiv3: TWebHTMLDiv;
WebHTMLDiv4: TWebHTMLDiv;
[async] procedure WebFormShow(Sender: TObject);
private
{ Private declarations }
f2:TForm2;
f3:TForm3;
f4:TForm4;
f5:TForm5;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.WebFormShow(Sender: TObject);
begin
f2:=TForm2.CreateNew(WebHTMLDiv1.ElementID, nil);
await(TForm2, f2.Load);
f3:=TForm3.CreateNew(WebHTMLDiv2.ElementID, nil);
await(TForm3, f3.Load);
f4:=TForm4.CreateNew(WebHTMLDiv3.ElementID, nil);
await(TForm4, f4.Load);
f5:=TForm5.CreateNew(WebHTMLDiv4.ElementID, nil);
await(TForm5, f5.Load);
end;
Where each WebForm has the OnCreate routine:
procedure WebFormCreate(Sender: TObject);
begin
writeln(Self.ClassName+' created.');
end;
The behaviour is as expected except for the last object, where the TForm5 OnCreate will fire as many times as there are other extant WebForms.
This behaviour will occur with whichever WebForm is created last.
I'm not sure why you added the call await(TFormX, fX.Load);
I have modified the demo under Demo\Basics\FormHosting to mimic this setup with 2 forms and added an extra panel where to host the 2nd created form.
The code to create the forms in the panels;:
procedure TFrmMain.btCreateSubF2Click(Sender: TObject);
begin
frm1 := TSubForm1.CreateNew(WebPanel1.ElementID, nil);
end;
procedure TFrmMain.btCreateSubF2Click(Sender: TObject);
begin
frm2 := TSubForm2.CreateNew(WebPanel1.ElementID, nil);
end;
and I couldn't see anything wrong with the OnCreate event handler set for both forms:
procedure TSubForm1.WebFormCreate(Sender: TObject);
begin
console.log(Self.ClassName+' created.');
end;
procedure TSubForm2.WebFormCreate(Sender: TObject);
begin
console.log(Self.ClassName+' created.');
end;
So, please use the technique as demonstrated in this demo.
Hi Bruno,
Thanks for the reply.
I am aware of using callbacks as you have described (that's what I'm currently doing).
I heavily dislike using callbacks to achieve this as I find it makes code harder to read and maintain.
I saw an old topic from years ago where the idea of an async CreateNew was mentioned. Could this be a possibility in the future?
If you do not want to use callbacks, modifying the code in the demo Demo\Basics\MultiForm to show the created form in a WebPanel1 on the form becomes:
var
newform: TForm2;
begin
newform := TForm2.Create(WebPanel1.ElementID);
TAwait.ExecP<TForm2>(newform.Load());
// init control after loading
newform.frm2Edit.Text := WebEdit1.Text;
try
// excute form and wait for close
TAwait.ExecP<TModalResult>(newform.Execute);
ShowMessage('Form 2 closed with new value:"'+newform.frm2Edit.Text+'"');
WebEdit1.Text := newform.frm2Edit.Text;
finally
newform.Free;
end;
end;
so, here you can further modify the created form after the await() on the async load function.