⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpletapi.c

📁 msj上的tapi例子
💻 C
字号:
//
//  MODULE: SimpleTAPI.c
//
//  PURPOSE: Demonstrates basic TAPI programming model
//

#include <stdio.h>
#include <windows.h>
#include <winbase.h>

#define TAPI_CURRENT_VERSION 0x00020000
#include <tapi.h>

#include "TapiInfo.h"

HLINEAPP	g_hLineApp;

// Buffers used for pretty printing stuff...
CHAR	strAddress[512];
CHAR	strText[512], strText2[512];

// Various flags...
BOOL	g_bIncoming;		// Waits for Incoming Calls
BOOL	g_bTranslate;		// Perform Address Translation
BOOL	g_bTranslateDialog;	// Display Translation Dialog
BOOL	g_bForce;			// Force specified device
BOOL	g_bQuit;			// Session terminating.
DWORD	g_dwMediaMode;		// MediaMode for calls.
BOOL	g_bTerminate;		// Flag to tell message thread to terminate
DWORD	g_dwDevId;			// TAPI device used.

// Handles and Messages
HANDLE g_hTAPIEvent;	// Created by TAPI
HANDLE g_hEvReply;		// Used for Asynch Reply
HLINE g_hLine;			// Line handle
HCALL g_hCall;			// Call handle

DWORD g_dwTAPIMsg;		// TAPI Message
DWORD g_dwNumDevs;		// Total number of TAPI devices
DWORD g_dwTAPIVer;		// TAPI Version

HANDLE	hEventThread;	// TAPI Event monitoring thread.


// Stuff defined somewhere else
extern DWORD WINAPI CallProc(LPVOID lpThreadParam);
extern DWORD WINAPI zTapiEventThread (LPVOID lpThreadParam);
extern BOOL ParseCommandLine(int ac, char * av[]);

// Stuff defined here...
BOOL WINAPI zControlHandlerRoutine (DWORD dwCtrlType);
DWORD SelectLine(HLINEAPP hLineApp, DWORD dwTAPIVersion, DWORD dwNumDevs,	DWORD dwMediaMode);
void EndSession();

