www.gusucode.com > 一个VC++传真机接口类源码程序 > 一个VC++传真机接口类/VC++写的一个传真机接口类库/VC++写的一个传真机接口类库/FAXRECV/tapifax.cpp
#include "stdafx.h" // Download by http://www.codesc.net #include "FAXRECV.h" #include "FAXRECVDlg.h" #include "..\\include\\SmarFaxh.h" #include "tapifax.h" time_t g_tInitTime; DWORD g_dwNumDevs; DWORD g_dwTAPIVer= 0x00020000; LINEINITIALIZEEXPARAMS lineInitializeExParams; #define TAPI_MAX_VERSION 0x0FFF0FFF // Public available define HANDLE hIOCP; /* handle for IO Completion port */ HLINEAPP g_hLineApp = NULL; BOOL g_bShuttingDown = FALSE; BOOL g_bStoppingCall = FALSE; BOOL g_bInitializing = FALSE; // This sample only supports one call in progress at a time. BOOL g_bTapiInUse = FALSE; // Data needed per call. This sample only supports one call. HCALL g_hCall = NULL; HLINE g_hLine = NULL; BOOL g_bConnected = FALSE; DWORD dwAPIVersion; #pragma comment(lib, "Tapi32.lib") BOOL InitializeTAPI(DWORD dwDeviceID) { long lReturn; BOOL bTryReInit = TRUE; HINSTANCE hInstance; // If we're already initialized, then initialization succeeds. if (g_hLineApp) return TRUE; if(g_bTapiInUse) return TRUE; // If we're in the middle of initializing, then fail, we're not done. if (g_bInitializing) return FALSE; g_bInitializing = TRUE; hInstance = GetModuleHandle(NULL); LPLINEDEVCAPS lpDevCaps = NULL; // Initialize TAPI do { #if TAPI_CURRENT_VERSION >= 0x00020000 memset(&lineInitializeExParams, 0, sizeof(LINEINITIALIZEEXPARAMS)); // Populate the options... lineInitializeExParams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS); lineInitializeExParams.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW; dwAPIVersion = TAPI_CURRENT_VERSION; lReturn = lineInitializeEx(&g_hLineApp, hInstance, lineCallbackFunc, "SmartFaxSample", &g_dwNumDevs, &dwAPIVersion, &lineInitializeExParams); #else // Note that you can't use this function and be UNICODE lReturn = lineInitialize(&g_hLineApp, hInstance, lineCallbackFunc, "SmartFaxSample", &g_dwNumDevs); #endif // If we get this error, its because some other app has yet // to respond to the REINIT message. Wait 5 seconds and try // again. If it still doesn't respond, tell the user. if (lReturn == LINEERR_REINIT) { if (bTryReInit) { MSG msg; DWORD dwTimeStarted; dwTimeStarted = GetTickCount(); while(GetTickCount() - dwTimeStarted < 5000) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } bTryReInit = FALSE; continue; } else { AfxMessageBox("A change to the system configuration requires that " "all Telephony applications relinquish their use of " "Telephony before any can progress. " "Some have not yet done so."); g_bInitializing = FALSE; return FALSE; } } if (lReturn == LINEERR_NODEVICE) { AfxMessageBox("No devices installed.\n"); g_bInitializing = FALSE; return FALSE; } else if(lReturn != SUCCESS) { AfxMessageBox("lineInitialize error: "); g_bInitializing = FALSE; return FALSE; } } while(lReturn != SUCCESS); LINEEXTENSIONID LineExtensionID; if (lReturn = lineNegotiateAPIVersion(g_hLineApp, dwDeviceID, 0x00010004, TAPI_MAX_VERSION, &dwAPIVersion, &LineExtensionID)) { TRACE(TEXT("lineNegotiateAPIVersion failed: %s.\r\n"), FormatTapiError(lReturn)); g_bInitializing = FALSE; return FALSE; } lpDevCaps = (LINEDEVCAPS *)malloc(sizeof(LINEDEVCAPS)+1000); // Allocate a little extra memory... if(!lpDevCaps) { TRACE("Out of memory \n"); g_bInitializing = FALSE; return FALSE; } memset(lpDevCaps, 0, sizeof(LINEDEVCAPS)+1000); lpDevCaps->dwTotalSize = sizeof(LINEDEVCAPS)+1000; if( (lReturn = lineGetDevCaps(g_hLineApp, dwDeviceID, dwAPIVersion,0,lpDevCaps)) != SUCCESS) { TRACE(TEXT("lineGetDevCaps failed: %s.\r\n"), FormatTapiError(lReturn)); free(lpDevCaps); g_bInitializing = FALSE; return FALSE; } if (!(lpDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM)) { TRACE("The selected line doesn't support DATAMODEM capabilities\n"); free(lpDevCaps); g_bInitializing = FALSE; return FALSE; } free(lpDevCaps); g_tInitTime = time(NULL); if (lReturn = lineOpen(g_hLineApp, dwDeviceID, &g_hLine, dwAPIVersion, 0, g_tInitTime, LINECALLPRIVILEGE_OWNER,LINEMEDIAMODE_DATAMODEM, NULL)) { TRACE(TEXT("lineOpen failed: %s.\r\n"), FormatTapiError(lReturn)); if(0x80000048) { AfxMessageBox("TAPI modem is not accessiable,Modem may be in user."); } g_bInitializing = FALSE; return FALSE; } if( (lReturn = lineSetStatusMessages(g_hLine, 0x1ffffff, 0) ) ) { TRACE(TEXT("lineOpen failed: %s.\r\n"), FormatTapiError(lReturn)); g_bInitializing = FALSE; return FALSE; } g_bInitializing = FALSE; g_bTapiInUse = TRUE; return TRUE; } // // FUNCTION: BOOL ShutdownTAPI() // // PURPOSE: Shuts down all use of TAPI // // PARAMETERS: // None // // RETURN VALUE: // True if TAPI successfully shut down. // // COMMENTS: // // If ShutdownTAPI fails, then its likely either a problem // with the service provider (and might require a system // reboot to correct) or the application ran out of memory. // // BOOL ShutdownTAPI() { long lReturn; // If we aren't initialized, then Shutdown is unnecessary. if (g_hLineApp == NULL) return TRUE; // Prevent ShutdownTAPI re-entrancy problems. if (g_bShuttingDown) return TRUE; g_bShuttingDown = TRUE; lineDrop(g_hCall, NULL, 0); lineDeallocateCall(g_hCall); lineClose(g_hLine); do { lReturn = lineShutdown(g_hLineApp); if(lReturn != SUCCESS ) TRACE("lineShutdown unhandled error: "); } while(lReturn != SUCCESS); g_bTapiInUse = FALSE; g_bConnected = FALSE; g_hLineApp = NULL; g_hCall = NULL; g_hLine = NULL; g_bShuttingDown = FALSE; TRACE("TAPI uninitialized.\n"); return TRUE; } #define CHAN_DEBUG_PRINT TRACE VOID FAR PASCAL lineCallbackFunc(DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { TRACE(" get the dwDevice %d \n",dwDevice); TRACE(" get the dwMessageID %d \n",dwMsg); TRACE(" get the dwCallbackInstance %d \n",dwCallbackInstance); TRACE(" get the dwParam1 %d \n",dwParam1); TRACE(" get the dwParam2 %d \n",dwParam2); TRACE(" get the dwParam3 %d \n",dwParam3); TRACE("----------------------------------------------\n"); static int n_RingTimes = 0 ; if(g_tInitTime !=(time_t)dwCallbackInstance) return ; switch(dwMsg) { case LINE_CALLSTATE: { switch(dwParam1) { case LINECALLSTATE_IDLE: { CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_IDLE\n"); lineDeallocateCall((HCALL) dwDevice); n_RingTimes = 0; if(g_FaxDialog&&IsWindow(g_FaxDialog->GetSafeHwnd())) { g_FaxDialog->PostMessage(WM_SMARTFAX,WM_FAXMONITORSTART,0); } } break; case LINECALLSTATE_CONNECTED: { CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_CONNECTED\n"); if(g_FaxDialog&&IsWindow(g_FaxDialog->GetSafeHwnd())) { g_FaxDialog->RecvFaxInTapi(); } } break; case LINECALLSTATE_DISCONNECTED: { CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_DISCONNECTED\n"); lineDrop((HCALL) dwDevice, NULL, 0); n_RingTimes = 0; } break; case LINECALLSTATE_CONFERENCED: { CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_CONFERENCED\n"); n_RingTimes = 0; } break; case LINECALLSTATE_OFFERING: { g_hCall = (HCALL) dwDevice; CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_OFFERING -------------------\n"); n_RingTimes = 0; } break; case LINECALLSTATE_ACCEPTED: { CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_ACCEPTED\n"); g_hCall = (HCALL) dwDevice; } break; } break; } case LINE_CLOSE: CHAN_DEBUG_PRINT("get Tapi msg LINE_CLOSE\n"); n_RingTimes = 0; break; case LINE_LINEDEVSTATE: { switch(dwParam1) { case LINECALLSTATE_IDLE: { CHAN_DEBUG_PRINT("get Tapi msg LINECALLSTATE_IDLE ..........\n "); n_RingTimes = 0; } break; case LINEDEVSTATE_RINGING: { CHAN_DEBUG_PRINT("get Tapi msg LINEDEVSTATE_RINGING\n"); if(g_FaxDialog&&IsWindow(g_FaxDialog->GetSafeHwnd())) { g_FaxDialog->PostMessage(WM_SMARTFAX,WM_FAXRING,n_RingTimes++); } } break; } break; } } // End switch(dwMsg) } // Turn a TAPI Line error into a printable string. LPTSTR FormatTapiError (long lError) { static LPTSTR pszLineError[] = { TEXT("LINEERR No Error"), TEXT("LINEERR_ALLOCATED"), TEXT("LINEERR_BADDEVICEID"), TEXT("LINEERR_BEARERMODEUNAVAIL"), TEXT("LINEERR Unused constant, ERROR!!"), TEXT("LINEERR_CALLUNAVAIL"), TEXT("LINEERR_COMPLETIONOVERRUN"), TEXT("LINEERR_CONFERENCEFULL"), TEXT("LINEERR_DIALBILLING"), TEXT("LINEERR_DIALDIALTONE"), TEXT("LINEERR_DIALPROMPT"), TEXT("LINEERR_DIALQUIET"), TEXT("LINEERR_INCOMPATIBLEAPIVERSION"), TEXT("LINEERR_INCOMPATIBLEEXTVERSION"), TEXT("LINEERR_INIFILECORRUPT"), TEXT("LINEERR_INUSE"), TEXT("LINEERR_INVALADDRESS"), TEXT("LINEERR_INVALADDRESSID"), TEXT("LINEERR_INVALADDRESSMODE"), TEXT("LINEERR_INVALADDRESSSTATE"), TEXT("LINEERR_INVALAPPHANDLE"), TEXT("LINEERR_INVALAPPNAME"), TEXT("LINEERR_INVALBEARERMODE"), TEXT("LINEERR_INVALCALLCOMPLMODE"), TEXT("LINEERR_INVALCALLHANDLE"), TEXT("LINEERR_INVALCALLPARAMS"), TEXT("LINEERR_INVALCALLPRIVILEGE"), TEXT("LINEERR_INVALCALLSELECT"), TEXT("LINEERR_INVALCALLSTATE"), TEXT("LINEERR_INVALCALLSTATELIST"), TEXT("LINEERR_INVALCARD"), TEXT("LINEERR_INVALCOMPLETIONID"), TEXT("LINEERR_INVALCONFCALLHANDLE"), TEXT("LINEERR_INVALCONSULTCALLHANDLE"), TEXT("LINEERR_INVALCOUNTRYCODE"), TEXT("LINEERR_INVALDEVICECLASS"), TEXT("LINEERR_INVALDEVICEHANDLE"), TEXT("LINEERR_INVALDIALPARAMS"), TEXT("LINEERR_INVALDIGITLIST"), TEXT("LINEERR_INVALDIGITMODE"), TEXT("LINEERR_INVALDIGITS"), TEXT("LINEERR_INVALEXTVERSION"), TEXT("LINEERR_INVALGROUPID"), TEXT("LINEERR_INVALLINEHANDLE"), TEXT("LINEERR_INVALLINESTATE"), TEXT("LINEERR_INVALLOCATION"), TEXT("LINEERR_INVALMEDIALIST"), TEXT("LINEERR_INVALMEDIAMODE"), TEXT("LINEERR_INVALMESSAGEID"), TEXT("LINEERR Unused constant, ERROR!!"), TEXT("LINEERR_INVALPARAM"), TEXT("LINEERR_INVALPARKID"), TEXT("LINEERR_INVALPARKMODE"), TEXT("LINEERR_INVALPOINTER"), TEXT("LINEERR_INVALPRIVSELECT"), TEXT("LINEERR_INVALRATE"), TEXT("LINEERR_INVALREQUESTMODE"), TEXT("LINEERR_INVALTERMINALID"), TEXT("LINEERR_INVALTERMINALMODE"), TEXT("LINEERR_INVALTIMEOUT"), TEXT("LINEERR_INVALTONE"), TEXT("LINEERR_INVALTONELIST"), TEXT("LINEERR_INVALTONEMODE"), TEXT("LINEERR_INVALTRANSFERMODE"), TEXT("LINEERR_LINEMAPPERFAILED"), TEXT("LINEERR_NOCONFERENCE"), TEXT("LINEERR_NODEVICE"), TEXT("LINEERR_NODRIVER"), TEXT("LINEERR_NOMEM"), TEXT("LINEERR_NOREQUEST"), TEXT("LINEERR_NOTOWNER"), TEXT("LINEERR_NOTREGISTERED"), TEXT("LINEERR_OPERATIONFAILED"), TEXT("LINEERR_OPERATIONUNAVAIL"), TEXT("LINEERR_RATEUNAVAIL"), TEXT("LINEERR_RESOURCEUNAVAIL"), TEXT("LINEERR_REQUESTOVERRUN"), TEXT("LINEERR_STRUCTURETOOSMALL"), TEXT("LINEERR_TARGETNOTFOUND"), TEXT("LINEERR_TARGETSELF"), TEXT("LINEERR_UNINITIALIZED"), TEXT("LINEERR_USERUSERINFOTOOBIG"), TEXT("LINEERR_REINIT"), TEXT("LINEERR_ADDRESSBLOCKED"), TEXT("LINEERR_BILLINGREJECTED"), TEXT("LINEERR_INVALFEATURE"), TEXT("LINEERR_NOMULTIPLEINSTANCE") }; _declspec(thread) static TCHAR szError[512]; DWORD dwError; HMODULE hTapiUIMod = GetModuleHandle(TEXT("TAPIUI.DLL")); if (hTapiUIMod) { dwError = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, (LPCVOID)hTapiUIMod, TAPIERROR_FORMATMESSAGE(lError), 0, szError, sizeof(szError)/sizeof(TCHAR), NULL); if (dwError) return szError; } // Strip off the high bit to make the error code positive. dwError = (DWORD)lError & 0x7FFFFFFF; if ((lError > 0) || (dwError > sizeof(pszLineError)/sizeof(pszLineError[0]))) { wsprintf(szError, TEXT("Unknown TAPI error code: 0x%lx"), lError); return szError; } return pszLineError[dwError]; }