📄 dialdlg.cpp
字号:
// Written by JHCC, 1997
// DialDlg.cpp : implementation file
//
#include "stdafx.h"
#include "JHHB.h"
#include "tapix.h"
#include "TAPIErr.h"
#include "DialDlg.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,
};
/////////////////////////////////////////////////////////////////////////////
// CDialDlg dialog
CDialDlg::CDialDlg(CTAPIConnection* pConn, CWnd* pParent /*=NULL*/)
: CDialog(CDialDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDialDlg)
m_strCanonicalNumber = _T("");
m_strDialableNumber = _T("");
m_strDisplayableNumber = _T("");
//}}AFX_DATA_INIT
m_lpDeviceConfig = NULL;
m_pConn = pConn;
}
CDialDlg::~CDialDlg()
{
if (m_lpDeviceConfig != NULL)
{
delete m_lpDeviceConfig;
m_lpDeviceConfig = NULL;
}
}
void CDialDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDialDlg)
DDX_Control(pDX, IDC_CALLINGCARD, m_callingCard);
DDX_Control(pDX, IDC_DIAL, m_dialButton);
DDX_Control(pDX, IDC_DIALINGPROPERTIES, m_dialingProperties);
DDX_Control(pDX, IDC_CONFIGURELINE, m_configureLine);
DDX_Control(pDX, IDC_LOCATION, m_locationBox);
DDX_Control(pDX, IDC_USEDIALINGRULES, m_useDialingRules);
DDX_Control(pDX, IDC_COUNTRYCODE, m_countryCode);
DDX_Control(pDX, IDC_LINEICON, m_lineIcon);
DDX_Control(pDX, IDC_AREACODE, m_areaCode);
DDX_Control(pDX, IDC_PHONENUMBER, m_phoneNumber);
DDX_Control(pDX, IDC_TAPILINE, m_tapiLineBox);
DDX_Text(pDX, IDC_CANONICALNUMBER, m_strCanonicalNumber);
DDX_Text(pDX, IDC_DIALABLENUMBER, m_strDialableNumber);
DDX_Text(pDX, IDC_DISPLAYABLENUMBER, m_strDisplayableNumber);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDialDlg, CDialog)
//{{AFX_MSG_MAP(CDialDlg)
ON_CBN_SELENDOK(IDC_TAPILINE, OnSeleTapiline)
ON_BN_CLICKED(IDC_CONFIGURELINE, OnConfigureline)
ON_CBN_SELENDOK(IDC_COUNTRYCODE, OnSeleCountrycode)
ON_EN_CHANGE(IDC_AREACODE, OnChangeAreacode)
ON_EN_CHANGE(IDC_PHONENUMBER, OnChangePhonenumber)
ON_BN_CLICKED(IDC_USEDIALINGRULES, OnUsedialingrules)
ON_CBN_CLOSEUP(IDC_LOCATION, OnCloseupLocation)
ON_BN_CLICKED(IDC_DIALINGPROPERTIES, OnDialingproperties)
ON_BN_CLICKED(IDC_DIAL, OnDial)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialDlg message handlers
BOOL CDialDlg::OnInitDialog()
{
CDialog::OnInitDialog();
DWORD dwCountryID = 0;
// Initialize the Dialog Box. Lots to do here.
FillTAPILine();
CString szAreaCode;
FillLocationInfo(NULL, &dwCountryID, &szAreaCode);
FillCountryCodeList(dwCountryID);
m_useDialingRules.SetCheck(FALSE);
m_areaCode.SetWindowText(szAreaCode);
UseDialingRules();
DisplayPhoneNumber();
VerifyAndWarnUsableLine();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CDialDlg::OnSeleTapiline()
{
if (m_lpDeviceConfig != NULL)
{
delete m_lpDeviceConfig;
m_lpDeviceConfig = NULL;
}
DisplayPhoneNumber();
VerifyAndWarnUsableLine();
}
// 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 CDialDlg::OnConfigureline()
{
DWORD dwDeviceID = m_tapiLineBox.GetCurSel();
m_lpDeviceConfig = m_pConn->m_lineArray[dwDeviceID]->CallConfigDialogEdit(GetSafeHwnd(), m_dwSizeDeviceConfig);
DisplayPhoneNumber();
}
void CDialDlg::OnSeleCountrycode()
{
DisplayPhoneNumber();
}
void CDialDlg::OnChangeAreacode()
{
DisplayPhoneNumber();
}
void CDialDlg::OnChangePhonenumber()
{
DisplayPhoneNumber();
}
void CDialDlg::OnUsedialingrules()
{
UseDialingRules();
DisplayPhoneNumber();
}
void CDialDlg::OnCloseupLocation()
{
CString szCurrentLocation;
int nCurrentSelection = m_locationBox.GetCurSel();
m_locationBox.GetLBText(nCurrentSelection, szCurrentLocation);
// If the user selected a 'location', make it current.
FillLocationInfo(&szCurrentLocation, NULL, NULL);
DisplayPhoneNumber();
}
void CDialDlg::OnDialingproperties()
{
DWORD dwDeviceID = m_tapiLineBox.GetCurSel();
UpdateData(TRUE);
long lReturn = ::lineTranslateDialog(m_pConn->m_hLineApp, dwDeviceID,
CTAPIConnection::m_dwAPIHighVersion, GetSafeHwnd(), m_strCanonicalNumber);
if (lReturn != TAPISUCCESS)
TRACE1("lineTranslateDialog: %lx\n", lReturn);
// The user could have changed the default location, or
// added or removed a location while in the 'Dialing
// Properties' dialog. Refill the Location Info.
FillLocationInfo(NULL, NULL, NULL);
DisplayPhoneNumber();
}
void CDialDlg::OnDial()
{
// The Dial button has to be enabled and the line has
// to be currently usable to continue.
if (!(m_dialButton.IsWindowEnabled() &&
VerifyAndWarnUsableLine()))
return;
DisplayPhoneNumber();
// 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);
}
DWORD CDialDlg::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 CDialDlg::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);
}
// Fill (or refill) the 'Your Location' control
// This function is moderately multipurpose.
//
// If lpszCurrentLocation is NULL, then the 'Your Location' control
// is filled with all the locations stored in TAPI and the TAPI 'default'
// location is selected. This is done during initialization and
// also after the 'Dialing Properties' dialog has been displayed.
// This last is done because the user can change the current location
// or add and delete locations while in the 'Dialing Properties' dialog.
//
// If lpszCurrentLocation is a valid string pointer, then it is assumed
// that the 'Your Location' control is already filled and that the user
// is selecting a specific location. In this case, all of the existing
// TAPI locations are enumerated until the specified location is found.
// At this point, the specified location is set to the current location.
//
// In either case, if lpdwCountryID is not NULL, it is filled with the
// country ID for the current location. If lpszAreaCode is not NULL, it
// is filled with the area code defined for the current location. These
// values can be used later to initialize other "Dial" controls.
//
// This function also fills the 'Calling Card' control based on
// the information stored in the current location.
void CDialDlg::FillLocationInfo(CString* lpszCurrentLocation,
LPDWORD lpdwCountryID, CString* lpszAreaCode)
{
long lReturn;
DWORD dwPreferredCardID = MAXDWORD;
// First, get the TRANSLATECAPS
LPLINETRANSLATECAPS lpTranslateCaps = NULL;
int nSizeofTranslateCaps = sizeof(LINETRANSLATECAPS);
while (TRUE)
{
lpTranslateCaps =
(LPLINETRANSLATECAPS)new BYTE[nSizeofTranslateCaps];
if (lpTranslateCaps == NULL)
return;
lpTranslateCaps->dwTotalSize = nSizeofTranslateCaps;
do
{
lReturn = ::lineGetTranslateCaps(m_pConn->m_hLineApp, CTAPIConnection::m_dwAPIHighVersion,
lpTranslateCaps);
if (!CTAPIError::HandleLineErr(lReturn))
{
TRACE1("lineGetTranslateCaps unhandled error: %lu\n", lReturn);
delete lpTranslateCaps;
return;
}
}
while (lReturn != TAPISUCCESS);
if ((lpTranslateCaps->dwNeededSize) <=
(lpTranslateCaps->dwTotalSize))
{
break;
}
else
{
nSizeofTranslateCaps = lpTranslateCaps->dwNeededSize;
delete lpTranslateCaps;
}
}
// Find the location information in the TRANSLATECAPS
LPLINELOCATIONENTRY lpLocationEntry = (LPLINELOCATIONENTRY)
(((LPBYTE)lpTranslateCaps) + lpTranslateCaps->dwLocationListOffset);
// If lpszCurrentLocation, then make that location 'current'
if (lpszCurrentLocation)
{
// loop through all locations, looking for a location match
for (DWORD dwCounter = 0;
dwCounter < lpTranslateCaps->dwNumLocations;
++ dwCounter)
{
CString str = ((LPSTR)lpTranslateCaps) +
lpLocationEntry[dwCounter].dwLocationNameOffset;
if (str == *lpszCurrentLocation)
{
// Found it! Set the current location.
::lineSetCurrentLocation(m_pConn->m_hLineApp,
lpLocationEntry[dwCounter].dwPermanentLocationID);
// Set the return values.
if (lpdwCountryID)
*lpdwCountryID = lpLocationEntry[dwCounter].dwCountryID;
if (lpszAreaCode != NULL)
*lpszAreaCode = ((LPSTR)lpTranslateCaps) +
lpLocationEntry[dwCounter].dwCityCodeOffset;
// Store the preferred card ID for later use.
dwPreferredCardID = lpLocationEntry[dwCounter].dwPreferredCardID;
break;
}
}
// Was a match for lpszCurrentLocation found?
if (dwPreferredCardID == MAXDWORD)
{
TRACE0("lpszCurrentLocation not found\n");
m_callingCard.SetWindowText(_T("Invalid Location Selected"));
delete lpTranslateCaps;
return;
}
}
else // fill the combobox and use the TAPI 'current' location.
{
// First empty the combobox
m_locationBox.ResetContent();
// enumerate all the locations
for (DWORD dwCounter = 0;
dwCounter < lpTranslateCaps->dwNumLocations;
++ dwCounter)
{
// Put each one into the combobox
CString strLocation = (((LPBYTE) lpTranslateCaps) +
lpLocationEntry[dwCounter].dwLocationNameOffset);
m_locationBox.AddString(strLocation);
// Is this location the 'current' location?
if (lpLocationEntry[dwCounter].dwPermanentLocationID ==
lpTranslateCaps->dwCurrentLocationID)
{
// Return the requested information
if (lpdwCountryID)
*lpdwCountryID = lpLocationEntry[dwCounter].dwCountryID;
if (lpszAreaCode != 0)
*lpszAreaCode = ((LPSTR) lpTranslateCaps) +
lpLocationEntry[dwCounter].dwCityCodeOffset;
// Set this to be the active location.
m_locationBox.SetCurSel(lReturn);
dwPreferredCardID = lpLocationEntry[dwCounter].dwPreferredCardID;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -