问题描述
我有两个TIdTCPClient
组件(TCPClient1和TCPClient2),它们共享相同的OnStatus
属性(见下文)。
组件由它们的Tag
属性标识。如何在共享OnStatus
事件中识别正在调用的TCPClient?
procedure TForm2.TCPClientStatus(ASender: TObject; const AStatus: TIdStatus;
const AStatusText: string);
begin
end;
解决方法
1
参数指向引发事件的对象。对于ASender
,该发件人可以是任一:
-
TIdTCPClient
对象本身 - 客户的
TIdTCPClient
对象
在后一种情况下,IOHandler
事件会与TIdTCPClient.OnStatus
对象挂钩,前提是在客户端计算机内隐式创建该对象IOHandler
属性为Connect()
时的IOHandler
方法。在这种情况下,nil
被设置为该新对象的TIdTCPClient
。另一方面,如果您在调用Owner
之前明确地将自己的TIdIOHandler
派生组件分配给IOHandler
属性,则Connect()
事件将不会自动连接到TIdTCPClient.OnStatus
组件,因此,如果需要,您将不得不为该组件自己的IOHandler
事件单独分配一个处理程序。
因此,在OnStatus
事件处理程序内部,假设正在使用隐式 TIdTCPClient.OnStatus
对象,则可以像这样返回IOHandler
对象:
TIdTCPClient
,
在所有事件处理程序中,在每个组件中,Sender
参数始终是触发事件的对象实例。
要帮助该对象,可以执行简单的投射或安全的投射。对于您使用的TIdTCPClient
和要检查的Tag
属性,它将变为:
TIdTCPClient(Sender).Tag
或
(Sender as TIdTCPClient).Tag
第二种形式更安全,因为如果出于任何原因Sender
都不是假定类型,那么您将在运行时得到一个异常,可以使用try/except
构造进行管理/检测。
您甚至可以在不同类型的组件之间共享同一事件处理程序。我不太了解Indy并没有给出相关示例,因此我将OnClick
事件用于TButton
和TEdit
。您可以使用is
运算符检查类型:
if Sender is TButton then
// Do something using TButton(Sender).SomeProperty
else if Sender is TEdit then
// Do something using TEdit(Sender).SomeProperty