?? tapi14.cpp
字號:
// Tapi14.cpp : implementation file
//
#include "stdafx.h"
#include "Tapi14.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// A pointer to my class because TAPI needs a callback
CTapi14* CTapi14::MyThis = NULL;
CString strStatus; //用于向主窗口傳遞顯示信息
/////////////////////////////////////////////////////////////////////////////
// CTapi14
CTapi14::CTapi14()
{
MyThis = this; //使MyThis指向當前的類實例
m_LineHandle = NULL; //線路句柄初始化為NULL
}
void CTapi14::Create(HWND& hWnd)
{
m_hWnd = hWnd; //主程序的窗口句柄
m_hInst =(HINSTANCE)::GetWindowLong(m_hWnd, GWL_HINSTANCE);
//將一些必要的屬性設置為NULL
SetProp( m_hWnd, "HCALL", NULL );
SetProp( m_hWnd, "HLINE", NULL );
SetProp( m_hWnd, "HCOMM", NULL );
}
CTapi14::~CTapi14()
{
//清除保存的屬性值
RemoveProp( m_hWnd, "HCALL" );
RemoveProp( m_hWnd, "HLINE" );
RemoveProp( m_hWnd, "HCOMM" );
}
//***********************************************
// 呼叫函數
//***********************************************
LONG CTapi14::DialCall(CString PhoneNumber )
{
LONG retcode = 0;
DWORD i;
DWORD RetApiVersion;
LINEEXTENSIONID ExtensionID;
//檢查電話號碼是否為空
if( lstrlen( PhoneNumber ) < 1 )
return( ERRORS );
//初始化線路,并注冊回調函數
if( m_LineHandle == NULL ) {
retcode = ::lineInitialize(
&m_LineHandle,
m_hInst,
(LINECALLBACK)lineCallbackFunc,
"FELIX TAPI",
&m_dwLines );
if( retcode < 0 ) {
TapiStatus("Tapi出錯..." );
return (retcode);
}
else
TapiStatus("Tapi初始化完畢..." );
}
//
// 遍歷API線路
// 若發現正確的屬性,則跳出,繼續向下執行
//
m_hLine = (HLINE)GetProp( m_hWnd, "HLINE" );
if( m_hLine == NULL )
{
for( i=0; i < m_dwLines; i++ )
{
// 對每條線路協商TAPI版本
retcode = ::lineNegotiateAPIVersion(
m_LineHandle,
i,
EARLY_TAPI_VERSION,
WIN2KTAPIVERSION,
&RetApiVersion,
&ExtensionID );
retcode = ::lineOpen( m_LineHandle,
i,
&m_hLine,
RetApiVersion,
0,
(DWORD)m_hWnd,
LINECALLPRIVILEGE_MONITOR |
LINECALLPRIVILEGE_OWNER,
LINEMEDIAMODE_DATAMODEM,
NULL );
if( retcode == 0 )
break;
}
if( retcode != 0 )
return( ERRORS );
}
//
// 找到可用的線路
SetProp( m_hWnd, "HLINE",(HANDLE)(HLINE)m_hLine );
//
// 設置線路屬性,以便撥打外線
memset( &m_LineParams, 0, sizeof( LINECALLPARAMS ) );
m_LineParams.dwTotalSize = sizeof( LINECALLPARAMS );
m_LineParams.dwMinRate = 9600;
m_LineParams.dwMaxRate = 28800;
m_LineParams.dwBearerMode = LINEBEARERMODE_VOICE;
m_LineParams.dwMediaMode = LINEMEDIAMODE_DATAMODEM;
//
// 最后,呼叫電話!
retcode = ::lineMakeCall( m_hLine,
&m_hCall,
PhoneNumber,
0,
&m_LineParams );
if( retcode < 0 )
return (retcode);
else
//等待5s,該時間可以根據實際情況重新設定
Delay(5000);
return( retcode );
}
//
// 回調函數lineCallbackFunc(..)
//
// 異步接收TAPI的事件
//
void CALLBACK CTapi14::lineCallbackFunc(
DWORD dwDevice,
DWORD dwMessage,
DWORD dwCallbackInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3)
{
MyThis->SetCallbackParams(
dwDevice,
dwMessage,
dwCallbackInstance,
dwParam1,
dwParam2,
dwParam3);
}
//設置回調函數參數
void CTapi14::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();
}
// *******************************************
// 處理TAPI消息的回調函數
//
void CTapi14::TapiCallBack()
{
switch (m_dwMessage)
{
case LINE_LINEDEVSTATE:
switch (m_dwParam1)
{
case LINEDEVSTATE_REINIT:
TapiStatus("重新初始化線路..." );
break;
case LINEDEVSTATE_RINGING:
TapiStatus("振鈴..." );
break;
}
break;
case LINE_CALLSTATE:
HandleCallState();
break;
case LINE_CLOSE:
{
TapiStatus("線路已關閉..." );
break;
}
case LINE_REPLY:
{
TapiStatus("線路有回應..." );
::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;
} /* switch */
} /* TapiCallBack() */
//********************************
//****處理呼叫狀態的函數****
//********************************
void CTapi14::HandleCallState()
{
if ((HCALL) m_dwDevice != m_hCall) {
TapiStatus("無效的設備ID ...");
return;
}
switch( m_dwParam1 )
{
case LINECALLSTATE_IDLE:
{
TapiStatus("線路空閑...");
::SendMessage(m_hWnd, WM_TAPI_IDLE, 0, 0);
HangupCall();
break;
}
case LINECALLSTATE_ACCEPTED:
{
SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
::PostMessage( m_hWnd,
WM_TAPI_CALL_ACCEPTED,
0,
(LPARAM)(HCALL)m_dwDevice );
break;
}
case LINECALLSTATE_PROCEEDING:
{
SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
::PostMessage( m_hWnd,
WM_TAPI_CALL_PROCEEDING,
0,
(LPARAM)(HCALL)m_dwDevice );
break;
}
case LINECALLSTATE_CONNECTED:
{
LineStateConnected();
break;
}
case LINECALLSTATE_OFFERING:
{
TapiStatus("線路已提供...");
break;
}
case LINECALLSTATE_DIALTONE:
{
TapiStatus("撥號音...");
break;
}
case LINECALLSTATE_DIALING:
{
TapiStatus("正在撥號...");
::SendMessage(m_hWnd, WM_TAPI_DIALING, 0, 0);
break;
}
case LINECALLSTATE_BUSY:
{
TapiStatus("線路忙,掛機...");
HangupCall();
break;
}
case LINECALLSTATE_SPECIALINFO:
{
TapiStatus("特殊的信息,可能無法撥號...");
HangupCall();
break;
}
case LINECALLSTATE_DISCONNECTED:
{
LPSTR pszReasonDisconnected;
switch (m_dwParam2)
{
case LINEDISCONNECTMODE_NORMAL:
pszReasonDisconnected = "遠端斷線";
::SendMessage(m_hWnd, WM_TAPI_DISCONNECT, 0, 0);
break;
case LINEDISCONNECTMODE_UNKNOWN:
pszReasonDisconnected = "連接解除:未知原因";
break;
case LINEDISCONNECTMODE_REJECT:
pszReasonDisconnected = "遠端退出通話";
break;
case LINEDISCONNECTMODE_PICKUP:
pszReasonDisconnected =
"連接解除: 本地電話摘機";
break;
case LINEDISCONNECTMODE_FORWARDED:
pszReasonDisconnected = "連接解除: Forwarded";
break;
case LINEDISCONNECTMODE_BUSY:
pszReasonDisconnected = "連接解除: 線路忙";
break;
case LINEDISCONNECTMODE_NOANSWER:
pszReasonDisconnected = "連接解除:無應答";
break;
case LINEDISCONNECTMODE_BADADDRESS:
pszReasonDisconnected = "連接解除: 地址無效";
break;
case LINEDISCONNECTMODE_UNREACHABLE:
pszReasonDisconnected = "連接解除: 不可到達";
break;
case LINEDISCONNECTMODE_CONGESTION:
pszReasonDisconnected = "連接解除: 堵塞";
break;
case LINEDISCONNECTMODE_INCOMPATIBLE:
pszReasonDisconnected = "連接解除: 不兼容";
break;
case LINEDISCONNECTMODE_UNAVAIL:
pszReasonDisconnected = "連接解除: 不再有效";
break;
case LINEDISCONNECTMODE_NODIALTONE:
pszReasonDisconnected = "連接解除:無撥號音";
break;
default:
pszReasonDisconnected =
"連接解除: LINECALLSTATE; Bad Reason";
break;
}
TapiStatus(pszReasonDisconnected);
HangupCall();
break;
}
} /* switch */
}
LONG CTapi14::LineStateConnected()
{
TapiStatus("Hey I am connected!");
//
// 本地變量的處理
LPVARSTRING lpVarStringStruct = NULL;
size_t sizeofVarStringStruct = sizeof( VARSTRING ) + 1024;
long lreturn;
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 );
//
// 獲取comm句柄并將其存入屬性區
m_hComm = *((LPHANDLE )( ( LPBYTE )lpVarStringStruct + lpVarStringStruct->dwStringOffset ) );
SetProp( (HWND)m_dwCallbackInstance, "HCOMM", m_hComm );
SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
::SendMessage(m_hWnd,
WM_TAPI_CONNECT,
TAPI_LINECALLSTATE_CONNECTED,
(LPARAM)(HANDLE)m_hComm );
LocalFree( lpVarStringStruct );
return lreturn;
}
//
// 掛機函數
//
LONG CTapi14::HangupCall()
{
LONG retcode = 0;
TapiStatus("正在停止通話...");
m_hCall = (HCALL)GetProp( m_hWnd, "HCALL" );
m_hComm = (HANDLE)GetProp( m_hWnd, "HCOMM" );
if( m_hComm != NULL )
{
CloseHandle( m_hComm );
SetProp( m_hWnd, "HCALL", NULL );
}
if( m_hCall != NULL )
{
retcode = lineDrop( m_hCall,
NULL,
0 );
TapiStatus("電話已經掛機...");
SetProp( m_hWnd, "HCALL", NULL );
}
LINECALLINFO LineCallInfo;
//
// 裝載呼叫信息到結構中
memset( &LineCallInfo, 0, sizeof( LINECALLINFO ) );
LineCallInfo.dwTotalSize = sizeof( LINECALLINFO );
lineGetCallInfo( (HCALL)m_dwDevice, &LineCallInfo );
//
// 收回電話資源
retcode = lineDeallocateCall( (HCALL)m_dwDevice );
TapiStatus("收回電話資源...");
//
// 電話空閑,清除
m_hLine = (HLINE)GetProp( m_hWnd, "HLINE" );
//
// 關閉活動的線路
if( m_hLine != NULL )
{
retcode = lineClose( m_hLine );
TapiStatus("線路已關閉...");
SetProp( m_hWnd, "HLINE", (HANDLE)NULL );
}
TapiStatus("呼叫已停止...");
return retcode;
}
//****************************************************
//****通過LINECALLINFO結構設置線路句柄****
//***************************************************
void CTapi14::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 CTapi14::TapiStatus(LPSTR lpszError, BOOL bShowMsgBox)
{
strcpy(m_szMessage, lpszError);
strStatus=m_szMessage;
::SendMessage(m_hWnd, WM_TAPI_STATUS, 0, 0);
Delay(400);
//想以對話框形式顯示.
if(bShowMsgBox)
AfxMessageBox(m_szMessage);
// 輸出到調試窗口
OutputDebugString(m_szMessage);
OutputDebugString("\n");
}
void CTapi14::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 + -