Delphi跨单元交互:Unit2中TSocket事件如何修改Unit1窗体TCircle控件颜色
实现方案
核心思路是在Unit2的通信类中自定义公开事件,由Unit1订阅这些事件并实现对应业务逻辑,完全避免Unit2依赖Unit1,实现解耦。
第一步:修改Unit2,定义事件并触发逻辑
修改后的Unit2代码如下:
uses SysUtils, ScktComp; type // 自定义事件类型:连接成功事件 TConnectedEvent = procedure(Sender: TObject) of object; // 自定义事件类型:收到数据事件,将收到的字符串作为参数传出 TDataReceivedEvent = procedure(Sender: TObject; const RecvText: string) of object; TCommunication = class(TObject) ClientSocket1 : TClientSocket; procedure ClientOnRead(Sender: TObject; Socket: TCustomWinSocket); procedure ClientOnConnect(Sender: TObject; Socket: TCustomWinSocket); public // 公开事件属性,供外部订阅 OnConnected: TConnectedEvent; OnDataReceived: TDataReceivedEvent; constructor Create; destructor Destroy; override; end; procedure TCommunication.ClientOnConnect(Sender: TObject; Socket: TCustomWinSocket); begin // 外部已订阅事件则触发 if Assigned(OnConnected) then OnConnected(Self); end; procedure TCommunication.ClientOnRead(Sender: TObject; Socket: TCustomWinSocket); var s : String; begin s := ClientSocket1.Socket.ReceiveText; // 外部已订阅事件则触发,把收到的数据传出去 if Assigned(OnDataReceived) then OnDataReceived(Self, s); end; constructor TCommunication.Create; begin ClientSocket1 := TClientSocket.Create(nil); with ClientSocket1 do begin Address := '127.0.0.1'; Port := 4545; OnConnect := ClientOnConnect; OnRead := ClientOnRead; end; end; destructor TCommunication.Destroy; begin ClientSocket1.Free; inherited; end;
第二步:修改Unit1,订阅事件并实现业务逻辑
修改后的Unit1代码如下:
uses ..., Unit2, Vcl.Graphics; // 引用Graphics单元调用颜色常量 type TForm1 = class(TForm) Button1: TButton; Circle1: TCircle; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private // 声明事件处理方法 procedure OnCommunicationConnected(Sender: TObject); procedure OnCommunicationDataReceived(Sender: TObject; const RecvText: string); ... var Form1: TForm1; Communication: TCommunication; implementation procedure TForm1.Button1Click(Sender: TObject); begin Communication.ClientSocket1.Active := True; end; procedure TForm1.FormCreate(Sender: TObject); begin Communication := TCommunication.Create; // 绑定事件处理方法 Communication.OnConnected := OnCommunicationConnected; Communication.OnDataReceived := OnCommunicationDataReceived; end; // 连接成功后的业务逻辑:修改Circle颜色 procedure TForm1.OnCommunicationConnected(Sender: TObject); begin Circle1.Fill.Color := clGreen; end; // 收到数据后的业务逻辑:可执行多步窗体操作 procedure TForm1.OnCommunicationDataReceived(Sender: TObject; const RecvText: string); begin // 示例:可以在这里实现任意窗体业务逻辑,比如: // 1. 把收到的内容显示到Memo控件 // Memo1.Lines.Add(RecvText); // 2. 解析数据后更新其他控件状态 // 3. 弹出提示、更新列表等其他操作 end;
注意事项
- 非阻塞模式下
TClientSocket的事件默认在主线程触发,可以直接修改VCL控件属性,不需要额外同步。 - 如果后续通信逻辑调整为多线程实现,修改VCL控件前需要调用
Synchronize同步到主线程执行。
内容的提问来源于stack exchange,提问作者Wellington Telles Cunha
相关产品推荐
相关产品推荐

