|
|
/****************************************************************************
Copyright (c) 1998-1999 Microsoft Corporation Module Name: cpldialingrulesps.cpp Author: toddb - 10/06/98
****************************************************************************/
// Property Sheet stuff for the main page
#include "cplPreComp.h"
#include "cplLocationPS.h"
#include <setupapi.h> // for HDEVINFO
#include <winuser.h> // for HDEVNOTIFY
// Global Variables
HFONT g_hfontBold = NULL; HINSTANCE g_hInstUI = NULL;
// Prototypes
BOOL CALLBACK SetToForegroundEnumProc( HWND hwnd, LPARAM lParam ); extern "C" INT_PTR CALLBACK LocWizardDlgProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam );
extern "C" LONG EnsureOneLocation (HWND hwnd);
void CountryRunOnce();
class CDialingRulesPropSheet { public: CDialingRulesPropSheet(LPCWSTR pwszAddress, DWORD dwAPIVersion); ~CDialingRulesPropSheet();
#ifdef TRACELOG
DECLARE_TRACELOG_CLASS(CDialingRulesPropSheet) #endif
LONG DoPropSheet(HWND hwndParent, int iTab);
protected: LONG CheckForOtherInstances();
static INT_PTR CALLBACK Dailing_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); BOOL Dailing_OnInitDialog(HWND hDlg); BOOL Dailing_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl); BOOL Dailing_OnNotify(HWND hwndDlg, LPNMHDR pnmhdr); void LaunchLocationPropSheet(BOOL bNew, HWND hwndParent); void DeleteSelectedLocation(HWND hwndList); void AddLocationToList(HWND hwndList, CLocation *pLoc, BOOL bSelect); void UpdateLocationInList(HWND hwndList, CLocation *pLocOld, CLocation *pLocNew); void UpdateControlStates(HWND hDlg); void SetCheck(HWND hwndList, CLocation * pLoc, int iImage);
static INT_PTR CALLBACK Advanced_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); BOOL Advanced_OnInitDialog(HWND hDlg); BOOL Advanced_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl);
HANDLE m_hMutex; DWORD m_dwDefaultCountryID; CLocation * m_pLocSelected; // pointer the the CLocation for the selected item in the list view.
// can be NULL if no item is selected.
CLocations m_locs; // The locations data used to build the locations list
LPCWSTR m_pwszAddress; // The address (number) we are translating
int m_iSortCol; // which column to sort by
DWORD m_dwAPIVersion; // The version of tapi used to call internalConfig
};
CDialingRulesPropSheet::CDialingRulesPropSheet(LPCWSTR pwszAddress, DWORD dwAPIVersion) { m_pwszAddress = pwszAddress; m_hMutex = NULL; m_pLocSelected = NULL; m_dwDefaultCountryID = GetProfileInt(TEXT("intl"), TEXT("iCountry"), 1); m_iSortCol = 0; m_dwAPIVersion = dwAPIVersion; }
CDialingRulesPropSheet::~CDialingRulesPropSheet() { if ( m_hMutex ) CloseHandle( m_hMutex ); }
typedef struct tagMODEMDLG { HDEVINFO hdi; HDEVNOTIFY NotificationHandle; int cSel; DWORD dwFlags; } MODEMDLG, FAR * LPMODEMDLG;
LONG CDialingRulesPropSheet::DoPropSheet(HWND hwndParent, int iTab) { LONG result; PROPSHEETHEADER psh; HPROPSHEETPAGE ahpsp[3]; PROPSHEETPAGE apsp[3]; HINSTANCE hInstModemUI = NULL;
DLGPROC pfnModemDialogProc = NULL; MODEMDLG md; md.hdi = INVALID_HANDLE_VALUE; md.cSel = 0; md.dwFlags = 0;
result = CheckForOtherInstances(); if ( result ) { return result; }
// if iTab is -1 then we only show the dialing rules tab and we hide the modem
// and advanced tabs. When lineTranslateDialog is called we pass -1 for iTab,
// when the CPL is invoked we pass the starting page number as iTab.
if ( -1 != iTab ) { // we can't link directly to modemui.dll because we live inside TAPI,
// so delay load all the required MODEMUI functions up front.
hInstModemUI = LoadLibrary(TEXT("modemui.dll")); if (!hInstModemUI) { return FALSE; } // get proc the functions we need.
pfnModemDialogProc = (DLGPROC)GetProcAddress(hInstModemUI,"ModemCplDlgProc"); if ( !pfnModemDialogProc ) { FreeLibrary(hInstModemUI); return FALSE; // Review: Does this return code matter?
} }
// Review: The old dialing page had some pre-launch configuration to do.
// Some sort of lineConfigure function or something. Check if this is needed.
// We delay the initialization until here
result = (LONG)m_locs.Initialize(); if (result && (result != LINEERR_INIFILECORRUPT)) { TCHAR szCaption[MAX_INPUT]; TCHAR szMessage[512];
LoadString(GetUIInstance(), IDS_NAME, szCaption, ARRAYSIZE(szCaption)); LoadString(GetUIInstance(), IDS_CANNOT_START_TELEPHONCPL, szMessage, ARRAYSIZE(szMessage)); MessageBox(hwndParent, szMessage, szCaption, MB_OK | MB_ICONWARNING); return result; }
// If there are no locations, launch the simple location dialog
if ( 0 == m_locs.GetNumLocations() ) { // if we are in lineTranslateDialog mode, then we display the simple
int iRes; iRes = (int)DialogBoxParam(GetUIInstance(), MAKEINTRESOURCE(IDD_SIMPLELOCATION),NULL, LocWizardDlgProc, (LPARAM)m_dwAPIVersion);
if ( IDOK == iRes ) { // now we need to re-initalize to pick up the new location
m_locs.Initialize();
// Now we need to figure out the ID of the location we just created
CLocation * pLoc; m_locs.Reset(); if ( S_OK == m_locs.Next( 1, &pLoc, NULL ) ) { // Set this ID as the default location
m_locs.SetCurrentLocationID(pLoc->GetLocationID()); CountryRunOnce(); }
// we've already made a commited change, so save the result
m_locs.SaveToRegistry(); result = NO_ERROR; } else { // If this was lineTranslateDialog and the user canceled the simple location
// dialog then we have already warned them of what might happen. If this is
// a down level legacy call then we return an old error code
if ( m_dwAPIVersion < TAPI_VERSION2_2 ) { // return an old error code that legacy apps understand
return LINEERR_OPERATIONFAILED; } else { // as of TAPI_VERSION2_2 we have a new error value just for this case:
return LINEERR_USERCANCELLED; } } }
// Initialize the header:
psh.dwSize = sizeof(psh); psh.dwFlags = PSH_DEFAULT; psh.hwndParent = hwndParent; psh.hInstance = GetUIInstance(); psh.hIcon = NULL; psh.pszCaption = MAKEINTRESOURCE(IDS_NAME); psh.nPages = (-1!=iTab)?3:1; psh.nStartPage = (-1!=iTab)?iTab:0; psh.pfnCallback = NULL; psh.phpage = ahpsp;
// Now setup the Property Sheet Page
apsp[0].dwSize = sizeof(apsp[0]); apsp[0].dwFlags = PSP_DEFAULT; apsp[0].hInstance = GetUIInstance(); apsp[0].pszTemplate = MAKEINTRESOURCE(IDD_MAIN_DIALINGRULES); apsp[0].pfnDlgProc = CDialingRulesPropSheet::Dailing_DialogProc; apsp[0].lParam = (LPARAM)this; ahpsp[0] = CreatePropertySheetPage (&apsp[0]);
if ( -1 != iTab ) { apsp[1].dwSize = sizeof(apsp[1]); apsp[1].dwFlags = PSP_DEFAULT; apsp[1].hInstance = hInstModemUI; apsp[1].pszTemplate = MAKEINTRESOURCE(20011); apsp[1].pfnDlgProc = pfnModemDialogProc; apsp[1].lParam = (LPARAM)&md; ahpsp[1] = CreatePropertySheetPage (&apsp[1]);
apsp[2].dwSize = sizeof(apsp[2]); apsp[2].dwFlags = PSP_DEFAULT; apsp[2].hInstance = GetUIInstance(); apsp[2].pszTemplate = MAKEINTRESOURCE(IDD_MAIN_ADVANCED); apsp[2].pfnDlgProc = CDialingRulesPropSheet::Advanced_DialogProc; apsp[2].lParam = 0; ahpsp[2] = CreatePropertySheetPage (&apsp[2]); }
if (-1 == PropertySheet( &psh )) { result = GetLastError (); LOG ((TL_ERROR, "PropertySheet failed, error 0x%x", result)); }
// now we're done with modemui, so release it.
if(hInstModemUI) FreeLibrary(hInstModemUI);
return result; }
LONG CDialingRulesPropSheet::CheckForOtherInstances() { TCHAR szCaption[MAX_INPUT]; if ( !LoadString(GetUIInstance(), IDS_NAME, szCaption, 128) ) { return LINEERR_OPERATIONFAILED; }
m_hMutex = CreateMutex (NULL, FALSE, TEXT("tapi_dp_mutex")); if (!m_hMutex) { return LINEERR_OPERATIONFAILED; } else if (GetLastError() == ERROR_ALREADY_EXISTS) { EnumWindows( SetToForegroundEnumProc, (LPARAM)szCaption ); return LINEERR_INUSE; } return 0; }
BOOL CALLBACK SetToForegroundEnumProc( HWND hwnd, LPARAM lParam ) { TCHAR szBuf[MAX_INPUT];
GetWindowText (hwnd, szBuf, 128);
if (!lstrcmpi (szBuf, (LPTSTR)lParam)) { SetForegroundWindow (hwnd); return FALSE; }
return TRUE; }
extern "C" LONG WINAPI internalConfig( HWND hwndParent, PCWSTR pwsz, INT iTab, DWORD dwAPIVersion ) { CDialingRulesPropSheet drps(pwsz, dwAPIVersion);
return drps.DoPropSheet(hwndParent, iTab); }
// ********************************************************************
//
// Dialing Rules Property Page functions
//
// ********************************************************************
INT_PTR CALLBACK CDialingRulesPropSheet::Dailing_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { CDialingRulesPropSheet* pthis = (CDialingRulesPropSheet*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch(uMsg) { case WM_INITDIALOG: pthis = (CDialingRulesPropSheet*)(((PROPSHEETPAGE*)lParam)->lParam); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis); return pthis->Dailing_OnInitDialog(hwndDlg);
case WM_COMMAND: return pthis->Dailing_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam );
case WM_NOTIFY: return pthis->Dailing_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) a101HelpIDs); break; case WM_CONTEXTMENU: // Process right-clicks on controls
WinHelp ((HWND) wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a101HelpIDs); break; }
return 0; }
int CALLBACK Dialing_ListSort(LPARAM lItem1, LPARAM lItem2, LPARAM lCol) { if (!lItem1) { return -1; } if (!lItem2) { return 1; }
CLocation * pLoc1 = (CLocation *)lItem1; CLocation * pLoc2 = (CLocation *)lItem2;
if ( 1 == lCol) { // sort based on column 1, the area code
int iAC1 = StrToIntW(pLoc1->GetAreaCode()); int iAC2 = StrToIntW(pLoc2->GetAreaCode());
if (iAC1!=iAC2) return iAC1-iAC2;
// fall through if the area codes are identical
}
// sort based on column 0, the location name
return StrCmpIW(pLoc1->GetName(), pLoc2->GetName()); }
BOOL CDialingRulesPropSheet::Dailing_OnInitDialog(HWND hDlg) { // Setup the header for the list control
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_LOCATION, 70 }, { IDS_AREACODE, 30 }, };
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);
HIMAGELIST himl = ImageList_Create(16, 16, ILC_COLOR|ILC_MASK, 2, 2); HBITMAP hBmp = CreateMappedBitmap(GetUIInstance(), IDB_BUTTONS, 0, NULL, 0); if (NULL != hBmp) { ImageList_AddMasked( himl, hBmp, CLR_DEFAULT); DeleteObject( hBmp ); } ListView_SetImageList(hwndList, himl, LVSIL_SMALL);
m_locs.Reset();
CLocation * pLoc; DWORD dwCurLocID = m_locs.GetCurrentLocationID();
while ( S_OK == m_locs.Next( 1, &pLoc, NULL ) ) { AddLocationToList( hwndList, pLoc, FALSE );
if ( pLoc->GetLocationID() == dwCurLocID ) { m_dwDefaultCountryID = pLoc->GetCountryID(); } }
int iItems = m_locs.GetNumLocations();
UpdateControlStates(hDlg);
ListView_SortItems( hwndList, Dialing_ListSort, m_iSortCol);
SetCheck(hwndList, m_pLocSelected, TRUE);
if (!m_pwszAddress) { ShowWindow(GetDlgItem(hDlg,IDC_PHONENUMBERTEXT), SW_HIDE); } else if (m_pLocSelected) { UpdateSampleString(GetDlgItem(hDlg, IDC_PHONENUMBERSAMPLE), m_pLocSelected, m_pwszAddress, NULL); }
// Select the default item from the location list:
SetFocus(hwndList);
return 0; }
void CDialingRulesPropSheet::UpdateControlStates(HWND hDlg) { int iItems = m_locs.GetNumLocations();
// Set the button states
EnableWindow( GetDlgItem(hDlg, IDC_EDIT), 0!=m_pLocSelected ); EnableWindow( GetDlgItem(hDlg, IDC_SETDEFAULT), 0!=m_pLocSelected );
// if nothing is selected or there is only one item then you cannot
// delete that item
EnableWindow( GetDlgItem(hDlg, IDC_DELETE), ((m_pLocSelected)&&(1<iItems)) ); }
void CDialingRulesPropSheet::AddLocationToList(HWND hwndList, CLocation *pLoc, BOOL bSelected) { TCHAR szText[MAX_INPUT]; SHUnicodeToTChar( pLoc->GetName(), szText, ARRAYSIZE(szText) );
LVITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvi.iItem = 0; lvi.iSubItem = 0; lvi.pszText = szText; lvi.iImage = 0; lvi.lParam = (LONG_PTR)pLoc;
bSelected = bSelected || (pLoc->GetLocationID() == m_locs.GetCurrentLocationID()); if ( bSelected ) { // Set m_pLocSelected to the current location. It will be selected later.
lvi.mask |= LVIF_STATE; lvi.state = lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED; lvi.iImage = 1; SetCheck(hwndList, m_pLocSelected, FALSE); m_pLocSelected = pLoc; }
int iItem = ListView_InsertItem( hwndList, &lvi );
SHUnicodeToTChar( pLoc->GetAreaCode(), szText, ARRAYSIZE(szText) ); ListView_SetItemText( hwndList, iItem, 1, szText ); }
void CDialingRulesPropSheet::UpdateLocationInList(HWND hwndList, CLocation *pLocOld, CLocation *pLocNew) { LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = (LPARAM)pLocOld; int iItem = ListView_FindItem(hwndList,-1,&lvfi);
if (-1 != iItem && pLocNew) { TCHAR szText[MAX_INPUT]; SHUnicodeToTChar( pLocNew->GetName(), szText, ARRAYSIZE(szText) );
LVITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iItem = iItem; lvi.iSubItem = 0; lvi.pszText = szText; lvi.lParam = (LONG_PTR)pLocNew;
ListView_SetItem( hwndList, &lvi );
SHUnicodeToTChar( pLocNew->GetAreaCode(), szText, ARRAYSIZE(szText) ); ListView_SetItemText( hwndList, iItem, 1, szText ); } else { ListView_DeleteItem(hwndList, iItem); } }
BOOL CDialingRulesPropSheet::Dailing_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl) { switch ( wID ) { case IDC_NEW: case IDC_EDIT: LaunchLocationPropSheet(IDC_NEW == wID, hwndParent); break;
case IDC_DELETE: DeleteSelectedLocation(GetDlgItem(hwndParent,IDC_LIST)); break;
default: return 0; } return 1; }
void CDialingRulesPropSheet::LaunchLocationPropSheet( BOOL bNew, HWND hwndParent ) { CLocation * pLoc = new CLocation;
if (NULL == pLoc) { return; } if ( bNew ) { WCHAR wszNewLoc[MAX_INPUT];
// We offer the default name "My Location" only if there are no locations alread defined.
if ( m_locs.GetNumLocations() > 0 ) { wszNewLoc[0] = TEXT('\0'); } else { TCHAR szNewLoc[MAX_INPUT];
LoadString(GetUIInstance(), IDS_MYLOCATION, szNewLoc, ARRAYSIZE(szNewLoc)); SHTCharToUnicode(szNewLoc, wszNewLoc, ARRAYSIZE(wszNewLoc)); } pLoc->Initialize(wszNewLoc,L"",L"",L"",L"",L"",L"",0,m_dwDefaultCountryID,0,LOCATION_USETONEDIALING); } else if (m_pLocSelected) { CAreaCodeRule * pRule;
pLoc->Initialize( m_pLocSelected->GetName(), m_pLocSelected->GetAreaCode(), m_pLocSelected->GetLongDistanceCarrierCode(), m_pLocSelected->GetInternationalCarrierCode(), m_pLocSelected->GetLongDistanceAccessCode(), m_pLocSelected->GetLocalAccessCode(), m_pLocSelected->GetDisableCallWaitingCode(), m_pLocSelected->GetLocationID(), m_pLocSelected->GetCountryID(), m_pLocSelected->GetPreferredCardID(), 0, m_pLocSelected->FromRegistry() ); pLoc->UseCallingCard(m_pLocSelected->HasCallingCard()); pLoc->UseCallWaiting(m_pLocSelected->HasCallWaiting()); pLoc->UseToneDialing(m_pLocSelected->HasToneDialing());
m_pLocSelected->ResetRules(); while ( S_OK == m_pLocSelected->NextRule(1,&pRule,NULL) ) { CAreaCodeRule * pNewRule = new CAreaCodeRule;
if (NULL == pNewRule) { // No more memory, so get out of the loop.
break; } pNewRule->Initialize( pRule->GetAreaCode(), pRule->GetNumberToDial(), 0, pRule->GetPrefixList(), pRule->GetPrefixListSize() ); pNewRule->SetAppliesToAllPrefixes(pRule->HasAppliesToAllPrefixes()); pNewRule->SetDialAreaCode(pRule->HasDialAreaCode()); pNewRule->SetDialNumber(pRule->HasDialNumber());
pLoc->AddRule(pNewRule); pLoc->Changed(); } } else { // Out of memory, failed to create pLoc
delete pLoc; return; }
CLocationPropSheet nlps( bNew, pLoc, &m_locs, m_pwszAddress ); int iRes = nlps.DoPropSheet(hwndParent);
if ( PSN_APPLY == iRes ) { HWND hwndList = GetDlgItem(hwndParent,IDC_LIST); if (bNew) { // we don't ask for an ID until we really need it to avoid hitting tapisrv
// any more than we have to.
pLoc->NewID(); m_locs.Add(pLoc); AddLocationToList(hwndList, pLoc, TRUE); UpdateControlStates(hwndParent); } else { m_locs.Replace(m_pLocSelected, pLoc); UpdateLocationInList(hwndList, m_pLocSelected, pLoc); m_pLocSelected = pLoc; } ListView_SortItems( hwndList, Dialing_ListSort, m_iSortCol);
if ( m_pwszAddress ) { UpdateSampleString(GetDlgItem(hwndParent, IDC_PHONENUMBERSAMPLE), m_pLocSelected, m_pwszAddress, NULL); } SendMessage(GetParent(hwndParent),PSM_CHANGED,(WPARAM)hwndParent,0); } else { delete pLoc; } }
void CDialingRulesPropSheet::DeleteSelectedLocation(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_DELETELOCTEXT, szText, ARRAYSIZE(szText)); LoadString(GetUIInstance(), IDS_CONFIRMDELETE, szTitle, ARRAYSIZE(szTitle));
result = SHMessageBoxCheck( hwndParent, szText, szTitle, MB_YESNO, IDYES, TEXT("TAPIDeleteLocation") ); if ( IDYES == result ) { LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = (LPARAM)m_pLocSelected; int iItem = ListView_FindItem(hwndList,-1,&lvfi); if ( -1 != iItem ) { m_locs.Remove(m_pLocSelected); iItem = DeleteItemAndSelectPrevious( hwndParent, IDC_LIST, iItem, IDC_DELETE, IDC_ADD );
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_pLocSelected = (CLocation *)lvi.lParam; } else { m_pLocSelected = NULL; }
UpdateControlStates(hwndParent); SendMessage(GetParent(hwndParent),PSM_CHANGED,(WPARAM)hwndParent,0); } else { // It's really bad if this ever happens (which it shouldn't). This means our
// data is in an unknown state and we might do anything (even destroy data).
LOG((TL_ERROR, "DeleteSelectedLocation: Location Not Found!")); } } }
void CDialingRulesPropSheet::SetCheck(HWND hwndList, CLocation * pLoc, int iImage) { LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = (LPARAM)pLoc; int iItem = ListView_FindItem(hwndList,-1,&lvfi);
if (-1 != iItem) { LVITEM lvi; lvi.mask = LVIF_IMAGE; lvi.iItem = iItem; lvi.iSubItem = 0; lvi.iImage = iImage;
ListView_SetItem( hwndList, &lvi ); ListView_EnsureVisible (hwndList, iItem, TRUE); ListView_Update( hwndList, iItem ); // need the font to be drawn non-bold
} }
BOOL CDialingRulesPropSheet::Dailing_OnNotify(HWND hwndDlg, LPNMHDR pnmhdr) { switch (pnmhdr->idFrom) { case IDC_LIST: #define pnmlv ((LPNMLISTVIEW)pnmhdr)
switch (pnmhdr->code) { case LVN_ITEMCHANGED: if ( (pnmlv->uChanged & LVIF_STATE) && (pnmlv->uNewState & LVIS_SELECTED) ) { LVITEM lvi; lvi.iItem = pnmlv->iItem; lvi.iSubItem = pnmlv->iSubItem; lvi.mask = LVIF_PARAM; ListView_GetItem( pnmhdr->hwndFrom, &lvi ); CLocation * pLoc = (CLocation *)lvi.lParam;
// pLoc can be NULL if this is our special "empty list item"
if ( pLoc ) { m_dwDefaultCountryID = pLoc->GetCountryID(); m_locs.SetCurrentLocationID(pLoc->GetLocationID());
// clear the previous check
SetCheck( pnmhdr->hwndFrom, m_pLocSelected, FALSE );
// Store the currently selected item
m_pLocSelected = pLoc;
// Set the new check
SetCheck( pnmhdr->hwndFrom, m_pLocSelected, TRUE );
if (m_pwszAddress) { UpdateSampleString(GetDlgItem(hwndDlg, IDC_PHONENUMBERSAMPLE), m_pLocSelected, m_pwszAddress, NULL); } }
UpdateControlStates(hwndDlg); SendMessage(GetParent(hwndDlg),PSM_CHANGED,(WPARAM)hwndDlg,0); } break;
case NM_DBLCLK: if ( !m_pLocSelected ) { // Do new case
LaunchLocationPropSheet(TRUE,hwndDlg); } else { // Do edit case
LaunchLocationPropSheet(FALSE,hwndDlg); } break;
case NM_CUSTOMDRAW: #define lplvcd ((LPNMLVCUSTOMDRAW)pnmhdr)
if(lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT) { // Request prepaint notifications for each item.
SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYITEMDRAW); return CDRF_NOTIFYITEMDRAW; }
if(lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { LVITEM lvi; lvi.iItem = (int)lplvcd->nmcd.dwItemSpec; lvi.iSubItem = 0; lvi.mask = LVIF_PARAM; ListView_GetItem( pnmhdr->hwndFrom, &lvi ); CLocation * pLoc = (CLocation *)lvi.lParam;
// pLoc can be NULL if this is our special item
if(pLoc && pLoc->GetLocationID() == m_locs.GetCurrentLocationID()) { if (!g_hfontBold) { // we do lazy creation of the font because we need to match whatever
// font the listview control is using and we can't tell which font
// that is until we actually have the HDC for the listbox.
LOGFONT lf; HFONT hfont = (HFONT)GetCurrentObject(lplvcd->nmcd.hdc, OBJ_FONT); GetObject(hfont, sizeof(LOGFONT), &lf); lf.lfWeight += FW_BOLD-FW_NORMAL; g_hfontBold = CreateFontIndirect(&lf); } if (g_hfontBold) { SelectObject(lplvcd->nmcd.hdc, g_hfontBold); SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NEWFONT); return CDRF_NEWFONT; } }
SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_DODEFAULT); return CDRF_DODEFAULT; } return 0; #undef lplvcd
case LVN_COLUMNCLICK: m_iSortCol = pnmlv->iSubItem; ListView_SortItems( pnmhdr->hwndFrom, Dialing_ListSort, m_iSortCol); break;
case LVN_GETEMPTYTEXT: #define pnmlvi (((NMLVDISPINFO *)pnmhdr)->item)
LoadString(GetUIInstance(), IDS_CLICKNEW, pnmlvi.pszText, pnmlvi.cchTextMax); SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,TRUE); #undef pnmlvi
break;
default: break; } #undef pnmlv
break;
default: switch (pnmhdr->code) { case PSN_APPLY: // TODO: Ensure that a location is selected in the list
m_locs.SaveToRegistry(); break; } return 0; } return 1; }
// ********************************************************************
//
// Advanced Property Page functions (formerly Telephony Drivers page)
//
// ********************************************************************
#include "drv.h"
INT_PTR CALLBACK CDialingRulesPropSheet::Advanced_DialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { CDialingRulesPropSheet* pthis = (CDialingRulesPropSheet*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch(uMsg) { case WM_INITDIALOG: pthis = (CDialingRulesPropSheet*)(((PROPSHEETPAGE*)lParam)->lParam); SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis); return pthis->Advanced_OnInitDialog(hwndDlg);
case WM_COMMAND: return pthis->Advanced_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)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) a113HelpIDs); break; case WM_CONTEXTMENU: // Process right-clicks on controls
WinHelp ((HWND) wParam, gszHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) a113HelpIDs); break; }
return 0; }
BOOL CDialingRulesPropSheet::Advanced_OnInitDialog(HWND hDlg) { UINT uUpdated;
if ( !FillDriverList(GetDlgItem(hDlg, IDC_LIST)) ) { EndDialog(hDlg, IDCANCEL); return FALSE; }
// DWLP_USER is used to store state information about wheter we have disabled
// the property sheet's cancel button. For starters we have not done this.
SetWindowLong( hDlg, DWLP_USER, FALSE );
UpdateDriverDlgButtons (hDlg);
return TRUE; }
BOOL CDialingRulesPropSheet::Advanced_OnCommand(HWND hwndParent, int wID, int wNotifyCode, HWND hwndCrl) { switch (wID) { case IDC_ADD: // add a new driver
if ( IDOK == DialogBoxParam( GetUIInstance(), MAKEINTRESOURCE( IDD_ADD_DRIVER ), hwndParent, AddDriver_DialogProc, 0 ) ) { FillDriverList(GetDlgItem(hwndParent, IDC_LIST));
if (SetWindowLong(hwndParent, DWLP_USER, TRUE) == FALSE) { // We have performed a non-cancelable action, update the property sheet to reflect this
PropSheet_CancelToClose( GetParent( hwndParent ) ); }
UpdateDriverDlgButtons(hwndParent);
} // end if
break;
case IDC_LIST: if ( LBN_SELCHANGE == wNotifyCode ) { UpdateDriverDlgButtons(hwndParent); break; } else if ( LBN_DBLCLK != wNotifyCode || !IsWindowEnabled( GetDlgItem( hwndParent, IDC_EDIT ) )) { // we only fall through if the user double clicked on an editable item
break; }
// fall through
case IDC_EDIT: if ( SetupDriver(hwndParent, GetDlgItem(hwndParent, IDC_LIST)) ) { if ( SetWindowLong( hwndParent, DWLP_USER, TRUE ) == FALSE ) // modified
{ PropSheet_CancelToClose( GetParent(hwndParent) ); } }
break;
case IDC_REMOVE: { TCHAR szCaption[MAX_INPUT]; TCHAR szMessage[512];
LoadString(GetUIInstance(), IDS_REMOVEPROVIDER, szCaption, ARRAYSIZE(szCaption)); LoadString(GetUIInstance(), IDS_CONFIRM_DRIVER_REMOVE, szMessage, ARRAYSIZE(szMessage)); MessageBeep( MB_ICONASTERISK ); if ( IDYES == MessageBox(hwndParent, szMessage, szCaption, MB_YESNO | MB_DEFBUTTON2) ) { if (SetWindowLong (hwndParent, DWLP_USER, TRUE) == FALSE) // modified
{ PropSheet_CancelToClose( GetParent( hwndParent ) ); }
RemoveSelectedDriver( hwndParent, GetDlgItem(hwndParent, IDC_LIST) );
UpdateDriverDlgButtons (hwndParent); } } break; }
return 1; }
HINSTANCE GetUIInstance() { if ( NULL == g_hInstUI ) { g_hInstUI = LoadLibrary(TEXT("tapiui.dll")); // g_hInstUI = GetModuleHandle(TEXT("tapi32.dll"));
}
return g_hInstUI; }
LONG EnsureOneLocation (HWND hwnd) { CLocations locs;
locs.Initialize();
// If there are no locations, launch the simple location dialog
if ( 0 == locs.GetNumLocations() ) { // if we are in lineTranslateDialog mode, then we display the simple
int iRes; iRes = (int)DialogBoxParam(GetUIInstance(), MAKEINTRESOURCE(IDD_SIMPLELOCATION),hwnd, LocWizardDlgProc, (LPARAM)TAPI_VERSION2_2);
if ( IDOK == iRes ) { // now we need to re-initalize to pick up the new location
locs.Initialize();
// Now we need to figure out the ID of the location we just created
CLocation * pLoc; locs.Reset(); if ( S_OK == locs.Next( 1, &pLoc, NULL ) ) { // Set this ID as the default location
locs.SetCurrentLocationID(pLoc->GetLocationID()); CountryRunOnce(); }
// we've already made a commited change, so save the result
locs.SaveToRegistry(); } else { return LINEERR_USERCANCELLED; } }
return S_OK; }
void CountryRunOnce() { //
// This is soft modem workaround provided by unimodem team.
//
// 1. Some vendors set the GCI code incorrectly based on the TAPI location
// key (which is a bad thing L)
// 2. Some modems do not conform to GCI
// 3. Some modems do not correctly accept AT+GCI commands.
// (+GCI is Modems AT commands for setting country)
//
// The conformance check ensures the GCI value is properly sync
// with the TAPI location. It disables GCI if the modem does not conform
// to the GCI spec.
//
// This function can take as long as 15 seconds. We should make sure the UI
// doesn't appear to hang during the call.
//
typedef void (*COUNTRYRUNONCE)(); HMODULE hLib;
hLib=LoadLibrary(TEXT("modemui.dll"));
if (hLib != NULL) {
COUNTRYRUNONCE Proc;
Proc=(COUNTRYRUNONCE)GetProcAddress(hLib,"CountryRunOnce");
if (Proc != NULL) { Proc(); }
FreeLibrary(hLib); } }
|