Delphi7中IB TWS API 9.71的dispinterface数据接收问题
Delphi7中IB TWS API无法接收返回数据的问题排查
问题背景
在Delphi7中编写程序使用IB TWS API 9.71单元,能够正常调用API的功能(如连接、发送请求),但无法接收API返回的数据。相关代码如下:
TWSLib_TLB单元部分代码
unit TWSLib_TLB; const LIBID_TWSLib: TGUID = '{0A77CCF5-052C-11D6-B0EC-00B0D074179C}'; DIID__DTws: TGUID = '{0A77CCF6-052C-11D6-B0EC-00B0D074179C}'; DIID__DTwsEvents: TGUID = '{0A77CCF7-052C-11D6-B0EC-00B0D074179C}'; CLASS_Tws: TGUID = '{0A77CCF8-052C-11D6-B0EC-00B0D074179C}'; type _DTwsEvents = dispinterface; // DispIntf: _DTwsEvents // Flags: (4096) Dispatchable // GUID: {0A77CCF7-052C-11D6-B0EC-00B0D074179C} // *********************************************************************// _DTwsEvents = dispinterface procedure currentTime(time: Integer); dispid 32; // OLE Control Proxy class declaration // Control Name : TTws // Help String : Tws Control // Default Interface: _DTws // Def. Intf. DISP? : Yes // Event Interface: _DTwsEvents // TypeFlags : (34) CanCreate Control TTwscurrentTime = procedure(ASender: TObject; time: Integer) of object;
程序中的错误代码
procedure TForm1.Connect_TWSClick(Sender: TObject); var Disp:IDispatch; Event:_DTwsEvents; begin Tws1.connect('127.0.0.1', 7496, 0, 0); Disp:=CreateComObject(CLASS_Tws) as IDispatch; Event:=_DTwsEvents(Disp); time:=1; Tws1.reqCurrentTime; Event.currentTime(time); //此处time应获取当前时间,但并未更新 end;
根据API手册说明:"ActiveX事件从系统接收信息并提供给应用程序,本节定义可通过DTwsEvents接口接收的ActiveX事件",其中currentTime方法用于*"接收服务器端的当前系统时间"*。
错误分析
你的代码存在三个核心错误:
- 错误创建独立Tws COM对象:窗体上已有的
Tws1控件已经封装了Tws的COM实例和事件框架,但你额外通过CreateComObject(CLASS_Tws)创建了新对象,这个新对象和正在通信的Tws1完全无关,事件绑定到它自然收不到返回数据。 - 错误调用事件回调方法:
Event.currentTime(time)不是主动获取数据的方法,它是API收到服务器返回时自动触发的回调接口,手动调用只会传入你自己设置的time:=1,无法获取服务器数据。 - 未绑定事件处理程序:没有将事件逻辑绑定到
Tws1的currentTime事件上,导致服务器返回数据时无对应代码处理。
正确实现方式
步骤1:添加事件处理过程
在窗体类声明中添加currentTime事件的处理方法:
type TForm1 = class(TForm) Tws1: TTws; Connect_TWSClick: TButton; procedure Connect_TWSClick(Sender: TObject); // 新增事件处理过程 procedure Tws1currentTime(Sender: TObject; time: Integer); private { Private declarations } public { Public declarations } end;
步骤2:实现事件处理逻辑
编写Tws1currentTime方法处理服务器返回的时间:
procedure TForm1.Tws1currentTime(Sender: TObject; time: Integer); begin // 可将时间显示到控件或做其他处理 ShowMessage('服务器返回的当前时间:' + IntToStr(time)); end;
步骤3:修正连接请求代码
移除多余的COM对象创建代码,直接使用Tws1发送请求:
procedure TForm1.Connect_TWSClick(Sender: TObject); begin Tws1.connect('127.0.0.1', 7496, 0, 0); // 发送获取时间请求,等待事件触发 Tws1.reqCurrentTime; end;
关键说明
- 确保在Delphi对象 inspector 中,将
Tws1控件的currentTime事件关联到你编写的Tws1currentTime方法(也可手动在代码中绑定)。 currentTime事件是被动触发的,服务器返回数据时API会自动调用你的处理方法,无需手动调用。
内容的提问来源于stack exchange,提问作者keymaker
相关产品推荐
相关产品推荐

