tapifax.cpp
上传用户:zf1208
上传日期:2007-06-11
资源大小:291k
文件大小:12k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "FAXSEND.h"
  3. #include "FAXSENDDlg.h"
  4. #include "SmarFaxh.h"
  5. #include "tapifax.h"
  6. time_t g_tInitTime;
  7. DWORD g_dwNumDevs;
  8. DWORD g_dwTAPIVer= 0x00020000;
  9. LINEINITIALIZEEXPARAMS lineInitializeExParams;
  10. #define TAPI_MAX_VERSION 0x0FFF0FFF
  11. // Public available define 
  12. HANDLE    hIOCP;            /* handle for IO Completion port */
  13. HLINEAPP g_hLineApp = NULL;
  14. BOOL g_bShuttingDown = FALSE;
  15. BOOL g_bStoppingCall = FALSE;
  16. BOOL g_bInitializing = FALSE;
  17. // This sample only supports one call in progress at a time.
  18. BOOL g_bTapiInUse = FALSE;
  19. // Data needed per call.  This sample only supports one call.
  20. HCALL g_hCall = NULL;
  21. HLINE g_hLine = NULL;
  22. BOOL  g_bConnected = FALSE;
  23. DWORD dwAPIVersion;
  24. #pragma comment(lib, "Tapi32.lib")
  25. BOOL InitializeTAPI(DWORD dwDeviceID)
  26. {
  27. long lReturn;
  28.     BOOL bTryReInit = TRUE;
  29. HINSTANCE hInstance;
  30.     // If we're already initialized, then initialization succeeds.
  31.     if (g_hLineApp)
  32.         return TRUE;
  33. if(g_bTapiInUse)
  34. return TRUE;
  35.     // If we're in the middle of initializing, then fail, we're not done.
  36.     if (g_bInitializing)
  37.         return FALSE;
  38.     g_bInitializing = TRUE;
  39. hInstance = GetModuleHandle(NULL);
  40. LPLINEDEVCAPS lpDevCaps = NULL;
  41.  // Initialize TAPI
  42.     do
  43.     {
  44. #if TAPI_CURRENT_VERSION >= 0x00020000
  45. memset(&lineInitializeExParams, 0, sizeof(LINEINITIALIZEEXPARAMS));
  46. // Populate the options...
  47. lineInitializeExParams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS);
  48. lineInitializeExParams.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW;
  49. dwAPIVersion = TAPI_CURRENT_VERSION;
  50. lReturn = lineInitializeEx(&g_hLineApp, hInstance, lineCallbackFunc, 
  51. "SmartFaxSample", &g_dwNumDevs, 
  52. &dwAPIVersion, &lineInitializeExParams);
  53. #else
  54. // Note that you can't use this function and be UNICODE
  55.  lReturn = lineInitialize(&g_hLineApp, hInstance, 
  56.   lineCallbackFunc, "SmartFaxSample", &g_dwNumDevs);
  57. #endif
  58.         // If we get this error, its because some other app has yet
  59.         // to respond to the REINIT message.  Wait 5 seconds and try
  60.         // again.  If it still doesn't respond, tell the user.
  61.         if (lReturn == LINEERR_REINIT)
  62.         {
  63.             if (bTryReInit)
  64.             {
  65.                 MSG msg; 
  66.                 DWORD dwTimeStarted;
  67.                 dwTimeStarted = GetTickCount();
  68.                 while(GetTickCount() - dwTimeStarted < 5000)
  69.                 {
  70.                     if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  71.                     {
  72.                         TranslateMessage(&msg);
  73.                         DispatchMessage(&msg);
  74.                     }
  75.                 }
  76.             
  77.                 bTryReInit = FALSE;
  78.                 continue;
  79.             }
  80.             else
  81.             {
  82.                 AfxMessageBox("A change to the system configuration requires that "
  83.                     "all Telephony applications relinquish their use of "
  84.                     "Telephony before any can progress.  "
  85.                     "Some have not yet done so.");
  86.                 g_bInitializing = FALSE;
  87.                 return FALSE;
  88.             }
  89.         }
  90.         if (lReturn == LINEERR_NODEVICE)
  91.         {
  92.           
  93. AfxMessageBox("No devices installed.n");
  94.             g_bInitializing = FALSE;
  95.             return FALSE;            
  96.         }
  97.         else if(lReturn != SUCCESS)
  98.         {
  99.             AfxMessageBox("lineInitialize  error: ");
  100.             g_bInitializing = FALSE;
  101.             return FALSE;
  102.         }
  103.     } while(lReturn != SUCCESS);
  104. LINEEXTENSIONID LineExtensionID;
  105.    if (lReturn = lineNegotiateAPIVersion(g_hLineApp, dwDeviceID, 
  106.       0x00010004, TAPI_MAX_VERSION, &dwAPIVersion, &LineExtensionID))
  107.    {
  108.       TRACE(TEXT("lineNegotiateAPIVersion failed: %s.rn"), FormatTapiError(lReturn));
  109.   g_bInitializing = FALSE;
  110.       return FALSE;
  111.    }
  112.    lpDevCaps = (LINEDEVCAPS *)malloc(sizeof(LINEDEVCAPS)+1000); // Allocate a little extra memory...
  113.    if(!lpDevCaps)
  114.    {
  115. TRACE("Out of memory n");
  116. g_bInitializing = FALSE;
  117. return FALSE;
  118.    }
  119.    memset(lpDevCaps, 0, sizeof(LINEDEVCAPS)+1000);
  120.    lpDevCaps->dwTotalSize = sizeof(LINEDEVCAPS)+1000;
  121.    
  122.    if( (lReturn = lineGetDevCaps(g_hLineApp, dwDeviceID, dwAPIVersion,0,lpDevCaps)) != SUCCESS)
  123.    {
  124. TRACE(TEXT("lineGetDevCaps failed: %s.rn"), FormatTapiError(lReturn));  
  125. free(lpDevCaps);
  126. g_bInitializing = FALSE;
  127.      return FALSE;   
  128.    }
  129.    
  130.    
  131.    if (!(lpDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM))
  132.    {
  133.    TRACE("The selected line doesn't support DATAMODEM capabilitiesn");    
  134.    free(lpDevCaps);
  135.    g_bInitializing = FALSE;
  136.    return FALSE;   
  137.    }
  138.    
  139.     free(lpDevCaps);
  140.   
  141.    
  142. g_tInitTime = time(NULL);
  143. if (lReturn = lineOpen(g_hLineApp, dwDeviceID, &g_hLine, dwAPIVersion, 0, g_tInitTime,
  144. LINECALLPRIVILEGE_OWNER,LINEMEDIAMODE_DATAMODEM, NULL))
  145. {
  146. TRACE(TEXT("lineOpen failed: %s.rn"), FormatTapiError(lReturn));
  147. if(0x80000048)
  148. {
  149. AfxMessageBox("TAPI modem is not accessiable,Modem may be in user.");
  150. }
  151. g_bInitializing = FALSE;
  152. return FALSE;
  153. }
  154.    if( (lReturn = lineSetStatusMessages(g_hLine, 0x1ffffff, 0) ) )
  155.    {
  156.    TRACE(TEXT("lineOpen failed: %s.rn"), FormatTapiError(lReturn));
  157.    g_bInitializing = FALSE;
  158.  
  159.    return FALSE;
  160.    }
  161.     g_bInitializing = FALSE;
  162. g_bTapiInUse = TRUE;
  163. return TRUE;
  164. }
  165. //
  166. //  FUNCTION: BOOL ShutdownTAPI()
  167. //
  168. //  PURPOSE: Shuts down all use of TAPI
  169. //
  170. //  PARAMETERS:
  171. //    None
  172. //
  173. //  RETURN VALUE:
  174. //    True if TAPI successfully shut down.
  175. //
  176. //  COMMENTS:
  177. //
  178. //    If ShutdownTAPI fails, then its likely either a problem
  179. //    with the service provider (and might require a system
  180. //    reboot to correct) or the application ran out of memory.
  181. //
  182. //
  183. BOOL ShutdownTAPI()
  184. {
  185.     long lReturn;
  186.     // If we aren't initialized, then Shutdown is unnecessary.
  187.     if (g_hLineApp == NULL)
  188.         return TRUE;
  189.     // Prevent ShutdownTAPI re-entrancy problems.
  190.     if (g_bShuttingDown)
  191.         return TRUE;
  192.     g_bShuttingDown = TRUE;
  193. lineDrop(g_hCall, NULL, 0);
  194. //lineDeallocateCall(hCall);
  195. lineClose(g_hLine);
  196.     
  197.     do
  198.     {
  199.         lReturn = lineShutdown(g_hLineApp);
  200.               
  201. if(lReturn != SUCCESS )
  202. TRACE("lineShutdown unhandled error: ");
  203.        
  204.     } while(lReturn != SUCCESS);
  205.     g_bTapiInUse = FALSE;
  206.     g_bConnected = FALSE;
  207.     g_hLineApp = NULL;
  208.     g_hCall = NULL;
  209.     g_hLine = NULL;
  210.     g_bShuttingDown = FALSE;
  211.     TRACE("TAPI uninitialized.n");
  212.     return TRUE;
  213. }
  214. #define CHAN_DEBUG_PRINT TRACE
  215. VOID FAR PASCAL  lineCallbackFunc(DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
  216. {
  217. static int n_RingTimes = 0 ;
  218. if(g_tInitTime !=(time_t)dwCallbackInstance)
  219. return ;
  220.  switch(dwMsg)
  221.     {
  222.        
  223.         case LINE_CALLSTATE:
  224.         {
  225.             switch(dwParam1)
  226.             {
  227.               
  228. case LINECALLSTATE_CONNECTED:
  229. {
  230.     
  231. if(g_FaxDialog&&IsWindow(g_FaxDialog->GetSafeHwnd()))
  232. {
  233. g_FaxDialog->TapiSendFax();
  234. }
  235. }
  236. break;
  237.                 case LINECALLSTATE_DISCONNECTED:
  238.                 {
  239. lineDrop((HCALL) dwDevice, NULL, 0);
  240. n_RingTimes = 0;
  241.                     
  242.                 }
  243. break;
  244.             
  245.             }
  246.         }
  247.            
  248.     } 
  249. }
  250. // Turn a TAPI Line error into a printable string.
  251. LPTSTR FormatTapiError (long lError)
  252. {
  253.    static LPTSTR pszLineError[] = 
  254.    {
  255.      TEXT("LINEERR No Error"),
  256.      TEXT("LINEERR_ALLOCATED"),
  257.      TEXT("LINEERR_BADDEVICEID"),
  258.      TEXT("LINEERR_BEARERMODEUNAVAIL"),
  259.      TEXT("LINEERR Unused constant, ERROR!!"),
  260.      TEXT("LINEERR_CALLUNAVAIL"),
  261.      TEXT("LINEERR_COMPLETIONOVERRUN"),
  262.      TEXT("LINEERR_CONFERENCEFULL"),
  263.      TEXT("LINEERR_DIALBILLING"),
  264.      TEXT("LINEERR_DIALDIALTONE"),
  265.      TEXT("LINEERR_DIALPROMPT"),
  266.      TEXT("LINEERR_DIALQUIET"),
  267.      TEXT("LINEERR_INCOMPATIBLEAPIVERSION"),
  268.      TEXT("LINEERR_INCOMPATIBLEEXTVERSION"),
  269.      TEXT("LINEERR_INIFILECORRUPT"),
  270.      TEXT("LINEERR_INUSE"),
  271.      TEXT("LINEERR_INVALADDRESS"),
  272.      TEXT("LINEERR_INVALADDRESSID"),
  273.      TEXT("LINEERR_INVALADDRESSMODE"),
  274.      TEXT("LINEERR_INVALADDRESSSTATE"),
  275.      TEXT("LINEERR_INVALAPPHANDLE"),
  276.      TEXT("LINEERR_INVALAPPNAME"),
  277.      TEXT("LINEERR_INVALBEARERMODE"),
  278.      TEXT("LINEERR_INVALCALLCOMPLMODE"),
  279.      TEXT("LINEERR_INVALCALLHANDLE"),
  280.      TEXT("LINEERR_INVALCALLPARAMS"),
  281.      TEXT("LINEERR_INVALCALLPRIVILEGE"),
  282.      TEXT("LINEERR_INVALCALLSELECT"),
  283.      TEXT("LINEERR_INVALCALLSTATE"),
  284.      TEXT("LINEERR_INVALCALLSTATELIST"),
  285.      TEXT("LINEERR_INVALCARD"),
  286.      TEXT("LINEERR_INVALCOMPLETIONID"),
  287.      TEXT("LINEERR_INVALCONFCALLHANDLE"),
  288.      TEXT("LINEERR_INVALCONSULTCALLHANDLE"),
  289.      TEXT("LINEERR_INVALCOUNTRYCODE"),
  290.      TEXT("LINEERR_INVALDEVICECLASS"),
  291.      TEXT("LINEERR_INVALDEVICEHANDLE"),
  292.      TEXT("LINEERR_INVALDIALPARAMS"),
  293.      TEXT("LINEERR_INVALDIGITLIST"),
  294.      TEXT("LINEERR_INVALDIGITMODE"),
  295.      TEXT("LINEERR_INVALDIGITS"),
  296.      TEXT("LINEERR_INVALEXTVERSION"),
  297.      TEXT("LINEERR_INVALGROUPID"),
  298.      TEXT("LINEERR_INVALLINEHANDLE"),
  299.      TEXT("LINEERR_INVALLINESTATE"),
  300.      TEXT("LINEERR_INVALLOCATION"),
  301.      TEXT("LINEERR_INVALMEDIALIST"),
  302.      TEXT("LINEERR_INVALMEDIAMODE"),
  303.      TEXT("LINEERR_INVALMESSAGEID"),
  304.      TEXT("LINEERR Unused constant, ERROR!!"),
  305.      TEXT("LINEERR_INVALPARAM"),
  306.      TEXT("LINEERR_INVALPARKID"),
  307.      TEXT("LINEERR_INVALPARKMODE"),
  308.      TEXT("LINEERR_INVALPOINTER"),
  309.      TEXT("LINEERR_INVALPRIVSELECT"),
  310.      TEXT("LINEERR_INVALRATE"),
  311.      TEXT("LINEERR_INVALREQUESTMODE"),
  312.      TEXT("LINEERR_INVALTERMINALID"),
  313.      TEXT("LINEERR_INVALTERMINALMODE"),
  314.      TEXT("LINEERR_INVALTIMEOUT"),
  315.      TEXT("LINEERR_INVALTONE"),
  316.      TEXT("LINEERR_INVALTONELIST"),
  317.      TEXT("LINEERR_INVALTONEMODE"),
  318.      TEXT("LINEERR_INVALTRANSFERMODE"),
  319.      TEXT("LINEERR_LINEMAPPERFAILED"),
  320.      TEXT("LINEERR_NOCONFERENCE"),
  321.      TEXT("LINEERR_NODEVICE"),
  322.      TEXT("LINEERR_NODRIVER"),
  323.      TEXT("LINEERR_NOMEM"),
  324.      TEXT("LINEERR_NOREQUEST"),
  325.      TEXT("LINEERR_NOTOWNER"),
  326.      TEXT("LINEERR_NOTREGISTERED"),
  327.      TEXT("LINEERR_OPERATIONFAILED"),
  328.      TEXT("LINEERR_OPERATIONUNAVAIL"),
  329.      TEXT("LINEERR_RATEUNAVAIL"),
  330.      TEXT("LINEERR_RESOURCEUNAVAIL"),
  331.      TEXT("LINEERR_REQUESTOVERRUN"),
  332.      TEXT("LINEERR_STRUCTURETOOSMALL"),
  333.      TEXT("LINEERR_TARGETNOTFOUND"),
  334.      TEXT("LINEERR_TARGETSELF"),
  335.      TEXT("LINEERR_UNINITIALIZED"),
  336.      TEXT("LINEERR_USERUSERINFOTOOBIG"),
  337.      TEXT("LINEERR_REINIT"),
  338.      TEXT("LINEERR_ADDRESSBLOCKED"),
  339.      TEXT("LINEERR_BILLINGREJECTED"),
  340.      TEXT("LINEERR_INVALFEATURE"),
  341.      TEXT("LINEERR_NOMULTIPLEINSTANCE")
  342.    };
  343.    _declspec(thread) static TCHAR szError[512];
  344.    DWORD dwError;
  345.    HMODULE hTapiUIMod = GetModuleHandle(TEXT("TAPIUI.DLL"));
  346.    if (hTapiUIMod)
  347.    {
  348.       dwError = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
  349.                     (LPCVOID)hTapiUIMod, TAPIERROR_FORMATMESSAGE(lError),
  350.                     0, szError, sizeof(szError)/sizeof(TCHAR), NULL);
  351.       if (dwError)
  352.          return szError;
  353.    }
  354.    // Strip off the high bit to make the error code positive.
  355.    dwError = (DWORD)lError & 0x7FFFFFFF;
  356.    if ((lError > 0) || (dwError > sizeof(pszLineError)/sizeof(pszLineError[0])))
  357.    {
  358.       wsprintf(szError, TEXT("Unknown TAPI error code: 0x%lx"), lError);
  359.       return szError;
  360.    }
  361.    return pszLineError[dwError];
  362. }