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:
but the mentioned problem is steel happening on application close!
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