2016-04-19 8 views
1

私は、特定のブランドやモデルに縛られていない私のアプリ(すなわち、キャリパー、重量スケールなど)にいくつかの測定デバイスを接続する必要があります。方法(QueryValue)。デバイスは、COMポートに接続されており、非同期の方法でアクセスされます:ジェネリックインターフェイスによる非同期イベント

  1. は、「オン応答

待つの値を求める(= COMポートに特定の文字列を送信)

  • 私のコンポーネントは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を呼び出すために時を知るためのイベントを必要とする:ここでは、私がこれまで行ってきたものです。この種のデータフローを実行する通常の方法は何ですか?あなたは

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

    をインターフェースとComPortRxCharの終わりに(割り当てられている場合)通常FMyEventハンドラを呼び出すよう

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

    その後TDeviceクラスでそれを実現するためのイベントプロパティを追加することができます

  • 答えて

    1

    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'メソッドの中に' Assigned(FMyEvent)then FMyEvent(Self); 'と書くと(私が以前に行ったように、私はインターフェイスなしで)、' Get/SetMyEvent'は暗黙のうちに何を意味しますか? – paradise

    +0

    例が追加されました。 – MBo

    +0

    ありがとうございます!それは私がそれを理解した方法です;)それはかなり良い解決策ですが、私はまだ欠点を見ています:**私はクライアント側で**実装だけではなく**インタフェースを使用するので、それは 'EventHandler' 'Sender'を' IDevice'としてキャストするのですか?さもなければ、IDevice var( 'Button1Click'のあなたの" id ")をクラスvarとして宣言する必要があります。 – paradise

    関連する問題