Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1661 lines
51 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: pb.cpp
  4. //
  5. // Module: CMDIAL32.DLL
  6. //
  7. // Synopsis: Handle the phone book dialog and call cmpbk32.dll.
  8. //
  9. // Copyright (c) 1998-1999 Microsoft Corporation
  10. //
  11. // Author: fengsun Created Header 1/14/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. #define MAX_PB_WAIT 30000 // max miliiseconds to wait for PB mutex
  16. //+----------------------------------------------------------------------------
  17. //
  18. // Function: ExtendArray
  19. //
  20. // Synopsis: Increase the array for one element as the size nSize
  21. // Reallocate and copy *ppvArray and increase *pnCount
  22. //
  23. // Arguments: void **ppvArray - the point to the array pointer
  24. // size_t nSize - the size of one element
  25. // UINT *pnCount - the number of element currently in the array
  26. //
  27. // Returns:
  28. //
  29. // History: feng sun Created Header 1/14/98
  30. //
  31. //+----------------------------------------------------------------------------
  32. static void ExtendArray(IN OUT void **ppvArray, size_t nSize, IN OUT UINT *pnCount)
  33. {
  34. void *pvTmp;
  35. if (NULL != ppvArray && NULL != pnCount)
  36. {
  37. pvTmp = CmMalloc(nSize*(*pnCount+1));
  38. if (NULL != pvTmp)
  39. {
  40. CopyMemory(pvTmp,*ppvArray,nSize*(*pnCount));
  41. CmFree(*ppvArray);
  42. *ppvArray = pvTmp;
  43. (*pnCount)++;
  44. }
  45. }
  46. }
  47. //+---------------------------------------------------------------------------
  48. //
  49. // struct ServiceInfo
  50. //
  51. // Synopsis: Save the information of a service under .cms [Service Types]
  52. //
  53. // History: fengsun created 1/14/97
  54. //
  55. //----------------------------------------------------------------------------
  56. typedef struct tagServiceInfo
  57. {
  58. DWORD_PTR dwPB;
  59. UINT nServiceString;
  60. PPBFS pFilter;
  61. PPBFS pFilterA;
  62. PPBFS pFilterB;
  63. LPTSTR pszFile;
  64. } ServiceInfo;
  65. class CPhoneBookInfo
  66. {
  67. public:
  68. CPhoneBookInfo();
  69. ~CPhoneBookInfo();
  70. BOOL Load(LPCTSTR pszFile, BOOL fHasValidTopLevelPBK, BOOL fHasValidReferencedPBKs);
  71. void LoadServiceTypes(HWND hwndDlg, UINT nIdServiceType, LPCTSTR pszServiceType);
  72. void LoadCountries(HWND hwndDlg, UINT nIdCountry, DWORD dwCountryId);
  73. void LoadRegions(HWND hwndDlg, UINT nIdRegion, LPCTSTR pszRegionName);
  74. void LoadNumbers(HWND hwndDlg,
  75. UINT nIdNumberA,
  76. UINT nIdNumberB,
  77. UINT nIdMore,
  78. LPCTSTR pszPhoneNumber,
  79. LPCTSTR pszPhoneBookFile);
  80. //BOOL GetDisp(DWORD dwCookie, LPTSTR pszDisp, DWORD *pdwDisp);
  81. BOOL GetDesc(DWORD dwCookie, LPTSTR pszDesc, DWORD *pdwDesc);
  82. BOOL HasMoreNumbers();
  83. BOOL GetCanonical(DWORD dwCookie, LPTSTR pszCanonical, DWORD *pdwCanonical);
  84. BOOL GetNonCanonical(DWORD dwCookie, LPTSTR pszNonCanonical, DWORD *pdwNonCanonical);
  85. LPCTSTR GetFile(DWORD dwCookie);
  86. BOOL GetDUN(DWORD dwCookie, LPTSTR pszDUN, DWORD *pdwDUN);
  87. private:
  88. BOOL LoadFile(LPCTSTR pszFile, PPBFS pFilterA, PPBFS pFilterB);
  89. BOOL ServiceCB(LPCTSTR pszSvc,
  90. PPBFS pFilter,
  91. PPBFS pFilterA,
  92. PPBFS pFilterB,
  93. DWORD dwPB,
  94. LPCTSTR pszFile);
  95. void LoadRegionsCB(unsigned int nIdx, DWORD_PTR dwParam);
  96. void LoadNumbersCB(unsigned int nIdx, DWORD_PTR dwParam);
  97. void LoadCountriesA(HWND hwndDlg, UINT nIdCountry, DWORD dwCountryId);
  98. void LoadCountriesW(HWND hwndDlg, UINT nIdCountry, DWORD dwCountryId);
  99. CPBMap m_Map;
  100. UINT m_nServiceString;
  101. LPTSTR *m_ppszServiceString;
  102. UINT m_nServiceInfo; // the number of elements in m_psiServiceInfo
  103. ServiceInfo *m_psiServiceInfo; // a array to save the information of all the services
  104. // under [Service Types]
  105. UINT m_nIdServiceType;
  106. UINT m_nIdCountry;
  107. UINT m_nIdRegion;
  108. UINT *m_pnRegionIdx;
  109. UINT m_nRegionIdx;
  110. typedef struct {
  111. CPhoneBookInfo *pInfo;
  112. PPBFS pFilterA;
  113. PPBFS pFilterB;
  114. DWORD dwPB;
  115. LPCSTR pszFile;
  116. } SCBS;
  117. friend BOOL WINAPI _ServiceCB(LPCSTR pszSvc, PPBFS pFilter, DWORD_PTR dwParam);
  118. friend BOOL WINAPI _ReferenceCB(LPCSTR pszFile,
  119. LPCSTR pszURL,
  120. PPBFS pFilterA,
  121. PPBFS pFilterB,
  122. DWORD_PTR dwParam);
  123. friend void WINAPI _LoadRegionsCB(unsigned int nIdx, DWORD_PTR dwParam);
  124. friend void WINAPI _LoadNumbersCB(unsigned int nIdx, DWORD_PTR dwParam);
  125. };
  126. LPCTSTR CPhoneBookInfo::GetFile(DWORD dwCookie)
  127. {
  128. DWORD dwParam;
  129. CMTRACE(TEXT("CPhoneBookInfo::GetFile"));
  130. DWORD_PTR dwPB = m_Map.PBFromCookie(dwCookie, &dwParam);
  131. if (dwPB == CPBMAP_ERROR)
  132. {
  133. return (TEXT(""));
  134. }
  135. MYDBGASSERT(dwParam < m_nServiceInfo);
  136. return (m_psiServiceInfo[dwParam].pszFile);
  137. }
  138. /*
  139. BOOL CPhoneBookInfo::GetDisp(DWORD dwCookie, LPTSTR pszDisp, DWORD *pdwDisp)
  140. {
  141. MYDBG(("CPhoneBookInfo::GetDisp"));
  142. return (PhoneBookGetPhoneDisp(m_Map.PBFromCookie(dwCookie),m_Map.IdxFromCookie(dwCookie),pszDisp,pdwDisp));
  143. }
  144. */
  145. BOOL CPhoneBookInfo::GetDesc(DWORD dwCookie, LPTSTR pszDesc, DWORD *pdwDesc)
  146. {
  147. #ifdef UNICODE
  148. BOOL bReturn = FALSE;
  149. DWORD dwSize = *pdwDesc;
  150. LPSTR pszAnsiDesc = (LPSTR)CmMalloc(dwSize);
  151. if (pszAnsiDesc)
  152. {
  153. bReturn = PhoneBookGetPhoneDesc(m_Map.PBFromCookie(dwCookie), m_Map.IdxFromCookie(dwCookie), pszAnsiDesc, pdwDesc);
  154. MYVERIFY(0 != MultiByteToWideChar(CP_ACP, 0, pszAnsiDesc, -1, pszDesc, dwSize));
  155. CmFree(pszAnsiDesc);
  156. }
  157. return bReturn;
  158. #else
  159. return (PhoneBookGetPhoneDesc(m_Map.PBFromCookie(dwCookie),m_Map.IdxFromCookie(dwCookie),pszDesc,pdwDesc));
  160. #endif
  161. }
  162. BOOL CPhoneBookInfo::GetCanonical(DWORD dwCookie, LPTSTR pszCanonical, DWORD *pdwCanonical)
  163. {
  164. #ifdef UNICODE
  165. BOOL bReturn = FALSE;
  166. DWORD dwSize = *pdwCanonical;
  167. LPSTR pszAnsiCanonical = (LPSTR)CmMalloc(dwSize);
  168. if (pszAnsiCanonical)
  169. {
  170. bReturn = PhoneBookGetPhoneCanonical(m_Map.PBFromCookie(dwCookie), m_Map.IdxFromCookie(dwCookie),
  171. pszAnsiCanonical, pdwCanonical);
  172. MYVERIFY(0 != MultiByteToWideChar(CP_ACP, 0, pszAnsiCanonical, -1, pszCanonical, dwSize));
  173. CmFree(pszAnsiCanonical);
  174. }
  175. return bReturn;
  176. #else
  177. return (PhoneBookGetPhoneCanonical(m_Map.PBFromCookie(dwCookie), m_Map.IdxFromCookie(dwCookie),
  178. pszCanonical, pdwCanonical));
  179. #endif
  180. }
  181. BOOL CPhoneBookInfo::GetNonCanonical(DWORD dwCookie, LPTSTR pszNonCanonical, DWORD *pdwNonCanonical)
  182. {
  183. #ifdef UNICODE
  184. BOOL bReturn = FALSE;
  185. DWORD dwSize = *pdwNonCanonical;
  186. LPSTR pszAnsiNonCanonical = (LPSTR)CmMalloc(dwSize);
  187. if (pszAnsiNonCanonical)
  188. {
  189. bReturn = PhoneBookGetPhoneNonCanonical(m_Map.PBFromCookie(dwCookie), m_Map.IdxFromCookie(dwCookie),
  190. pszAnsiNonCanonical, pdwNonCanonical);
  191. MYVERIFY(0 != MultiByteToWideChar(CP_ACP, 0, pszAnsiNonCanonical, -1, pszNonCanonical, dwSize));
  192. CmFree(pszAnsiNonCanonical);
  193. }
  194. return bReturn;
  195. #else
  196. return (PhoneBookGetPhoneNonCanonical(m_Map.PBFromCookie(dwCookie),m_Map.IdxFromCookie(dwCookie),pszNonCanonical,pdwNonCanonical));
  197. #endif
  198. }
  199. BOOL CPhoneBookInfo::GetDUN(DWORD dwCookie, LPTSTR pszDUN, DWORD *pdwDUN)
  200. {
  201. #ifdef UNICODE
  202. BOOL bReturn = FALSE;
  203. DWORD dwSize = *pdwDUN;
  204. LPSTR pszAnsiDUN = (LPSTR)CmMalloc(dwSize);
  205. if (pszAnsiDUN)
  206. {
  207. bReturn = PhoneBookGetPhoneDUN(m_Map.PBFromCookie(dwCookie), m_Map.IdxFromCookie(dwCookie),
  208. pszAnsiDUN, pdwDUN);
  209. MYVERIFY(0 != MultiByteToWideChar(CP_ACP, 0, pszAnsiDUN, -1, pszDUN, dwSize));
  210. CmFree(pszAnsiDUN);
  211. }
  212. return bReturn;
  213. #else
  214. return (PhoneBookGetPhoneDUN(m_Map.PBFromCookie(dwCookie), m_Map.IdxFromCookie(dwCookie),
  215. pszDUN, pdwDUN));
  216. #endif
  217. }
  218. CPhoneBookInfo::CPhoneBookInfo()
  219. {
  220. m_nServiceString = 0;
  221. m_ppszServiceString = NULL;
  222. m_nServiceInfo = 0;
  223. m_psiServiceInfo = NULL;
  224. m_pnRegionIdx = NULL;
  225. m_nRegionIdx = 0;
  226. }
  227. CPhoneBookInfo::~CPhoneBookInfo()
  228. {
  229. while (m_nServiceString)
  230. {
  231. CmFree(m_ppszServiceString[--m_nServiceString]);
  232. }
  233. CmFree(m_ppszServiceString);
  234. m_ppszServiceString = NULL;
  235. while (m_nServiceInfo)
  236. {
  237. PhoneBookFreeFilter(m_psiServiceInfo[m_nServiceInfo-1].pFilter);
  238. PhoneBookFreeFilter(m_psiServiceInfo[m_nServiceInfo-1].pFilterA);
  239. PhoneBookFreeFilter(m_psiServiceInfo[m_nServiceInfo-1].pFilterB);
  240. CmFree(m_psiServiceInfo[m_nServiceInfo-1].pszFile);
  241. m_nServiceInfo--;
  242. }
  243. CmFree(m_psiServiceInfo);
  244. m_psiServiceInfo = NULL;
  245. CmFree(m_pnRegionIdx);
  246. m_pnRegionIdx = NULL;
  247. m_nRegionIdx = 0;
  248. }
  249. BOOL PhoneBookParseInfoWrapper(LPCTSTR pszFile, PhoneBookParseInfoStruct* piInfo)
  250. {
  251. #ifdef UNICODE
  252. BOOL bReturn;
  253. LPSTR pszAnsiFile = WzToSzWithAlloc(pszFile);
  254. if (NULL == pszAnsiFile)
  255. {
  256. return FALSE;
  257. }
  258. else
  259. {
  260. bReturn = PhoneBookParseInfo(pszAnsiFile, piInfo);
  261. CmFree(pszAnsiFile);
  262. }
  263. return bReturn;
  264. #else
  265. return PhoneBookParseInfo(pszFile, piInfo);
  266. #endif
  267. }
  268. BOOL CPhoneBookInfo::Load(LPCTSTR pszFile, BOOL fHasValidTopLevelPBK, BOOL fHasValidReferencedPBKs)
  269. {
  270. PhoneBookParseInfoStruct iInfo;
  271. BOOL bRes = FALSE;
  272. CMTRACE(TEXT("CPhoneBookInfo::Load"));
  273. CmFree(m_pnRegionIdx);
  274. m_pnRegionIdx = NULL;
  275. m_nRegionIdx = 0;
  276. if (!pszFile)
  277. {
  278. SetLastError(ERROR_INVALID_PARAMETER);
  279. return (FALSE);
  280. }
  281. ZeroMemory(&iInfo,sizeof(iInfo));
  282. iInfo.dwSize = sizeof(iInfo);
  283. if (fHasValidTopLevelPBK)
  284. {
  285. if (!PhoneBookParseInfoWrapper(pszFile,&iInfo))
  286. {
  287. return (FALSE);
  288. }
  289. bRes = LoadFile(pszFile,iInfo.pFilterA,iInfo.pFilterB);
  290. PhoneBookFreeFilter(iInfo.pFilterA);
  291. PhoneBookFreeFilter(iInfo.pFilterB);
  292. if (!bRes)
  293. {
  294. return (FALSE);
  295. }
  296. }
  297. if (fHasValidReferencedPBKs)
  298. {
  299. iInfo.pfnRef = _ReferenceCB;
  300. iInfo.dwRefParam = (DWORD_PTR) this;
  301. if (!PhoneBookParseInfoWrapper(pszFile,&iInfo))
  302. {
  303. return (FALSE);
  304. }
  305. PhoneBookFreeFilter(iInfo.pFilterA);
  306. PhoneBookFreeFilter(iInfo.pFilterB);
  307. }
  308. return (TRUE);
  309. }
  310. void CPhoneBookInfo::LoadServiceTypes(HWND hwndDlg, UINT nIdServiceType, LPCTSTR pszServiceType)
  311. {
  312. UINT nIdx;
  313. UINT nTmpIdx;
  314. CMTRACE(TEXT("CPhoneBookInfo::LoadServiceTypes"));
  315. CmFree(m_pnRegionIdx);
  316. m_pnRegionIdx = NULL;
  317. m_nRegionIdx = 0;
  318. m_nIdServiceType = nIdServiceType;
  319. SendDlgItemMessageU(hwndDlg, nIdServiceType, CB_RESETCONTENT,0,0);
  320. for (nIdx=0; nIdx < m_nServiceString; nIdx++)
  321. {
  322. nTmpIdx = (UINT) SendDlgItemMessageU(hwndDlg, nIdServiceType, CB_ADDSTRING, 0, (LPARAM) m_ppszServiceString[nIdx]);
  323. SendDlgItemMessageU(hwndDlg, nIdServiceType, CB_SETITEMDATA, nTmpIdx, nIdx);
  324. }
  325. if (SendDlgItemMessageU(hwndDlg, nIdServiceType, CB_GETCOUNT, 0, 0) > 1)
  326. {
  327. LPTSTR pszDesc = NULL;
  328. EnableWindow(GetDlgItem(hwndDlg, nIdServiceType), TRUE);
  329. //
  330. // If the service type is empty, select the first type as a default
  331. //
  332. if ((!pszServiceType) || pszServiceType[0] == '\0')
  333. {
  334. pszDesc = CmStrCpyAlloc(m_ppszServiceString[0]);
  335. }
  336. else
  337. {
  338. pszDesc = CmStrCpyAlloc(pszServiceType);
  339. }
  340. //
  341. // Search for the specified default and if found, make it the current
  342. // selection. Previously, we did this in the loop above, but 16-bit
  343. // combos, don't remember the CURSEL when strings are added.
  344. //
  345. nTmpIdx = (UINT) SendDlgItemMessageU(hwndDlg,
  346. nIdServiceType,
  347. CB_FINDSTRINGEXACT,
  348. (WPARAM) -1,
  349. (LPARAM) pszDesc);
  350. if (nTmpIdx == CB_ERR)
  351. {
  352. nTmpIdx = 0;
  353. }
  354. SendDlgItemMessageU(hwndDlg, nIdServiceType, CB_SETCURSEL, nTmpIdx, 0);
  355. CmFree(pszDesc);
  356. }
  357. else
  358. {
  359. EnableWindow(GetDlgItem(hwndDlg, nIdServiceType), FALSE);
  360. }
  361. }
  362. typedef struct tagLoadCountriesCBStruct
  363. {
  364. DWORD_PTR dwPB;
  365. HWND hwndDlg;
  366. UINT nId;
  367. DWORD dwCountryId;
  368. } LoadCountriesCBStruct;
  369. //
  370. // Note: this function and its mirror function _LoadCountriesCBW must stay in sync
  371. //
  372. static void WINAPI _LoadCountriesCBA(unsigned int nIdx, DWORD_PTR dwParam)
  373. {
  374. LoadCountriesCBStruct *pParam = (LoadCountriesCBStruct *) dwParam;
  375. CHAR szCountry[256];
  376. UINT nTmpIdx;
  377. DWORD dwCountryId = PhoneBookGetCountryId(pParam->dwPB, nIdx);
  378. DWORD dwLen;
  379. szCountry[0] = '\0';
  380. dwLen = sizeof(szCountry) / sizeof(CHAR);
  381. PhoneBookGetCountryNameA(pParam->dwPB, nIdx, szCountry, &dwLen);
  382. wsprintfA(szCountry + lstrlenA(szCountry), " (%u)", dwCountryId);
  383. nTmpIdx = (UINT) SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM)szCountry);
  384. if (nTmpIdx != CB_ERR)
  385. {
  386. return;
  387. }
  388. nTmpIdx = (UINT) SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_ADDSTRING, 0, (LPARAM) szCountry);
  389. SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_SETITEMDATA, nTmpIdx, dwCountryId);
  390. if (pParam->dwCountryId && (dwCountryId == pParam->dwCountryId))
  391. {
  392. SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_SETCURSEL, nTmpIdx, 0);
  393. }
  394. }
  395. //
  396. // Note: this function and its mirror function _LoadCountriesCBA must stay in sync
  397. //
  398. static void WINAPI _LoadCountriesCBW(unsigned int nIdx, DWORD_PTR dwParam)
  399. {
  400. LoadCountriesCBStruct *pParam = (LoadCountriesCBStruct *) dwParam;
  401. WCHAR szCountry[256];
  402. UINT nTmpIdx;
  403. DWORD dwCountryId = PhoneBookGetCountryId(pParam->dwPB, nIdx);
  404. DWORD dwLen;
  405. szCountry[0] = L'\0';
  406. dwLen = sizeof(szCountry) / sizeof(WCHAR);
  407. PhoneBookGetCountryNameW(pParam->dwPB, nIdx, szCountry, &dwLen);
  408. wsprintfW(szCountry + lstrlenW(szCountry), L" (%u)", dwCountryId);
  409. nTmpIdx = (UINT) SendDlgItemMessageW(pParam->hwndDlg, pParam->nId, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM)szCountry);
  410. if (nTmpIdx != CB_ERR)
  411. {
  412. return;
  413. }
  414. nTmpIdx = (UINT) SendDlgItemMessageW(pParam->hwndDlg, pParam->nId, CB_ADDSTRING, 0, (LPARAM) szCountry);
  415. SendDlgItemMessageW(pParam->hwndDlg, pParam->nId, CB_SETITEMDATA, nTmpIdx, dwCountryId);
  416. if (pParam->dwCountryId && (dwCountryId == pParam->dwCountryId))
  417. {
  418. SendDlgItemMessageW(pParam->hwndDlg, pParam->nId, CB_SETCURSEL, nTmpIdx, 0);
  419. }
  420. }
  421. void CPhoneBookInfo::LoadCountries(HWND hwndDlg, UINT nIdCountry, DWORD dwCountryId)
  422. {
  423. CMTRACE(TEXT("CPhoneBookInfo::LoadCountries"));
  424. if (OS_NT51)
  425. {
  426. return LoadCountriesW(hwndDlg, nIdCountry, dwCountryId);
  427. }
  428. else
  429. {
  430. return LoadCountriesA(hwndDlg, nIdCountry, dwCountryId);
  431. }
  432. }
  433. //
  434. // Note: this function and its mirror function LoadCountriesW must stay in sync
  435. //
  436. void CPhoneBookInfo::LoadCountriesA(HWND hwndDlg, UINT nIdCountry, DWORD dwCountryId)
  437. {
  438. UINT nIdx;
  439. DWORD_PTR nServiceType;
  440. CMTRACE(TEXT("CPhoneBookInfo::LoadCountriesA"));
  441. CmFree(m_pnRegionIdx);
  442. m_pnRegionIdx = NULL;
  443. m_nRegionIdx = 0;
  444. m_nIdCountry = nIdCountry;
  445. SendDlgItemMessageA(hwndDlg, nIdCountry, CB_RESETCONTENT, 0, 0);
  446. nIdx = (UINT) SendDlgItemMessageA(hwndDlg, m_nIdServiceType, CB_GETCURSEL, 0, 0);
  447. if (nIdx == CB_ERR)
  448. {
  449. return;
  450. }
  451. nServiceType = SendDlgItemMessageA(hwndDlg, m_nIdServiceType, CB_GETITEMDATA, nIdx, 0);
  452. MYDBGASSERT(nServiceType<m_nServiceInfo);
  453. for (nIdx=0; nIdx < m_nServiceInfo; nIdx++)
  454. {
  455. if (m_psiServiceInfo[nIdx].nServiceString == nServiceType)
  456. {
  457. LoadCountriesCBStruct sParam = {m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  458. hwndDlg,
  459. nIdCountry,
  460. dwCountryId?dwCountryId:PhoneBookGetCurrentCountryId()};
  461. PhoneBookEnumCountries(m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  462. _LoadCountriesCBA,
  463. m_psiServiceInfo[nIdx].pFilter,
  464. (DWORD_PTR) &sParam);
  465. }
  466. }
  467. if ((SendDlgItemMessageA(hwndDlg,nIdCountry,CB_GETCURSEL,0,0) == CB_ERR) &&
  468. (SendDlgItemMessageA(hwndDlg,nIdCountry,CB_GETCOUNT,0,0) != 0))
  469. {
  470. SendDlgItemMessageA(hwndDlg,nIdCountry,CB_SETCURSEL,0,0);
  471. }
  472. }
  473. //
  474. // Note: this function and its mirror function LoadCountriesA must stay in sync
  475. //
  476. void CPhoneBookInfo::LoadCountriesW(HWND hwndDlg, UINT nIdCountry, DWORD dwCountryId)
  477. {
  478. UINT nIdx;
  479. DWORD_PTR nServiceType;
  480. CMTRACE(TEXT("CPhoneBookInfo::LoadCountriesW"));
  481. CmFree(m_pnRegionIdx);
  482. m_pnRegionIdx = NULL;
  483. m_nRegionIdx = 0;
  484. m_nIdCountry = nIdCountry;
  485. SendDlgItemMessageW(hwndDlg, nIdCountry, CB_RESETCONTENT, 0, 0);
  486. nIdx = (UINT) SendDlgItemMessageW(hwndDlg, m_nIdServiceType, CB_GETCURSEL, 0, 0);
  487. if (nIdx == CB_ERR)
  488. {
  489. return;
  490. }
  491. nServiceType = SendDlgItemMessageW(hwndDlg, m_nIdServiceType, CB_GETITEMDATA, nIdx, 0);
  492. MYDBGASSERT(nServiceType<m_nServiceInfo);
  493. for (nIdx=0; nIdx < m_nServiceInfo; nIdx++)
  494. {
  495. if (m_psiServiceInfo[nIdx].nServiceString == nServiceType)
  496. {
  497. LoadCountriesCBStruct sParam = {m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  498. hwndDlg,
  499. nIdCountry,
  500. dwCountryId?dwCountryId:PhoneBookGetCurrentCountryId()};
  501. PhoneBookEnumCountries(m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  502. _LoadCountriesCBW,
  503. m_psiServiceInfo[nIdx].pFilter,
  504. (DWORD_PTR) &sParam);
  505. }
  506. }
  507. if ((SendDlgItemMessageW(hwndDlg,nIdCountry,CB_GETCURSEL,0,0) == CB_ERR) &&
  508. (SendDlgItemMessageW(hwndDlg,nIdCountry,CB_GETCOUNT,0,0) != 0))
  509. {
  510. SendDlgItemMessageW(hwndDlg,nIdCountry,CB_SETCURSEL,0,0);
  511. }
  512. }
  513. typedef struct tagLoadRegionsCBStruct
  514. {
  515. CPhoneBookInfo *pPhoneBook;
  516. DWORD_PTR dwPB;
  517. HWND hwndDlg;
  518. UINT nId;
  519. LPCSTR pszRegionName;
  520. UINT nServiceInfo;
  521. } LoadRegionsCBStruct;
  522. void CPhoneBookInfo::LoadRegionsCB(unsigned int nIdx, DWORD_PTR dwParam)
  523. {
  524. UINT nTmpIdx;
  525. LoadRegionsCBStruct *pParam = (LoadRegionsCBStruct *) dwParam;
  526. CHAR szRegionName[256];
  527. DWORD dwLen;
  528. dwLen = sizeof(szRegionName) / sizeof(CHAR);
  529. PhoneBookGetRegionNameA(pParam->dwPB, nIdx, szRegionName, &dwLen);
  530. ExtendArray((void **) &m_pnRegionIdx, sizeof(*m_pnRegionIdx)*m_nServiceInfo, &m_nRegionIdx);
  531. for (nTmpIdx = 0; nTmpIdx < m_nServiceInfo; nTmpIdx++)
  532. {
  533. m_pnRegionIdx[m_nServiceInfo*(m_nRegionIdx-1) + nTmpIdx] = UINT_MAX;
  534. }
  535. nTmpIdx = (UINT) SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_FINDSTRINGEXACT, 0, (LPARAM) szRegionName);
  536. if (nTmpIdx == CB_ERR)
  537. {
  538. nTmpIdx = (UINT) SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_ADDSTRING, 0, (LPARAM) szRegionName);
  539. SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_SETITEMDATA, nTmpIdx, m_nRegionIdx - 1);
  540. if (pParam->pszRegionName && (lstrcmpA(szRegionName, pParam->pszRegionName) == 0))
  541. {
  542. SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_SETCURSEL, nTmpIdx, 0);
  543. }
  544. m_pnRegionIdx[m_nServiceInfo*(m_nRegionIdx-1) + pParam->nServiceInfo] = nIdx;
  545. }
  546. else
  547. {
  548. DWORD_PTR dwTmp = SendDlgItemMessageA(pParam->hwndDlg, pParam->nId, CB_GETITEMDATA, nTmpIdx, 0);
  549. m_pnRegionIdx[m_nServiceInfo*dwTmp + pParam->nServiceInfo] = nIdx;
  550. }
  551. }
  552. static void WINAPI _LoadRegionsCB(unsigned int nIdx, DWORD_PTR dwParam)
  553. {
  554. ((LoadRegionsCBStruct *) dwParam)->pPhoneBook->LoadRegionsCB(nIdx,dwParam);
  555. }
  556. void CPhoneBookInfo::LoadRegions(HWND hwndDlg, UINT nIdRegion, LPCTSTR pszRegionName)
  557. {
  558. UINT nIdx;
  559. DWORD dwServiceType;
  560. DWORD dwCountryID;
  561. CMTRACE(TEXT("CPhoneBookInfo::LoadRegions"));
  562. CmFree(m_pnRegionIdx);
  563. m_pnRegionIdx = NULL;
  564. m_nRegionIdx = 0;
  565. m_nIdRegion = nIdRegion;
  566. SendDlgItemMessageU(hwndDlg,nIdRegion,CB_RESETCONTENT,0,0);
  567. nIdx = (UINT) SendDlgItemMessageU(hwndDlg,m_nIdServiceType,CB_GETCURSEL,0,0);
  568. if (nIdx == CB_ERR)
  569. {
  570. return;
  571. }
  572. dwServiceType = (DWORD)SendDlgItemMessageU(hwndDlg,m_nIdServiceType,CB_GETITEMDATA,nIdx,0);
  573. MYDBGASSERT(dwServiceType<m_nServiceInfo);
  574. nIdx = (UINT) SendDlgItemMessageU(hwndDlg,m_nIdCountry,CB_GETCURSEL,0,0);
  575. if (nIdx == CB_ERR)
  576. {
  577. return;
  578. }
  579. dwCountryID = (DWORD)SendDlgItemMessageU(hwndDlg,m_nIdCountry,CB_GETITEMDATA,nIdx,0);
  580. for (nIdx=0;nIdx<m_nServiceInfo;nIdx++)
  581. {
  582. if (m_psiServiceInfo[nIdx].nServiceString == dwServiceType)
  583. {
  584. #ifdef UNICODE
  585. LPSTR pszAnsiRegionName = WzToSzWithAlloc(pszRegionName);
  586. if (NULL == pszAnsiRegionName)
  587. {
  588. return;
  589. }
  590. #endif
  591. LoadRegionsCBStruct sParam = {this,
  592. m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  593. hwndDlg,
  594. nIdRegion,
  595. #ifdef UNICODE
  596. pszAnsiRegionName,
  597. #else
  598. pszRegionName,
  599. #endif
  600. nIdx};
  601. PhoneBookEnumRegions(sParam.dwPB,
  602. _LoadRegionsCB,
  603. dwCountryID,
  604. m_psiServiceInfo[nIdx].pFilter,
  605. (DWORD_PTR) &sParam);
  606. #ifdef UNICODE
  607. CmFree(pszAnsiRegionName);
  608. #endif
  609. }
  610. }
  611. if (SendDlgItemMessageU(hwndDlg,nIdRegion,CB_GETCOUNT,0,0) != 0)
  612. {
  613. EnableWindow(GetDlgItem(hwndDlg,nIdRegion),TRUE); /* 10763 */
  614. EnableWindow(GetDlgItem(hwndDlg, IDC_PHONEBOOK_REGION_STATIC), TRUE);
  615. }
  616. else
  617. {
  618. EnableWindow(GetDlgItem(hwndDlg,nIdRegion),FALSE);
  619. EnableWindow(GetDlgItem(hwndDlg, IDC_PHONEBOOK_REGION_STATIC), FALSE);
  620. }
  621. if ((SendDlgItemMessageU(hwndDlg,nIdRegion,CB_GETCURSEL,0,0) == CB_ERR) &&
  622. (SendDlgItemMessageU(hwndDlg,nIdRegion,CB_GETCOUNT,0,0) != 0))
  623. {
  624. SendDlgItemMessageU(hwndDlg,nIdRegion,CB_SETCURSEL,0,0);
  625. }
  626. }
  627. typedef struct tagLoadNumbersCBStruct
  628. {
  629. CPhoneBookInfo *pPhoneBook;
  630. DWORD_PTR dwPB;
  631. HWND hwndDlg;
  632. UINT nIdA;
  633. UINT nIdB;
  634. UINT nIdMore;
  635. PPBFS pFilterA;
  636. PPBFS pFilterB;
  637. LPCSTR pszPhoneNumber;
  638. LPCSTR pszPhoneBookFile;
  639. } LoadNumbersCBStruct;
  640. void CPhoneBookInfo::LoadNumbersCB(unsigned int nIdx, DWORD_PTR dwParam)
  641. {
  642. UINT nTmpIdx;
  643. LoadNumbersCBStruct *pParam = (LoadNumbersCBStruct *) dwParam;
  644. CHAR szPhoneNumber[256];
  645. DWORD dwType = PhoneBookGetPhoneType(pParam->dwPB, nIdx);
  646. UINT nId;
  647. UINT nOtherId;
  648. DWORD dwLen;
  649. BOOL bMatch = FALSE;
  650. DWORD dwCookie = m_Map.ToCookie(pParam->dwPB, nIdx);
  651. LPSTR pszAnsiPhoneBookFile;
  652. #ifdef UNICODE
  653. pszAnsiPhoneBookFile = WzToSzWithAlloc(GetFile(dwCookie));
  654. if (NULL == pszAnsiPhoneBookFile)
  655. {
  656. CMASSERTMSG(FALSE, TEXT("CPhoneBookInfo::LoadNumbersCB -- Insufficient memory for Wide to Ansi conversion."));
  657. goto exit;
  658. }
  659. #else
  660. pszAnsiPhoneBookFile = GetFile(dwCookie);
  661. #endif
  662. if (PhoneBookMatchFilter(pParam->pFilterA,dwType))
  663. {
  664. nId = pParam->nIdA;
  665. nOtherId = pParam->nIdB;
  666. }
  667. else if (PhoneBookMatchFilter(pParam->pFilterB,dwType))
  668. {
  669. nId = pParam->nIdB;
  670. nOtherId = pParam->nIdA;
  671. }
  672. else
  673. {
  674. goto exit;
  675. }
  676. if (pParam->pszPhoneNumber && pParam->pszPhoneBookFile)
  677. {
  678. dwLen = sizeof(szPhoneNumber) / sizeof(TCHAR);
  679. PhoneBookGetPhoneCanonical(pParam->dwPB, nIdx, szPhoneNumber, &dwLen);
  680. if ((lstrcmpA(szPhoneNumber, pParam->pszPhoneNumber) == 0) &&
  681. (lstrcmpA(pszAnsiPhoneBookFile, pParam->pszPhoneBookFile) == 0))
  682. {
  683. bMatch = TRUE;
  684. }
  685. }
  686. if (GetDlgItem(pParam->hwndDlg,nId))
  687. {
  688. dwLen = sizeof(szPhoneNumber) / sizeof(TCHAR);
  689. PhoneBookGetPhoneDisp(pParam->dwPB, nIdx, szPhoneNumber, &dwLen);
  690. nTmpIdx = (UINT) SendDlgItemMessageA(pParam->hwndDlg, nId, LB_FINDSTRINGEXACT, (WPARAM) -1,
  691. (LPARAM) szPhoneNumber);
  692. if (nTmpIdx != LB_ERR)
  693. {
  694. goto exit;
  695. }
  696. nTmpIdx = (UINT) SendDlgItemMessageA(pParam->hwndDlg, nId, LB_ADDSTRING, 0, (LPARAM) szPhoneNumber);
  697. DWORD_PTR dwSet = SendDlgItemMessageA(pParam->hwndDlg, nId, LB_SETITEMDATA, nTmpIdx, (LPARAM) dwCookie);
  698. #ifdef DEBUG
  699. if (LB_ERR == dwSet)
  700. {
  701. CMTRACE(TEXT("PBDlgProc() LB_SETITEMDATA failed"));
  702. }
  703. #endif
  704. }
  705. else
  706. {
  707. EnableWindow(GetDlgItem(pParam->hwndDlg,pParam->nIdMore),TRUE);
  708. if (bMatch)
  709. {
  710. SendMessageA(pParam->hwndDlg, WM_COMMAND, pParam->nIdMore, 0);
  711. }
  712. }
  713. exit:
  714. #ifdef UNICODE
  715. CmFree(pszAnsiPhoneBookFile);
  716. #endif
  717. return;
  718. }
  719. static void WINAPI _LoadNumbersCB(unsigned int nIdx, DWORD_PTR dwParam)
  720. {
  721. ((LoadNumbersCBStruct *) dwParam)->pPhoneBook->LoadNumbersCB(nIdx,dwParam);
  722. }
  723. void CPhoneBookInfo::LoadNumbers(HWND hwndDlg,
  724. UINT nIdNumberA,
  725. UINT nIdNumberB,
  726. UINT nIdMore,
  727. LPCTSTR pszPhoneNumber,
  728. LPCTSTR pszPhoneBookFile)
  729. {
  730. UINT nIdx;
  731. DWORD dwServiceType;
  732. DWORD dwCountryID;
  733. DWORD dwRegionIdx = UINT_MAX;
  734. CMTRACE(TEXT("CPhoneBookInfo::LoadNumbers"));
  735. LPSTR pszAnsiPhoneNumber = NULL;
  736. LPSTR pszAnsiPhoneBookFile = NULL;
  737. #ifdef UNICODE
  738. pszAnsiPhoneNumber = WzToSzWithAlloc(pszPhoneNumber);
  739. if (NULL == pszAnsiPhoneNumber)
  740. {
  741. CMTRACE(TEXT("CPhoneBookInfo::LoadNumbers -- Insufficient Memory to convert from Wide to MBCS for pszPhoneNumber"));
  742. goto exit;
  743. }
  744. pszAnsiPhoneBookFile = WzToSzWithAlloc(pszPhoneBookFile);
  745. if (NULL == pszAnsiPhoneBookFile)
  746. {
  747. CMTRACE(TEXT("CPhoneBookInfo::LoadNumbers -- Insufficient Memory to convert from Wide to MBCS for pszPhoneBookFile"));
  748. goto exit;
  749. }
  750. #else
  751. pszAnsiPhoneNumber = (LPSTR)pszPhoneNumber;
  752. pszAnsiPhoneBookFile = (LPSTR)pszPhoneBookFile;
  753. #endif
  754. SendDlgItemMessageA(hwndDlg, nIdNumberA, LB_RESETCONTENT, 0, 0);
  755. SendDlgItemMessageA(hwndDlg, nIdNumberB, LB_RESETCONTENT, 0, 0);
  756. #if 0
  757. // EnableWindow(GetDlgItem(hwndDlg,nIdMore),FALSE); Note: More button is now obsolete
  758. #endif
  759. //
  760. // Get the current service type
  761. //
  762. nIdx = (UINT) SendDlgItemMessageA(hwndDlg, m_nIdServiceType, CB_GETCURSEL, 0, 0);
  763. if (nIdx == CB_ERR)
  764. {
  765. goto exit;
  766. }
  767. dwServiceType = (DWORD)SendDlgItemMessageA(hwndDlg, m_nIdServiceType, CB_GETITEMDATA, nIdx, 0);
  768. MYDBGASSERT(dwServiceType < m_nServiceInfo);
  769. //
  770. // Get the current country code
  771. //
  772. nIdx = (UINT) SendDlgItemMessageA(hwndDlg, m_nIdCountry, CB_GETCURSEL, 0, 0);
  773. if (nIdx == CB_ERR)
  774. {
  775. goto exit;
  776. }
  777. dwCountryID = (DWORD)SendDlgItemMessageA(hwndDlg, m_nIdCountry, CB_GETITEMDATA, nIdx, 0);
  778. //
  779. // Get the current region ID
  780. //
  781. nIdx = (UINT) SendDlgItemMessageA(hwndDlg, m_nIdRegion, CB_GETCURSEL, 0, 0);
  782. if (nIdx != CB_ERR)
  783. {
  784. dwRegionIdx = (DWORD)SendDlgItemMessageA(hwndDlg, m_nIdRegion, CB_GETITEMDATA, nIdx, 0);
  785. }
  786. for (nIdx=0; nIdx < m_nServiceInfo; nIdx++)
  787. {
  788. if (m_psiServiceInfo[nIdx].nServiceString == dwServiceType)
  789. {
  790. if ((dwRegionIdx == UINT_MAX) ||
  791. (m_pnRegionIdx[m_nServiceInfo*dwRegionIdx+nIdx] != UINT_MAX))
  792. {
  793. LoadNumbersCBStruct sParam = {this,
  794. m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  795. hwndDlg,
  796. nIdNumberA,
  797. nIdNumberB,
  798. nIdMore,
  799. m_psiServiceInfo[nIdx].pFilterA,
  800. m_psiServiceInfo[nIdx].pFilterB,
  801. pszAnsiPhoneNumber,
  802. pszAnsiPhoneBookFile};
  803. PhoneBookEnumNumbers(sParam.dwPB,
  804. _LoadNumbersCB,
  805. dwCountryID,
  806. (dwRegionIdx == UINT_MAX) ? UINT_MAX : m_pnRegionIdx[m_nServiceInfo*dwRegionIdx+nIdx],
  807. m_psiServiceInfo[nIdx].pFilter,
  808. (DWORD_PTR) &sParam);
  809. }
  810. else
  811. {
  812. //
  813. // Multiple PBKs (especially if one has no regions) can create a
  814. // situation in which we have a valid region selection in the combo
  815. // but the m_pnRegionIdx[m_nServiceInfo*dwRegionIdx+nIdx] is
  816. // UINT_MAX. What we do in this situation is enumerate the
  817. // numbers such that only those without regions are added to the
  818. // list by enumerating phone numbers with region 0.
  819. //
  820. if ((dwRegionIdx != UINT_MAX) &&
  821. (m_pnRegionIdx[m_nServiceInfo*dwRegionIdx+nIdx] == UINT_MAX))
  822. {
  823. LoadNumbersCBStruct sParam = {this,
  824. m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB),
  825. hwndDlg,
  826. nIdNumberA,
  827. nIdNumberB,
  828. nIdMore,
  829. m_psiServiceInfo[nIdx].pFilterA,
  830. m_psiServiceInfo[nIdx].pFilterB,
  831. pszAnsiPhoneNumber,
  832. pszAnsiPhoneBookFile};
  833. PhoneBookEnumNumbersWithRegionsZero(sParam.dwPB,
  834. _LoadNumbersCB,
  835. dwCountryID,
  836. m_psiServiceInfo[nIdx].pFilter,
  837. (DWORD_PTR) &sParam);
  838. }
  839. }
  840. }
  841. }
  842. exit:
  843. #ifdef UNICODE
  844. CmFree(pszAnsiPhoneNumber);
  845. CmFree(pszAnsiPhoneBookFile);
  846. #endif
  847. return;
  848. }
  849. BOOL CPhoneBookInfo::HasMoreNumbers()
  850. {
  851. //
  852. // Filters are stored by service type, so examine each one.
  853. //
  854. for (UINT nIdx = 0; nIdx < m_nServiceInfo; nIdx++)
  855. {
  856. if (PhoneBookHasPhoneType(m_Map.GetPBByIdx(m_psiServiceInfo[nIdx].dwPB), m_psiServiceInfo[nIdx].pFilterB))
  857. {
  858. return TRUE;
  859. }
  860. }
  861. return FALSE;
  862. }
  863. BOOL CPhoneBookInfo::LoadFile(LPCTSTR pszFile, PPBFS pFilterA, PPBFS pFilterB)
  864. {
  865. CMTRACE(TEXT("CPhoneBookInfo::LoadFile"));
  866. LPSTR pszAnsiFile = NULL;
  867. BOOL bRes = TRUE;
  868. #ifdef UNICODE
  869. pszAnsiFile = WzToSzWithAlloc(pszFile);
  870. if (!pszAnsiFile)
  871. {
  872. return FALSE;
  873. }
  874. #else
  875. pszAnsiFile = (LPSTR)pszFile;
  876. #endif
  877. SCBS sSvc = {this,pFilterA,pFilterB,0,pszAnsiFile};
  878. PhoneBookParseInfoStruct iInfo;
  879. sSvc.dwPB = m_Map.Open(pszAnsiFile, m_nServiceInfo);
  880. if (sSvc.dwPB == CPBMAP_ERROR)
  881. {
  882. bRes = FALSE;
  883. goto exit;
  884. }
  885. ZeroMemory(&iInfo, sizeof(iInfo));
  886. iInfo.dwSize = sizeof(iInfo);
  887. iInfo.pfnSvc = _ServiceCB;
  888. iInfo.dwSvcParam = (DWORD_PTR) &sSvc;
  889. CMTRACE(TEXT("CPhoneBookInfo::LoadFile - ParseInfo"));
  890. bRes = PhoneBookParseInfo(pszAnsiFile, &iInfo);
  891. PhoneBookFreeFilter(iInfo.pFilterA);
  892. PhoneBookFreeFilter(iInfo.pFilterB);
  893. exit:
  894. #ifdef UNICODE
  895. CmFree(pszAnsiFile);
  896. #endif
  897. return (bRes);
  898. }
  899. BOOL CPhoneBookInfo::ServiceCB(LPCTSTR pszSvc,
  900. PPBFS pFilter,
  901. PPBFS pFilterA,
  902. PPBFS pFilterB,
  903. DWORD dwPB,
  904. LPCTSTR pszFile)
  905. {
  906. ServiceInfo *psiInfo;
  907. UINT nIdx;
  908. CMTRACE(TEXT("CPhoneBookInfo::ServiceCB"));
  909. //
  910. // Extended m_psiServiceInfo and set up the new element
  911. //
  912. ExtendArray((void **) &m_psiServiceInfo,sizeof(*m_psiServiceInfo),&m_nServiceInfo);
  913. psiInfo = &m_psiServiceInfo[m_nServiceInfo-1];
  914. psiInfo->dwPB = dwPB;
  915. psiInfo->pFilter = pFilter;
  916. psiInfo->pFilterA = PhoneBookCopyFilter(pFilterA);
  917. psiInfo->pFilterB = PhoneBookCopyFilter(pFilterB);
  918. psiInfo->pszFile = CmStrCpyAlloc(pszFile);
  919. for (nIdx=0;nIdx<m_nServiceString;nIdx++)
  920. {
  921. if (lstrcmpU(pszSvc,m_ppszServiceString[nIdx]) == 0)
  922. {
  923. psiInfo->nServiceString = nIdx;
  924. break;
  925. }
  926. }
  927. if (nIdx == m_nServiceString)
  928. {
  929. ExtendArray((void **) &m_ppszServiceString,sizeof(*m_ppszServiceString),&m_nServiceString);
  930. m_ppszServiceString[m_nServiceString-1] = CmStrCpyAlloc(pszSvc);
  931. psiInfo->nServiceString = m_nServiceString - 1;
  932. }
  933. return (TRUE);
  934. }
  935. static BOOL WINAPI _ReferenceCB(LPCSTR pszFile,
  936. LPCSTR pszURL,
  937. PPBFS pFilterA,
  938. PPBFS pFilterB,
  939. DWORD_PTR dwParam)
  940. {
  941. CPhoneBookInfo *pParam = (CPhoneBookInfo *) dwParam;
  942. #ifdef UNICODE
  943. LPWSTR pszwFile = NULL;
  944. pszwFile = SzToWzWithAlloc(pszFile);
  945. BOOL bReturn = FALSE;
  946. if (NULL != pszwFile)
  947. {
  948. bReturn = pParam->LoadFile(pszwFile, pFilterA, pFilterB);
  949. CmFree(pszwFile);
  950. }
  951. else
  952. {
  953. CMTRACE(TEXT("_ReferenceCB -- CmMalloc returned a NULL pointer."));
  954. }
  955. return bReturn;
  956. #else
  957. return (pParam->LoadFile(pszFile, pFilterA, pFilterB));
  958. #endif
  959. }
  960. static BOOL CALLBACK _ServiceCB(LPCSTR pszSvc, PPBFS pFilter, DWORD_PTR dwParam)
  961. {
  962. CPhoneBookInfo::SCBS *pParam = (CPhoneBookInfo::SCBS *) dwParam;
  963. #ifdef UNICODE
  964. BOOL bReturn = FALSE;
  965. LPWSTR pszwSvc = SzToWzWithAlloc(pszSvc);
  966. LPWSTR pszwFile = SzToWzWithAlloc(pParam->pszFile);
  967. if ((NULL != pszwFile) && (NULL != pszwSvc))
  968. {
  969. bReturn = (pParam->pInfo->ServiceCB)(pszwSvc,
  970. pFilter,
  971. pParam->pFilterA,
  972. pParam->pFilterB,
  973. pParam->dwPB,
  974. pszwFile);
  975. }
  976. CmFree(pszwSvc);
  977. CmFree(pszwFile);
  978. return bReturn;
  979. #else
  980. return (pParam->pInfo->ServiceCB(pszSvc,
  981. pFilter,
  982. pParam->pFilterA,
  983. pParam->pFilterB,
  984. pParam->dwPB,
  985. pParam->pszFile));
  986. #endif
  987. }
  988. typedef struct tagPBDlgArgs
  989. {
  990. PBArgs *pPBArgs;
  991. CPhoneBookInfo cPB;
  992. BMPDATA BmpData;
  993. } PBDlgArgs;
  994. static BOOL PBDlgFillData(HWND hwndDlg, PBArgs *pPBArgs, CPhoneBookInfo *pPB, BOOL fValidateDun)
  995. {
  996. UINT nTmpIdx;
  997. UINT nId;
  998. DWORD dwLen;
  999. GetDlgItemTextU(hwndDlg,IDC_PHONEBOOK_SERVICETYPE_COMBO,pPBArgs->szServiceType,sizeof(pPBArgs->szServiceType)/sizeof(TCHAR)-1);
  1000. nTmpIdx = (UINT) SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_COUNTRY_COMBO,CB_GETCURSEL,0,0);
  1001. if (nTmpIdx != CB_ERR)
  1002. {
  1003. pPBArgs->dwCountryId = (DWORD)SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_COUNTRY_COMBO,CB_GETITEMDATA,nTmpIdx,0);
  1004. }
  1005. else
  1006. {
  1007. pPBArgs->dwCountryId = PhoneBookGetCurrentCountryId();
  1008. }
  1009. GetDlgItemTextU(hwndDlg,IDC_PHONEBOOK_REGION_COMBO,pPBArgs->szRegionName,sizeof(pPBArgs->szRegionName)/sizeof(TCHAR)-1);
  1010. nId = IDC_PHONEBOOK_PHONE_LIST;
  1011. nTmpIdx = (UINT) SendDlgItemMessageU(hwndDlg,nId,LB_GETCURSEL,0,0);
  1012. if (nTmpIdx == LB_ERR)
  1013. {
  1014. if (GetDlgItem(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST))
  1015. {
  1016. nId = IDC_PHONEBOOKEX_PHONE_LIST;
  1017. nTmpIdx = (UINT) SendDlgItemMessageU(hwndDlg,nId,LB_GETCURSEL,0,0);
  1018. UINT nTmpCount = (UINT) SendDlgItemMessageU(hwndDlg,nId,LB_GETCOUNT,0,0);
  1019. }
  1020. }
  1021. if (nTmpIdx != LB_ERR)
  1022. {
  1023. DWORD dwIdx = (DWORD)SendDlgItemMessageU(hwndDlg,nId,LB_GETITEMDATA,nTmpIdx,0);
  1024. if (dwIdx != LB_ERR)
  1025. {
  1026. dwLen = sizeof(pPBArgs->szNonCanonical) / sizeof(TCHAR);
  1027. pPB->GetNonCanonical(dwIdx,pPBArgs->szNonCanonical,&dwLen);
  1028. dwLen = sizeof(pPBArgs->szCanonical) / sizeof(TCHAR);
  1029. pPB->GetCanonical(dwIdx,pPBArgs->szCanonical,&dwLen);
  1030. dwLen = sizeof(pPBArgs->szDesc) / sizeof(TCHAR);
  1031. pPB->GetDesc(dwIdx,pPBArgs->szDesc,&dwLen);
  1032. lstrcpynU(pPBArgs->szPhoneBookFile,pPB->GetFile(dwIdx),sizeof(pPBArgs->szPhoneBookFile)/sizeof(TCHAR));
  1033. dwLen = sizeof(pPBArgs->szDUNFile) / sizeof(TCHAR);
  1034. pPB->GetDUN(dwIdx,pPBArgs->szDUNFile,&dwLen);
  1035. if (fValidateDun)
  1036. {
  1037. //
  1038. // Make sure we can support any DUN settings associated with the number
  1039. //
  1040. if (FALSE == ValidateDialupDunSettings(pPBArgs->szPhoneBookFile, pPBArgs->szDUNFile, pPBArgs->pszCMSFile))
  1041. {
  1042. return FALSE;
  1043. }
  1044. }
  1045. }
  1046. #ifdef DEBUG
  1047. if (LB_ERR == dwIdx)
  1048. {
  1049. CMTRACE(TEXT("PBDlgProc() LB_GETITEMDATA failed"));
  1050. }
  1051. #endif
  1052. }
  1053. return TRUE;
  1054. }
  1055. INT_PTR CALLBACK PBDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1056. {
  1057. PBDlgArgs *pArgs = (PBDlgArgs *) GetWindowLongU(hwndDlg,DWLP_USER);
  1058. static DWORD adwHelp[] = {IDC_PHONEBOOK_SERVICETYPE_COMBO,IDH_PHONEBOOK_SERVICETYP,
  1059. IDC_PHONEBOOK_COUNTRY_COMBO,IDH_PHONEBOOK_COUNTRY,
  1060. IDC_PHONEBOOK_REGION_COMBO,IDH_PHONEBOOK_STATEREG,
  1061. IDC_PHONEBOOK_REGION_STATIC,IDH_PHONEBOOK_STATEREG,
  1062. IDC_PHONEBOOK_PHONE_LIST,IDH_PHONEBOOK_ACCESSNUMS,
  1063. IDC_PHONEBOOK_HELP_BUTTON, IDH_CMHELP,
  1064. //IDC_PHONEBOOK_MORE_BUTTON,IDH_PHONEBOOK_MORE,
  1065. IDC_PHONEBOOKEX_MESSAGE_DISPLAY,IDH_PHONEBOOK_SVCMSG,
  1066. IDC_PHONEBOOKEX_MORE_STATIC,IDH_PHONEBOOK_MORENUMS,
  1067. IDC_PHONEBOOKEX_PHONE_LIST,IDH_PHONEBOOK_MORENUMS,
  1068. 0,0};
  1069. switch (uMsg)
  1070. {
  1071. case WM_INITDIALOG:
  1072. CMTRACE(TEXT("PBDlgProc - WM_INITDIALOG"));
  1073. UpdateFont(hwndDlg);
  1074. pArgs = (PBDlgArgs *) lParam;
  1075. SetWindowLongU(hwndDlg,DWLP_USER,(LONG_PTR) pArgs);
  1076. SetDlgItemTextU(hwndDlg,IDC_PHONEBOOKEX_MESSAGE_DISPLAY,pArgs->pPBArgs->pszMessage);
  1077. pArgs->cPB.LoadServiceTypes(hwndDlg,IDC_PHONEBOOK_SERVICETYPE_COMBO,pArgs->pPBArgs->szServiceType);
  1078. pArgs->cPB.LoadCountries(hwndDlg,IDC_PHONEBOOK_COUNTRY_COMBO,pArgs->pPBArgs->dwCountryId);
  1079. pArgs->cPB.LoadRegions(hwndDlg,IDC_PHONEBOOK_REGION_COMBO,pArgs->pPBArgs->szRegionName);
  1080. pArgs->cPB.LoadNumbers(hwndDlg,
  1081. IDC_PHONEBOOK_PHONE_LIST,
  1082. IDC_PHONEBOOKEX_PHONE_LIST,
  1083. IDC_PHONEBOOK_MORE_BUTTON,
  1084. pArgs->pPBArgs->szCanonical,
  1085. pArgs->pPBArgs->szPhoneBookFile);
  1086. if ((SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_PHONE_LIST,LB_GETCURSEL,0,0) == LB_ERR) &&
  1087. (!GetDlgItem(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST) ||
  1088. (SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST,LB_GETCURSEL,0,0) == LB_ERR)))
  1089. {
  1090. EnableWindow(GetDlgItem(hwndDlg,IDOK),FALSE);
  1091. }
  1092. SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_BITMAP,STM_SETIMAGE,IMAGE_BITMAP,(LPARAM) &pArgs->BmpData);
  1093. if (IsLogonAsSystem())
  1094. {
  1095. EnableWindow(GetDlgItem(hwndDlg, IDC_PHONEBOOK_HELP_BUTTON), FALSE);
  1096. }
  1097. return (FALSE);
  1098. case WM_COMMAND:
  1099. switch (LOWORD(wParam))
  1100. {
  1101. case IDOK:
  1102. if (PBDlgFillData(hwndDlg, pArgs->pPBArgs, &pArgs->cPB, TRUE))
  1103. {
  1104. EndDialog(hwndDlg,1);
  1105. }
  1106. return (TRUE);
  1107. case IDC_PHONEBOOK_HELP_BUTTON:
  1108. CmWinHelp(hwndDlg, hwndDlg, pArgs->pPBArgs->pszHelpFile,HELP_FORCEFILE,ICM_TRB);
  1109. return (TRUE);
  1110. case IDCANCEL:
  1111. EndDialog(hwndDlg,0);
  1112. return (TRUE);
  1113. case IDC_PHONEBOOK_MORE_BUTTON:
  1114. MYDBGASSERT(FALSE); // Now obsolete
  1115. PBDlgFillData(hwndDlg, pArgs->pPBArgs, &pArgs->cPB, FALSE);
  1116. EndDialog(hwndDlg,2);
  1117. return (TRUE);
  1118. default:
  1119. if ((HIWORD(wParam) == CBN_SELCHANGE) || (HIWORD(wParam) == LBN_SELCHANGE))
  1120. {
  1121. switch (LOWORD(wParam))
  1122. {
  1123. case IDC_PHONEBOOK_SERVICETYPE_COMBO:
  1124. PBDlgFillData(hwndDlg, pArgs->pPBArgs, &pArgs->cPB, FALSE);
  1125. pArgs->cPB.LoadCountries(hwndDlg,IDC_PHONEBOOK_COUNTRY_COMBO,pArgs->pPBArgs->dwCountryId);
  1126. // fall through
  1127. case IDC_PHONEBOOK_COUNTRY_COMBO:
  1128. pArgs->cPB.LoadRegions(hwndDlg,IDC_PHONEBOOK_REGION_COMBO,pArgs->pPBArgs->szRegionName);
  1129. // fall through
  1130. case IDC_PHONEBOOK_REGION_COMBO:
  1131. pArgs->cPB.LoadNumbers(hwndDlg,
  1132. IDC_PHONEBOOK_PHONE_LIST,
  1133. IDC_PHONEBOOKEX_PHONE_LIST,
  1134. IDC_PHONEBOOK_MORE_BUTTON,
  1135. pArgs->pPBArgs->szCanonical,
  1136. pArgs->pPBArgs->szPhoneBookFile);
  1137. if ((SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_PHONE_LIST,LB_GETCURSEL,0,0) == LB_ERR) &&
  1138. (!GetDlgItem(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST) ||
  1139. (SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST,LB_GETCURSEL,0,0) == LB_ERR)))
  1140. {
  1141. EnableWindow(GetDlgItem(hwndDlg,IDOK),FALSE);
  1142. }
  1143. else
  1144. {
  1145. EnableWindow(GetDlgItem(hwndDlg,IDOK),TRUE);
  1146. }
  1147. return (TRUE);
  1148. case IDC_PHONEBOOK_PHONE_LIST:
  1149. if (SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_PHONE_LIST,LB_GETCURSEL,0,0) != LB_ERR)
  1150. {
  1151. EnableWindow(GetDlgItem(hwndDlg,IDOK),TRUE);
  1152. SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST,LB_SETCURSEL,(WPARAM) -1,0);
  1153. }
  1154. return (TRUE);
  1155. case IDC_PHONEBOOKEX_PHONE_LIST:
  1156. if (SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOKEX_PHONE_LIST,LB_GETCURSEL,0,0) != LB_ERR)
  1157. {
  1158. EnableWindow(GetDlgItem(hwndDlg,IDOK),TRUE);
  1159. SendDlgItemMessageU(hwndDlg,IDC_PHONEBOOK_PHONE_LIST,LB_SETCURSEL,(WPARAM) -1,0);
  1160. }
  1161. return (TRUE);
  1162. default:
  1163. break;
  1164. }
  1165. }
  1166. if (HIWORD(wParam) == LBN_DBLCLK)
  1167. {
  1168. switch (LOWORD(wParam))
  1169. {
  1170. case IDC_PHONEBOOK_PHONE_LIST:
  1171. case IDC_PHONEBOOKEX_PHONE_LIST:
  1172. if (SendDlgItemMessageU(hwndDlg,LOWORD(wParam),LB_GETCURSEL,0,0) != LB_ERR)
  1173. {
  1174. SendMessageU(hwndDlg, WM_COMMAND, IDOK, 0);
  1175. }
  1176. break;
  1177. default:
  1178. break;
  1179. }
  1180. }
  1181. break;
  1182. }
  1183. break;
  1184. case WM_HELP:
  1185. {
  1186. LPHELPINFO lpHelpInfo = (LPHELPINFO) lParam;
  1187. CmWinHelp((HWND) (lpHelpInfo->hItemHandle),
  1188. (HWND) (lpHelpInfo->hItemHandle),
  1189. pArgs->pPBArgs->pszHelpFile,
  1190. HELP_WM_HELP,
  1191. (ULONG_PTR) ((LPTSTR) adwHelp));
  1192. return (TRUE);
  1193. }
  1194. case WM_CONTEXTMENU:
  1195. {
  1196. POINT pt = {LOWORD(lParam), HIWORD(lParam)};
  1197. HWND hWndItem;
  1198. ScreenToClient(hwndDlg, &pt);
  1199. hWndItem = ChildWindowFromPoint(hwndDlg, pt);
  1200. if (hWndItem != NULL &&
  1201. HaveContextHelp(hwndDlg, hWndItem))
  1202. {
  1203. CmWinHelp((HWND) wParam, hWndItem,pArgs->pPBArgs->pszHelpFile,HELP_CONTEXTMENU,(ULONG_PTR) (LPSTR) adwHelp);
  1204. return (TRUE);
  1205. }
  1206. //
  1207. // 170599: Assertion when right click phone book dialog title bar
  1208. // Return FALSE, DefaultWindowProc will handle this message then.
  1209. //
  1210. return (FALSE);
  1211. }
  1212. case WM_PALETTEISCHANGING:
  1213. CMTRACE2(TEXT("PBDlgProc() got WM_PALETTEISCHANGING message, wParam=0x%x, hwndDlg=0x%x."), wParam, hwndDlg);
  1214. break;
  1215. case WM_PALETTECHANGED:
  1216. {
  1217. if ((wParam != (WPARAM) hwndDlg) && pArgs->BmpData.hDIBitmap)
  1218. {
  1219. PaletteChanged(&pArgs->BmpData, hwndDlg, IDC_PHONEBOOK_BITMAP);
  1220. }
  1221. else
  1222. {
  1223. CMTRACE2(TEXT("PBDlgProc().WM_PALETTECHANGED not changing palette, wParam=0x%x, hwndDlg=0x%x."),
  1224. wParam, hwndDlg);
  1225. }
  1226. break;
  1227. }
  1228. case WM_QUERYNEWPALETTE:
  1229. QueryNewPalette(&pArgs->BmpData, hwndDlg, IDC_PHONEBOOK_BITMAP);
  1230. break;
  1231. default:
  1232. break;
  1233. }
  1234. return (FALSE);
  1235. }
  1236. BOOL DisplayPhoneBook(HWND hwndDlg, PBArgs *pPBArgs, BOOL fHasValidTopLevelPBK, BOOL fHasValidReferencedPBKs)
  1237. {
  1238. PBDlgArgs sDlgArgs;
  1239. BOOL bRes = FALSE;
  1240. HWND hwndParent = NULL;
  1241. CNamedMutex PbMutex;
  1242. memset(&sDlgArgs,0,sizeof(sDlgArgs));
  1243. sDlgArgs.pPBArgs = pPBArgs;
  1244. //
  1245. // Show wait cursor and attempt to grab PB access mutex
  1246. //
  1247. HCURSOR hPrev = SetCursor(LoadCursorU(NULL,IDC_WAIT));
  1248. if (PbMutex.Lock(c_pszCMPhoneBookMutex, TRUE, MAX_PB_WAIT))
  1249. {
  1250. sDlgArgs.cPB.Load(pPBArgs->pszCMSFile, fHasValidTopLevelPBK, fHasValidReferencedPBKs);
  1251. PbMutex.Unlock();
  1252. }
  1253. else
  1254. {
  1255. SetCursor(hPrev);
  1256. CMTRACE(TEXT("DisplayPhoneBook() - Unable to grab PB access mutex."));
  1257. return bRes;
  1258. }
  1259. //
  1260. // We have a phonebook to display, setup graphics
  1261. //
  1262. if (pPBArgs->pszBitmap && *pPBArgs->pszBitmap)
  1263. {
  1264. sDlgArgs.BmpData.hDIBitmap = CmLoadBitmap(g_hInst, pPBArgs->pszBitmap);
  1265. }
  1266. if (!sDlgArgs.BmpData.hDIBitmap)
  1267. {
  1268. sDlgArgs.BmpData.hDIBitmap = CmLoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_PB));
  1269. }
  1270. if (sDlgArgs.BmpData.hDIBitmap)
  1271. {
  1272. //
  1273. // Create a new Device Dependent bitmap
  1274. //
  1275. sDlgArgs.BmpData.phMasterPalette = pPBArgs->phMasterPalette;
  1276. sDlgArgs.BmpData.bForceBackground = TRUE; // paint as a background app
  1277. CreateBitmapData(sDlgArgs.BmpData.hDIBitmap, &sDlgArgs.BmpData, hwndDlg, TRUE);
  1278. }
  1279. //
  1280. // Determine the template to be used, if the aggregate PB contains any
  1281. // surcharge numbers then use the EX template for displaying more numbers.
  1282. //
  1283. LPCTSTR pszDlgBox = NULL;
  1284. if (sDlgArgs.cPB.HasMoreNumbers())
  1285. {
  1286. pszDlgBox = MAKEINTRESOURCE(IDD_PHONEBOOKEX);
  1287. }
  1288. else
  1289. {
  1290. pszDlgBox = MAKEINTRESOURCE(IDD_PHONEBOOK);
  1291. }
  1292. MYDBGASSERT(pszDlgBox);
  1293. //
  1294. // Restore cursor and display the PB dialog
  1295. //
  1296. SetCursor(hPrev);
  1297. hwndParent = hwndDlg;
  1298. #if 0
  1299. /*
  1300. //
  1301. // Previously, the user drove the template decision by electing to see
  1302. // More numbers via the More button. The return code from the proc would
  1303. // dictate if we should simply call it a again with a different template.
  1304. // Hence this loop and switch.
  1305. //
  1306. while (1)
  1307. {
  1308. switch (DialogBoxParam(g_hInst, pszDlgBox, hwndParent, (DLGPROC) PBDlgProc, (LPARAM) &sDlgArgs))
  1309. {
  1310. case 1:
  1311. bRes = TRUE;
  1312. break;
  1313. case 2:
  1314. pszDlgBox = MAKEINTRESOURCE(IDD_PHONEBOOKEX);
  1315. continue;
  1316. case 0:
  1317. default:
  1318. break;
  1319. }
  1320. //
  1321. // Release bitmap resources for dlg
  1322. //
  1323. ReleaseBitmapData(&sDlgArgs.BmpData);
  1324. return (bRes);
  1325. }
  1326. */
  1327. #else
  1328. bRes = (BOOL) DialogBoxParamU(g_hInst, pszDlgBox, hwndParent, (DLGPROC) PBDlgProc, (LPARAM) &sDlgArgs);
  1329. ReleaseBitmapData(&sDlgArgs.BmpData);
  1330. return (bRes);
  1331. #endif
  1332. }