unit Telephone1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Tapi,stdCtrls,mmsystem;
type
TMediaMode=(
LineMediaMode__DataModem,
LineMediaMode__InteractiveVoice,
LineMediaMode__VOICEVIEW,
LineMediaMode__AUTOMATEDVOICE
);
TBearerMode=(LineBearermode__Data,
LineBearerMode__Voice
);
TMediaDevType=(Wave_in,Wave_Out,Mci_Wave,mci_midi);
TOnErrEvent=Procedure (Sender:TObject;ErrStr:string;ErrCode:integer) of object;
TOnConnectEvent=Procedure (Sender:TObject) Of Object;
TOnDisConnectEvent=Procedure (Sender:TObject) OF Object;
TOnCallInEvent=Procedure (Sender:TObject) OF object;
TOnGetCallRingNumsEvent=Procedure(Sender:TObject;NumRings:Integer) of Object;
TOnDialEvent=Procedure (Sender:TObject) OF object;
TONGetCallerIdEvent=Procedure (Sender:Tobject) OF object;
TOnGetKeyEvent=Procedure (Sender:TObject;key:Char) of object;
TTelephone1 = class(TComponent)
private
ReplyCode:Integer;
fStatus
word;
ToneList:LPLineMonitorTone;
fError :Boolean;
hInstance :tHandle;
NumLines :integer;
fDeviceID:Integer;
hTapi, //program handle;
hLine,
HModem ,
tapiVersion :integer;
dwMediaModes :integer;
fMediaMode :TMediaMode;
fBearerMode :tBearerMode;
nBearerMode :integer;
fNumRings:byte;
fOnError : TOnErrEvent;
fOnGetKey:TOnGetKeyEvent;
fOnConnect:TOnConnectEvent;
fOnDisConnect:TOnDisConnectEvent;
fOnDial:TOnDialEvent;
fOnGetCallRingNums:TOnGetCallRingNumsEvent;
fOnCallIn:TOnCallInEvent;
fOnGetCallerId:TOnGetCallerIdEvent;
fMediaDevType:TMediaDevType;
strDeviceClass:String;
lpszTerminationDigits:array[0..400] of char;
GetDeviceID,GetCallInfo:Boolean;
Ver:String;
// lpLineCallBack:TLineCallBack;
{ Private declarations }
// Function tLineCallback(hDevice, dwMessage, dwInstance,
// dwParam1, dwParam2, dwParam3: Longint):TlineCallBack;
//{$IFDEF WIN32}
// stdcall;
//{$ELSE}
// export;
//{$ENDIF}
protected
hDevice, dwMessage, dwInstance,
dwParam1, dwParam2, dwParam3: Longint;
Handle:integer;
// lpDeviceId:lpVARSTRING;
// lpszDeviceClass:array[0..30] of char;
AddressId,AddressSize,AddressMode:Integer;
Procedure ProcMessage(Var Messages:TMessage);
Function GetOS:String;
{ Protected declarations }
public
CreateMakeCall:Boolean;
LineDevCaps:TLineDevCaps;
CallerNum:String[13];
LineCallParams:TLineCallInfo;
CallInfo:TLineCallInfo ;
lpszDeviceClass:array[0..30] of char;
CallParams:TLineCallParams;
extid: TLineExtensionID;
lpsAddress:array[0..30] of Char;
ErrStr:String;
Inited:Boolean;
hCall,
hCallIn:Integer;
bCallIn:Boolean;
GetAddressIdReturn:Integer;
CallStatus:TLineCallStatus;
sysWaveOutHandle
Word;
ModemList:TStringList;
lpDeviceID:TVarString;//lpVarString;
constructor Create;
destructor Destroy; override;
Procedure Dial(CallNum:String);
Procedure Answer;
procedure HangUp;
procedure GetWaveOutDevId;
Procedure PlayWave(WaveFileName:String;Wait:boolean);
procedure Open;
procedure SetModem(ModemName:string);
Function GetErrStr(ErrCode:Integer):String;
procedure Close;
// Function GetAddressId:Boolean;
// Function RingBack:Boolean;
// Function GetDevHandle(Handle,hType:integer);
//property appHand
{ Public declarations }
published
procedure init;
property Error :Boolean read fError write fError;
property Status
word read fStatus write fStatus;
property BearerMode:TBearerMode read fBearerMode write fBearerMode;
//property States :Byte read fStates write fStates;
property Mediamode :tMediamode read fMediaMode write fMediaMode;
property MediaDevType:TMediaDevType Read fMediaDevType write fMediaDevType;
Property OnError : TOnErrEvent read fOnError write fOnError;
property OnConnect:TOnConnectEvent read fOnConnect write fOnConnect;
property OndisConnect:TOnDisConnectEvent read fOnDisConnect write fOnDisConnect;
property OnCallIn: TOnCallInEvent read fOnCallIn write fOnCallIn;
property OnGetCallerid :TOnGetCallerIdEvent read fOnGetCallerid write fOnGetCallerid;
property OnDial : TOnDialEvent read fOnDial write fOndial;
property OnGetKey:TOnGetkeyEvent read fOnGetkey write fOnGetKey;
property OnGetCallRingNums:TOnGetCallRingNumsEvent read fOnGetCallRingNums write fOnGetCallRingNums;
property NumRings:byte read fNumRings write fNumRings;
property DeviceClass:string read strDeviceClass write strDeviceClass;
{ Published declarations }
end;
procedure Register;
//procedure LineCallback(hDevice, dwMessage, dwInstance,
// dwParam1, dwParam2, dwParam3: Longint);
//{$IFDEF WIN32}
// stdcall;
//{$ELSE}
// export;
//{$ENDIF}
implementation
Const
WM_LineCallState_Connect=WM_user+102;
WM_LineCallState_DisConnect=WM_user+103;
WM_ReplyErr=WM_user+104;
WM_Line_ReplyOK=WM_User+105;
WM_LineCallState_CallIN=WM_User+106;
WM_Error=WM_User+107;
WM_LineCallState_Busy=WM_User+108;
WM_LineCallState_Proceeding=WM_User+109;
WM_LineCallState_Dialing=WM_User+110;
WM_lineCallState_IDle=WM_User+111;
WM_Dial=WM_user+112;
WM_lineCallState_RingBack=WM_user+113;
WM_LineCallState_RH=WM_User+114;
WM_LineCallState_CallID=WM_User+115;
WM_LineDEvState_Error=WM_User+116;
WM_OtherMessage=WM_User+117;
WM_Line_Generat=WM_user+118;
WM_GetCallhandle=WM_user+119;
WM_LineDevSate_Ring=WM_User+120;
WM_Connected_Dial=WM_User+121;
RingNumPostmessage=2;
dwFirstDigitTimeout=1;
dwInterDigitTimeout=100;
Const
TelePhoneStatus_idle=1;
TelephoneStatus_MakeCall=2;
TelephoneStatus_Connect=3;
TelephoneStatus_DisConnect=4;
TelephoneStatus_Callin=5;
TelephoneStatus_LineDrop=6;
TelephoneStatus_HandUp=7;
var
hTelephone:Thandle;
HandleCall:Integer;
procedure LineCallback(hDevice, dwMessage, dwInstance,
dwParam1, dwParam2, dwParam3: Longint);
{$IFDEF WIN32}
stdcall;
{$ELSE}
export;
{$ENDIF}
var
handle:integer;
begin
Handle:=hTelephone;
if dwMessage = LINE_REPLY then
begin
Case dwParam2 of
0
ostMessage(handle,WM_GetCallhandle,0,0);
else
postmessage(handle,Wm_error,DwParam2,0);
end;
end
else If dwMessage=Line_CallInfo then
begin
Case dwParam1 of
LINECALLINFOSTATE_CallerID :begin
postMessage(handle,WM_LineCallState_CallID,0,0);
end;
end;
end
else if dwMessage = LINE_CALLSTATE then
begin
case dwParam1 of
LINECALLSTATE_IDLE:
if HandleCall <> 0 then
begin
PostMessage(handle,WM_LineCallState_IDLE,0,0);
end;
LINECALLSTATE_CONNECTED:
if HandleCall <> 0 then
PostMessage(handle,WM_LineCallState_Connect,HandleCall,0);
LINECALLSTATE_PROCEEDING:
PostMessage(handle,WM_LineCallState_Proceeding,0,0);
LINECALLSTATE_DIALING:
PostMessage(handle,WM_LineCallState_Dialing,0,0);
LINECALLSTATE_DISCONNECTED:
PostMessage(handle,WM_LineCallState_DisConnect,0,0);
LINECALLSTATE_BUSY:
PostMessage(handle,WM_LineCallState_Busy,0,0);
LineCallState_Offering:
begin
HandleCall := THCall(hDevice);
postMessage(handle,WM_LineCallState_CAllIN,dwParam3,0);
end;
LINECALLSTATE_RINGBACK :
begin
postMessage(handle,WM_LineCallState_RingBack,0,0);
end;
{LineDisConnectMode_Normal:
PostMessage(handle,WM_LineCallState_DisConnect,0,0);
LineDisConnectMode_busy:
PostMessage(handle,WM_LineCallState_Busy,0,0); }
end;
end
else IF dwMessage = LINE_LINEDEVSTATE then
begin
Case dwParam1 Of
LINEDEVSTATE_Reinit:
postMessage(handle,WM_LineDEvState_Error,0,0);
LINEDEVSTATE_RINGING:
postMessage(Handle,WM_LineDevSate_Ring,dwParam3,0);
end;
end
Else IF dwMessage=LINE_MONITORDIGITS then
begin
PostMessage(Handle,WM_Line_Generat,dwParam1,0);
end
Else IF dwMessage=LINE_MONITORTONE then
begin
Case dwParam1 of
WM_Connected_Dial:begin
PostMessage(Handle,WM_Connected_Dial,dwParam1,0);
end;
end;
end
Else begin
PostMessage(Handle,WM_OtherMessage,dwMessage,DwParam1);
end;
End;
procedure tTelephone1.close;
begin
HangUp;
end;
Function tTelephone1.GetOS ;
var
OS:TOSVersionInfo;
begin
Result:='UnKonw';
ZeroMemory(@OS,SizeOF(os));
OS.dwOSVersionInfoSize:=SizeOF(os);
GetVersionEx(OS);
IF OS.dwPlatformId=Ver_Platform_WIN32_Nt then
begin
Case OS.dwMajorVersion OF
3:Result:='NT3';
4:Result:='NT4';
5:Result:='2K';
end;
IF (OS.dwMajorVersion=5) and (OS.dwMinorVersion=1) then
Result:='WINXP';
end
else
IF (OS.dwMajorVersion=4) and (OS.dwMinorVersion=0) then
begin
Result:='WIN95_1';
IF (Trim(os.szCSDVersion)='B') then
Result:='WIN95_2';
end
else
IF(OS.dwMajorVersion=4) and (OS.dwMinorVersion=10) then
begin
Result:='WIN98_1';
IF Trim(OS.szCSDVersion)='A' then Result:='Win98_2';
end
else
IF (OS.dwMajorVersion=4) and (OS.dwMinorVersion=90) then
Result:='WINME';
end;
constructor tTelephone1.Create ;
begin
inherited create(self);
Inited:=false;
Error:=false;
Handle:=hTelephone;
bCallIn:=false;
NumRings:=20;
GetDeviceID:=False;
GetCallInfo:=false;
New(ToneList);
//ModemList:=TStringList.Create;
end;
Function tTelephone1.GetErrStr ;
var
ErrStr:String;
begin
Case ErrCode of
LINEERR_ADDRESSBLOCKED:ErrStr:='LINEERR_ADDRESSBLOCKED';
LINEERR_ALLOCATED :ErrStr:='LineErr_Allocated';
LINEERR_BADDEVICEID :ErrStr:='LineErr_Baddeviceid';
LINEERR_BEARERMODEUNAVAIL:ErrStr:='LINEERR_BEARERMODEUNAVAIL';
LINEERR_CALLUNAVAIL :ErrStr:='LINEERR_CALLUNAVAIL';
LINEERR_COMPLETIONOVERRUN:ErrStr:='LINEERR_COMPLETIONOVERRUN';
LINEERR_CONFERENCEFULL:ErrStr:='LINEERR_CONFERENCEFULL';
LINEERR_DIALBILLING :ErrStr:='LINEERR_DIALBILLING';
LINEERR_DIALQUIET:ErrStr:='LINEERR_DIALQUIET';
LINEERR_DIALDIALTONE:ErrStr:='LINEERR_DIALDIALTONE';
LINEERR_DIALPROMPT:ErrStr:='LINEERR_DIALPROMPT';
LINEERR_INCOMPATIBLEAPIVERSION:ErrStr:='LINEERR_INCOMPATIBLEAPIVERSION';
LINEERR_INCOMPATIBLEEXTVERSION:ErrStr:='LINEERR_INCOMPATIBLEEXTVERSION';
LINEERR_INIFILECORRUPT:ErrStr:='LINEERR_INIFILECORRUPT';
LINEERR_INUSE:ErrStr:='LINEERR_INUSE';
LINEERR_INVALADDRESS:ErrStr:='LINEERR_INVALADDRESS';
LINEERR_INVALADDRESSID:ErrStr:='LINEERR_INVALADDRESSID';
LINEERR_INVALADDRESSMODE:ErrStr:='LINEERR_INVALADDRESSMODE';
LINEERR_INVALADDRESSSTATE:ErrStr:='LINEERR_INVALADDRESSSTATE';
LINEERR_INVALAGENTACTIVITY:ErrStr:='LINEERR_INVALAGENTACTIVITY';
LINEERR_INVALAGENTGROUP:ErrStr:='LINEERR_INVALAGENTGROUP';
LINEERR_INVALAGENTID:ErrStr:='LINEERR_INVALAGENTID';
//LINEERR_INVALAGENTSKILL:ErrStr:='LINEERR_INVALAGENTSKILL';
LINEERR_INVALAGENTSTATE:ErrStr:='LINEERR_INVALAGENTSTATE';
//LINEERR_INVALAGENTSUPERVISOR:ErrStr:='LINEERR_INVALAGENTSUPERVISOR';
LINEERR_INVALAPPHANDLE:ErrStr:='LINEERR_INVALAPPHANDLE';
LINEERR_INVALAPPNAME:ErrStr:='LINEERR_INVALAPPNAME';
LINEERR_INVALBEARERMODE:ErrStr:='LINEERR_INVALBEARERMODE';
LINEERR_INVALCALLCOMPLMODE:ErrStr:='LINEERR_INVALCALLCOMPLMODE';
LINEERR_INVALCALLHANDLE:ErrStr:='LINEERR_INVALCALLHANDLE';
LINEERR_INVALCALLPARAMS:ErrStr:='LINEERR_INVALCALLPARAMS';
LINEERR_INVALCALLPRIVILEGE:ErrStr:='LINEERR_INVALCALLPRIVILEGE';
LINEERR_INVALCALLSELECT:ErrStr:='LINEERR_INVALCALLSELECT';
LINEERR_INVALCALLSTATE:ErrStr:='LINEERR_INVALCALLSTATE';
LINEERR_INVALCALLSTATELIST:ErrStr:='LINEERR_INVALCALLSTATELIST';
LINEERR_INVALCARD:ErrStr:='LINEERR_INVALCARD';
LINEERR_INVALCOMPLETIONID:ErrStr:='LINEERR_INVALCOMPLETIONID';
LINEERR_INVALCONFCALLHANDLE:ErrStr:='LINEERR_INVALCONFCALLHANDLE';
LINEERR_INVALCONSULTCALLHANDLE:ErrStr:='LINEERR_INVALCONSULTCALLHANDLE';
LINEERR_INVALCOUNTRYCODE:ErrStr:='LINEERR_INVALCOUNTRYCODE';
LINEERR_INVALDEVICECLASS:ErrStr:='LINEERR_INVALDEVICECLASS';
LINEERR_INVALDIGITLIST:ErrStr:='LINEERR_INVALDIGITLIST';
LINEERR_INVALDIGITMODE:ErrStr:='LINEERR_INVALDIGITMODE';
LINEERR_INVALDIGITS:ErrStr:='LINEERR_INVALDIGITS';
LINEERR_INVALFEATURE:ErrStr:='LINEERR_INVALFEATURE';
LINEERR_INVALGROUPID:ErrStr:='LINEERR_INVALGROUPID';
LINEERR_INVALLINEHANDLE:ErrStr:='LINEERR_INVALLINEHANDLE';
LINEERR_INVALLINESTATE:ErrStr:='LINEERR_INVALLINESTATE';
LINEERR_INVALLOCATION:ErrStr:='LINEERR_INVALLOCATION';
LINEERR_INVALMEDIALIST:ErrStr:='LINEERR_INVALMEDIALIST';
LINEERR_INVALMEDIAMODE:ErrStr:='LINEERR_INVALMEDIAMODE';
LINEERR_INVALMESSAGEID:ErrStr:='LINEERR_INVALMESSAGEID';
LINEERR_INVALPARAM:ErrStr:='LINEERR_INVALPARAM';
LINEERR_INVALPARKMODE:ErrStr:='LINEERR_INVALPARKMODE';
LINEERR_INVALPASSWORD:ErrStr:='LINEERR_INVALPASSWORD';
LINEERR_INVALPOINTER:ErrStr:='LINEERR_INVALPOINTER';
LINEERR_INVALPRIVSELECT:ErrStr:='LINEERR_INVALPRIVSELECT';
LINEERR_INVALRATE:ErrStr:='LINEERR_INVALRATE';
LINEERR_INVALREQUESTMODE:ErrStr:='LINEERR_INVALREQUESTMODE';
LINEERR_INVALTERMINALID:ErrStr:='LINEERR_INVALTERMINALID';
LINEERR_INVALTERMINALMODE:ErrStr:='LINEERR_INVALTERMINALMODE';
LINEERR_INVALTIMEOUT:ErrStr:='LINEERR_INVALTIMEOUT';
LINEERR_INVALTONE:ErrStr:='LINEERR_INVALTONE';
LINEERR_INVALTONELIST:ErrStr:='LINEERR_INVALTONELIST';
LINEERR_INVALTONEMODE:ErrStr:='LINEERR_INVALTONEMODE';
LINEERR_INVALTRANSFERMODE:ErrStr:='LINEERR_INVALTRANSFERMODE';
LINEERR_LINEMAPPERFAILED:ErrStr:='LINEERR_LINEMAPPERFAILED';
LINEERR_NOCONFERENCE:ErrStr:='LINEERR_NOCONFERENCE';
LINEERR_NODEVICE:ErrStr:='LINEERR_NODEVICE';
LINEERR_NODRIVER:ErrStr:='LINEERR_NODRIVER';
LINEERR_NOMEM:ErrStr:='LINEERR_NOMEM';
LINEERR_NOMULTIPLEINSTANCE:ErrStr:='LINEERR_NOMULTIPLEINSTANCE';
LINEERR_NOREQUEST:ErrStr:='LINEERR_NOREQUEST';
LINEERR_NOTOWNER:ErrStr:='LINEERR_NOTOWNER';
LINEERR_NOTREGISTERED:ErrStr:='LINEERR_NOTREGISTERED';
LINEERR_OPERATIONFAILED:ErrStr:='LINEERR_OPERATIONFAILED';
LINEERR_OPERATIONUNAVAIL:ErrStr:='LINEERR_OPERATIONUNAVAIL';
LINEERR_RATEUNAVAIL:ErrStr:='LINEERR_RATEUNAVAIL';
LINEERR_REINIT:ErrStr:='LINEERR_REINIT';
LINEERR_RESOURCEUNAVAIL:ErrStr:='LINEERR_RESOURCEUNAVAIL';
LINEERR_STRUCTURETOOSMALL:ErrStr:='LINEERR_STRUCTURETOOSMALL';
LINEERR_TARGETNOTFOUND:ErrStr:='LINEERR_TARGETNOTFOUND';
LINEERR_TARGETSELF:ErrStr:='LINEERR_TARGETSELF';
LINEERR_UNINITIALIZED:ErrStr:='LINEERR_UNINITIALIZED';
LINEERR_USERUSERINFOTOOBIG:ErrStr:='LINEERR_USERUSERINFOTOOBIG';
end;
GetErrStr:=ErrStr;
end;
Procedure tTelephone1.PlayWave ;
var
MmCkInfoParent : TMMCkInfo;
MmCkInfoSubchunk : TMMCkInfo;
FormatSize : DWORD;
WaveOutHandle : HWaveOut;
WaveFormat : PWaveFormatEx;
Res : LongInt;
WaveOutDevCaps : TWaveOutCaps;
DeviceId : DWORD;
Temp : array[0..100] of Char;
Flags : LongInt;
FileName:string;
WaveOutHeader : PWaveHdr; //Wave头
WaveOutBuffer1 : Pointer; //Wave缓冲区
WaveOutBufferSize : LongInt;
BytesInBuffer : LongInt;
MmioOutHandle:integer;
Channels : Byte; //声音
BitsPerSample : Byte; //
SamplesPerSecond : Integer; //采样频率
WaveInBufferSize : LongInt; //
BytesToPlay : LongInt; //Wave文件的字节数
PlayWaveError :Boolean;
begin
try
IF fileExists(WaveFileName) then
begin
PlayWaveError:=false;
Filename:=WaveFileName;
GetWaveOutDevid;
WaveOutHandle:=0;
DeviceId := sysWaveOutHandle;
MmioOutHandle:= mmioOpen(StrPCopy(Temp, FileName),
nil, MMIO_READ or MMIO_ALLOCBUF);
//打开Wave文件
MmCkInfoParent.fccType :=mmioStringToFOURCC('WAVE', 0);
Res := MmioDescend(MmioOutHandle,@MmCkInfoParent, nil, MMIO_FINDRIFF);
//降序查找'Wave'标志
if res<>0 then
begin
ErrStr:='非Wave文件';
PlayWaveError :=true;
PostMessage(handle,WM_Error,res,0);
end;
IF Not(PlayWaveError) then
begin
mmCkInfoSubchunk.ckid := mmioStringToFOURCC('fmt ', 0);
//确定'fmt'格式块
Res := mmioDescend(MmioOutHandle, @MmCkinfoSubchunk, @MmCkinfoParent, MMIO_FINDCHUNK);
if Res<>0 then
begin
ErrStr:='非fmt格式块';
//PostMessage('');
PlayWaveError :=true;
PostMessage(handle,WM_Error,res,0);
exit;
end;
end;
IF Not(PlayWaveError) then
begin
FormatSize := MmCkinfoSubchunk.cksize;
GetMem(WaveFormat, FormatSize);
//分配内存
Res := mmioRead(MmioOutHandle, PChar(WaveFormat), FormatSize);
if Res = -1 then
begin
ErrStr:='读取块出错';
PlayWaveError :=true;
PostMessage(handle,WM_Error,res,0);
exit;
end;
end;
IF Not(PlayWaveError) then
begin
WaveOutBufferSize:= (WaveFormat.nSamplesPerSec*(WaveFormat.wBitsPerSample div 8)* WaveFormat.nChannels*200); //最大200秒
mmioAscend(MmioOutHandle, @MmCkinfoSubchunk, 0);
MmCkinfoSubchunk.ckid := mmioStringToFOURCC('data', 0);
Res := mmioDescend(MmioOutHandle, @MmCkinfoSubchunk, @MmCkinfoParent, MMIO_FINDCHUNK);
//查找'data'块
BytesToPlay := MmCkinfoSubchunk.cksize;
//获得Wave文件的大小
Flags := CALLBACK_WINDOW;
Res := waveOutOpen(@WaveOutHandle,DeviceID,//WAVE_MAPPER,//DeviceId,
WaveFormat,MakeLong(handle,0), DWord(self), Flags);
//打开设备
if (Res <>MMSYSERR_NOERROR) then
begin
ErrStr:='打开设备时出错';
PlayWaveError :=true;
PostMessage(handle,WM_Error,res,0);
//Showmessage('打开设备时出错');
exit;
end;
end;
IF WaveFormat<>nil then
FreeMem(WaveFormat, SizeOf(FormatSize));
//释放内存
IF Not(PlayWaveError) then
begin
GetMem(WaveOutHeader, SizeOf(TWaveHdr));
//分配WaveOutHeader内存
WaveOutHeader^.dwFlags := 0;
WaveOutHeader^.dwLoops := 0;
WaveOutHeader^.dwUser := 0;
GetMem(WaveOutBuffer1, WaveOutBufferSize);
//为数据分配内存
BytesInBuffer := BytesToPlay;
Res := mmioRead(MmioOutHandle,PChar(WaveOutBuffer1), BytesToPlay);
//读波形数据到缓冲区中
WaveOutHeader^.lpData :=Pchar(WaveOutBuffer1);
WaveOutHeader^.dwBufferLength := BytesInBuffer;
waveOutPrepareHeader(WaveOutHandle, WaveOutHeader, SizeOf(TWaveHdr));
Res := waveOutWrite(WaveOutHandle, WaveOutHeader, SizeOf(TWaveHdr));
IF Res<>MMSYSERR_NOERROR then
begin
ErrStr:='播放文件错误!';
PlayWaveError :=true;
PostMessage(handle,WM_Error,res,0);
exit;
end;
if Wait then while WaveoutHeader.dwFlags<>3 do begin end;
end;
end
else
begin
ErrStr:='声音文件不存在!';
postMessage(handle,WM_Error,0,0)
end;
IF WaveOutHeader<>nil then
FreeMem(WaveOutHeader, SizeOf(FormatSize));
IF WaveOutBuffer1<>nil then
FreeMem(WaveOutBuffer1, SizeOf(FormatSize));
except
end;
//准备
end;
destructor tTelephone1.Destroy;
begin
if hTapi <> 0 then
lineShutDown(hTapi);
IF hLine<>0 then
lineClose(hline);
inherited destroy;
end;
{Function tTelePhone1.GetAddressId:Boolean;
begin
AddressMode:=LINEADDRESSMODE_DIALABLEADDR ;
IF bCallIn then
GetAddressIdReturn:=LineGetAddressId(hCallIn,AddressId,AddressMode,lpsAddress,AddressSize);
GetAddressid:=GetAddressIdReturn=0;
end;
}
Procedure tTelePhone1.procMessage;
var
dwLineGetcallInfo,dwCallInfoSize,dwDeviceIdSize,dwGetId:dWord;
buf:array[0..4096]of char;
beginptr,endPtr,ptrCallerNum:dword;
dwNumRings:Integer;
begin
Case Messages.Msg Of
WM_LineCallState_Connect :begin
IF CreateMakeCall then
begin
lineMonitorDigits(HandleCall,LINEDIGITMODE_DTMFEND);
{New(ToneList);
ToneList^.dwAppSpecific:=WM_Connected_Dial;
ToneList^.dwDuration:=100;
ToneList^.dwFrequency1 :=0;
ToneList^.dwFrequency2 :=0;
ToneList^.dwFrequency3 :=0;
ReplyCode:=lineMonitorTones(hCall,ToneList,1);
IF ReplyCode<0 then
begin
ErrStr:='LineMonitorTones: '+GetErrStr(Replycode);
postMessage(handle,WM_Error,0,0);
end; }
end;
if Assigned(fOnConnect) then
OnConnect(self);
end;
WM_lineCallState_IDle:begin
if bCallin then
lineDeallocateCall(hCallIn)
else
LineDeallocateCall(hCall);
bCallIn:=false;
end;
WM_LineCallState_DisConnect:begin
HangUp;
IF Assigned(fOnDisConnect) then
OnDisConnect(self);
end;
WM_Error,WM_LineDEvState_Error : begin
IF assigned(fONError) then
OnError(self,ErrStr,Messages.WParam);
end;
WM_LineCallState_CallID:begin
CallerNum:='';
Fillchar(CallInfo,SizeOf(CallInfo),0);
CallInfo.dwTotalSize:=SizeOf(CallInfo);//4096;
LineGetCallInfo(hCallIn,CallInfo);
CallInfo.dwTotalSize:=CallInfo.dwNeededSize;
dwLineGetcallInfo:=LineGetCallInfo(hCallIn,CallInfo);
IF dwLineGetCallInfo=0 then
begin
Move(callinfo,buf[0],CallInfo.dwTotalSize );
IF Callinfo.dwCallerIDSize>0 then
for ptrCallerNum:=Callinfo.dwCallerIDOffset to Callinfo.dwCallerIDOffset+CallInfo.dwCallerIDSize-2 do
CallerNum:=CallerNum+buf[ptrCallerNum];
if Assigned(fOnGetCallerId) then
OnGetCallerId(self);
end
else
begin
ErrStr:=Format('%u',[dwLineGetCallInfo]);
postMessage(handle,WM_Error,0,0);
end;
end;
WM_LineCallState_CAllIN :Begin
bCallIn:=true;
hCallin:=HandleCall;
lineMonitorDigits(HandleCall,LINEDIGITMODE_DTMFEND);
if Assigned(fOnCallIn) then
OnCallIn(self);
end;
WM_LineDevSate_Ring:Begin
if Assigned(fOnGetCallRingNums) then
OnGetCallRingNums(self,Messages.WParam);
end;
WM_Dial :begin
IF Assigned(fOnDial) then
OnDial(self);
end;
WM_LineCallState_Busy:begin
ErrStr:='Busy!';
IF assigned(fONError) then
OnError(self,ErrStr,0);
end;
WM_Line_Generat:Begin
IF Assigned(fOnGetKey) then
ONGetKey(self,char(Messages.WParam));
end;
WM_OtherMessage:begin
end;
WM_LineCallState_RingBack:begin
{ToneList.dwAppSpecific:=WM_Connected_Dial;
ToneList.dwDuration:=1;
ToneList.dwFrequency1 :=0;
ToneList.dwFrequency2 :=0;
ToneList.dwFrequency3 :=0;
lineMonitorTones(hCall,ToneList,0);
ShowMessage('RingBack!');}
end;
WM_Connected_Dial:begin
// ShowMessage('Connect Dial');
end;
end;
end;
procedure TTelephone1.init;
var
PtrModem,lsPtr:Integer;
lsModemName:string;
buf:array[0..4096] of byte;
begin
IF Not(inited) then
begin
CreateMakeCall:=false;
ModemList:=TStringList.Create ;
Error:=false;
inited:=true;
ErrStr:='';
if not (csDesigning in ComponentState) then
hTelephone := AllocateHWnd(ProcMessage);
Ver:=GetOS;
IF Pos('NT',Ver)<>0 then
Begin
ErrStr:='NT';
Error:=true;
end
else
IF pos('2K',Ver)<>0 then
begin
ErrStr:='2K';
Error:=true;
end;
Handle:=hTelePhone;
Status:=TelePhoneStatus_idle;
IF fBearerMode=LineBearerMode__Voice then nBearermode:=LineBearerMode_voice else
IF fBearerMode=LineBearerMode__Data then nBearermode:=LineBearerMode_Data ;
IF MediaMode=LineMediaMode__DataModem then dwMediaModes:=LineMediaMode_DataModem
else IF MediaMode=LineMediaMode__InteractiveVoice then dwMediaModes:=LineMediaMode_interactiveVoice
else IF MediaMode=LineMediaMode__VOICEVIEW then dwMediaModes:=LineMediaMode_VoiceView
Else IF MeDiaMode=LineMediamode__AUTOMATEDVOICE then dwMediaModes:=LINEMEDIAMODE_AUTOMATEDVOICE;
FillChar(LineCallParams, sizeof(TLineCallInfo), 0);
with LineCallParams do
begin
dwTotalSize := sizeof(LineCAllParams);
dwBearerMode :=nBearermode;//LINEBEARERMODE_VOICE;
dwMediaMode :=dwMediaMode;//LINEMEDIAMODE_INTERACTIVEVOICE;
end;
ReplyCode:=lineInitialize(hTapi, HInstance,
lineCallback, nil,NumLines);
IF ReplyCode < 0 then { < 0 is an error }
begin
Error:=true;
hTapi := 0;
ErrStr:='LineInitialize '+GetErrStr(Replycode);
end
else if NumLines = 0 then { no TAPI devices?? }
begin
lineShutDown(hTapi);
hTapi := 0;
Error:=true;
ErrStr:='NumLines=0';
end ;
IF Not(Error) then
begin
ReplyCode:= lineNegotiateAPIVersion(hTapi, 0, $00010000, $10000000,
tapiVersion, extid);
IF ReplyCode < 0 then { Check for version (copied from a TAPI sample) }
begin
lineShutDown(hTapi);
hTapi := 0;
Error:=true;
ErrStr:='LineNegotiateAPIVerSion '+GetErrStr(ReplyCode);//'Ver Error!';
end
end
end
else
begin
Error:=true;
ErrStr:='Inited already';
end;
IF Error then
PostMessage(handle,WM_Error,0,0)
else
for ptrModem:=0 to NumLines-1 do
begin
lsModemName:='';
fillchar(buf,4096,' ');
Fillchar(LineDevCaps,SizeOf(TLineDevCaps),0);
LineDevCaps.dwTotalSize:=SizeOF(TLineDevCaps);
ReplyCode:=LineGetDevcaps(hTapi,ptrModem,tapiVersion,0,LineDevCaps);
LineDevCaps.dwTotalSize :=LineDevCaps.dwNeededSize ;
ReplyCode:=LineGetDevcaps(hTapi,ptrModem,tapiVersion,0,LineDevCaps);
IF ReplyCode<0 then ErrStr:=GetErrStr(ReplyCode)
else
begin
fillchar(buf,4097,0);
Move(LineDevCaps,buf[0],LineDevCaps.dwTotalSize);
for lsptr:=0 to LineDevCaps.dwLineNamesize do
lsModemName:=lsModemName+chr(buf[lsPtr+LineDevCaps.dwLineNameOffSet]);
Modemlist.add(lsModemName);
end;
end;
End;
{---Error----
Function tTelephone1.RingBack:Boolean;
begin
LineGetCallStatus(hCall,CallStatus);
RingBack:=CallStatus.dwcallstate=LineCallState_RingBack;
end;
}
procedure tTelephone1.SetModem ;
var
ptr:integer;
begin
fDeviceId:=0;
Ptr:=0;
while Ptr<=Modemlist.Count-1 do
begin
IF Pos(ModemName,String(Modemlist[Ptr]))<>0 then
begin
fDeviceID:=Ptr;
Ptr:=Modemlist.count;
end
else
ptr:=ptr+1;
end;
end;
procedure tTelephone1.Open ;
begin
//LINECALLPRIVILEGE_owner or LINECALLPRIVILEGE_Monitor //LINEMAPPER
ReplyCode:= lineOpen(hTapi, fDeviceid, hLine, tapiVersion, 0, 0,
LINECALLPRIVILEGE_OWNER or LINECALLPRIVILEGE_Monitor , dwMediaModes , @LineCallParams); //LINEMEDIAMODE_AUTOMATEDVOICE
if ReplyCode< 0 then
begin
lineShutDown(hTapi);
hTapi := 0;
hLine := 0;
Error:=true;
ErrStr:='LineOpen '+GetErrStr(ReplyCode);
PostMessage(handle,WM_Error,0,0)
end
Else
begin
LineSetStatusMessages(hLine,LINEDEVSTATE_RINGING ,0);
end;
end;
procedure tTelephone1.Dial;
var
telephone:array[0..20] of char;
ErrCode:Word;
begin
IF Not(Error)and inited then
begin
StrPCopy(telephone,CallNum);
FillChar(LineCallParams, sizeof(TlineCallParams), 0);
with LineCallParams do
begin
dwTotalSize := sizeof(LineCAllParams);
dwBearerMode :=nBearermode;//LINEBEARERMODE_voice;//
dwMediaMode :=dwMediaMode;//LINEMEDIAMODE_DataModem;//
end;
CreateMakeCall:=true;
ReplyCode:=LineMakeCall(hLine,hCall,telephone,0,@LinecallParams);
IF ReplyCode<0 then
begin
ErrStr:='LineMackCall '+GetErrStr(ReplyCode);
PostMessage(hTelephone,WM_Error,0,0);
end
else
begin
PostMessage(hTelephone,WM_Dial,0,0);
end;
end
Else
PostMessage(handle,WM_Error,0,0);
end;
Procedure tTelephone1.Answer ;
begin
ReplyCode:=LineAnswer(hCallin,nil,0);
IF ReplyCode<0 then
begin
ErrStr:='Line Answer:'+GetErrStr(ReplyCode);
postMessage(Handle,WM_Error,0,0);
end;
end;
Procedure tTelephone1.HangUp;
begin
IF bCallIn then
LineDrop(hCallin,nil,0)
else
LineDrop(hCall,nil,0);
Status:=TelephoneStatus_HandUp;
end;
Procedure tTelephone1.GetWaveOutDevId;
var
ReplyCode,Needsize
Word;
buf:array[0..4096] of byte;
aa
word;
begin
StrPCopy(lpszDeviceClass,'wave/out');
lpDeviceid.dwTotalSize :=sizeOf(TvarString);
lpDeviceid.dwNeededSize :=lpDeviceid.dwTotalSize ;
IF bCallIn then
ReplyCode:=LineGetIdA(hLine,0,HCallIn,LINECALLSELECT_CAll, lpDeviceId ,lpszDeviceClass)
else
ReplyCode:=LineGetIdA(hLine,0,HCall,LINECALLSELECT_Call, lpDeviceId ,lpszDeviceClass);
NeedSize:=lpdeviceid.dwNeededSize;
lpDeviceid.dwTotalSize :=NeedSize;
IF bCallIn then
ReplyCode:=LineGetIdA(hLine,0,HCallIn,LINECALLSELECT_Call, lpDeviceId ,lpszDeviceClass)
else
ReplyCode:=LineGetIdA(hLine,0,HCall,LINECALLSELECT_Call, lpDeviceId ,lpszDeviceClass);
IF ReplyCode<>0 then
begin
ErrStr:='GetDeviceId Error';
PostMessage(Handle,WM_Error,ReplyCode,0);
end
else
begin
Move(lpDeviceid,buf[0],lpDeviceid.dwTotalSize);
Move(buf[lpDeviceid.dwStringOffset],sysWaveOutHandle,lpDeviceid.dwStringsize);
end;
end;
procedure Register;
begin
RegisterComponents('Samples', [TTelephone1]);
end;
end.
我从网上下载过一些资料,如用到某位仁兄的资料,请原谅!如有问题,请与我联系!
fmer@163.net