delphitcpservertpagecontrolsystem-errorttabsheet

How to safe add a Tabsheet to a PageControl in TIdCmdTCPServer OnConnect event?


I want to add a Tabsheet dynamically to a PageControl when a client connected to my IdCmdTCPServer same as this code:

procedure TForm1.IdCmdTCPServer1Connect(AContext: TIdContext);
var
  ATabSheet: TTabSheet;
begin
  ATabSheet := TTabSheet.Create(PageControl1);
  ATabSheet.PageControl := PageControl1;
  ATabSheet.Caption := 'Hello!';
  {...}
end;

Its OK, but when closing application i will get EOSError with message: "System Error. Code: 1400. Invalid window handle". I've been added this code block in a TButton's OnClick event, and application will close without any problem. Is there any safer way to do this?


After David Heffernan's help, I've Changed my methode this way:

....

type
  TMyThrd = class(TThread)
    protected
      procedure Execute; override;
  end;

...

procedure TMyThrd.Execute;
begin
  with TTabsheet.Create(Form1.PageControl1) do
    PageControl := Form1.PageControl1;
end;

...

procedure TForm1.cmdAddTabCommand(ASender: TIdCommand);
begin
  with TMyThrd.Create(True) do
  begin
    FreeOnTerminate := True;
    Resume;
  end;
end;

And command test result:

addtab Command Testing Result

but the mentioned problem is steel happening on application close!


Solution

  • Your event handler, and therefore the VCL accessing code that it contains, executes on a thread other than the GUI thread. All code that accesses VCL objects must execute on the GUI thread. Hence, you will need to change your code to make sure that the VCL portions are marshalled on to the GUI thread.

    Use TIdSync or TThread.Synchronize to marshal the VCL portions of your code onto the GUI thread. Remy gives an example of the former approach here: Indy synchronize ServerTCPExecute