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

📄 datamode.c

📁 tapi编程的一个小例子
💻 C
字号:
// This code was designed as a simple example of TAPI.  By no means was
// this designed to be an all inclusive example.  This code and example is 
// provided "AS IS" without warranty of any kind, either expressed or implied,
// including but not limited to the implied warranties of merchantability 
// and/or fitness for a particular purpose.
//
// This was designed on Windows 95 with Microsoft MSVC 2.0 compiler.
// This program will NOT run on WinNT and has not been tested on Win 3.1/3.11.
//
//	Files required to compile program :
//		datamode.c
//		tapi.h
//		resource.h
//		datamode.rc
//		datamode.def
//		tapi32.lib
//
//	Author 	: Mike Zercher
//	Date	: 5/26/95
//
// This program and all related files are public domain and may be freely
// distributed.  By using the program or any included part, the user assumes
// full responsibility for it's proper use and may not hold the author liable
// for any loss or damage.  If unable to accept this condition, the program
// and all related parts may not be used and must be destroyed immediately.

#include "windows.h"
#include "tapi.h"
#include "resource.h"

LONG ConnectToData( HWND, LPTSTR );
void CALLBACK LineCallBackProc(DWORD hDevice,DWORD dwMessage,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2,DWORD dwParam3);
BOOL WINAPI MainDialog(HWND hDlg, WORD msg, WORD wParam, LONG lParam);
void SendStatus( HWND hWnd, LPTSTR OutputString );
void SetVariableProperties( HWND hWnd, DWORD hDevice );

#define tapiVersionCur                            (MAKELONG(4,1))

#define	TAPI_LINE_REPLY					5000
#define TAPI_LINECALLSTATE_CONNECTED	5001
#define TAPI_LINECALLSTATE_IDLE			5002
#define TAPI_LINECALLSTATE_DISCONNECTED	5003
#define TAPI_LINECALLSTATE_BUSY			5004
#define TAPI_LINECALLSTATE_ACCEPTED		5005
#define TAPI_LINECALLSTATE_PROCEEDING	5006
#define TAPI_LINECALLSTATE_OFFERING		5007
#define TAPI_LINECALLSTATE_DIALTONE		5008
#define TAPI_LINECALLSTATE_DIALING		5009


LINECALLPARAMS LineParams;
DWORD lines;

HINSTANCE hInst;
HWND MainWin, ButtonWnd;
HLINEAPP LineHandle = NULL;

int PASCAL WinMain( HANDLE hInstance, HANDLE hPrev, LPSTR lpCmd, int nShow )
{
   	SetMessageQueue( 100 );
   	hInst = hInstance;
	DialogBox( hInstance, MAKEINTRESOURCE( ID_MAIN_SCREEN ), NULL, MainDialog ); 
   	return( FALSE );
}



BOOL WINAPI MainDialog(HWND hDlg, WORD msg, WORD wParam, LONG lParam)
{

	switch (msg)
	{
		case WM_INITDIALOG:
		{
			// Set the necessary properties to null
			SetProp( hDlg, "HCALL", NULL );
			SetProp( hDlg, "HLINE", NULL );
			SetProp( hDlg, "HCOMM", NULL );
			break;
		}

		case WM_COMMAND:
		{

			switch( wParam )
			{			
				case IDOK:					// This is the exit routine.
				{
					HCALL hCall;
					HLINE hLine;
					HANDLE hComm;

					hCall = (HCALL)GetProp( hDlg, "HCALL" );	// Get the properties
					hLine = (HLINE)GetProp( hDlg, "HLINE" );
					hComm = (HANDLE)GetProp( hDlg, "HCOMM" );

					if( hComm != NULL )							// is there a comm handle?
					{
						CloseHandle( hComm );					// Yes, close it down.
						SetProp( hDlg, "HCOMM", NULL );			// Set its value to NULL
					}

					if( hCall != NULL )							// is there a call present?
					{
						lineDrop( hCall, NULL, 0 );				// Close down the line.
						SetProp( hDlg, "HCALL", NULL );			// Set it's value to NULL
					}

					if( hLine != NULL )							// is the line open?
					{
						lineClose( hLine );						// Yes, close it down
						SetProp( hDlg, "HLINE", NULL );			// Set it to NULL
					}

					if( LineHandle != NULL )					//Was the line initialized?
					{
						lineShutdown( LineHandle );				//Yes, shut it down
						LineHandle = NULL;						// Set it to NULL
					}
					RemoveProp( hDlg, "HCALL" );				// Remove the properties
					RemoveProp( hDlg, "HLINE" );
					RemoveProp( hDlg, "HCOMM" );
	   				EndDialog( hDlg, FALSE );					// Goodbye
	   				break;
   				}
   				
   				case ID_CALL:
   				{
					// This is where the call will be called from.

					char PhoneNumber[ 100 ];
					HCALL hCall;

					// Check and see if there is anything left hanging open
					hCall = (HCALL)GetProp( hDlg, "HCALL" );
					if( hCall != NULL  )						// Is there a current call?
					{
					 	MessageBox( hDlg, "Please Disconnect before making another call!", " Tapi Error", MB_ICONSTOP );
						break;
					}
					// Get the Phone Number from the dialog
					GetDlgItemText( hDlg, ID_PHONE, PhoneNumber, sizeof( PhoneNumber ) );
					if( ConnectToData( hDlg, PhoneNumber ) < 0 )
						SendStatus( hDlg, "Unable to start a TAPI Function" );
	   				break;
	   			}

				case ID_DISCONNECT:						// Time to Disconnect a call
				{
					LONG retcode;
					HCALL hCall;
					HANDLE hComm;

					hCall = (HCALL)GetProp( hDlg, "HCALL" );	// Get the properties
					hComm = (HANDLE)GetProp( hDlg, "HCOMM" );

					if( hComm != NULL )						// Is there a comm handle?
					{
						CloseHandle( hComm );				// Yes, close it
						SetProp( hDlg, "HCALL", NULL );
					}
					if( hCall != NULL )						// Is there a call?
					{
						retcode = lineDrop( hCall, NULL, 0 );  // Drop the call
						SendStatus( hDlg, "Call is Dropped" );
						SetProp( hDlg, "HCALL", NULL );
					}
					break;
				}

				case TAPI_LINE_REPLY:
				{
					SendStatus( hDlg, "Line Reply" ); 
				 	break;
				}

				case TAPI_LINECALLSTATE_CONNECTED:
				{
					SendStatus( hDlg, "Line Call State is Connected" ); 
					break;
				}						   

				case TAPI_LINECALLSTATE_IDLE:
				{
					LONG retcode;
					HLINE hLine;

					// Since the call has been closed, you may now close down the line
					hLine = (HLINE)GetProp( hDlg, "HLINE" ); 
					if( hLine != NULL )			// Make sure there is a line open
					{
						retcode = lineClose( hLine );  // Yes there was
						SetProp( hDlg, "HLINE", (HANDLE)NULL );
					}
					SendStatus( hDlg, "Line Call State is idle" );
					break;
				}

				// The rest of this switch is calls that are originated from my TAPI
				// callback function.  This is just to show you how you can wait for
				// certain functions to happen without using PeekMessage loops

				case TAPI_LINECALLSTATE_DISCONNECTED:
				{
					SendStatus( hDlg, "Line Call State is Disconnected" );
					break;
				}

				case TAPI_LINECALLSTATE_BUSY:
				{
					SendStatus( hDlg, "Line Call State is Busy" );
					break;
				}

				case TAPI_LINECALLSTATE_ACCEPTED:
				{
					SendStatus( hDlg, "Line Call State is Accepted" );
					break;
				}

				case TAPI_LINECALLSTATE_PROCEEDING:
				{
					SendStatus( hDlg, "Line Call State is Proceeding" );
					break;
				}

				case TAPI_LINECALLSTATE_OFFERING:
				{
					SendStatus( hDlg, "Line Call State is Offering" );
					break;
				}

				case TAPI_LINECALLSTATE_DIALTONE:
				{
					SendStatus( hDlg, "Line Call State is DialTone" );
					break;
				}

				case TAPI_LINECALLSTATE_DIALING:
				{
					SendStatus( hDlg, "Line Call State is Dialing" );
					break;
				}

				default:
   					break;
   			}
			break;
		}

		default:
			break;
	}
	return (FALSE);
}



LONG ConnectToData( HWND hWnd, LPTSTR PhoneNumber )
{
	// Here is the meat of the connection of a phone line.  This is not all inclusive
	// and by no means have all the error checking present.

	LONG	retcode;
	DWORD	i;
	DWORD	ApiVersion;
	DWORD	RetApiVersion;
	LINEEXTENSIONID	ExtensionID;
	HLINE	hLine;
	HCALL	hCall;

	if( lstrlen( PhoneNumber ) < 1 ) //No Phone Number Provided
		return( -1 );	

	// Initialize the Line Handle
	if( LineHandle == NULL )
		retcode = lineInitialize( &LineHandle, hInst, (LINECALLBACK)LineCallBackProc, "DataModem", &lines );

	if( retcode < 0 )
		return( retcode );

	hLine = (HLINE)GetProp( hWnd, "HLINE" );
	if( hLine == NULL )
	{
		for( i=0; i < lines; i++ )
		{
			// Negotiate the API Version
			ApiVersion = tapiVersionCur;
			retcode = lineNegotiateAPIVersion( LineHandle, i, ApiVersion, ApiVersion, &RetApiVersion,
				&ExtensionID );

			retcode = lineOpen( LineHandle, i, &hLine, RetApiVersion, 0, (DWORD)hWnd,
				LINECALLPRIVILEGE_OWNER | LINECALLPRIVILEGE_MONITOR,
				LINEMEDIAMODE_DATAMODEM, NULL );
			if( retcode == 0 )
				break;
		}
		if( retcode != 0 )
			return( -1 );
	}

	SetProp( hWnd, "HLINE",(HANDLE)(HLINE)hLine );

	// This will set up some line parameters for TAPI
	memset( &LineParams, 0, sizeof( LINECALLPARAMS ) );	// Make sure you clear the memory first
	LineParams.dwTotalSize = sizeof( LINECALLPARAMS );
	LineParams.dwMinRate = 9600;						//This is needed for me. You may leave
	LineParams.dwMaxRate = 9600;						// these alone or put your own values in.
	LineParams.dwMediaMode = LINEMEDIAMODE_DATAMODEM;

	retcode = lineMakeCall( hLine, &hCall, PhoneNumber, 0, &LineParams );
	return( retcode );
}


void CALLBACK LineCallBackProc(DWORD hDevice,DWORD dwMessage,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2,DWORD dwParam3)
{   
	
    switch (dwMessage) 
        { 
        case LINE_LINEDEVSTATE:
            switch (dwParam1)
            {
            	case LINEDEVSTATE_REINIT:
            		break;

            	case LINEDEVSTATE_RINGING:
            		break;
            } 
            break;
        /* process state transition */
        case LINE_CALLSTATE:
            {
				switch( dwParam1 )
				{
					case LINECALLSTATE_IDLE:
					{
						LONG retcode;
						LINECALLINFO LineCallInfo;

						// This will get information about the call
						memset( &LineCallInfo, 0, sizeof( LINECALLINFO ) );
						LineCallInfo.dwTotalSize = sizeof( LINECALLINFO );
						lineGetCallInfo( (HCALL)hDevice, &LineCallInfo );

						// OK, time to dealloc the line
						retcode = lineDeallocateCall( (HCALL)hDevice );
						// Notify main window of idle state
						PostMessage((HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_IDLE, (LPARAM)(HLINE)LineCallInfo.hLine );
						break;	   
					}													     
					case LINECALLSTATE_ACCEPTED:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_ACCEPTED,(LPARAM)(HCALL)hDevice );
					 	break;
					}

					case LINECALLSTATE_PROCEEDING:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_PROCEEDING,(LPARAM)(HCALL)hDevice );
						break;
					}

					case LINECALLSTATE_CONNECTED:
					{
						LPVARSTRING lpVarStringStruct = NULL;
						size_t sizeofVarStringStruct = sizeof( VARSTRING ) + 1024;
						HANDLE CommFile = NULL;
						long lreturn;

						// This is how to get the comm handle from TAPI.
						// MAKE SURE YOU CLOSE THIS HANDLE. If you don't, TAPI keeps
						// the resource locked and you will not be able to make other
						// calls on the line.  The error result will be resource unavailable
						lpVarStringStruct = LocalAlloc( 0, sizeofVarStringStruct );
						do
						{
							memset( lpVarStringStruct, 0, sizeofVarStringStruct );
							lpVarStringStruct->dwTotalSize = (DWORD)sizeofVarStringStruct;
							lreturn = lineGetID( 0, 0, (HCALL)hDevice, LINECALLSELECT_CALL, lpVarStringStruct, "comm/datamodem" );
						} while( lreturn != 0 );

						CommFile = *( (LPHANDLE )( ( LPBYTE )lpVarStringStruct + lpVarStringStruct->dwStringOffset ) );
						SetProp( (HWND)dwInstance, "HCOMM", CommFile );
						SetVariableProperties( (HWND)dwInstance, hDevice );
						// Notify the main window that you are now connected.
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_CONNECTED, (LPARAM)(HANDLE)CommFile );
						LocalFree( lpVarStringStruct );
						break;
					}

					case LINECALLSTATE_OFFERING:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_OFFERING, (LPARAM)(HCALL)hDevice );
						break;
					}

					case LINECALLSTATE_DIALTONE:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_DIALTONE, (LPARAM)(HCALL)hDevice );
						break;
					}

					case LINECALLSTATE_DIALING:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_DIALING, (LPARAM)(HCALL)hDevice );
						break;
					}

					case LINECALLSTATE_BUSY:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_BUSY, 0 );
						break;
					}

					case LINECALLSTATE_DISCONNECTED:
					{
						SetVariableProperties( (HWND)dwInstance, hDevice );
						PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINECALLSTATE_DISCONNECTED, (LPARAM)(HCALL)hDevice );
						break;
					}
				}
            	break;
            }
        case LINE_CLOSE: 
            {
            break; 
            }
        /* handle the async completion of TAPI functions lineMakeCall/lineDropCall */
        case LINE_REPLY:
		{
			PostMessage( (HWND)dwInstance, WM_COMMAND, TAPI_LINE_REPLY, 0 );
            break;
		}

        /* other messages that can be processed */
        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 */ 
        
} /* LineCallBackProc */


void SendStatus( HWND hDlg, LPTSTR OutputString )
{
	DWORD dwIndex;
	int i;

	dwIndex = SendDlgItemMessage( hDlg, ID_STATUS_LIST, LB_ADDSTRING, 0, (LPARAM)(LPSTR)OutputString );
	if( dwIndex == LB_ERR )		// Oops no more room in listbox, delete the top 10 entries
	{
		for( i = 0; i < 10; i++ )
			SendDlgItemMessage( hDlg, ID_STATUS_LIST, LB_DELETESTRING, 0, 0 );
		// Ok, There should be room now, resubmit it 
		dwIndex = SendDlgItemMessage( hDlg, ID_STATUS_LIST, LB_ADDSTRING, 0, (LPARAM)(LPSTR)OutputString );
	}
	SendDlgItemMessage( hDlg, ID_STATUS_LIST, LB_SETCURSEL, (WPARAM)dwIndex, 0 );
	return;
}


void SetVariableProperties( 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( hWnd, "HLINE", (HANDLE)(HLINE)LineCallInfo.hLine );
	return;
}
  

⌨️ 快捷键说明

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