TapiLine.cpp
上传用户:dcy024
上传日期:2013-05-27
资源大小:9k
文件大小:14k
源码类别:

TAPI编程

开发平台:

Visual C++

  1. // TapiLine.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "dialer.h"
  5. #include "TapiLine.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. // A pointer to my class because TAPI needs a callback
  12. CTapiLine* CTapiLine::MyThis = NULL;
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CTapiLine
  15. CTapiLine::CTapiLine()
  16. {
  17. MyThis = this;
  18. m_LineHandle = NULL;
  19. }
  20. void CTapiLine::Create(HWND& hWnd)
  21. {
  22. m_hWnd = hWnd;
  23. m_hInst =(HINSTANCE)::GetWindowLong(m_hWnd, GWL_HINSTANCE);
  24. // Set the necessary properties to null
  25. SetProp( m_hWnd, "HCALL", NULL );
  26. SetProp( m_hWnd, "HLINE", NULL );
  27. SetProp( m_hWnd, "HCOMM", NULL );
  28. }
  29. CTapiLine::~CTapiLine()
  30. {
  31. // drop the saved properties
  32. RemoveProp( m_hWnd, "HCALL" );
  33. RemoveProp( m_hWnd, "HLINE" );
  34. RemoveProp( m_hWnd, "HCOMM" );
  35. }
  36. // ***********************************************
  37. // This routine places the actual call
  38. //
  39. LONG CTapiLine::DialCall( LPTSTR PhoneNumber )
  40. {
  41. LONG retcode =  0; // local returns
  42. DWORD i; // counter for lines
  43. DWORD RetApiVersion; // return version
  44. LINEEXTENSIONID ExtensionID; // struc for API call
  45. //
  46. // make sure you have a phone number
  47. if( lstrlen( PhoneNumber ) < 1 )
  48. return( ERRORS );
  49. // Initialize the line, register the callback
  50. if( m_LineHandle == NULL ) {
  51. retcode = ::lineInitialize( &m_LineHandle, m_hInst, 
  52. (LINECALLBACK)lineCallbackFunc, 
  53. "MSM TAPI", &m_dwLines );
  54. if( retcode < 0 )  {
  55. TapiStatus("Tapi error..." );
  56. return (retcode);
  57. }
  58. else
  59. TapiStatus("Tapi initialized..." );
  60. }
  61. //
  62. // go through all the lines to get API and properties
  63. // if you find one that has the right properties, 
  64. // jump out and continue to next section of code
  65. //
  66. m_hLine = (HLINE)GetProp( m_hWnd, "HLINE" );
  67. if( m_hLine == NULL )
  68. {
  69. for( i=0; i < m_dwLines; i++ )
  70. {
  71. // Negotiate the API Version for each line
  72. retcode = ::lineNegotiateAPIVersion( m_LineHandle, i, 
  73. EARLY_TAPI_VERSION, 
  74. WIN95TAPIVERSION,
  75. &RetApiVersion,
  76. &ExtensionID );
  77. retcode = ::lineOpen( m_LineHandle, i, &m_hLine, 
  78.                 RetApiVersion, 0, (DWORD)m_hWnd,
  79.                                 LINECALLPRIVILEGE_MONITOR | 
  80.             LINECALLPRIVILEGE_OWNER,
  81.             LINEMEDIAMODE_DATAMODEM, 
  82. NULL );
  83. if( retcode == 0 )
  84. break;
  85. }
  86. if( retcode != 0 )
  87. return( ERRORS );
  88. }
  89. //
  90. // found a good line
  91. SetProp( m_hWnd, "HLINE",(HANDLE)(HLINE)m_hLine );
  92. //
  93. // now set of properties of the line for outbound dialing
  94. memset( &m_LineParams, 0, sizeof( LINECALLPARAMS ) );
  95. m_LineParams.dwTotalSize = sizeof( LINECALLPARAMS );
  96. m_LineParams.dwMinRate = 9600; // setting data rates
  97. m_LineParams.dwMaxRate = 28800; //
  98.     m_LineParams.dwBearerMode = LINEBEARERMODE_VOICE; 
  99. m_LineParams.dwMediaMode  = LINEMEDIAMODE_DATAMODEM;
  100. //
  101. // finally place the call!
  102. retcode = ::lineMakeCall( m_hLine, &m_hCall, 
  103. PhoneNumber, 0, 
  104. &m_LineParams );
  105. if( retcode < 0 ) 
  106. return (retcode); // tell'em how it turned out!
  107. else
  108. Delay(5000); // make a 5 secs delay... or according to ur needs 
  109. return( retcode ); // tell'em how it turned out!
  110. }
  111. //
  112. //  FUNCTION: lineCallbackFunc(..)
  113. //
  114. //  PURPOSE: Receive asynchronous TAPI events
  115. //
  116. void CALLBACK CTapiLine::lineCallbackFunc(
  117.     DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, 
  118.     DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
  119. {
  120. MyThis->SetCallbackParams(
  121. dwDevice, dwMessage, 
  122. dwCallbackInstance, 
  123. dwParam1, dwParam2, 
  124. dwParam3);
  125. }
  126. void CTapiLine::SetCallbackParams(
  127. DWORD dwDevice, DWORD dwMessage, 
  128. DWORD dwCallbackInstance, 
  129. DWORD dwParam1, DWORD dwParam2, 
  130. DWORD dwParam3)
  131. {
  132. m_dwDevice = dwDevice;
  133. m_dwMessage = dwMessage;
  134. m_dwCallbackInstance = dwCallbackInstance;
  135. m_dwParam1 = dwParam1;
  136. m_dwParam2 = dwParam2; 
  137. m_dwParam3 = dwParam3;
  138. // Load our own Override here because thats the virtual function...
  139. TapiCallBack();
  140. }
  141. // *******************************************
  142. // The callback to handle TAPI messages
  143. //
  144. // This routine handles all messages generated by TAPI services.
  145. // Most of these messages are ignored here or just passsed on to
  146. // the main dialog for posting to the progress window.
  147. //
  148. void CTapiLine::TapiCallBack()
  149. {   
  150.     switch (m_dwMessage) 
  151.         { 
  152.         case LINE_LINEDEVSTATE: // we'll ignore these for now...
  153.             switch (m_dwParam1)
  154.             {
  155.              case LINEDEVSTATE_REINIT:
  156. TapiStatus("LINEDEVSTATE_REINIT..." );
  157.              break;
  158.              case LINEDEVSTATE_RINGING:
  159. TapiStatus("LINEDEVSTATE_RINGING..." );
  160.              break;
  161.             } 
  162. break; // LINE_LINEDEVSTATE:
  163.         case LINE_CALLSTATE: // review the call state messages
  164.             HandleCallState();
  165.             break;
  166.        
  167.        case LINE_CLOSE: // the line has been closed!
  168. {
  169. TapiStatus("LINE_CLOSED..." );
  170. break; 
  171. }
  172.        case LINE_REPLY: // pass on TAPI_REPLY messages
  173. {
  174. TapiStatus("Line Reply..." );
  175. ::PostMessage( m_hWnd, WM_TAPI_LINE_REPLY, 
  176. m_dwParam2,  
  177. (LPARAM)(HCALL)m_dwDevice );
  178.             break;
  179. }
  180.         //
  181. // other messages that we'll ignore here
  182. //
  183.         case LINE_REQUEST:
  184.         case LINE_ADDRESSSTATE:
  185.             break;
  186.         case LINE_CALLINFO:
  187.             break;
  188.         case LINE_DEVSPECIFIC:
  189.             break;
  190.         case LINE_DEVSPECIFICFEATURE:
  191.             break;
  192.         case LINE_GATHERDIGITS:
  193.             break;
  194.         case LINE_GENERATE:
  195.             break;
  196.         case LINE_MONITORDIGITS:
  197.             break;
  198.         case LINE_MONITORMEDIA:
  199.             break;
  200.         case LINE_MONITORTONE:
  201.             break;
  202.         } /* switch */ 
  203.         
  204. } /* TapiCallBack() */
  205. void CTapiLine::HandleCallState()
  206. {
  207.     // Error if this CALLSTATE doesn't apply to our call in progress.
  208.     if ((HCALL) m_dwDevice != m_hCall) {
  209. TapiStatus("LINE_CALLSTATE: Unknown device ID ...");
  210.         return;
  211.     }
  212. switch( m_dwParam1 )
  213. {
  214.         case LINECALLSTATE_IDLE:
  215. {
  216. TapiStatus("Line is idle...");
  217. ::SendMessage(m_hWnd, WM_TAPI_IDLE, 0, 0); 
  218. HangupCall();
  219. break;
  220. }      
  221. case LINECALLSTATE_ACCEPTED: // just pass message on...
  222. {
  223. SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
  224. ::PostMessage( m_hWnd, WM_TAPI_CALL_ACCEPTED, 
  225. 0,  (LPARAM)(HCALL)m_dwDevice );
  226.   break;
  227. }
  228. case LINECALLSTATE_PROCEEDING: // post progress message
  229. {
  230. SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
  231. ::PostMessage( m_hWnd, WM_TAPI_CALL_PROCEEDING, 
  232. 0,  (LPARAM)(HCALL)m_dwDevice );
  233. break;
  234. }
  235. case LINECALLSTATE_CONNECTED: // hey, we got through!
  236. {
  237. LineStateConnected();
  238. break;
  239. }
  240. case LINECALLSTATE_OFFERING: // pass it on
  241. {
  242. TapiStatus("LINECALLSTATE_OFFERING...");
  243. break;
  244. }
  245. case LINECALLSTATE_DIALTONE:
  246. {
  247. TapiStatus("Dial Tone...");
  248.             break;
  249. }
  250.         case LINECALLSTATE_DIALING: // pass it on
  251. {
  252. TapiStatus("Dialing...");
  253. ::SendMessage(m_hWnd, WM_TAPI_DIALING, 0, 0); 
  254.             break;
  255. }
  256.         case LINECALLSTATE_BUSY:
  257. {
  258. TapiStatus("Line busy, shutting down...");
  259.             HangupCall();
  260.             break;
  261. }
  262.         case LINECALLSTATE_SPECIALINFO:
  263. {
  264. TapiStatus("Special Info, probably couldn't dial number...");
  265.             HangupCall();
  266.             break;
  267. }
  268.         case LINECALLSTATE_DISCONNECTED:
  269.         {
  270.             LPSTR pszReasonDisconnected;
  271.             switch (m_dwParam2)
  272.             {
  273.                 case LINEDISCONNECTMODE_NORMAL:
  274.                     pszReasonDisconnected = "Remote Party Disconnected";
  275. ::SendMessage(m_hWnd, WM_TAPI_DISCONNECT, 0, 0); 
  276.                     break;
  277.                 case LINEDISCONNECTMODE_UNKNOWN:
  278.                     pszReasonDisconnected = "Disconnected: Unknown reason";
  279.                     break;
  280.                 case LINEDISCONNECTMODE_REJECT:
  281.                     pszReasonDisconnected = "Remote Party rejected call";
  282.                     break;
  283.                 case LINEDISCONNECTMODE_PICKUP:
  284.                     pszReasonDisconnected = 
  285.                         "Disconnected: Local phone picked up";
  286.                     break;
  287.                 case LINEDISCONNECTMODE_FORWARDED:
  288.                     pszReasonDisconnected = "Disconnected: Forwarded";
  289.                     break;
  290.                 case LINEDISCONNECTMODE_BUSY:
  291.                     pszReasonDisconnected = "Disconnected: Busy";
  292.                     break;
  293.                 case LINEDISCONNECTMODE_NOANSWER:
  294.                     pszReasonDisconnected = "Disconnected: No Answer";
  295.                     break;
  296.                 case LINEDISCONNECTMODE_BADADDRESS:
  297.                     pszReasonDisconnected = "Disconnected: Bad Address";
  298.                     break;
  299.                 case LINEDISCONNECTMODE_UNREACHABLE:
  300.                     pszReasonDisconnected = "Disconnected: Unreachable";
  301.                     break;
  302.                 case LINEDISCONNECTMODE_CONGESTION:
  303.                     pszReasonDisconnected = "Disconnected: Congestion";
  304.                     break;
  305.                 case LINEDISCONNECTMODE_INCOMPATIBLE:
  306.                     pszReasonDisconnected = "Disconnected: Incompatible";
  307.                     break;
  308.                 case LINEDISCONNECTMODE_UNAVAIL:
  309.                     pszReasonDisconnected = "Disconnected: Unavail";
  310.                     break;
  311.                 case LINEDISCONNECTMODE_NODIALTONE:
  312.                     pszReasonDisconnected = "Disconnected: No Dial Tone";
  313.                     break;
  314.                 default:
  315.                     pszReasonDisconnected = 
  316.                         "Disconnected: LINECALLSTATE; Bad Reason";
  317.                     break;
  318.             }
  319. TapiStatus(pszReasonDisconnected);
  320.             HangupCall();
  321.             break;
  322.         }
  323. } /* switch */ 
  324. }
  325. LONG CTapiLine::LineStateConnected()
  326. {
  327. TapiStatus("Hey I am connected!");
  328. //
  329. // local vars for processing
  330. LPVARSTRING lpVarStringStruct = NULL;
  331. size_t sizeofVarStringStruct = sizeof( VARSTRING ) + 1024;
  332. long lreturn;
  333. // get the comm handle.  Be sure to drop this handle when
  334. // the call is done or you'll get device unavailable errors
  335. // and have to REBOOT!
  336. lpVarStringStruct = ( LPVARSTRING )LocalAlloc( 0, sizeofVarStringStruct );
  337. do
  338. {
  339. memset( lpVarStringStruct, 0, sizeofVarStringStruct );
  340. lpVarStringStruct->dwTotalSize = (DWORD)sizeofVarStringStruct;
  341. lreturn = lineGetID( 0, 0, (HCALL)m_dwDevice, LINECALLSELECT_CALL, lpVarStringStruct, "comm/datamodem" );
  342. } while( lreturn != 0 );
  343. //
  344. // get comm device handle and save it to properties area
  345. m_hComm = *( (LPHANDLE )( ( LPBYTE )lpVarStringStruct + lpVarStringStruct->dwStringOffset ) );
  346. SetProp( (HWND)m_dwCallbackInstance, "HCOMM", m_hComm );
  347. SetVarProps( (HWND)m_dwCallbackInstance, m_dwDevice );
  348. //
  349. // tell main dialog we got through
  350. ::SendMessage(m_hWnd, WM_TAPI_CONNECT, 
  351.   TAPI_LINECALLSTATE_CONNECTED, 
  352.   (LPARAM)(HANDLE)m_hComm );
  353. LocalFree( lpVarStringStruct ); // drop mem space
  354. return lreturn;
  355. }
  356. //
  357. //  FUNCTION: LONG HangupCall()
  358. //
  359. //  PURPOSE: Hangup the call in progress if it exists.
  360. //
  361. LONG CTapiLine::HangupCall()
  362. {         
  363. LONG retcode = 0; // some local stuff
  364. TapiStatus("Stopping Call in progress...");
  365. //
  366. // try to get the handles
  367. m_hCall = (HCALL)GetProp( m_hWnd, "HCALL" );
  368. m_hComm = (HANDLE)GetProp( m_hWnd, "HCOMM" );
  369. //
  370. // if we have a comm handle, drop it
  371. if( m_hComm != NULL )
  372. {
  373. CloseHandle( m_hComm );
  374. SetProp( m_hWnd, "HCALL", NULL );
  375. }
  376. //
  377. // if we have a call handle, drop it
  378. if( m_hCall != NULL )
  379. {
  380. retcode = lineDrop( m_hCall, NULL, 0 );
  381. TapiStatus("Call Dropped...");
  382. SetProp( m_hWnd, "HCALL", NULL );
  383. }
  384. LINECALLINFO LineCallInfo;
  385. //
  386. // load call info into structure
  387. memset( &LineCallInfo, 0, sizeof( LINECALLINFO ) );
  388. LineCallInfo.dwTotalSize = sizeof( LINECALLINFO );
  389. lineGetCallInfo( (HCALL)m_dwDevice, &LineCallInfo );
  390. //
  391. // deallocate the call
  392. retcode = lineDeallocateCall( (HCALL)m_dwDevice );
  393. TapiStatus("Call deallocated...");
  394. //
  395. // call went idle, do cleanup
  396. m_hLine = (HLINE)GetProp( m_hWnd, "HLINE" ); 
  397. //
  398. // if we have a live line, close it
  399. if( m_hLine != NULL )
  400. {
  401. retcode = lineClose( m_hLine );
  402. TapiStatus("Line Closed...");
  403. SetProp( m_hWnd, "HLINE", (HANDLE)NULL );
  404. }
  405. TapiStatus("Call stopped...");
  406.     return retcode;
  407. }
  408. // ***************************************************
  409. // get line handle from LINECALLINFO structure
  410. //
  411. void CTapiLine::SetVarProps(HWND hWnd, DWORD hDevice )
  412. {
  413. LINECALLINFO LineCallInfo;
  414. memset( &LineCallInfo, 0, sizeof( LINECALLINFO ) );
  415. SetProp( hWnd, "HCALL", (HANDLE)(HCALL)hDevice );
  416. LineCallInfo.dwTotalSize = sizeof( LINECALLINFO );
  417. lineGetCallInfo( (HCALL)hDevice, &LineCallInfo );
  418.   SetProp(m_hWnd, "HLINE", (HANDLE)(HLINE)LineCallInfo.hLine );
  419. return;
  420. }
  421. void CTapiLine::TapiStatus(LPSTR lpszError, BOOL bShowMsgBox)
  422. {
  423. strcpy(m_szMessage, lpszError);
  424. ::SendMessage(m_hWnd, WM_TAPI_STATUS, 0, 0); 
  425. // Give some delay if u want it ok..
  426. Delay(400);
  427. // u wanna show it using dialog box.. 
  428. if(bShowMsgBox)
  429. AfxMessageBox(m_szMessage);
  430. // output it in the debugger
  431. OutputDebugString(m_szMessage);
  432. OutputDebugString("n");
  433. }
  434. void CTapiLine::Delay(UINT lFactor)
  435. {
  436. MSG msg;
  437. DWORD dwTimeStarted;
  438. dwTimeStarted = GetTickCount();
  439. // get control of message loop
  440.     while(GetTickCount() - dwTimeStarted < lFactor)
  441. if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  442.         {
  443. TranslateMessage(&msg);
  444. DispatchMessage(&msg);
  445. }
  446. }
  447. }