Du musst die
Unit mit TCAPIISDN Kopieren da alles was fehler enthält privat deklariert ist.
Ich hab die Klasse dann umbenannt in TADCCapi (ADC = Brötchengeber).
Suche nach //A.R.
Wenn du Audio dateien abspielst sag bescheid da hab ich noch einen Patch um das Kancken am ende der
der Dateien zu verhindern(Oder suche nach "fill" und passe an der Stelle die Packetgröße an statt sie mit 0 aufzufüllen ).
Ach ja, aus den ereignissen heraus läst sich keine Weitere CAPI Function aufrufen.
Beispiel: im IncommingCall ereigniss kannst bleibt die Connect Methodeun wirksam.
Das liegt daran weil der Handshake mit der CAPI erst nach dem ereignis erfolgt.
Lösung: eine Klasse dazu stellen vom Typ TWincontrol die Handler für WM_USER+n messages empfängt
und die Methoden Triggert.Jetzt kann in den Ereignissen die Message Gesendet werden welche Capi Funktion benutzt werden soll, ...nur PostMessage verwenden.
Delphi-Quellcode:
procedure TADCCapi.CapiEvent( aConnection : TConnection;
aMsg : TCapiMessage;
var aDefaultHandling : boolean );
var // astruct:TStruct;
aDTMFDigits:string;
i:integer;
begin
SetFError; { Damit die Anwendung den richtigen Error mitkriegt }
if (aMsg.Header.WordCommand<>DATA_B3_IND) and (aMsg.Header.WordCommand<>DATA_B3_CONF) then
if _debug>1 then begin
Debug(CapiGetCommandString(aMsg.Header.WordCommand)+' ('+inttostr(aMsg.Header.WordCommand)+')');
end
else if _debug>5 then
Debug(CapiGetCommandString(aMsg.Header.WordCommand));
if _debug>4 then
debugcapimessage(amsg);
case aMsg.Header.WordCommand of
{ ---------------------------------------------------------------}
LISTEN_CONF : begin
end;
{ ---------------------------------------------------------------}
DISCONNECT_CONF : Begin
end;
{----------------------------------------------------------------}
CONNECT_CONF : begin
// Das TConnection-Objekt ist bei einem Fehler bereits NIL
if not assigned(aConnection) then
Begin
{in der Messagenumber wird die ConnectionID gespeichert
um die Verbindung ermitteln zu können (siehe CPHand) }
FConnectionInfos.FreeConnectionInfo(
TConnectConf(aMsg).header.messagenumber)
end
else
begin //A.R.
{dieses event Signalisiert das gerade gewählt wird oder
das es einen Fehler bei der Verbindung gab.
Ohne dieses Event ginge CONNECT_CONF !!verloren!! }
ConnectingFailed(TConnectConf(aMsg).header.messagenumber);
end;
end;
{ ---------------------------------------------------------------}
CONNECT_IND : begin
if Assigned(FIncomingCall)
then FIncomingCall(aConnection.ID,
TConnectInd(aMsg).CallingPartyNumber.Contents,
TConnectInd(aMsg).CalledPartyNumber.Contents,
TConnectInd(aMsg).CipValue,
CapiGetCipValueString(TConnectInd(aMsg).CipValue));
{Timer vorübergehend deaktivieren}
if assigned(FTimer) then FTimer.OnTimer := nil;
FConnectionInfos.createConnectionInfo(aConnection.ID,
TConnectInd(aMsg).CallingPartyNumber.Contents,
TConnectInd(aMsg).CalledPartyNumber.Contents,
TConnectInd(aMsg).CipValue);
if FDefaultResponseTimeOut > 0 then begin
{ Die Anwendung oder der Benutzer dürfen jetzt auswählen,
was sie mit dem Anruf tun wollen }
{ ConnectionInfo sind Daten über die Verbindung (aConnection)
Das Objekt wird beim Disconnect wieder gelöscht.
TimeOut:=False bedeutet: Noch kein TimeOut erfolgt!}
if _debug>2 then
debug('>> Timer '+inttostr(aConnection.id)+' started');
if not Assigned(FTimer) then begin // Bei Bedarf Timer erzeugen
FTimer := TTimer.Create(self);
FTimer.Interval := 1000; { jede Sekunde }
end;
end else begin
{Es gibt keine Wartezeit. Die Standardreaktion setzt sofort ein.
TimeOut:=True, da der TimeOut sofort erfolgte. Der Timer reagiert
dann nicht.}
if _debug>2 then
debug('>> Default Response');
{ Die aktuelle Verbindung mit den Standardwerten beantworten }
ResponseCall (aConnection.ID, FDefaultResponse, FDefaultRejectCause);
end;
if assigned(FTimer) then FTimer.OnTimer := OnTimerTick;
end;
{ ---------------------------------------------------------------}
DATA_B3_IND : begin
ProcessSending(aConnection);
ProcessReceiving(aConnection,Pointer(TDataB3Ind(aMsg).data),
TDataB3Ind(aMsg).datalength);
end;
CONNECT_B3_IND : begin
if FDefaultResponse=rClear
then begin { Reaktion soll rClear und nicht rAccept sein }
aDefaultHandling := false; { kein rjeAcceptCall schicken }
FCapi.PutMessage( { sondern Ruf ablehnen }
TConnectB3Resp.Create( aConnection.NCCI,
rjeB3NormalClear,
TStruct.CreateEmpty));
FCapi.Disconnect(aConnection); { ... und auflegen }
end;
end;
{ ---------------------------------------------------------------}
CONNECT_B3_ACTIVE_IND : begin
if assigned(FOnConnect) then
FOnConnect(aConnection.ID);
end;
{ ---------------------------------------------------------------}
FACILITY_CONF : begin
end;
FACILITY_IND : begin
case TFacilityInd(aMsg).FacilitySelector of
1:begin { DTMF - Töne }
aDTMFDigits:=ExtractDTMFDigit(TFacilityInd(aMsg).FacilityIndicationParameter);
if _debug>2 then
debug('>> DTMF Digits:'+aDTMFDigits);
if assigned(FOnDTMF) then begin
if _debug>2 then
debug('?? DTMF Digits.Count = '+inttostr(length(aDTMFDigits)));
for i:=1 to length(aDTMFDigits) do
FOnDTMF(aConnection.ID,aDTMFDigits[i])
end;
end;
end;
end;
DISCONNECT_IND : begin { DISCONNECT_RESP macht TCapi }
if assigned(FOnDisconnect) then
FOnDisconnect(aConnection.ID);
{ Connection-Info kann gelöscht werden }
StopRecord(aConnection.ID);
StopPlay(aConnection.ID);
FConnectionInfos.FreeConnectionInfo(aConnection.ID);
if FConnectionInfos.Count=0 then begin {Es besteht keine Verbindung }
FTimer.Free; { mehr, also kann der Timer gelöscht werden }
FTimer := nil;
end;
end;
end;
end;