把来电号码显示在电脑里(100分)

  • 主题发起人 主题发起人 nbwsj
  • 开始时间 开始时间
要不要分啦?说来说去,还不知所云!
请哪位高手将完整的源码和相关硬件(什么卡来着?)资料发给我,
soft@kk518.com
我满意的话,200分全给他!
(如何加分呀?再+100!!!)
 
硬件资料:
http://www.dj.com.cn/product/product-d/product5.htm
网站上可以下载各种例程。价格2000元左右(一个通道)。

用语音卡的优点是可以实现很多功能,但是价格贵,其他朋友说的用支持来电显示的
Modem也是可以的,不知道有没有SDK。。。
 
用一个支持来电现实的modem就可以了。
 
http://stockss.126.com
 
aylm兄:
  看到你有来电显示的TAPI例程了,能否发一份给我,不胜感谢!he99@21cn.com
 
各位仁兄:
  谁有aylm兄说的那个电显示的TAPI例程,能否发一份给我,不胜感谢!he99@21cn.com
 
去买一个Usb语音盒就OK啦,还便宜 才4、500左右,找厂商给你提供SDK和简单的源码,我做过,不过代码在我的电脑上,我在网吧上网~~~~~穷阿
 
你是说400~500元左右吗?不过我已经有modem了,再去买不就浪费了?我还是希望谁能提供一段用modem显示来电的程序,但不希望是ocx的,要注册,很麻烦!只希望有电话打进来,就显示在Edit框中就行!谢谢你的回答!
 
我好惨啊,今天去买了个支持DTMF侦测产生的MODEM,结果发现怎么看不到来电号码怎么办啊
 
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:Dword;
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:DWord;
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 :Dword 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:PostMessage(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:DWord;
buf:array[0..4096] of byte;
aa:Dword;
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
 
  虽然我还没有看懂,但也非常感谢!
  我用一个叫async32的控件,在单位的电话线上得到了来电显示(说明我的MODEM有来电显示功能),但拿到别的地方,就显示不出来电话号码了,不知道为什么?换了六七个地方,都是这样,这几个地方的电话都在邮局申请了来电显示,而且有住宅电话、公用电话、单位电话(这些地方只能收到振铃),但只在我单位时显示了来电号码,真是怪!谁能解释一下!下面是我的原码,你们看一下,有没有什么错误!

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, CommInt;

type
TForm1 = class(TForm)
Edit1: TEdit;
Bclose: TButton;
Memo1: TMemo;
Memo2: TMemo;
Bopen: TButton;
Comm1: TComm;
procedure BcloseClick(Sender: TObject);
procedure BopenClick(Sender: TObject);
procedure Comm1RxChar(Sender: TObject; Count: Integer);
private
LineData: string;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

const
OnOff: array[0..1] of string = ('Off', 'On');

{$R *.DFM}

//关闭端口
procedure TForm1.BcloseClick(Sender: TObject);
begin
Comm1.Close;
Memo1.Lines.Add('Device closed: ' + Comm1.DeviceName);
end;

//打开端口
procedure TForm1.BopenClick(Sender: TObject);
var
S: string;
Count: Integer;
begin
Comm1.DeviceName := 'COM4';
Comm1.Close;//打开之前先关闭一下,不然打开一个已经打开的端口会出错
Comm1.Open;//打开端口
Comm1.SetRTSState(true);
Comm1.SetDTRState(true);
Memo1.Lines.add('Device ready: ' + Comm1.DeviceName);
S := 'AT#CID=1';//AT命令,打开来电显示功能
S := S + #13#10;//加上回车和换行
Count := Length(S);
Count := Comm1.Write(S[1], Count);//发到MODEM中
if Count = -1 then
Memo1.Lines.add('Error writing to: ' + Comm1.DeviceName)
else Memo1.Lines.add('Transmitting ' + IntToStr(Count) + ' characters');
end;

//接收
procedure TForm1.Comm1RxChar(Sender: TObject; Count: Integer);
type
CharBuf = array[0..9999] of Char;
var
Buffer: ^CharBuf;
Bytes, P : Integer;
begin
GetMem(Buffer, Comm1.ReadBufSize);
try
Fillchar(Buffer^, Comm1.ReadBufSize, 0);
Bytes := Comm1.Read(Buffer^, Count);
if Bytes = -1 then
Memo1.Lines.add('Error reading incoming data...')
else
begin
Memo1.Lines.add('Reading ' + IntToStr(Bytes) + ' characters');
for P := 0 to Bytes - 1 do
begin
case Buffer^[P] of
#0, #10:;
#13: begin//当收到一行字符时
if pos('NMBR=',linedata)>0 then //如果在收到的字符中有NMBR的字样,那么它后面的字符就是电话号码
begin
linedata:=copy(linedata,6,length(linedata)-5);
edit1.text:=linedata;
end;
Memo2.Lines.Add(LineData);
LineData := '';
end;
else
begin
LineData := LineData + CharBuf(Buffer^)[P];//接收每一个字符
end;
end; //case
end; //for do
end;
finally
FreeMem(Buffer);
end;
end;
end.
 
上去一下
 
如果是使用电话交换机的,如何做?
 
后退
顶部