You need to enable JavaScript to run this app. Delphi跨单元交互:Unit2中TSocket事件如何修改Unit1窗体TCircle控件颜色
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 01:36:07