通过通用接口的异步事件

时间:2016-04-19 09:16:47

标签: delphi asynchronous delphi-2007 tcomport

我必须将多个测量设备连接到我的应用程序(即卡尺,体重秤......),而不是绑定到特定的品牌或型号,所以在客户端我使用通用方法的接口({{1 }})。设备连接在COM端口上,并以异步方式访问:

  1. 要求一个值(=发送一个特定的字符序列 COM端口)
  2. 等待回复
  3. 在“业务”方面,我的组件在内部使用TComPort,数据接收事件为QueryValue。我想知道如何通过界面触发此事件?这是我到目前为止所做的:

    TComPort.OnRxChar

    但我需要一个事件来知道何时在客户端调用IDevice = interface procedure QueryValue; function GetValue: Double; end; TDevice = class(TInterfacedObject, IDevice) private FComPort: TComPort; FValue: Double; protected procedure ComPortRxChar; public constructor Create; procedure QueryValue; function GetValue: Double; end; constructor TDevice.Create; begin FComPort := TComPort.Create; FComPort.OnRxChar := ComPortRxChar; end; // COM port receiving data procedure TDevice.ComPortRxChar; begin FValue := ... end; procedure TDevice.GetValue; begin Result := FValue; end; 。执行这种数据流的常用方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以将事件属性添加到界面

IDevice = interface
  function GetValue: Double;
  procedure SetMyEvent(const Value: TNotifyEvent);
  function GetMyEvent: TNotifyEvent;
  property MyEvent: TNotifyEvent read GetMyEvent write SetMyEvent;
end;

并在TDevice类中实现它

TDevice = class(TInterfacedObject, IDevice)
private
  FMyEvent: TNotifyEvent;
  procedure SetMyEvent(const Value: TNotifyEvent);
  function GetMyEvent: TNotifyEvent;
public
  function GetValue: Double;
  procedure EmulChar;
end;

然后通常在FMyEvent的末尾调用ComPortRxChar处理程序(如果已分配)。

 Tform1...
  procedure EventHandler(Sender: TObject);

procedure TForm1.EventHandler(Sender: TObject);
var
  d: Integer;
  i: IDevice;
begin
  i := TDevice(Sender) as IDevice;
  d := Round(i.GetValue);
  ShowMessage(Format('The answer is %d...', [d]));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  id: IDevice;
begin
  id:= TDevice.Create;
  id.MyEvent := EventHandler;
  (id as TDevice).EmulChar; //emulate rxchar arrival
end;

procedure TDevice.EmulChar;
begin
  if Assigned(FMyEvent) then
    FMyEvent(Self);
end;

function TDevice.GetMyEvent: TNotifyEvent;
begin
  Result := FMyEvent;
end;

function TDevice.GetValue: Double;
begin
  Result := 42;
end;

procedure TDevice.SetMyEvent(const Value: TNotifyEvent);
begin
  FMyEvent := Value;
end;