⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dial.cpp

📁 VC写的用TAPI 2.0接口的拨号例子.该例子能够选择TAPI通道,然后通过该通道拨打指定号码,接通后,会播放"这时一个morning call,请起床的语音通知"
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <conio.h>
#include <TAPI.h>
#include "Dial.h"
#include "WavePlay.h"

HLINEAPP    m_hLineApp;
DWORD	    m_nLines;
LPLINEINFO	pLineInfo;
LPVARSTRING lpDeviceID;
DWORD		dwActiveChn;
LINEDEVCAPS* pldc = 0;
//---------------------------------------------------------------------------
void FinishPlay(LPLINEINFO pLineData)
{                                     
	MMRESULT mmrc;

	if (!pLineData->hWaveOut) return;
	waveOutUnprepareHeader(pLineData->hWaveOut,pLineData->lpWaveHdr, sizeof(WAVEHDR));
	if ( mmrc = waveOutClose(pLineData->hWaveOut) )	
	{
		printf("\n###Line %d wave Out close error #%x!",pLineData->nLineID,mmrc);
	}
	else
	{
		printf("\nLine %d wave Out close success",pLineData->nLineID);	
	}

	pLineData->hWaveOut = NULL;
	LocalUnlock((HLOCAL)pLineData->lpWaveDataAlloc); //unlock the memory
	free (pLineData->lpWaveHdr); 
	
	return;	
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void OnHangUp(HCALL hCall, DWORD ID)
{
	LONG tr = lineDrop(hCall, 0, 0);
	if( tr > 0 )
	{
		printf("\nLine %d Call dropping...",ID);
	}
	else
	{
		printf("\n###Line %d Can't drop call.",ID);
	}
}
//---------------------------------------------------------------------------
void OnCallState(LPLINEINFO pLineData)
{
	MMRESULT mmrc;

	ADCALLBACK pCall = pLineData->pCallBack;
	HCALL hCall = (HCALL)pCall.dwDevice;
	DWORD nCallState = pCall.dwParam1;
	DWORD dwParam2 = pCall.dwParam2;
	DWORD nCallPrivilege = pCall.dwParam3;

	struct FlagMap { DWORD nFlag; LPCSTR szFlag; };
	static FlagMap aFlags[] = 
	{
		{LINECALLSTATE_IDLE,		"idle"},
		{LINECALLSTATE_ACCEPTED,    "accepted"},
		{LINECALLSTATE_DIALTONE,    "dial tone detected"},
		{LINECALLSTATE_DIALING,		"dialing"},
		{LINECALLSTATE_RINGBACK,	"ring-back detected"},
		{LINECALLSTATE_BUSY,		"busy detected"},
		{LINECALLSTATE_SPECIALINFO, "error detected"},
		{LINECALLSTATE_CONNECTED,   "connected"},
		{LINECALLSTATE_PROCEEDING,  "proceeding"},
		{LINECALLSTATE_DISCONNECTED,"disconnected"},
	};

	for (int i=0; i < 10; i++)
	{
		if ( aFlags[i].nFlag == nCallState )
		{
			printf("\nLine %d Call %s", pLineData->nLineID, aFlags[i].szFlag);
			break;
		}
	}

	switch( nCallState )
	{
		case LINECALLSTATE_DISCONNECTED:
			switch( dwParam2 )
			{
				case LINEDISCONNECTMODE_NODIALTONE:
					printf("\nLine %d No dial tone",pLineData->nLineID);
					OnHangUp(hCall,pLineData->dwLineID);
					break;
				case LINEDISCONNECTMODE_NOANSWER:	//this call is no answer
					printf("\nLine %d No answer.",pLineData->nLineID);
					OnHangUp(hCall,pLineData->dwLineID);
					break;
				default:
					if (pLineData->dwCallState & TAPI_PLAYGREET)  //hang up when play hello.wav
					{
						pLineData->dwCallState = TAPI_HANGUP;
						if ( mmrc = waveOutReset(pLineData->hWaveOut) )
							printf("\n###Line %d Can't reset wave out error #%x",pLineData->nLineID,mmrc);
						else
							FinishPlay(pLineData);
						OnHangUp(pLineData->hCall,pLineData->dwLineID);
					}
					break;							
			}
			break;

		case LINECALLSTATE_IDLE:
			lineDeallocateCall(hCall);
			printf("\nLine %d linedellocateCall", pLineData->nLineID);
			lineClose(pLineData->hLine);
			printf("\nLine %d lineclose\n", pLineData->nLineID);

			SelectChn();
			while(!OpenLine(&pLineInfo[dwActiveChn])) SelectChn();
			break;

		case LINECALLSTATE_BUSY:
			OnHangUp(hCall,pLineInfo->dwLineID);
			break;
		case LINECALLSTATE_PROCEEDING:
			break;
		case LINECALLSTATE_CONNECTED:
			pLineData->hCall = hCall;
			//call WavePlay to play hello.wave in DeviceID
			pLineData->hWaveOut=WavePlay(pLineData->dwWaveID,"hello.wav", pLineData);
			pLineData->dwCallState |= TAPI_PLAYGREET;
			break;
	}
}
//---------------------------------------------------------------------------
void CALLBACK ADmorelineCallbackFunc(DWORD dwDevice, DWORD nMsg, DWORD dwCallbackInstance,
									DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
	lpDeviceID->dwTotalSize =  sizeof (VARSTRING) + 64;	      			 
	lineGetID(0, 0, (HCALL)dwDevice, LINECALLSELECT_CALL, lpDeviceID,"tapi/line");
	DWORD dwID = (DWORD) *((BYTE*)lpDeviceID+sizeof(VARSTRING)); // get id for wave out
	FillMemory(lpDeviceID,sizeof (VARSTRING) + 64, 'f');  //fill lpdevice with 'f' byte

	if ( dwID >= m_nLines )	  //chech device range
		return;

	ADCALLBACK pCall={dwDevice,nMsg,dwCallbackInstance,dwParam1,dwParam2,dwParam3};	

	switch( nMsg )
	{
		case LINE_REPLY:
			printf("\nLine %d Call Back ------>LINE_REPLY",dwID);
			break;	 
		case LINE_CALLSTATE:
			printf("\nLine %d Call Back ------>LINE CALLSTATE",dwID);
			pLineInfo[dwID].pCallBack =	pCall;
			OnCallState(&pLineInfo[dwID]);
            break;
		case LINE_CLOSE:
            // Line has been shut down.
            printf("\nLine %d Call Back ------>LINE_CLOSE",dwID);
            OnHangUp((HCALL)dwDevice,dwID);   // all handles invalidated by this time
            break;
        case LINE_CREATE:
            printf("\nLine %d Call Back ------>LINE_CREATE",dwID);
            break;
        case LINE_GATHERDIGITS :
            printf("\nLine %d Call Back ------>LINE_LINE_GATHERDIGITS",dwID);
            break;
		case LINE_CALLINFO :
			printf("\nLine %d Call Back ------>LINE_CALLINFO",dwID);
			ADmorelineGetCallInfo(pLineInfo[dwID].hCall,&pLineInfo[dwID].lpCallInfo);
			if ((dwParam1==LINECALLINFOSTATE_APPSPECIFIC) &&    //check dwAppSpecific state
				(pLineInfo[dwID].dwCallState!=TAPI_HANGUP) &&	//check call is alive
				(pLineInfo[dwID].lpCallInfo->dwAppSpecific==TAPI_SETAPP_ENDPLAYGREET))
			{
					pLineInfo[dwID].dwCallState &= ~TAPI_PLAYGREET;
					FinishPlay(&pLineInfo[dwID]);	      //then call WaveRecord Rec ICM
					OnHangUp(pLineInfo[dwID].hCall,pLineInfo[dwID].nLineID);
			}
			break;
        default:
            printf("\nLine %d Call Back ------>lineCallbackFunc message ignored",dwID);
            break;
	}
}	
//---------------------------------------------------------------------------
long ADmorelineGetCallInfo(HCALL hCall,LINECALLINFO** ppd)
{
	DWORD	dwNeededSize = sizeof(LINECALLINFO);
	LONG    tr = 0;
	do
	{
		//Get some more memory if we don't have enough
		if( !*ppd || (*ppd)->dwTotalSize < dwNeededSize )
		{
			*ppd = (LPLINECALLINFO)realloc(*ppd, dwNeededSize);

			if( *ppd )
			{
				(*ppd)->dwTotalSize = dwNeededSize;
			}
			else
			{
				return LINEERR_NOMEM;
			}
		}

		//Fill in the buffer
		tr = lineGetCallInfo(hCall, *ppd);

		//check how much memory we need 
		//because TSPs succeed even if the data size is too small
		if( (tr == LINEERR_STRUCTURETOOSMALL ) ||
			( tr ==	0 && (*ppd)->dwTotalSize < (*ppd)->dwNeededSize) )
		{
			dwNeededSize = (*ppd)->dwNeededSize;
			tr = LINEERR_STRUCTURETOOSMALL;
		}					 

	}
	while( tr == LINEERR_STRUCTURETOOSMALL );

	return tr;
}
//---------------------------------------------------------------------------
long ADmoreGetLineDevCaps(HLINEAPP hLineApp, DWORD nApiVersion, DWORD nLineID,
							LINEDEVCAPS** ppd)
{
	DWORD	dwNeededSize = sizeof(LINEDEVCAPS);
	LONG    tr = 0;

	do
	{
		//Get some more memory if we don't have enough
		if( !*ppd || (*ppd)->dwTotalSize < dwNeededSize )
		{
			*ppd = (LPLINEDEVCAPS)realloc(*ppd, dwNeededSize);

			if( *ppd )
			{
				(*ppd)->dwTotalSize = dwNeededSize;
			}
			else
			{
				return LINEERR_NOMEM;
			}
		}

		//Fill in the buffer
		tr = lineGetDevCaps(hLineApp, nLineID, nApiVersion, 0, *ppd);

		//check how much memory we need 
		//because TSPs succeed even if the data size is too small
		if( (tr == LINEERR_STRUCTURETOOSMALL ) ||
			( tr ==	0 && (*ppd)->dwTotalSize < (*ppd)->dwNeededSize) )
		{
			dwNeededSize = (*ppd)->dwNeededSize;
			tr = LINEERR_STRUCTURETOOSMALL;
		}					 

	}
	while( tr == LINEERR_STRUCTURETOOSMALL );

	if (((*ppd) -> dwLineNameSize) &&
        ((*ppd) -> dwLineNameOffset) &&
	    ((*ppd) -> dwStringFormat == STRINGFORMAT_ASCII))
    {							   //get line Name on dwLineOffset
        strcpy(pLineInfo[nLineID].szLineName,
			           ((char *) (*ppd)) + (*ppd) -> dwLineNameOffset);
    }
	else
    {
        strcpy(pLineInfo[nLineID].szLineName,"UnknowName");
    }
	return tr;

}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -