📄 mytapi_.c
字号:
#include "comdial.h"
#include "resource.h"
MYTAPI mytapi;
extern HWND hTTYWnd;
/////////////////////////////////////////////////////////////////////
// telephonyInitialize - mega function to retrieve all
// configuration information needed for telephony, plus
// initialize TAPI and open the line.
////////////////////////////////////////////////////////////////////
int telephonyInitialize(HWND hWnd, HINSTANCE hInst)
{
LONG lrc;
int i;
LINEEXTENSIONID extensions;
// initialize application use of TAPI
while (lineInitialize(&mytapi.hTAPI, hInst,
mytapi.CallbackProc = (LINECALLBACK)MakeProcInstance((FARPROC)LineCallBackProc, hInst),
"TAPIProcess", &mytapi.dwNumLines) == LINEERR_REINIT) {
Sleep (5); // sleep for five seconds
if (MessageBox(hWnd, "Telephony system is reinitializing - Click \
Cancel to abort", "Error", MB_RETRYCANCEL) ==IDCANCEL)
goto done;
} // end while (TAPI reinitializing)
// bool indicates lineInitialize called successfully
mytapi.bInitialized = TRUE;
// check every logical line for one that support modem data
for (i=0; (unsigned)i<mytapi.dwNumLines; i++) {
// negotiate version of TAPI to use
lrc = lineNegotiateAPIVersion(mytapi.hTAPI, i, WIN95TAPIVERSION,
WIN95TAPIVERSION, &mytapi.dwVersionToUse, &extensions);
if (lrc)
continue;
// get line device caps
lrc = mylineGetDevCaps ();
if (lrc)
goto done;
// check that the line supports answering machines
if (mytapi.pLinedevcaps->dwMediaModes & LINEMEDIAMODE_AUTOMATEDVOICE) {
mytapi.dwLine = i;
break;
}
}
return 0;
done:
// error! clean up and return error code
telephonyShutdown();
return lrc;
}
/////////////////////////////////////////////////////////////////////
// telephonyOpen - open the telephone line device
//
////////////////////////////////////////////////////////////////////
int telephonyOpen(HWND hWnd, HINSTANCE hInst)
{
LONG lrc;
// open the line device
lrc = lineOpen(mytapi.hTAPI, mytapi.dwLine, &mytapi.hLine,
mytapi.dwVersionToUse, 0, 0,
LINECALLPRIVILEGE_OWNER,
LINEMEDIAMODE_AUTOMATEDVOICE,
NULL);
if (lrc)
goto done;
// bool indicates lineOpen called successfully
mytapi.bLineopen = TRUE;
// get the telephony icon and make it ours
myDrawTAPIIcon(hWnd);
// receive all possible status messages for the
// line device and address
lineSetStatusMessages(mytapi.hLine,
mytapi.pLinedevcaps->dwLineStates,
0);
// set ring count for the no-message waiting situation
lineSetNumRings (mytapi.hLine, 0, RINGCNT);
lineGetNumRings(mytapi.hLine, 0, &mytapi.nRingCnt);
// success
return 0;
done:
// error! clean up and return error code
telephonyShutdown();
return lrc;
} // end procedure (telephony initialize)
/////////////////////////////////////////////////////////////////////
// myDrawTAPIIcon - get telephony icon and make it ours
////////////////////////////////////////////////////////////////////
void myDrawTAPIIcon(HWND hwnd)
{
HICON hIcon;
// get handle to telephony icon
lineGetIcon (mytapi.dwLine, NULL, &hIcon);
// make the icon ours
SetClassLong (hwnd, GCL_HICON, (LONG)hIcon);
}
/////////////////////////////////////////////////////////////////////
// mylineGetWaveID - get wave handle
////////////////////////////////////////////////////////////////////
LONG mylineGetWaveID (DWORD dwSelect, LPSTR waveDev)
{
DWORD dwWaveDev;
VARSTRING *vs;
LONG lrc;
DWORD dwSize;
// allocate memory for structure
vs = (VARSTRING *) calloc (1, sizeof(VARSTRING));
// set structure size
vs->dwTotalSize = sizeof(VARSTRING);
do {
// get information into structure
if (dwSelect == LINECALLSELECT_LINE)
lrc = lineGetID(mytapi.hLine, 0L, NULL, dwSelect, vs, waveDev);
if (dwSelect == LINECALLSELECT_CALL)
lrc = lineGetID(mytapi.hLine, 0L, mytapi.hCall, dwSelect, vs, waveDev);
// bomb out if error
if (lrc) {
free (vs);
return -1;
}
// reallocate and try again
if (vs->dwTotalSize < vs->dwNeededSize) {
dwSize = vs->dwNeededSize;
free (vs);
vs = (VARSTRING *) calloc(1, dwSize);
vs->dwTotalSize = dwSize;
continue;
} /* end if (need more space) */
break; /* success */
} while (TRUE);
// copy wave id
dwWaveDev = (DWORD) *((DWORD *)((LPSTR)vs + vs->dwStringOffset));
free (vs);
return dwWaveDev;
} /* end function (mylineGetWaveID) */
/////////////////////////////////////////////////////////////////////
// mylineGetDevCaps - get LINEDEVCAPS structure
////////////////////////////////////////////////////////////////////
LONG mylineGetDevCaps()
{
LONG lrc;
DWORD dwsize;
// if space already allocated for structure, free it up
if (mytapi.bLinedevcapsalloced) {
free (mytapi.pLinedevcaps);
mytapi.bLinedevcapsalloced = FALSE;
}
// allocate memory for structure
mytapi.pLinedevcaps = (LINEDEVCAPS *) calloc(1, sizeof(LINEDEVCAPS));
if (!mytapi.pLinedevcaps)
return LINEERR_NOMEM;
mytapi.bLinedevcapsalloced = TRUE;
// set structure size
mytapi.pLinedevcaps->dwTotalSize = sizeof(LINEDEVCAPS);
do {
// get information into structure
lrc = lineGetDevCaps(mytapi.hTAPI, mytapi.dwLine, mytapi.dwVersionToUse,
0, mytapi.pLinedevcaps);
// bomb out if error
if (lrc) {
free (mytapi.pLinedevcaps);
mytapi.bLinedevcapsalloced = FALSE;
return lrc;
}
dwsize = mytapi.pLinedevcaps->dwNeededSize;
// reallocate and try again
if (mytapi.pLinedevcaps->dwTotalSize < dwsize) {
free (mytapi.pLinedevcaps);
mytapi.bLinedevcapsalloced = FALSE;
mytapi.pLinedevcaps = (LINEDEVCAPS *) calloc(1, dwsize);
if (!mytapi.pLinedevcaps)
return LINEERR_NOMEM;
mytapi.bLinedevcapsalloced = TRUE;
mytapi.pLinedevcaps->dwTotalSize = dwsize;
continue;
}
break;
} while (TRUE);
return lrc;
}
/////////////////////////////////////////////////////////////////////
// mylineGetCallStatus - get LINECALLSTATUS structure
////////////////////////////////////////////////////////////////////
LONG mylineGetCallStatus()
{
LONG lrc;
DWORD dwsize;
// if space already allocated for structure, free it up
if (mytapi.bLinecallstatusalloced) {
free (mytapi.pLinecallstatus);
mytapi.bLinecallstatusalloced = FALSE;
}
// allocate memory for structure
mytapi.pLinecallstatus = (LINECALLSTATUS *) calloc(1, sizeof(LINECALLSTATUS));
if (!mytapi.pLinecallstatus)
return LINEERR_NOMEM;
mytapi.bLinecallstatusalloced = TRUE;
// set structure size
mytapi.pLinecallstatus->dwTotalSize = sizeof(LINECALLSTATUS);
do {
// get information into structure
lrc = lineGetCallStatus(mytapi.hCall, mytapi.pLinecallstatus);
// bomb out if error
if (lrc) {
free (mytapi.pLinecallstatus);
mytapi.bLinecallstatusalloced = FALSE;
return lrc;
}
// reallocate and try again
dwsize = mytapi.pLinecallstatus->dwNeededSize;
if (mytapi.pLinecallstatus->dwTotalSize < dwsize) {
free (mytapi.pLinecallstatus);
mytapi.bLinecallstatusalloced = FALSE;
mytapi.pLinecallstatus = (LINECALLSTATUS *) calloc(1, dwsize);
if (!mytapi.pLinecallstatus)
return LINEERR_NOMEM;
mytapi.bLinecallstatusalloced = TRUE;
mytapi.pLinecallstatus->dwTotalSize = dwsize;
continue;
}
break;
} while (TRUE);
return lrc;
}
/////////////////////////////////////////////////////////////////////
// telephonyShutdown - mega functions to close line, shut down
// telephony, close modem handle, restore serial device
// configuration, and free up various allocated structures.
////////////////////////////////////////////////////////////////////
void telephonyShutdown()
{
// close line if open
if (mytapi.bLineopen)
lineClose(mytapi.hLine);
// shutdown tapi if initialized
if (mytapi.bInitialized)
lineShutdown(mytapi.hTAPI);
// free up various structures if allocated
if (mytapi.bLinedevcapsalloced)
free (mytapi.pLinedevcaps);
if (mytapi.bLinedevstatusalloced)
free (mytapi.pLinedevstatus);
if (mytapi.bLinecallinfoalloced)
free(mytapi.pLinecallinfo);
if (mytapi.bLinecallstatusalloced)
free(mytapi.pLinecallstatus);
// set flags to indicate that the structures are no longer
// allocated
mytapi.bLinedevcapsalloced = FALSE;
mytapi.bLinedevstatusalloced = FALSE;
mytapi.bLineopen = FALSE;
mytapi.bInitialized = FALSE;
mytapi.bLinecallinfoalloced = FALSE;
mytapi.bLinecallstatusalloced = FALSE;
mytapi.bWaitForCall = FALSE;
} // end function (telephonyShutdown)
/////////////////////////////////////////////////////////////////////
// LineCallBackProc - message function for TAPI events
////////////////////////////////////////////////////////////////////
/* callback function */
void FAR PASCAL LineCallBackProc(DWORD dwDevice,DWORD dwMessage,
DWORD dwInstance,DWORD dwParam1,DWORD dwParam2,DWORD dwParam3)
{
HMENU hMenu;
LONG lrc;
switch (dwMessage) {
case LINE_CALLSTATE:
switch (dwParam3) {
case LINECALLPRIVILEGE_MONITOR:
break;
case LINECALLPRIVILEGE_OWNER:
// update local call information
mylineGetCallStatus();
// update menus
hMenu = GetMenu(hTTYWnd);
// answer call
if (mytapi.pLinecallstatus->dwCallFeatures & LINECALLFEATURE_ANSWER)
EnableMenuItem( hMenu, IDM_ANSWER, MF_ENABLED | MF_BYCOMMAND ) ;
else
EnableMenuItem( hMenu, IDM_ANSWER, MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
// save call handle and get device ids
if (mytapi.hCall != (HCALL)dwDevice) {
mytapi.hCall = (HCALL)dwDevice;
mytapi.dwWaveInID = mylineGetWaveID(LINECALLSELECT_CALL, "wave/in");
mytapi.dwWaveOutID = mylineGetWaveID(LINECALLSELECT_CALL, "wave/out");
// FOR DEBUGGING; REMOVE FROM FINAL VERSION
mytapi.dwWaveOutID = 0;
mytapi.dwWaveInID = 0;
}
break;
default:
break;
} //end switch
switch (dwParam1) {
case LINECALLSTATE_IDLE:
// deallocate call resources
lineDeallocateCall (mytapi.hCall);
mytapi.hCall = NULL;
break;
case LINECALLSTATE_OFFERING:
break;
case LINECALLSTATE_CONNECTED:
mytapi.h_waveout =playSound (mytapi.dwWaveOutID,"greeting.wav", hTTYWnd);
mytapi.iPlayState = PLAYSTATE_IDLE;
mytapi.iPlaySubState = PLAYSUBSTATE_PASSWORD0;
lrc = lineMonitorDigits(mytapi.hCall, LINEDIGITMODE_DTMF);
break;
default:
break;
} //end switch
break;
case LINE_CLOSE:
break;
case LINE_LINEDEVSTATE:
switch (dwParam1) {
case LINEDEVSTATE_RINGING:
mytapi.nRings = dwParam3;
if (mytapi.bWaitForCall && mytapi.nRings == mytapi.nRingCnt) {
// answer incoming calls
lrc = lineAnswer(mytapi.hCall,NULL,0);
if (!(lrc >0 )) {
ProcessTAPIError(lrc);
myMessageBox("Error answering call");
}
mytapi.nRings = 0;
}
break;
}
break;
case LINE_MONITORDIGITS:
switch (dwParam2) {
case LINEDIGITMODE_DTMF:
{
char c;
char name[30];
switch (c = LOBYTE(dwParam1)) {
case '1':
// if in the idle state,
// transition to the password state
switch (mytapi.iPlayState) {
case PLAYSTATE_IDLE:
if (mytapi.h_waveout =playSound (mytapi.dwWaveOutID,"pw.wav", hTTYWnd)) {
mytapi.iPlayState = PLAYSTATE_PASSWORD;
mytapi.iPlaySubState = PLAYSUBSTATE_PASSWORD0;
}
break;
default:
break;
}
break;
case '2':
// if in the idle state,
// transition to the recording state
switch (mytapi.iPlayState) {
case PLAYSTATE_IDLE:
if (mytapi.h_waveout =playSound (mytapi.dwWaveOutID,"record.wav", hTTYWnd)) {
mytapi.iPlayState = PLAYSTATE_RECORD;
recordMessage (mytapi.dwWaveInID);
}
break;
case PLAYSTATE_PASSWORD:
switch (mytapi.iPlaySubState) {
case PLAYSUBSTATE_PASSWORD2:
mytapi.iPlaySubState = PLAYSUBSTATE_PASSWORD3;
break;
default:
mytapi.iPlaySubState = PLAYSUBSTATE_PASSWORD0;
break;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -