当我的Tabsheet
客户端与此代码相同时,我想动态地向PageControl
添加IdCmdTCPServer
:
procedure TForm1.IdCmdTCPServer1Connect(AContext: TIdContext);
var
ATabSheet: TTabSheet;
begin
ATabSheet := TTabSheet.Create(PageControl1);
ATabSheet.PageControl := PageControl1;
ATabSheet.Caption := 'Hello!';
{...}
end;
没关系,但是在关闭应用程序时,我会收到EOSError的消息:“系统错误。代码:1400。窗口句柄无效”。
我已经在TButton
的{{1}}事件中添加了此代码块,应用程序将关闭而没有任何问题。
有没有更安全的方法呢?
在David Heffernan的帮助之后,我改变了我的方法:
OnClick
命令测试结果:
但提到的问题是在应用程序关闭时发生的钢铁!
答案 0 :(得分:1)
您的事件处理程序,以及它包含的VCL访问代码,在GUI线程以外的线程上执行。访问VCL对象的所有代码都必须在GUI线程上执行。因此,您需要更改代码以确保将VCL部分编组到GUI线程上。
使用TIdSync或TThread.Synchronize将代码的VCL部分封送到GUI线程中。雷米在这里给出了前一种方法的一个例子:Indy synchronize ServerTCPExecute
答案 1 :(得分:0)
最终正确的想法:
uses
..., IdSync, ...
...
type
TSyncThrd = class(TIdSync)
protected
procedure DoSynchronize; override;
end;
...
procedure TForm1.cmdAddTabCommand(ASender: TIdCommand);
begin
with TSyncThrd.Create do
begin
try
Synchronize;
finally
Free;
end;
end;
end;
...
procedure TSyncThrd.DoSynchronize;
begin
with TTabsheet.Create(Form1.PageControl1) do
PageControl := Form1.PageControl1;
end;
当然,在应用程序关闭之前必须关闭当前连接。如果不是,则会发生invalid pointer operation
!
特别感谢David Heffernan