如何在TIdCmdTCPServer OnConnect事件中安全地将Tabsheet添加到PageControl?

时间:2013-05-30 08:04:09

标签: delphi tcpserver tpagecontrol system-error ttabsheet

当我的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

命令测试结果:

addtab Command Testing Result

但提到的问题是在应用程序关闭时发生的钢铁!

2 个答案:

答案 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