int main (int argc, char * argv[])
{
LINEINITIALIZEEXPARAMS lineInitializeExParams;
LONG lRes;
LINETRANSLATEOUTPUT *lpTranslateOutput;

	g_dwTAPIVer = 0x00020000;

	g_bIncoming = FALSE;
	g_hCall = NULL;
	g_bQuit = FALSE;

	ParseCommandLine(argc, argv);

	SetConsoleCtrlHandler(zControlHandlerRoutine, TRUE);

	g_hEvReply = CreateEvent(NULL, FALSE, FALSE, NULL);

	// Clear the structure before using...
	memset(&lineInitializeExParams, 0, sizeof(LINEINITIALIZEEXPARAMS));
	// Populate the options...
	lineInitializeExParams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS);
	lineInitializeExParams.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
	// Initialize TAPI.
	lRes = lineInitializeEx(&g_hLineApp, NULL, NULL, 
		"CallTest", &g_dwNumDevs, &g_dwTAPIVer, &lineInitializeExParams);
	if(lRes != 0)  //Oops!
	{
		FormatLineError(lRes, strText);
		printf("TAPI Error: %s on lineInitializeEx.\r\n", strText);
		CloseHandle(g_hEvReply);
		return -1;
	}

	// Got the event handle...
	g_hTAPIEvent = lineInitializeExParams.Handles.hEvent;
	// Start event monitoring...
	hEventThread = CreateThread(NULL, 0, zTapiEventThread, NULL, 0, 0);
	if(hEventThread == NULL)  // Bummer...
	{
		printf("Win32 Error %d on CreateThread (event thread).\r\n", GetLastError());
		g_bTerminate = TRUE;
		WaitForSingleObject(hEventThread,  INFINITE);
		CloseHandle(hEventThread);
		CloseHandle(g_hEvReply);
		lineShutdown(g_hLineApp);
		return -1;
	}
	if(! g_bForce) // Select the device that supports specified media modes.
		g_dwDevId = SelectLine(g_hLineApp, g_dwTAPIVer, g_dwNumDevs, g_dwMediaMode);
	if(g_dwDevId == 0xffffffff) 
	{
		printf("No suitable line found.\r\n");
		g_bTerminate = TRUE;
		WaitForSingleObject(hEventThread,  INFINITE);
		CloseHandle(hEventThread);
		CloseHandle(g_hEvReply);
		lineShutdown(g_hLineApp);
		ExitProcess(0);
	}

	// Open the line...
	lRes = lineOpen(g_hLineApp, g_dwDevId, &g_hLine, 0x00020000, 0x00000000, 1, 
			LINECALLPRIVILEGE_OWNER, g_dwMediaMode, NULL);
	if(lRes != 0)
	{	//  Doh!
		FormatLineError(lRes, strText);
		printf("TAPI Error: %s on lineOpen.\r\n", strText);
		g_bTerminate = TRUE;
		WaitForSingleObject(hEventThread,  INFINITE);
		CloseHandle(hEventThread);
		CloseHandle(g_hEvReply);
		return -1;
	}

	// We want to be notified for everything
	lRes = lineSetStatusMessages(g_hLine, 0x1ffffff, 0);
	if(lRes != 0)
	{	
		FormatLineError(lRes, strText);
		printf("TAPI Error: %s on lineOpen.\r\n", strText);
	}

	if(g_bIncoming)
	{
		printf("Waiting for incoming call.\r\n");
		while (1)
		{
			// Now we wait for notification...
			WaitForSingleObject(g_hEvReply, INFINITE);
			if(g_dwTAPIMsg == LINECALLSTATE_OFFERING)
			{
				printf("Answering.\r\n");
				lRes = lineAnswer(g_hCall, NULL, 0);
				if(lRes != 0)
				{	//  Doh!
					FormatLineError(lRes, strText);
					printf("TAPI Error: %s on lineMakeCall.\r\n", strText);
					EndSession();
				}
				break;
			}
		}
	}
	else
	{
		if(g_bTranslateDialog) 
		{
			lRes = lineTranslateDialog(g_hLineApp, g_dwDevId, g_dwTAPIVer, NULL, strAddress);
			if(lRes != 0)
			{	
				FormatLineError(lRes, strText);
				printf("TAPI Error: %s on lineTranslateDialog.\r\n", strText);
			}
		}

		
		if(g_bTranslate)
		{
			printf("Performing translation\r\nSource: %s\r\n", strAddress);
			lpTranslateOutput = (LINETRANSLATEOUTPUT *)malloc(sizeof(LINETRANSLATEOUTPUT)+1000);
			lpTranslateOutput->dwTotalSize = sizeof(LINETRANSLATEOUTPUT)+1000;
			while (1)
			{
				lRes = lineTranslateAddress(g_hLineApp, g_dwDevId, g_dwTAPIVer, strAddress, 0, 0, lpTranslateOutput);
				if(lRes != 0)
					{	
					FormatLineError(lRes, strText);
					printf("TAPI Error: %s on lineTranslateAddress.\r\n", strText);
					}
				if(lpTranslateOutput->dwTotalSize < lpTranslateOutput->dwNeededSize)
					lpTranslateOutput = (LINETRANSLATEOUTPUT *)realloc(lpTranslateOutput, lpTranslateOutput->dwNeededSize);
				else break;
			} 
			strcpy(strAddress, (LPSTR)((DWORD)lpTranslateOutput+(DWORD)lpTranslateOutput->dwDialableStringOffset));
			printf("Results: %s\r\n",(LPSTR)((DWORD)lpTranslateOutput+(DWORD)lpTranslateOutput->dwDisplayableStringOffset)); 
		}
		printf("Calling %s\r\n", strAddress);
		lRes = lineMakeCall(g_hLine, &g_hCall, strAddress, 0, NULL);
		if(lRes != 0)
		{	//  Doh!
			FormatLineError(lRes, strText);
			printf("TAPI Error: %s on lineMakeCall.\r\n", strText);
		}
	}


	// All done.  Wait for the event thread to finish.
	WaitForSingleObject(hEventThread, INFINITE);
	CloseHandle(hEventThread);
	if(!g_bQuit)
	{
		EndSession();
	}

}


BOOL WINAPI zControlHandlerRoutine (DWORD dwCtrlType) 
{ 

  // Got an control handler event
  switch (dwCtrlType) 
  { 
    case CTRL_C_EVENT:        // Handle any event that will cause
    case CTRL_BREAK_EVENT:    // a termination of our program
    case CTRL_CLOSE_EVENT:
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
    {
		g_bQuit = TRUE;
		EndSession();
		break;
    }

    default:
      break;
  } 

  return(FALSE);

} // End of zControlHandlerRoutine

