windows-nt/Source/XPSP1/NT/net/tapi/client/cplareacodetab.cpp
2020-09-26 16:20:57 +08:00

484 lines
14 KiB
C++

/****************************************************************************
Copyright (c) 1998-1999 Microsoft Corporation
Module Name: cplareacodetab.cpp
Author: toddb - 10/06/98
****************************************************************************/
//
// Functions used only by the Area Code Rules tab of the New Location Property Sheet.
// Shared functions are in the Location.cpp file.
//
#include "cplPreComp.h"
#include "cplLocationPS.h"
INT_PTR CALLBACK CLocationPropSheet::AreaCode_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CLocationPropSheet* pthis = (CLocationPropSheet*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch(uMsg)
{
case WM_INITDIALOG:
pthis = (CLocationPropSheet*)(((PROPSHEETPAGE*)lParam)->lParam);
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis);
return pthis->AreaCode_OnInitDialog(hwndDlg);
case WM_COMMAND:
return pthis->AreaCode_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam );
case WM_NOTIFY:
return pthis->AreaCode_OnNotify(hwndDlg, (LPNMHDR)lParam);
case WM_HELP:
// Process clicks on controls after Context Help mode selected
WinHelp ((HWND)((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) a103HelpIDs);
break;
case WM_CONTEXTMENU:
// Process right-clicks on controls
WinHelp ((HWND) wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a103HelpIDs);
break;
}
return 0;
}
void BuildRuleDescription(CAreaCodeRule * pRule, LPTSTR szText, UINT cchSize)
{
TCHAR szAreaCode[MAX_INPUT];
TCHAR szNumToDial[MAX_INPUT];
BOOL hHasDialAreaCode = pRule->HasDialAreaCode();
BOOL bHasDialNumber = pRule->HasDialNumber();
// we almost always need these strings so go ahead and convert them
SHUnicodeToTChar( pRule->GetAreaCode(), szAreaCode, ARRAYSIZE(szAreaCode));
SHUnicodeToTChar( pRule->GetNumberToDial(), szNumToDial, ARRAYSIZE(szNumToDial));
// Just a little sanity check so we don't get crappy looking strings.
if ( bHasDialNumber && !*szNumToDial )
{
bHasDialNumber = FALSE;
}
int iFormatString;
// TODO: Special default rules processing
// if ( pRule == special rule that always shows up last )
// {
// iFormatString = IDS_DAIL_ONEpAC_ALLOTHER;
// }
// else
if ( pRule->HasAppliesToAllPrefixes() )
{
if ( bHasDialNumber )
{
if ( hHasDialAreaCode )
{
// Dial '%2' plus the area code before the number for all numbers within the %1 area code.
iFormatString = IDS_DIAL_XpAC_FORALL;
}
else
{
// Dial '%2' before the number for all numbers within the %1 area code.
iFormatString = IDS_DIAL_X_FORALL;
}
}
else if ( hHasDialAreaCode )
{
// Dial the area code before the number for all numbers within the %1 area code.
iFormatString = IDS_DIAL_AC_FORALL;
}
else
{
// Dial only the number for all numbers within the %1 area code.
iFormatString = IDS_DIAL_NUMONLY_FORALL;
}
}
else
{
if ( bHasDialNumber )
{
if ( hHasDialAreaCode )
{
// Dial '%2' plus the area code before the number for numbers with the selected prefixes within the %1 area code.
iFormatString = IDS_DIAL_XpAC_FORSELECTED;
}
else
{
// Dial '%2' before the number for numbers with the selected prefixes within the %1 area code.
iFormatString = IDS_DIAL_X_FORSELECTED;
}
}
else if ( hHasDialAreaCode )
{
// Dial the area code before the number for numbers with the selected prefixes within the %1 area code.
iFormatString = IDS_DIAL_AC_FORSELECTED;
}
else
{
// Dial only the number for numbers with the selected prefixes within the %1 area code.
iFormatString = IDS_DIAL_NUMONLY_FORSELECTED;
}
}
TCHAR szFormatString[512];
LPTSTR aArgs[] = {szAreaCode,szNumToDial};
LoadString( GetUIInstance(), iFormatString, szFormatString, ARRAYSIZE(szFormatString) );
FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
szFormatString, 0,0, szText, cchSize, (va_list *)aArgs );
}
void BuildRuleText(CAreaCodeRule * pRule, LPTSTR szText, UINT cchSize)
{
TCHAR szNumToDial[MAX_INPUT];
SHUnicodeToTChar( pRule->GetNumberToDial(), szNumToDial, ARRAYSIZE(szNumToDial));
// Just a little sanity check so we don't get crappy looking strings.
BOOL bHasDialNumber = pRule->HasDialNumber();
if ( bHasDialNumber && !*szNumToDial )
{
bHasDialNumber = FALSE;
}
if ( bHasDialNumber )
{
int iFormatString;
TCHAR szFormatString[512];
LPTSTR aArgs[] = {szNumToDial};
if ( pRule->HasDialAreaCode() )
{
// both string
iFormatString = IDS_DIALXPLUSAREACODE;
}
else
{
// dial number string
iFormatString = IDS_DIALX;
}
LoadString( GetUIInstance(), iFormatString, szFormatString, ARRAYSIZE(szFormatString) );
FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
szFormatString, 0,0, szText, cchSize, (va_list *)aArgs );
}
else if ( pRule->HasDialAreaCode() )
{
// area code only string
LoadString( GetUIInstance(), IDS_DIALAREACODE, szText, cchSize );
}
else
{
// none of the above string
LoadString( GetUIInstance(), IDS_DIALNUMBERONLY, szText, cchSize );
}
}
BOOL CLocationPropSheet::AreaCode_OnInitDialog(HWND hDlg)
{
// add the three columns to the listview
RECT rc;
TCHAR szText[MAX_INPUT];
HWND hwndList = GetDlgItem(hDlg, IDC_LIST);
GetClientRect(hwndList, &rc);
int cxList = rc.right - GetSystemMetrics(SM_CXVSCROLL);
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
lvc.pszText = szText;
struct {
int iStrID;
int cxPercent;
} aData[] = {
{ IDS_AREACODE, 20 },
{ IDS_PREFIXES, 20 },
{ IDS_RULE, 60 },
};
for (int i=0; i<ARRAYSIZE(aData); i++)
{
LoadString(GetUIInstance(), aData[i].iStrID, szText, ARRAYSIZE(szText));
lvc.iSubItem = i;
lvc.cx = MulDiv(cxList, aData[i].cxPercent, 100);
ListView_InsertColumn( hwndList, i, &lvc );
}
ListView_SetExtendedListViewStyleEx(hwndList,
LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT,
LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);
PopulateAreaCodeRuleList( hwndList );
SetDataForSelectedRule(hDlg);
return 1;
}
void CLocationPropSheet::SetDataForSelectedRule(HWND hDlg)
{
TCHAR szText[512];
// Set the button states
EnableWindow(GetDlgItem(hDlg, IDC_EDIT), 0!=m_pRule);
EnableWindow(GetDlgItem(hDlg, IDC_DELETE), 0!=m_pRule);
if ( m_pRule )
{
// Set the description text
BuildRuleDescription(m_pRule, szText, ARRAYSIZE(szText));
}
else
{
// text for when no rule is selected:
LoadString(GetUIInstance(), IDS_SELECTARULE, szText, ARRAYSIZE(szText));
}
SetWindowText(GetDlgItem(hDlg, IDC_DESCRIPTIONTEXT), szText);
}
void CLocationPropSheet::AddRuleToList( HWND hwndList, CAreaCodeRule * pRule, BOOL bSelect )
{
TCHAR szText[512];
LVITEM lvi;
SHUnicodeToTChar( pRule->GetAreaCode(), szText, ARRAYSIZE(szText));
lvi.pszText = szText;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = 0;
lvi.iSubItem = 0;
lvi.stateMask = LVIS_STATEIMAGEMASK;
lvi.lParam = (LPARAM)pRule;
if ( bSelect )
{
lvi.mask |= LVIF_STATE;
lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
// We added the new rule in the selected state so update m_pRule
m_pRule = pRule;
// Since we now have a selected rule, update the button states
HWND hwndParent = GetParent(hwndList);
EnableWindow( GetDlgItem(hwndParent, IDC_EDIT), TRUE );
EnableWindow( GetDlgItem(hwndParent, IDC_DELETE), TRUE );
}
int iItem = ListView_InsertItem(hwndList, &lvi);
LoadString(GetUIInstance(), pRule->HasAppliesToAllPrefixes()?IDS_ALLPREFIXES:IDS_SELECTEDPREFIXES,
szText, ARRAYSIZE(szText));
ListView_SetItemText(hwndList, iItem, 1, szText);
BuildRuleText( pRule, szText, ARRAYSIZE(szText));
ListView_SetItemText(hwndList, iItem, 2, szText);
}
void CLocationPropSheet::RemoveRuleFromList(HWND hwndList, BOOL bSelect)
{
LVFINDINFO lvfi;
lvfi.flags = LVFI_PARAM;
lvfi.lParam = (LPARAM)m_pRule;
int iItem = ListView_FindItem(hwndList,-1,&lvfi);
if ( -1 != iItem )
{
if ( bSelect )
{
iItem = DeleteItemAndSelectPrevious( GetParent(hwndList), IDC_LIST, iItem, IDC_DELETE, IDC_NEW );
if ( -1 != iItem )
{
LVITEM lvi;
lvi.iItem = iItem;
lvi.iSubItem = 0;
lvi.mask = LVIF_PARAM;
ListView_GetItem( hwndList, &lvi );
// Store the currently selected item
m_pRule = (CAreaCodeRule *)lvi.lParam;
}
else
{
m_pRule = NULL;
}
}
else
{
ListView_DeleteItem(hwndList,iItem);
m_pRule = NULL;
}
}
}
void CLocationPropSheet::PopulateAreaCodeRuleList( HWND hwndList )
{
m_pLoc->ResetRules();
int i;
int iItems;
CAreaCodeRule * pRule;
iItems = m_pLoc->GetNumRules();
for (i=0; i<iItems; i++)
{
if ( S_OK == m_pLoc->NextRule(1,&pRule,NULL) )
{
AddRuleToList( hwndList, pRule, FALSE );
}
}
}
BOOL CLocationPropSheet::AreaCode_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl)
{
switch ( wID )
{
case IDC_NEW:
case IDC_EDIT:
LaunchNewRuleDialog(IDC_NEW == wID,hwndParent);
break;
case IDC_DELETE:
DeleteSelectedRule(GetDlgItem(hwndParent,IDC_LIST));
break;
default:
return 0;
}
return 1;
}
void CLocationPropSheet::LaunchNewRuleDialog(BOOL bNew, HWND hwndParent)
{
CAreaCodeRule * pRule;
if ( bNew )
{
// Initialize with default values
pRule = new CAreaCodeRule;
if ( !pRule )
{
return;
}
pRule->Initialize(L"",L"1",RULE_APPLIESTOALLPREFIXES,NULL,0);
}
else if ( m_pRule )
{
// Initialize with m_pRule's values
pRule = m_pRule;
}
else
{
// This should be impossible
return;
}
CAreaCodeRuleDialog acrd( bNew, pRule );
if ( IDOK == acrd.DoModal(hwndParent) )
{
// The user changed something
HWND hwndList = GetDlgItem(hwndParent,IDC_LIST);
SendMessage(GetParent(hwndParent), PSM_CHANGED, (WPARAM)hwndParent, 0);
if ( bNew )
{
m_pLoc->AddRule(pRule);
}
else
{
// Assert( m_pRule == pRule );
RemoveRuleFromList(hwndList, FALSE);
}
AddRuleToList(hwndList, pRule, TRUE);
SetDataForSelectedRule(hwndParent);
}
else if ( bNew )
{
delete pRule;
}
}
void CLocationPropSheet::DeleteSelectedRule(HWND hwndList)
{
// First we confirm the delete with the user
TCHAR szText[1024];
TCHAR szTitle[128];
int result;
HWND hwndParent = GetParent(hwndList);
LoadString(GetUIInstance(), IDS_DELETERULETEXT, szText, ARRAYSIZE(szText));
LoadString(GetUIInstance(), IDS_CONFIRMDELETE, szTitle, ARRAYSIZE(szTitle));
result = SHMessageBoxCheck( hwndParent, szText, szTitle, MB_YESNO, IDYES, TEXT("TAPIDeleteAreaCodeRule") );
if ( IDYES == result )
{
// remove the item corresponding to m_pRule from the list
m_pLoc->RemoveRule(m_pRule);
RemoveRuleFromList(hwndList, TRUE);
// Now we want to select the next rule in the list
HWND hwndParent = GetParent(hwndList);
SetDataForSelectedRule(hwndParent);
SendMessage(GetParent(hwndParent), PSM_CHANGED, (WPARAM)hwndParent, 0);
}
}
BOOL CLocationPropSheet::AreaCode_OnNotify(HWND hwndDlg, LPNMHDR pnmhdr)
{
// Let the generic handler have a crack at it first
OnNotify(hwndDlg, pnmhdr);
if (pnmhdr->idFrom == IDC_LIST)
{
#define pnmlv ((LPNMLISTVIEW)pnmhdr)
switch (pnmhdr->code)
{
case LVN_ITEMCHANGED:
if ( pnmlv->uChanged & LVIF_STATE )
{
if (pnmlv->uNewState & LVIS_SELECTED)
{
LVITEM lvi;
lvi.iItem = pnmlv->iItem;
lvi.iSubItem = pnmlv->iSubItem;
lvi.mask = LVIF_PARAM;
ListView_GetItem( pnmhdr->hwndFrom, &lvi );
// Store the currently selected item
m_pRule = (CAreaCodeRule *)lvi.lParam;
}
else
{
m_pRule = NULL;
}
SetDataForSelectedRule(hwndDlg);
}
break;
case NM_DBLCLK:
if ( (-1 == pnmlv->iItem) || !m_pRule )
{
// Do new case
LaunchNewRuleDialog(TRUE,hwndDlg);
}
else
{
// Do Edit case
LaunchNewRuleDialog(FALSE,hwndDlg);
}
break;
default:
break;
}
#undef pnmlv
}
return 1;
}