Delphi 如何在TIdCmdTCPServer OnConnect事件中将选项卡页安全添加到PageControl?
当客户端连接到我的Delphi 如何在TIdCmdTCPServer OnConnect事件中将选项卡页安全添加到PageControl?,delphi,tcpserver,tpagecontrol,system-error,ttabsheet,Delphi,Tcpserver,Tpagecontrol,System Error,Ttabsheet,当客户端连接到我的IdCmdTCPServer时,我想将选项卡页动态添加到页面控件,与此代码相同: procedure TForm1.IdCmdTCPServer1Connect(AContext: TIdContext); var ATabSheet: TTabSheet; begin ATabSheet := TTabSheet.Create(PageControl1); ATabSheet.PageControl := PageControl1; ATabSheet.Cap
IdCmdTCPServer
时,我想将选项卡页
动态添加到页面控件
,与此代码相同:
procedure TForm1.IdCmdTCPServer1Connect(AContext: TIdContext);
var
ATabSheet: TTabSheet;
begin
ATabSheet := TTabSheet.Create(PageControl1);
ATabSheet.PageControl := PageControl1;
ATabSheet.Caption := 'Hello!';
{...}
end;
没问题,但当关闭应用程序时,我会收到一条错误消息:“系统错误。代码:1400。无效的窗口句柄”。
我已经在TButton
的OnClick
事件中添加了这个代码块,应用程序将毫无问题地关闭。
有没有更安全的方法
在他的帮助下,我改变了我的方法:
....
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;
和命令测试结果:
但提到的问题是,在应用程序关闭时发生钢 事件处理程序及其包含的VCL访问代码在GUI线程以外的线程上执行。所有访问VCL对象的代码都必须在GUI线程上执行。因此,您需要更改代码,以确保VCL部分被编组到GUI线程 使用TIdSync或TThread.Synchronize将代码的VCL部分封送到GUI线程。雷米在这里给出了前一种方法的示例:最终正确的想法:
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;
当然,当前连接必须在应用程序关闭之前关闭。如果否,将发生无效指针操作
特别感谢也许这会有所帮助@bummi:谢谢你的建议。但是我检查了我的TCP部分代码,在
OnConnect
事件中没有这个块代码,它们运行得很好。当我添加此块时,问题就会出现!你必须按照我在回答中说的去做。调用TThread.Synchronize。不要再创建另一个线程!哪根线?你说的TThread
是一个类,我必须同步基于这个类的哪个标识符?使用类方法TThread.synchronize。或者是雷米在我回答的问题中描述的变体。但是现在你需要停止使用试错法,阅读线程的基础知识,同步的概念以及为什么需要同步。在你继续之前你需要理解。很多!我已经改变了我的代码和雷米的想法一样,这次没有看到错误消息,但是关闭应用程序时会出现“无效操作句柄”!