// SelectLine function returns the ID of last line device that supports requested MediaMode
// If not found, It will return 0xFFFFFFFF
DWORD SelectLine(
			HLINEAPP hLineApp,	// Valid LineApp Handle 
			DWORD dwTAPIVersion,	// TAPI Version to be used.
			DWORD dwNumDevs,	// Number of line devices
			DWORD dwMediaMode) // MediaMode to look for.
{
DWORD dwResult = 0xFFFFFFFF;
DWORD dwAPIVersion;
LINEEXTENSIONID ExtentionId;
LINEDEVCAPS *lpDevCaps;
DWORD	i;
LONG lRes;
BOOL bDone;

	for(i = 0 ; i < dwNumDevs ; i++)
		{

		lRes = lineNegotiateAPIVersion(hLineApp, i, dwTAPIVersion, dwTAPIVersion, 
										&dwAPIVersion, &ExtentionId);
		if(lRes != 0)  //Oops!
			{
			FormatLineError(lRes, strText);
			printf("TAPI Error: %s on lineNegotiateAPIVersion.\r\n", strText);
			}
		else
			{
			lpDevCaps = (LINEDEVCAPS *)malloc(sizeof(LINEDEVCAPS)+1000);	// Allocate a little extra memory...
			if(lpDevCaps == NULL) return dwResult;	// No luck allocating memory...

			memset(lpDevCaps, 0, sizeof(LINEDEVCAPS)+1000);
			lpDevCaps->dwTotalSize = sizeof(LINEDEVCAPS)+1000;
			bDone = FALSE;
			do // Go around and keep trying until there's enough memory
				{
				lRes = lineGetDevCaps(hLineApp, i, dwAPIVersion, 0, lpDevCaps);
				if(lRes != 0)  //Oops!
					{
					FormatLineError(lRes, strText);
					printf("TAPI Error: %s on lineGetDevCaps.\r\n", strText);
					free(lpDevCaps);
					break;
					}
				if(lpDevCaps->dwNeededSize > lpDevCaps->dwTotalSize)
					// Reallocate for dwNeededSize
					lpDevCaps = (LINEDEVCAPS *)realloc(lpDevCaps, lpDevCaps->dwNeededSize);
				else bDone = TRUE;
				}
			while (!bDone);

			printf("Line %d is %s.\r\n", i, (LPBYTE)((DWORD)lpDevCaps+(DWORD)lpDevCaps->dwLineNameOffset));
			if(lpDevCaps->dwMediaModes & dwMediaMode)
				{
				dwResult = i;
				printf("Line device %d selected.\r\n", i);
				}
			else printf("Line device %d rejected.\r\n", i);
			free(lpDevCaps);
			}
	}
	return dwResult;
}

void EndSession()
{
LINECALLSTATUS CallStatus;
LONG	lRes;
	if(g_hCall != NULL)  // Call might be in progress...
	{
		memset(&CallStatus, 0, sizeof(LINECALLSTATUS));

		lRes = lineGetCallStatus(g_hCall, &CallStatus); 
			// Technically, lineGetCallStatus returns more info than 
			// there is in the structure.  Since we don't care about it,
			// We just go on our merry way...
		if(lRes == 0) // If it didn't fail, there's at least a call that needs
			// to be droped.
		{
			printf("Call is still in progress.  Droping it.\r\n");
			lineDrop(g_hCall, NULL, 0);
		}
	}

	printf("Closing line. (Ctrl Handler)\r\n");
	lRes = lineClose(g_hLine);
	if(lRes != 0)
	{
		FormatLineError(lRes, strText);
		printf("TAPI Error: %s on lineClose.\r\n", strText);
	}

	g_bTerminate = TRUE;  // Tell the event thread that it's time to go...
	WaitForSingleObject(hEventThread, INFINITE); // Wait for it to comit suicide..
	CloseHandle(hEventThread);
	printf("Shutting down TAPI.\r\n");
	lRes = lineShutdown(g_hLineApp);
	if(lRes != 0)
	{
		FormatLineError(lRes, strText);
		printf("TAPI Error: %s on lineShutdown.\r\n", strText);
	}
	ExitProcess(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -