📄 win32_modem.cpp
字号:
continue;
else
{
break;
}
}
while(lReturn != SUCCESS);
g_bTapiInUse = FALSE;
g_bConnected = FALSE;
g_hLineApp = NULL;
g_hCall = NULL;
g_hLine = NULL;
g_bShuttingDown = FALSE;
//OutputDebugString("TAPI uninitialized.\n");
return TRUE;
}
//
// FUNCTION: bool HangupCall()
//
// PURPOSE: Hangup the call in progress if it exists.
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// TRUE if call hung up successfully.
//
// COMMENTS:
//
// If HangupCall 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 Win32_Modem::ModemHangupCall()
{
HangupCall();
} */
bool Win32_Modem::HangupCall()
{
LPLINECALLSTATUS pLineCallStatus = NULL;
long lReturn;
// Prevent HangupCall re-entrancy problems.
if (g_bStoppingCall)
return TRUE;
// if the 'Call' dialog is up, dismiss it.
if (g_hDialog)
PostMessage(g_hDialog, WM_COMMAND, IDCANCEL, 0);
// If Tapi is not being used right now, then the call is hung up.
if (!g_bTapiInUse)
return TRUE;
g_bStoppingCall = TRUE;
//OutputDebugString("Stopping Call in progress\n");
// Disable the 'hangup call' user interface.
// EnableHangupCall(g_hWndMainWindow, FALSE);
// Stop any data communications on the comm port.
StopComm();
// If there is a call in progress, drop and deallocate it.
if (g_hCall)
{
// I_lineGetCallStatus returns a LocalAlloc()d buffer
pLineCallStatus = I_lineGetCallStatus(pLineCallStatus, *g_hCall);
if (pLineCallStatus == NULL)
{
ShutdownTAPI();
g_bStoppingCall = FALSE;
return FALSE;
}
// Only drop the call when the line is not IDLE.
if (!((pLineCallStatus -> dwCallState) & LINECALLSTATE_IDLE))
{
do
{
lReturn = WaitForReply(lineDrop(*g_hCall, NULL, 0));
if (lReturn == WAITERR_WAITTIMEDOUT)
{
//OutputDebugString("Call timed out in WaitForReply.\n");
break;
}
if (lReturn == WAITERR_WAITABORTED)
{
//OutputDebugString("lineDrop: WAITERR_WAITABORTED.\n");
break;
}
// Was the call already in IDLE?
if (lReturn == LINEERR_INVALCALLSTATE)
break;
if (HandleLineErr(lReturn))
continue;
else
{
/* OutputDebugLineError(lReturn,
"lineDrop unhandled error: ");*/
break;
}
}
while(lReturn != SUCCESS);
// Wait for the dropped call to go IDLE before continuing.
lReturn = WaitForCallState(LINECALLSTATE_IDLE);
if (lReturn == WAITERR_WAITTIMEDOUT)
{
// OutputDebugString("Call timed out waiting for IDLE state.\n");
}
if (lReturn == WAITERR_WAITABORTED)
{
// OutputDebugString("WAITERR_WAITABORTED while waiting for IDLE state.\n");
}
//OutputDebugString("Call Dropped.\n");
}
// The call is now idle. Deallocate it!
do
{
lReturn = lineDeallocateCall(*g_hCall);
if (HandleLineErr(lReturn))
continue;
else
{
/* OutputDebugLineError(lReturn,
"lineDeallocateCall unhandled error: ");*/
break;
}
}
while(lReturn != SUCCESS);
//OutputDebugString("Call Deallocated.\n");
}
// if we have a line open, close it.
if (g_hLine)
{
do
{
lReturn = lineClose(g_hLine);
if (HandleLineErr(lReturn))
continue;
else
{
/* OutputDebugLineError(lReturn,
"lineClose unhandled error: ");*/
break;
}
}
while(lReturn != SUCCESS);
//OutputDebugString("Line Closed.\n");
}
// Call and Line are taken care of. Finish cleaning up.
// If there is device configuration information, free the memory.
if (g_lpDeviceConfig)
LocalFree(g_lpDeviceConfig);
g_lpDeviceConfig = NULL;
g_hCall = NULL;
g_hLine = NULL;
g_bConnected = FALSE;
g_bTapiInUse = FALSE;
g_bStoppingCall = FALSE; // allow HangupCall to be called again.
//OutputDebugString("Call stopped\n");
// Update the user interface.
// UpdateStatusBar("Ready to make a call.",1,0);
// EnableMakeCall(g_hWndMainWindow, TRUE);
// Need to free LocalAlloc()d buffer returned from I_lineGetCallStatus
if (pLineCallStatus)
LocalFree(pLineCallStatus);
return TRUE;
}
//
// FUNCTION: PostHangupCall()
//
// PURPOSE: Posts a message to the main TAPI thread to hangup the call.
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
// TAPI is thread specific, meaning that only the thread that does the
// lineInitialize can get asynchronous messages through the callback.
// Since the HangupCall can potentially go into a loop waiting for
// specific events, any other threads that call HangupCall can cause
// timing confusion. Best to just have other threads 'ask' the main thread
// to hangup the call.
//
void Win32_Modem::PostHangupCall()
{
#define IDM_HANGUPCALL 1011
// PostMessage(g_hWndMainWindow/*Win32_Modem::GetMainWindow()*/, WM_COMMAND, IDM_HANGUPCALL, 0);
}
//
// FUNCTION: DialCall()
//
// PURPOSE: Get a number from the user and dial it.
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// TRUE if able to get a number, find a line, and dial successfully.
//
// COMMENTS:
//
// This function makes several assumptions:
// - The number dialed will always explicitly come from the user.
// - There will only be one outgoing address per line.
//
bool Win32_Modem::DialCall()
{
long lReturn;
LPLINEADDRESSSTATUS lpLineAddressStatus = NULL;
LPLINEDEVCAPS lpLineDevCaps = NULL;
if (g_bTapiInUse)
{
//OutputDebugString("A call is already being handled\n");
return FALSE;
}
// If TAPI isn't initialized, its either because we couldn't initialize
// at startup (and this might have been corrected by now), or because
// a REINIT event was received. In either case, try to init now.
if (!g_hLineApp)
{
if (!InitializeTAPI(NULL))
return FALSE;
}
// If there are no line devices installed on the machine, lets give
// the user the opportunity to install one.
if (g_dwNumDevs < 1)
{
if (!HandleNoDevicesInstalled())
return FALSE;
}
// We now have a call active. Prevent future calls.
g_bTapiInUse = TRUE;
// EnableMakeCall(g_hWndMainWindow, FALSE);
// Get a phone number from the user.
// Phone number will be placed in global variables if successful
/* if (!GetAddressToDial())
{
HangupCall();
goto DeleteBuffers;
}*/
// Negotiate the API version to use for this device.
g_dwAPIVersion = I_lineNegotiateAPIVersion(g_dwDeviceID);
if (g_dwAPIVersion == 0)
{
MessageBox(g_hDlgParentWindow,
"Line Version unsupported by this Sample",
"Unable to Use Line",MB_OK);
HangupCall();
goto DeleteBuffers;
}
// Need to check the DevCaps to make sure this line is usable.
// The 'Dial' dialog checks also, but better safe than sorry.
lpLineDevCaps = I_lineGetDevCaps(lpLineDevCaps,
g_dwDeviceID, g_dwAPIVersion);
if (lpLineDevCaps == NULL)
{
HangupCall();
MessageBox(g_hDlgParentWindow,
"Error on Requested line",
"Unable to Use Line",MB_OK);
goto DeleteBuffers;
}
if (!(lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE ))
{
HangupCall();
MessageBox(g_hDlgParentWindow,
"Error on Requested line",
"The selected line doesn't support VOICE capabilities",
MB_OK);
goto DeleteBuffers;
}
if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM))
{
HangupCall();
MessageBox(g_hDlgParentWindow,
"Error on Requested line",
"The selected line doesn't support DATAMODEM capabilities",
MB_OK);
goto DeleteBuffers;
}
// Does this line have the capability to make calls?
// It is possible that some lines can't make outbound calls.
if (!(lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL))
{
HangupCall();
MessageBox(g_hDlgParentWindow,
"Error on Requested line",
"The selected line doesn't support MAKECALL capabilities",
MB_OK);
goto DeleteBuffers;
}
// Open the Line for an outgoing DATAMODEM call.
do
{
lReturn = lineOpen(g_hLineApp, g_dwDeviceID, &g_hLine,
g_dwAPIVersion, 0, 0,
LINECALLPRIVILEGE_NONE, LINEMEDIAMODE_DATAMODEM,
0);
if(lReturn == LINEERR_ALLOCATED)
{
HangupCall();
MessageBox(g_hDlgParentWindow,
"Line is already in use by a non-TAPI application "
"or by another TAPI Service Provider.",
"Unable to Use Line",MB_OK);
goto DeleteBuffers;
}
if (HandleLineErr(lReturn))
continue;
else
{
// OutputDebugLineError(lReturn, "lineOpen unhandled error: ");
MessageBox(g_hDlgParentWindow,
"Error on Requested line",
"Unable to Use Line",MB_OK);
HangupCall();
goto DeleteBuffers;
}
}
while(lReturn != SUCCESS);
// Tell the service provider that we want all notifications that
// have anything to do with this line.
do
{
// Set the messages we are interested in.
// Note that while most applications aren't really interested
// in dealing with all of the possible messages, its interesting
// to see which come through the callback for testing purposes.
lReturn = lineSetStatusMessages(g_hLine,
LINEDEVSTATE_OTHER |
LINEDEVSTATE_RINGING |
LINEDEVSTATE_CONNECTED | // Important state!
LINEDEVSTATE_DISCONNECTED | // Important state!
LINEDEVSTATE_MSGWAITON |
LINEDEVSTATE_MSGWAITOFF |
LINEDEVSTATE_INSERVICE |
LINEDEVSTATE_OUTOFSERVICE | // Important state!
LINEDEVSTATE_MAINTENANCE | // Important state!
LINEDEVSTATE_OPEN |
LINEDEVSTATE_CLOSE |
LINEDEVSTATE_NUMCALLS |
LINEDEVSTATE_NUMCOMPLETIONS |
LINEDEVSTATE_TERMINALS |
LINEDEVSTATE_ROAMMODE |
LINEDEVSTATE_BATTERY |
LINEDEVSTATE_SIGNAL |
LINEDEVSTATE_DEVSPECIFIC |
LINEDEVSTATE_REINIT | // Not allowed to disable this.
LINEDEVSTATE_LOCK |
LINEDEVSTATE_CAPSCHANGE |
LINEDEVSTATE_CONFIGCHANGE |
LINEDEVSTATE_COMPLCANCEL ,
LINEADDRESSSTATE_OTHER |
LINEADDRESSSTATE_DEVSPECIFIC|
LINEADDRESSSTATE_INUSEZERO |
LINEADDRESSSTATE_INUSEONE |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -