Search code examples
firemonkeyindybroadcast

Firemonkey - Indy UDP broadcast


A given class with a TIDUDPServer instance:

unit udpbroadcast_fm;

TUDPBC_FM = class( TObject )
protected
  IdUDPServer: TIdUDPServer; 
  Timer: TTimer;
  ...
  procedure IdUDPServerUDPRead( AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle );
  procedure TimerOnTimer( Sender: TObject );
public
  constructor Create;
  function SendDiscover: integer;  
properties  
  ...
end;

function TUDPBC_FM.SendDiscover: integer;  
begin
...
IdUDPServer.Broadcast( udpDiscovery, BCport );
...
end;

Im using this class to send a UDP broadcast message. My question is that how can i 'signal' back to a form/custom class instance from the onTimer event handler ('TimerOnTimer') of 'Timer' (defined as TUDPBC_FM field)?

The timer's interval been set to 2000msec, so there is two sec for all the devices to answer for the broadcast, then i want to send a signal to a form or class instance.

In my VCL application i was using messages for this, but now im on firemonkey.

Maybe the only way is to use another approach? For example, putting the timer as the form's field?).


unit mstcc_fm;

Tmstcc = class(TObject)
protected
  Fudpbc : TUDPBC_FM;
  ...
public
  function msts_Discover: integer; 
  ...
end;

function Tmstcc.msts_Discover: integer;    
begin
  ...
  Fudpbc.SendDiscover;
  ...
end;

Form unit:

unit main_fm;
...
procedure TfrmMain.btnDiscoverClick(Sender: TObject);
begin
  mstcc.msts_Discover;
  ...
end;

Solution

  • how can i 'signal' back to a form/custom class instance from the onTimer event handler ('TimerOnTimer') of 'Timer' (defined as TUDPBC_FM field)?

    You can use TThread.Queue(), eg:

    procedure TUDPBC_FM.NotifyProc;
    begin
      // do something...
    end;
    
    procedure TUDPBC_FM.TimerOnTimer(Sender: TObject);
    begin
      TThread.Queue(NotifyProc);
    end;
    

    procedure TUDPBC_FM.TimerOnTimer(Sender: TObject);
    begin
      TThread.Queue(
        procedure
        begin
          // do something...
        end
      );
    end;
    

    Or TIdNotify:

    procedure TUDPBC_FM.NotifyProc;
    begin
      // do something...
    end;
    
    procedure TUDPBC_FM.TimerOnTimer(Sender: TObject);
    begin
      TIdNotify.NotifyMethod(NotifyProc);
    end;
    

    type
      TMyNotify = class(TIdNotify)
      protected
        procedure DoNotify; override;
      end;
    
    procedure TMyNotify.DoNotify;
    begin
      // do something...
    end;
    
    procedure TUDPBC_FM.TimerOnTimer(Sender: TObject);
    begin
      TMyNotify.Create.Notify;
    end;