2016-04-19 28 views
1

我必須將多個測量設備連接到我的應用程序(即卡尺,體重秤等),而不是綁定到特定品牌或型號,所以在客戶端我使用通用接口方法(QueryValue)。設備連接COM端口和訪問關於異步方式:通過通用接口的異步事件

  1. 詢問的值(=對 COM端口發送一個特定的字符序列)
  2. 等待響應

在'業務「方面,我的組件在內部使用TComPort,數據接收事件爲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; 

但我需要一個事件來知道什麼時候在客戶端調用GetValue。執行這種數據流的常用方法是什麼?

回答

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; 
+0

請問您能開發嗎?在'TDevice'中,如何'將FMyEvent'連接到'Get/SetMyEvent'?如果在'TDevice.ComPortRxChar'方法中,我寫'如果賦值(FMyEvent),然後FMyEvent(Self);'(就像我曾經這樣做 - 我的意思是沒有接口),什麼時候暗示了Get/SetMyEvent? – paradise

+0

添加示例.. – MBo

+0

謝謝!這是我的理解;)這是一個很好的解決方案,但我仍然看到一個缺點:因爲我只在客戶端使用**接口,而不是實現(這是主要目標),是否有'EventHandler'將'Sender'作爲'IDevice'投入?否則,我應該將IDevice var(Button1Click中的「id」)聲明爲類var。 – paradise