📄 tapiline.cpp
字号:
// TapiLine.cpp : implementation file
//
#include "stdafx.h"
#include "snd.h"
#include "TapiLine.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CTapiLine* CTapiLine::MyThis = NULL;
CTapiLine::CTapiLine()
{
MyThis = this;
m_LineHandle = NULL;
}
void CTapiLine::Create(HWND& hWnd)
{
m_hWnd = hWnd;
m_hInst =(HINSTANCE)::GetWindowLong(m_hWnd, GWL_HINSTANCE);
SetProp( m_hWnd, "HCALL", NULL );
SetProp( m_hWnd, "HLINE", NULL );
SetProp( m_hWnd, "HCOMM", NULL );
}
CTapiLine::~CTapiLine()
{
RemoveProp( m_hWnd, "HCALL" );
RemoveProp( m_hWnd, "HLINE" );
RemoveProp( m_hWnd, "HCOMM" );
}
// ***********************************************
// This routine places the actual call
//
LONG CTapiLine::DialCall( char * strPhNo )
{
int nRet;
int i;
LONG nRetCode = 0;
DWORD dwApiVer;
LINEEXTENSIONID ExtensionID;
// nRet = strlen(strPhNo);
// if ( nRet <= 0 ) { AfxMessageBox("Phone # cannot NULL"); return -1; }
if ( m_LineHandle != NULL ) { AfxMessageBox("Already connected"); return -2; }
nRetCode = ::lineInitialize( &m_LineHandle, m_hInst,(LINECALLBACK)lineCallbackFunc,"MSM TAPI", &m_dwLines );
if( nRetCode < 0 ) { TRACE("Tapi error..." ); return -3; }
TRACE("Tapi initialized..." );
for( i = 0; i < (int)m_dwLines; i++ )
{
nRetCode = ::lineNegotiateAPIVersion( m_LineHandle, i,EARLY_TAPI_VERSION, WIN95TAPIVERSION,&dwApiVer,&ExtensionID );
if ( nRetCode != 0 ) { AfxMessageBox("Fatal Error in lineNegotiateAPIVersion"); return -4; }
nRetCode = ::lineOpen( m_LineHandle, i, &m_hLine,
dwApiVer, 0, (DWORD)m_hWnd,
LINECALLPRIVILEGE_NONE ,
LINEMEDIAMODE_DATAMODEM ,
NULL );
if( nRetCode == 0 ) { TRACE("Line # %d Successfully Opend",i); break;}
else { AfxMessageBox("Fatal Error in lineOpen"); return -5; }
}
memset( &m_LineParams, 0, sizeof( LINECALLPARAMS ) );
m_LineParams.dwTotalSize = sizeof( LINECALLPARAMS );
m_LineParams.dwMinRate = 0;
m_LineParams.dwMaxRate = 56800;
m_LineParams.dwBearerMode = LINEBEARERMODE_VOICE;
m_LineParams.dwMediaMode = LINEMEDIAMODE_DATAMODEM |LINEMEDIAMODE_INTERACTIVEVOICE ;
nRetCode = ::lineMakeCall( m_hLine, &m_hCall,strPhNo,92 , NULL );
//nRetCode = lineDial( m_hCall,strPhNo,92);
if( nRetCode < 0 ) { AfxMessageBox("Fatal Error in lineMakeCall"); return -6; }
else Delay(5000);
return( nRetCode );
}
void CALLBACK CTapiLine::lineCallbackFunc(
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
MyThis->SetCallbackParams(
dwDevice, dwMessage,
dwCallbackInstance,
dwParam1, dwParam2,
dwParam3);
}
void CTapiLine::SetCallbackParams(
DWORD dwDevice, DWORD dwMessage,
DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2,
DWORD dwParam3)
{
m_dwDevice = dwDevice;
m_dwMessage = dwMessage;
m_dwCallbackInstance = dwCallbackInstance;
m_dwParam1 = dwParam1;
m_dwParam2 = dwParam2;
m_dwParam3 = dwParam3;
TapiCallBack();
}
void CTapiLine::TapiCallBack()
{
switch (m_dwMessage)
{
case LINE_LINEDEVSTATE:
switch (m_dwParam1)
{
case LINEDEVSTATE_REINIT:
TRACE("LINEDEVSTATE_REINIT..." );
break;
case LINEDEVSTATE_RINGING:
TRACE("LINEDEVSTATE_RINGING..." );
break;
default:
TRACE("\nUnknown device state ... \n");
}
break;
case LINE_CALLSTATE: // review the call state messages
HandleCallState();
break;
case LINE_CLOSE: // the line has been closed!
TRACE("LINE_CLOSED..." );
break;
case LINE_REPLY: // pass on TAPI_REPLY messages
TRACE("Line Reply..." );
::PostMessage( m_hWnd, WM_TAPI_LINE_REPLY,m_dwParam2,(LPARAM)(HCALL)m_dwDevice ); break;
case LINE_REQUEST:
case LINE_ADDRESSSTATE:
break;
case LINE_CALLINFO:
break;
case LINE_DEVSPECIFIC:
break;
case LINE_DEVSPECIFICFEATURE:
break;
case LINE_GATHERDIGITS:
break;
case LINE_GENERATE:
break;
case LINE_MONITORDIGITS:
break;
case LINE_MONITORMEDIA:
break;
case LINE_MONITORTONE:
break;
default:
TRACE("\nUnknown Message ... \n");
}
}
void CTapiLine::HandleCallState()
{
if ((HCALL) m_dwDevice != m_hCall) {
TRACE("LINE_CALLSTATE: Unknown device ID ...");
return;
}
TRACE("\n Call Status = %d",m_dwParam1);
switch( m_dwParam1 )
{
case LINECALLSTATE_RINGBACK:
{
TRACE("\n Ring back tone received...");
break;
}
case LINECALLSTATE_IDLE:
{
TRACE("Line is idle...");
::SendMessage(m_hWnd, WM_TAPI_IDLE, 0, 0);
HangupCall();
break;
}
case LINECALLSTATE_ACCEPTED: // just pass message on...
{
SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
::PostMessage( m_hWnd, WM_TAPI_CALL_ACCEPTED,
0, (LPARAM)(HCALL)m_dwDevice );
break;
}
case LINECALLSTATE_PROCEEDING: // post progress message
{
SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
::PostMessage( m_hWnd, WM_TAPI_CALL_PROCEEDING,
0, (LPARAM)(HCALL)m_dwDevice );
break;
}
case LINECALLSTATE_CONNECTED: // hey, we got through!
{
LineStateConnected();
break;
}
case LINECALLSTATE_OFFERING: // pass it on
{
TRACE("LINECALLSTATE_OFFERING...");
break;
}
case LINECALLSTATE_DIALTONE:
{
TRACE("Dial Tone...");
break;
}
case LINECALLSTATE_DIALING: // pass it on
{
TRACE("Dialing...");
::SendMessage(m_hWnd, WM_TAPI_DIALING, 0, 0);
break;
}
case LINECALLSTATE_BUSY:
{
TRACE("Line busy, shutting down...");
HangupCall();
break;
}
case LINECALLSTATE_SPECIALINFO:
{
TRACE("Special Info, probably couldn't dial number...");
HangupCall();
break;
}
case LINECALLSTATE_DISCONNECTED:
{
LPSTR pszReasonDisconnected;
switch (m_dwParam2)
{
case LINEDISCONNECTMODE_NORMAL:
pszReasonDisconnected = "Remote Party Disconnected";
::SendMessage(m_hWnd, WM_TAPI_DISCONNECT, 0, 0);
break;
case LINEDISCONNECTMODE_UNKNOWN:
pszReasonDisconnected = "Disconnected: Unknown reason";
break;
case LINEDISCONNECTMODE_REJECT:
pszReasonDisconnected = "Remote Party rejected call";
break;
case LINEDISCONNECTMODE_PICKUP:
pszReasonDisconnected =
"Disconnected: Local phone picked up";
break;
case LINEDISCONNECTMODE_FORWARDED:
pszReasonDisconnected = "Disconnected: Forwarded";
break;
case LINEDISCONNECTMODE_BUSY:
pszReasonDisconnected = "Disconnected: Busy";
break;
case LINEDISCONNECTMODE_NOANSWER:
pszReasonDisconnected = "Disconnected: No Answer";
break;
case LINEDISCONNECTMODE_BADADDRESS:
pszReasonDisconnected = "Disconnected: Bad Address";
break;
case LINEDISCONNECTMODE_UNREACHABLE:
pszReasonDisconnected = "Disconnected: Unreachable";
break;
case LINEDISCONNECTMODE_CONGESTION:
pszReasonDisconnected = "Disconnected: Congestion";
break;
case LINEDISCONNECTMODE_INCOMPATIBLE:
pszReasonDisconnected = "Disconnected: Incompatible";
break;
case LINEDISCONNECTMODE_UNAVAIL:
pszReasonDisconnected = "Disconnected: Unavail";
break;
case LINEDISCONNECTMODE_NODIALTONE:
pszReasonDisconnected = "Disconnected: No Dial Tone";
break;
default:
pszReasonDisconnected =
"Disconnected: LINECALLSTATE; Bad Reason";
break;
}
TRACE(pszReasonDisconnected);
HangupCall();
break;
}
default:
TRACE("\nUnknown call state in param1\n");
}
}
LONG CTapiLine::LineStateConnected()
{
TRACE("Hey I am connected!");
LPVARSTRING lpVarStringStruct = NULL;
size_t sizeofVarStringStruct = sizeof( VARSTRING ) + 1024;
long lreturn;
// get the comm handle. Be sure to drop this handle when
// the call is done or you'll get device unavailable errors
// and have to REBOOT!
lpVarStringStruct = ( LPVARSTRING )LocalAlloc( 0, sizeofVarStringStruct );
do
{
memset( lpVarStringStruct, 0, sizeofVarStringStruct );
lpVarStringStruct->dwTotalSize = (DWORD)sizeofVarStringStruct;
lreturn = lineGetID( 0, 0, (HCALL)m_dwDevice, LINECALLSELECT_CALL, lpVarStringStruct, "comm/datamodem" );
} while( lreturn != 0 );
//
// get comm device handle and save it to properties area
m_hComm = *( (LPHANDLE )( ( LPBYTE )lpVarStringStruct + lpVarStringStruct->dwStringOffset ) );
SetProp( (HWND)m_dwCallbackInstance, "HCOMM", m_hComm );
SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
//
// tell main dialog we got through
::SendMessage(m_hWnd, WM_TAPI_CONNECT,
TAPI_LINECALLSTATE_CONNECTED,
(LPARAM)(HANDLE)m_hComm );
LocalFree( lpVarStringStruct ); // drop mem space
return lreturn;
}
LONG CTapiLine::HangupCall()
{
LONG nRetCode = 0;
LINECALLINFO LineCallInfo;
if ( m_hComm == NULL ) { AfxMessageBox("Not Connected"); return -1; }
CloseHandle( m_hComm );
m_hComm = NULL;
if ( m_hCall == NULL ) { AfxMessageBox("Not Connected"); return -1; }
nRetCode = lineDrop( m_hCall, NULL, 0 );
TRACE("Call Dropped...");
memset( &LineCallInfo, 0, sizeof( LINECALLINFO ) );
LineCallInfo.dwTotalSize = sizeof( LINECALLINFO );
lineGetCallInfo( (HCALL)m_dwDevice, &LineCallInfo );
nRetCode = lineDeallocateCall( (HCALL)m_dwDevice );
if ( m_hLine == NULL ) { AfxMessageBox("Line Already Clear"); return -1; }
nRetCode = lineClose( m_hLine );
TRACE("Call stopped...");
m_LineHandle = NULL;
return nRetCode;
}
void CTapiLine::SetVarProps(HWND hWnd, DWORD hDevice )
{
LINECALLINFO LineCallInfo;
memset( &LineCallInfo, 0, sizeof( LINECALLINFO ) );
SetProp( hWnd, "HCALL", (HANDLE)(HCALL)hDevice );
LineCallInfo.dwTotalSize = sizeof( LINECALLINFO );
lineGetCallInfo( (HCALL)hDevice, &LineCallInfo );
SetProp(m_hWnd, "HLINE", (HANDLE)(HLINE)LineCallInfo.hLine );
return;
}
void CTapiLine::Delay(UINT lFactor)
{
MSG msg;
DWORD dwTimeStarted;
dwTimeStarted = GetTickCount();
while(GetTickCount() - dwTimeStarted < lFactor)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -