📄 dialdlg.cpp
字号:
// Now locate the prefered card and display it.
LPLINECARDENTRY lpLineCardEntry = (LPLINECARDENTRY)
(((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwCardListOffset);
for (DWORD dwCounter = 0;
dwCounter < lpTranslateCaps->dwNumCards;
++ dwCounter)
{
if (lpLineCardEntry[dwCounter].dwPermanentCardID == dwPreferredCardID)
{
CString strCardName = ((LPBYTE)lpTranslateCaps) +
lpLineCardEntry[dwCounter].dwCardNameOffset;
m_callingCard.SetWindowText(strCardName);
break;
}
}
if (lpTranslateCaps)
delete lpTranslateCaps;
}
// Enable/disable Dialing Rule controls
// The sole purpose of this function is to enable or disable
// the controls that apply to dialing rules if the
// "Use Country Code and Area Code" checkbox is checked or unchecked,
// as appropriate.
void CDialDlg::UseDialingRules()
{
BOOL bEnableWindow = m_useDialingRules.GetCheck();
GetDlgItem(IDC_STATICCOUNTRYCODE)->EnableWindow(bEnableWindow);
GetDlgItem(IDC_STATICAREACODE)->EnableWindow(bEnableWindow);
GetDlgItem(IDC_STATICLOCATION)->EnableWindow(bEnableWindow);
GetDlgItem(IDC_STATICCALLINGCARD)->EnableWindow(bEnableWindow);
m_countryCode.EnableWindow(bEnableWindow);
m_areaCode.EnableWindow(bEnableWindow);
m_locationBox.EnableWindow(bEnableWindow);
m_callingCard.EnableWindow(bEnableWindow);
if (m_configureLine.IsWindowEnabled())
{
m_dialingProperties.EnableWindow(bEnableWindow);
}
}
// Create, Translate and Display the Phone Number
// This function uses the information stored in many other controls
// to build the phone number, translate it, and display it. Also
// makes sure the Dial button is enabled or disabled, based on if the
// number can be dialed or not.
//
// There are actually three phone numbers generated during this
// process: canonical, dialable and displayable. Normally, only the
// displayable number is shown to the user; the other two numbers are
// to be used by the program internally. However, for demonstration
// purposes (and because it is cool for developers to see these numbers),
// all three numbers are displayed.
void CDialDlg::DisplayPhoneNumber(void)
{
CString szTempBuffer;
// Disable the 'dial' button if there isn't a number to dial
if (m_phoneNumber.LineLength() == 0)
{
m_strCanonicalNumber = _T("");
m_strDialableNumber = _T("");
m_strDisplayableNumber = _T("无电话号码");
UpdateData(FALSE);
m_dialButton.EnableWindow(FALSE);
return;
}
// If we use the dialing rules, lets make canonical format.
// Canonical format is explained in the TAPI documentation and the
// string format needs to be followed very strictly.
m_strCanonicalNumber = _T("");
if (m_useDialingRules.GetCheck())
{
// First character *has* to be the plus sign.
m_strCanonicalNumber += '+';
// The country code *has* to be next.
// Country code was stored in the string with the country
// name and needs to be extracted at this point.
int i = m_countryCode.GetCurSel();
m_countryCode.GetLBText(i, szTempBuffer);
// Country code is at the end of the string, surounded by parens.
// This makes it easy to identify the country code.
int nStart = szTempBuffer.ReverseFind(_T('('));
int nEnd = szTempBuffer.Find(_T(')'));
m_strCanonicalNumber += szTempBuffer.Mid(nStart + 1, nEnd - nStart - 1);
// Next is the area code.
m_areaCode.GetWindowText(szTempBuffer);
// Note that the area code is optional. If it is included,
// then it has to be preceeded by *exactly* one space and it
// *has* to be surrounded by parens.
if (i)
{
m_strCanonicalNumber += _T(" (");
m_strCanonicalNumber += szTempBuffer;
m_strCanonicalNumber += _T(')');
}
// There has to be *exactly* one space before the rest of the number.
m_strCanonicalNumber += ' ';
// At this point, the phone number is appended to the
// canonical number. The next step is the same whether canonical
// format is used or not; just the prepended area code and
// country code are different.
}
m_phoneNumber.GetWindowText(szTempBuffer);
m_strCanonicalNumber += szTempBuffer;
DWORD dwDeviceID = m_tapiLineBox.GetCurSel();
// Translate the address!
LPLINETRANSLATEOUTPUT lpLineTranslateOutput = m_pConn->m_lineArray[dwDeviceID]->I_lineTranslateAddress(m_strCanonicalNumber);
// Unable to translate it?
if (lpLineTranslateOutput == NULL)
{
m_strCanonicalNumber = _T("");
m_strDialableNumber = _T("");
m_strDisplayableNumber = _T("非法的电话号码或地区号码");
UpdateData(FALSE);
m_dialButton.EnableWindow(FALSE);
return;
}
// Is the selected device useable with TapiComm?
if (dwDeviceID != MAXDWORD)
m_dialButton.EnableWindow(TRUE);
// Fill the appropriate phone number controls.
m_strDialableNumber = ((LPSTR) lpLineTranslateOutput +
lpLineTranslateOutput->dwDialableStringOffset);
m_strDisplayableNumber = ((LPSTR) lpLineTranslateOutput +
lpLineTranslateOutput->dwDisplayableStringOffset);
UpdateData(FALSE);
if (lpLineTranslateOutput)
delete lpLineTranslateOutput;
}
// Fill the 'Country Code' control
// This function fills the 'Country Code' control with country names.
// The country code is appended to the end of the name and the names
// are added to the control sorted. Because the country code is
// embedded in the string along with the country name, there is no need
// for any of the country information structures to be kept around. The
// country code can be extracted from the selected string at any time.
void CDialDlg::FillCountryCodeList(DWORD dwDefaultCountryID)
{
LPLINECOUNTRYLIST lpLineCountryList = NULL;
int nSizeofCountryList = sizeof(LINECOUNTRYLIST);
char szRenamedCountry[256];
// Get the country information stored in TAPI
while (TRUE)
{
lpLineCountryList =
(LPLINECOUNTRYLIST)new BYTE[nSizeofCountryList];
if (lpLineCountryList == NULL)
return;
// Make the call to fill the structure.
long lReturn;
lpLineCountryList->dwTotalSize = nSizeofCountryList;
do
{
lReturn = ::lineGetCountry(0, CTAPIConnection::m_dwAPIHighVersion,
lpLineCountryList);
if (!CTAPIError::HandleLineErr(lReturn))
{
TRACE0("lineGetCountry unhandled error\n");
delete lpLineCountryList;
return;
}
}
while (lReturn != TAPISUCCESS);
if ((lpLineCountryList->dwNeededSize) <=
(lpLineCountryList->dwTotalSize))
{
break;
}
else
{
// Buffer wasn't big enough. Make it bigger and try again.
nSizeofCountryList = lpLineCountryList->dwNeededSize;
delete lpLineCountryList;
}
}
// Find the first country entry
LPLINECOUNTRYENTRY lpLineCountryEntries = (LPLINECOUNTRYENTRY)
(((LPBYTE)lpLineCountryList) +
lpLineCountryList->dwCountryListOffset);
// Now enumerate through all the countries
for (DWORD dwCountry = 0;
dwCountry < lpLineCountryList->dwNumCountries;
++ dwCountry)
{
// append the country code to the country name
wsprintf(szRenamedCountry,"%s -- (%lu)",
(((LPSTR)lpLineCountryList) +
lpLineCountryEntries[dwCountry].dwCountryNameOffset),
lpLineCountryEntries[dwCountry].dwCountryCode);
// Now put this country name / code string into the combobox
int index = m_countryCode.AddString(szRenamedCountry);
// If this country is the default country, select it.
if (lpLineCountryEntries[dwCountry].dwCountryID
== dwDefaultCountryID)
{
m_countryCode.SetCurSel(index);
}
}
delete lpLineCountryList;
return;
}
// 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 CDialDlg::VerifyAndWarnUsableLine(void)
{
// Get the selected line device.
DWORD dwDeviceID = m_tapiLineBox.GetCurSel();
// 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);
if (m_strCanonicalNumber.GetLength() == 0)
{
m_dialButton.EnableWindow(FALSE);
}
else
m_dialButton.EnableWindow((lReturn == TAPISUCCESS));
// Any errors on this line prevent us from configuring it
// or using dialing properties.
if (lReturn == LINENOTUSEABLE_ERROR)
{
m_configureLine.EnableWindow(FALSE);
m_dialingProperties.EnableWindow(FALSE);
}
else
{
m_configureLine.EnableWindow(TRUE);
if (m_useDialingRules.GetCheck())
m_dialingProperties.EnableWindow(TRUE);
}
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 CDialDlg::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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -