📄 datamode.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 + -