Einzelnen Beitrag anzeigen

MorrisF

Registriert seit: 3. Apr 2019
41 Beiträge
 
#1

Methode/Klasse "Modal" aufrufen?

  Alt 10. Nov 2021, 10:27
Hallo liebe Delphi-Praxis Community,
Ich bin auf ein Problem mit einem meiner Delphi-Projekte gestoßen. Habe eine SIP-Phone-Klasse geschrieben, um Clients anzurufen.
Funktioniert soweit tadellos, aber ich will, dass das Programm wartet, bis der Anruf abgeschlossen ist.
So rufe ich einen Client an:
Delphi-Quellcode:
procedure TDialog_TelefonVOIP_Test.ButtonQuickCallClick(Sender: TObject);
var
  tmpTel: TTelefon;
begin
  tmpTel := TTelefon.Create(Self, '192.168.x.y', 'xy', '******', True, True);
  try
    tmpTel.Anrufen('001726599722', True, 'This is a text to speech test. Is this working?', True);
  finally
    FreeAndNil(tmpTel);
  end;
end;
Das Problem ist, dass das Programm in FreeAndNil(tmpTel) geht, bevor der Aufruf fertig/überhaupt gestartet ist.
Hier ist der vereinfachte Code meiner TTelefon-Klasse:
Delphi-Quellcode:
unit TEST_Telefon;

interface

uses
  Classes, SysUtils, Controls, Dialogs, Vcl.ExtCtrls, Vcl.Forms, System.Threading,
  sipclient, call, ringtone;

type
  RCallData = record
    Call: ICall;
    Number: string;
    TTS: Boolean;
    TTSText: string;
  end;

var
  CallData: RCallData;
  SIP_Client: Tsipclient;

type
  TTelefon = class(TObject)
  private
    FServerConnected: Boolean;
    FRinging: Boolean;
    FCallConnected: Boolean;

    Caller: TComponent;

    procedure OnAnswer(Sender: TObject; const aCall: ICall);
    procedure OnHangUp(Sender: TObject; const aCall: ICall);

  protected
    function Connect(const aServer, aUser, aPass: string): Boolean;
    function Disconnect(): Boolean;

  public
    Server: string;
    User: string;
    Pass: string;

    property ServerConnected: Boolean read FServerConnected;
    property Ringing: Boolean read FRinging;
    property CallConnected: Boolean read FCallConnected;

    constructor Create(aCaller: TComponent; const aServer, aUser, aPass: string; aConnect: Boolean=True);
    destructor Destroy(); override;

    function Call(aNumber: string; aTTS: Boolean=False; aTTSText: String=''): Boolean;
    function HangUp(aDisconnect: Boolean=False): Boolean;

    function GetAnrufStatus(aAnruf: ICall=nil): string;
  end;

implementation

{ TTelefon }

constructor TTelefon.Create(aCaller: TComponent; const aServer, aUser, aPass: string; aConnect: Boolean=True);
begin
  try
    Caller := aCaller;

    if not Assigned(SIP_Client) then
      SIP_Client := TSIPclient.Create(Caller);

    SIP_Client.OnAnswer := OnAnswer;
    SIP_Client.OnBye := OnHangup;

    Server := aServer;
    User := aUser;
    Pass := aPass;

    FServerConnected := False;
    FCallConnected := False;
    FRinging := False;

    if aConnect then
      FServerConnected := Connect(Server, User, Pass);
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

function TTelefon.Connect(const aServer, aUser, aPass: string): Boolean;
var
  tmpConnected: Boolean;
begin
  Result := False;
  try
    tmpConnected := False;

    SIP_Client.Host := aServer;
    SIP_Client.User := aUser;
    SIP_Client.Password := aPass;
    SIP_Client.Proxy := aServer;
    SIP_Client.Active := True;
    SIP_Client.Register;
    tmpConnected := True;

    Result := tmpConnected;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

function TTelefon.Call(aNumber: string; aTTS: Boolean=False; aTTSText: String=''): Boolean;
var
  tmpOK: Boolean;
begin
  try
    tmpOK := False;
    if not FServerConnected then
      FServerConnected := Connect(Server, User, Pass);

    if FServerConnected then
    begin
      CallData.Number := aNumber;
      CallData.TTS := aTTS;
      CallData.TTSText := aTTSText;

      if not Assigned(CallData.Call) then
        CallData.Call := SIP_Client.Call(CallData.Number)
      else if CallData.Call.State = csRinging then
        CallData.Call.Answer()
    end;

    Result := tmpOK;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

function TTelefon.HangUp(aDisconnect: Boolean=False): Boolean;
var
  tmpAufgelegt: Boolean;
begin
  Result := False;
  try
    tmpAufgelegt := False;

    if FCallConnected then
    begin
      if Assigned(CallData.Call) then
        CallData.Call.EndCall();
      tmpAufgelegt := True;

      if aDisconnect and FServerConnected then
        tmpAufgelegt := Disconnect();
    end
    else
      tmpAufgelegt := True;

    OnHangUp(nil, CallData.Call);

    Result := tmpAufgelegt;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

function TTelefon.Disconnect(): Boolean;
begin
  Result := False;
  try
    SIP_Client.Active := False;
    FServerConnected := False;
    Result := not FServerConnected;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

procedure TTelefon.OnAnswer(Sender: TObject; const aCall: ICall);
begin
  inherited;
  try
    if Assigned(aCall) then
      CallData.Call := aCall;
    FCallConnected := True;
    FRinging := False;

    if CallData.TTS AND (CallData.TTSText <> '') then
    begin
      Sleep(50);
      if not Assigned(CallData.Call) then
        CallData.Call := aCall;
      CallData.Call.PlayText(CallData.TTSText, Integer(0));
    end;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

procedure TTelefon.OnHangUp(Sender: TObject; const aCall: ICall);
begin
  inherited;
  try
    if Assigned(aCall) then
      CallData.Call := aCall;
    FCallConnected := False;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;

destructor TTelefon.Destroy();
begin
  try
    try
      if FCallConnected then
        HangUp();
      if FServerConnected then
        Disconnect();
    finally
      FreeAndNil(SIP_Client);
    end;
  except
    on e: Exception do
      ShowMessage(e.Message);
  end;
end;


end.
Ich glaube, ich brauche die Funktionalität von ShowModal() innerhalb der Anrufen()-Methode. Ist das möglich?
Ich würde mich freuen, wenn mir jemand helfen könnte!

Grüße

Morris F

Geändert von MorrisF (11. Nov 2021 um 09:50 Uhr) Grund: Mit Threads zu arbeiten macht hier keinen Sinn, da TSIPClient schon eine synkrone Klasse ist
  Mit Zitat antworten Zitat