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しかし、クライアント側でいつ呼び出すかを知るためにイベントが必要です。その種のデータフローを実行する通常の方法は何ですか?

4

1 に答える 1

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;
于 2016-04-19T10:00:47.387 に答える