📄 waitlinedlg.cpp
字号:
// Written by JHCC, 1997
// WaitLineDlg.cpp : implementation file
//
#include "stdafx.h"
#include "JHHB.h"
#include "WaitLineDlg.h"
#include "tapiErr.h"
#include "tapix.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Reasons why a line device might not be usable.
enum LINE_NOTUSEABLE_CODE
{
LINENOTUSEABLE_OK,
LINENOTUSEABLE_ERROR,
LINENOTUSEABLE_NOVOICE,
LINENOTUSEABLE_NODATAMODEM,
LINENOTUSEABLE_NOMAKECALL,
LINENOTUSEABLE_ALLOCATED,
LINENOTUSEABLE_INUSE,
LINENOTUSEABLE_NOCOMMDATAMODEM,
};
/////////////////////////////////////////////////////////////////////////////
// CWaitLineDlg dialog
CWaitLineDlg::CWaitLineDlg(CTAPIConnection* pConn, CWnd* pParent /*=NULL*/)
: CDialog(CWaitLineDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWaitLineDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_lpDeviceConfig = NULL;
m_pConn = pConn;
}
CWaitLineDlg::~CWaitLineDlg()
{
if (m_lpDeviceConfig != NULL)
{
delete m_lpDeviceConfig;
m_lpDeviceConfig = NULL;
}
}
void CWaitLineDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWaitLineDlg)
DDX_Control(pDX, IDC_LINEICON, m_lineIcon);
DDX_Control(pDX, ID_WAITCALL, m_waitCallButton);
DDX_Control(pDX, IDC_TAPILINE, m_tapiLineBox);
DDX_Control(pDX, IDC_CONFIGURELINE, m_configureLine);
//}}AFX_DATA_MAP
}
DWORD CWaitLineDlg::GetDeviceID(void)
{
return m_dwDeviceID;
}
// Fills the 'TAPI Line' control with the available line devices.
// This function enumerates through all the TAPI line devices and
// queries each for the device name. The device name is then put into
// the 'TAPI Line' control. These device names are kept in order rather
// than sorted. This allows "Dial" to know which device ID the user
// selected just by the knowing the index of the selected string.
//
// There are default values if there isn't a device name, if there is
// an error on the device, or if the device name is an empty string.
// The device name is also checked to make sure it is null terminated.
//
// Note that a Legacy API Version is negotiated. Since the fields in
// the LINEDEVCAPS structure that we are interested in haven't moved, we
// can negotiate a lower API Version than this sample is designed for
// and still be able to access the necessary structure members.
//
// The first line that is usable is selected as the 'default'
// line. Also note that if there was a previously selected line, this
// remains the default line. This would likely only occur if this
// function is called after the dialog has initialized once; for example,
// if a new line is added.
void CWaitLineDlg::FillTAPILine(void)
{
DWORD dwDefaultDevice = MAXDWORD;
// Make sure the control is empty. If it isn't,
// hold onto the currently selected ID and then reset it.
if (m_tapiLineBox.GetCount())
{
dwDefaultDevice = m_tapiLineBox.GetCurSel();
m_tapiLineBox.ResetContent();
}
for (int dwDeviceID = 0; dwDeviceID < m_pConn->GetNumDevs(); ++ dwDeviceID)
{
m_tapiLineBox.AddString(m_pConn->m_lineArray[dwDeviceID]->GetLineName());
// If this line is usable and we don't have a default initial
// line yet, make this the initial line.
if ((dwDefaultDevice == MAXDWORD) &&
(VerifyUsableLine(dwDeviceID) == TAPISUCCESS))
{
dwDefaultDevice = dwDeviceID;
}
}
if (dwDefaultDevice == MAXDWORD)
dwDefaultDevice = 0;
// Set the initial default line
m_tapiLineBox.SetCurSel(dwDefaultDevice);
}
// Verifies the line device selected by the user.
// This function is very specific to the "Dial" dialog. It gets
// the device selected by the user from the 'TAPI Line' control and
// VerifyUsableLine to make sure this line device is usable. If the
// line isn't useable, it notifies the user and disables the 'Dial'
// button so that the user can't initiate a call with this line.
//
// This function is also responsible for filling in the line specific
// icon found on the "Dial" dialog.
BOOL CWaitLineDlg::VerifyAndWarnUsableLine(void)
{
// Get the selected line device.
DWORD dwDeviceID = m_tapiLineBox.GetCurSel();
if (dwDeviceID == -1)
return FALSE;
// Get the "comm" device icon associated with this line device.
m_lineIcon.SetIcon(m_pConn->m_lineArray[dwDeviceID]->m_hLineIcon);
// Verify if the device is usable by TapiComm.
long lReturn = VerifyUsableLine(dwDeviceID);
// Enable or disable the 'Dial' button, depending on if the line is ok.
// Make sure there is a number to dial before enabling the button.
UpdateData(TRUE);
m_waitCallButton.EnableWindow((lReturn == TAPISUCCESS));
// Any errors on this line prevent us from configuring it
// or using dialing properties.
m_configureLine.EnableWindow((lReturn != LINENOTUSEABLE_ERROR));
switch (lReturn)
{
case TAPISUCCESS:
m_dwDeviceID = dwDeviceID;
return TRUE;
case LINENOTUSEABLE_ERROR:
MessageBox("The selected line is incompatible with the TapiComm sample",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_NOVOICE:
MessageBox("The selected line doesn't support VOICE capabilities",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_NODATAMODEM:
MessageBox("The selected line doesn't support DATAMODEM capabilities",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_NOMAKECALL:
MessageBox("The selected line doesn't support MAKECALL capabilities",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_ALLOCATED:
MessageBox("The selected line is already in use by a non-TAPI application",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_INUSE:
MessageBox("The selected line is already in use by a TAPI application",
"Warning",MB_OK);
break;
case LINENOTUSEABLE_NOCOMMDATAMODEM:
MessageBox("The selected line doesn't support the COMM/DATAMODEM device class",
"Warning",MB_OK);
break;
}
// m_dwDeviceID == MAXDWORD mean the selected device isn't usable.
m_dwDeviceID = MAXDWORD;
return FALSE;
}
// Verifies that a specific line device is useable by TapiComm.
// VerifyUsableLine takes the give device ID and verifies step by step
// that the device supports all the features that TapiComm requires.
long CWaitLineDlg::VerifyUsableLine(DWORD dwDeviceID)
{
TRACE1("Testing Line ID '0x%lx'\n", dwDeviceID);
// Must support LINEBEARERMODE_VOICE
if (!m_pConn->m_lineArray[dwDeviceID]->IsSupportVoice())
{
TRACE0("LINEBEARERMODE_VOICE not supported\n");
return LINENOTUSEABLE_NOVOICE;
}
// Must support LINEMEDIAMODE_DATAMODEM
if (!m_pConn->m_lineArray[dwDeviceID]->IsSupportDataModem())
{
TRACE0("LINEMEDIAMODE_DATAMODEM not supported\n");
return LINENOTUSEABLE_NODATAMODEM;
}
// Must be able to make calls
if (!m_pConn->m_lineArray[dwDeviceID]->IsSupportMakeCall())
{
TRACE0("LINEFEATURE_MAKECALL not supported\n");
return LINENOTUSEABLE_NOMAKECALL;
}
// It is necessary to open the line so we can check if
// there are any call appearances available. Other TAPI
// applications could be using all call appearances.
// Opening the line also checks for other possible problems.
if (!m_pConn->m_lineArray[dwDeviceID]->Open())
{
return LINENOTUSEABLE_ALLOCATED;
}
// Get LineAddressStatus to make sure the line isn't already in use.
LPLINEADDRESSSTATUS lpLineAddressStatus =
m_pConn->m_lineArray[dwDeviceID]->I_lineGetAddressStatus(0);
if (lpLineAddressStatus == NULL)
{
m_pConn->m_lineArray[dwDeviceID]->Close();
return LINENOTUSEABLE_ERROR;
}
// Are there any available call appearances (ie: is it in use)?
if (!((lpLineAddressStatus->dwAddressFeatures) & LINEADDRFEATURE_MAKECALL))
{
TRACE0("LINEADDRFEATURE_MAKECALL not available\n");
delete lpLineAddressStatus;
m_pConn->m_lineArray[dwDeviceID]->Close();
return LINENOTUSEABLE_INUSE;
}
delete lpLineAddressStatus;
// Make sure the "comm/datamodem" device class is supported
// Note that we **don't** want any of the 'extra' information
// normally returned in the VARSTRING structure. All we care
// about is if lineGetID **succeeds**.
LPVARSTRING lpVarString = NULL;
int nSizeofVarString = sizeof(VARSTRING);
// Allocate the VARSTRING structure
lpVarString = (LPVARSTRING)new BYTE[nSizeofVarString];
if (lpVarString == NULL)
{
m_pConn->m_lineArray[dwDeviceID]->Close();
return LINENOTUSEABLE_ERROR;
}
lpVarString->dwTotalSize = nSizeofVarString;
long lReturn = ::lineGetID(m_pConn->m_lineArray[dwDeviceID]->m_hLine, 0, 0, LINECALLSELECT_LINE,
lpVarString, "comm/datamodem");
if (!CTAPIError::HandleLineErr(lReturn))
{
TRACE1("lineGetID unhandled error: %lx\n", lReturn);
delete lpVarString;
m_pConn->m_lineArray[dwDeviceID]->Close();
return LINENOTUSEABLE_NOCOMMDATAMODEM;
}
delete lpVarString;
TRACE0("Line is suitable and available for use.\n");
m_pConn->m_lineArray[dwDeviceID]->Close();
return TAPISUCCESS;
}
BEGIN_MESSAGE_MAP(CWaitLineDlg, CDialog)
//{{AFX_MSG_MAP(CWaitLineDlg)
ON_BN_CLICKED(IDC_CONFIGURELINE, OnConfigureline)
ON_BN_CLICKED(ID_WAITCALL, OnWaitcall)
ON_CBN_SELENDOK(IDC_TAPILINE, OnSeleTapiline)
ON_BN_CLICKED(IDC_STATICCONNECTUSING, OnStaticconnectusing)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWaitLineDlg message handlers
BOOL CWaitLineDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Initialize the Dialog Box. Lots to do here.
FillTAPILine();
VerifyAndWarnUsableLine();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// At one point, used lineConfigDialog to configure the device.
// This has the unfortunate effect of configuring the device immediately,
// even if it is in use by another TAPI app.
// This can be really bad if data communications are already in
// progress (like with RAS).
//
// Now, PreConfigureDevice uses lineConfigDialogEdit to give the
// user the configuration UI, but it doesn't actually do anything to
// the line device.
void CWaitLineDlg::OnConfigureline()
{
DWORD dwDeviceID = m_tapiLineBox.GetCurSel();
m_lpDeviceConfig = m_pConn->m_lineArray[dwDeviceID]->CallConfigDialogEdit(GetSafeHwnd(), m_dwSizeDeviceConfig);
}
void CWaitLineDlg::OnWaitcall()
{
// The Dial button has to be enabled and the line has
// to be currently usable to continue.
if (!(m_waitCallButton.IsWindowEnabled() &&
VerifyAndWarnUsableLine()))
return;
// Get the displayable and dialable numbers and store
// them in global variables to be used while dialing.
UpdateData(TRUE);
m_dwDeviceID = m_tapiLineBox.GetCurSel();
if (m_lpDeviceConfig)
::lineSetDevConfig(m_dwDeviceID, m_lpDeviceConfig,
m_dwSizeDeviceConfig, "comm/datamodem");
EndDialog(TRUE);
}
void CWaitLineDlg::OnSeleTapiline()
{
if (m_lpDeviceConfig != NULL)
{
delete m_lpDeviceConfig;
m_lpDeviceConfig = NULL;
}
VerifyAndWarnUsableLine();
}
void CWaitLineDlg::OnStaticconnectusing()
{
// TODO: Add your control notification handler code here
}
void CWaitLineDlg::OnCancel()
{
// TODO: Add extra cleanup here
CDialog::OnCancel();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -