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.

449 lines
9.9 KiB

  1. // File: calv.cpp
  2. #include "precomp.h"
  3. #include "resource.h"
  4. #include "calv.h"
  5. #include "upropdlg.h"
  6. #include "speedial.h"
  7. #include "dirutil.h"
  8. #include "confroom.h"
  9. ///////////////////////////////
  10. // Globals for FEnabledNmAddr
  11. BOOL g_fGkEnabled = FALSE;
  12. BOOL g_fGatewayEnabled = FALSE;
  13. BOOL g_bGkPhoneNumberAddressing = FALSE;
  14. CALV::CALV(int ids, int iIcon, const int * pIdMenu /*=NULL*/, bool fOwnerData /*=false*/ ) :
  15. m_idsName(ids),
  16. m_hwnd(NULL),
  17. m_iIcon(iIcon),
  18. m_pIdMenu(pIdMenu),
  19. m_fAvailable(FALSE),
  20. m_fOwnerDataList( fOwnerData )
  21. {
  22. }
  23. CALV::~CALV()
  24. {
  25. }
  26. VOID CALV::ClearItems(void)
  27. {
  28. if (NULL != m_hwnd)
  29. {
  30. ListView_DeleteAllItems(m_hwnd);
  31. }
  32. }
  33. VOID CALV::DeleteItem(int iItem)
  34. {
  35. if (ListView_DeleteItem(GetHwnd(), iItem))
  36. {
  37. // Auto-select the next item
  38. ListView_SetItemState(GetHwnd(), iItem,
  39. LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  40. }
  41. }
  42. int CALV::GetSelection(void)
  43. {
  44. return ListView_GetNextItem(m_hwnd, -1, LVNI_ALL | LVNI_SELECTED);
  45. }
  46. VOID CALV::SetHeader(HWND hwnd, int ids)
  47. {
  48. m_hwnd = hwnd;
  49. DlgCallSetHeader(hwnd, ids);
  50. }
  51. // Return the name (from the first column)
  52. BOOL CALV::GetSzName(LPTSTR psz, int cchMax)
  53. {
  54. int iItem = GetSelection();
  55. if (-1 == iItem)
  56. return FALSE;
  57. return GetSzName(psz, cchMax, iItem);
  58. }
  59. BOOL CALV::GetSzName(LPTSTR psz, int cchMax, int iItem)
  60. {
  61. return GetSzData(psz, cchMax, iItem, IDI_DLGCALL_NAME);
  62. }
  63. // Return the "callTo" address (from the second column)
  64. BOOL CALV::GetSzAddress(LPTSTR psz, int cchMax)
  65. {
  66. int iItem = GetSelection();
  67. if (-1 == iItem)
  68. return FALSE;
  69. return GetSzAddress(psz, cchMax, iItem);
  70. }
  71. BOOL CALV::GetSzAddress(LPTSTR psz, int cchMax, int iItem)
  72. {
  73. return GetSzData(psz, cchMax, iItem, IDI_DLGCALL_ADDRESS);
  74. }
  75. BOOL CALV::GetSzData(LPTSTR psz, int cchMax, int iItem, int iCol)
  76. {
  77. LV_ITEM lvi;
  78. ClearStruct(&lvi);
  79. lvi.iItem = iItem;
  80. lvi.iSubItem = iCol;
  81. lvi.mask = LVIF_TEXT;
  82. lvi.pszText = psz;
  83. lvi.cchTextMax = cchMax;
  84. return ListView_GetItem(m_hwnd, &lvi);
  85. }
  86. LPARAM CALV::LParamFromItem(int iItem)
  87. {
  88. LV_ITEM lvi;
  89. ClearStruct(&lvi);
  90. lvi.iItem = iItem;
  91. lvi.mask = LVIF_PARAM;
  92. return ListView_GetItem(GetHwnd(), &lvi) ? lvi.lParam : 0;
  93. }
  94. /* G E T A D D R I N F O */
  95. /*-------------------------------------------------------------------------
  96. %%Function: GetAddrInfo
  97. General interface to get the rich address info.
  98. -------------------------------------------------------------------------*/
  99. RAI * CALV::GetAddrInfo(void)
  100. {
  101. return GetAddrInfo(NM_ADDR_ULS);
  102. }
  103. /* G E T A D D R I N F O */
  104. /*-------------------------------------------------------------------------
  105. %%Function: GetAddrInfo
  106. Utility routine, usually called by GetAddrInfo()
  107. -------------------------------------------------------------------------*/
  108. RAI * CALV::GetAddrInfo(NM_ADDR_TYPE addrType)
  109. {
  110. TCHAR szName[CCHMAXSZ_NAME];
  111. if (!GetSzName(szName, CCHMAX(szName)))
  112. return NULL;
  113. TCHAR szAddress[CCHMAXSZ_ADDRESS];
  114. if (!GetSzAddress(szAddress, CCHMAX(szAddress)))
  115. return NULL;
  116. return CreateRai(szName, addrType, szAddress);
  117. }
  118. /* S E T B U S Y C U R S O R */
  119. /*-------------------------------------------------------------------------
  120. %%Function: SetBusyCursor
  121. -------------------------------------------------------------------------*/
  122. VOID CALV::SetBusyCursor(BOOL fBusy)
  123. {
  124. extern int g_cBusy; // in dlgcall.cpp
  125. g_cBusy += fBusy ? 1 : -1;
  126. ASSERT(g_cBusy >= 0);
  127. // Wiggle the mouse - force user to send a WM_SETCURSOR
  128. POINT pt;
  129. if (::GetCursorPos(&pt))
  130. {
  131. ::SetCursorPos(pt.x, pt.y);
  132. }
  133. }
  134. /* D O M E N U */
  135. /*-------------------------------------------------------------------------
  136. %%Function: DoMenu
  137. -------------------------------------------------------------------------*/
  138. VOID CALV::DoMenu(POINT pt, const int * pIdMenu)
  139. {
  140. HMENU hMenu = ::LoadMenu(::GetInstanceHandle(), MAKEINTRESOURCE(IDM_DLGCALL));
  141. if (NULL == hMenu)
  142. return;
  143. HMENU hMenuTrack = ::GetSubMenu(hMenu, 0);
  144. ASSERT(NULL != hMenu);
  145. {
  146. // Bold the "Call" menuitem:
  147. MENUITEMINFO iInfo;
  148. iInfo.cbSize = sizeof(iInfo);
  149. iInfo.fMask = MIIM_STATE;
  150. if(::GetMenuItemInfo(hMenuTrack, IDM_DLGCALL_CALL, FALSE, &iInfo))
  151. {
  152. iInfo.fState |= MFS_DEFAULT;
  153. ::SetMenuItemInfo(hMenuTrack, IDM_DLGCALL_CALL, FALSE, &iInfo);
  154. }
  155. }
  156. // Is anything selected?
  157. int iSelItem = GetSelection();
  158. UINT uFlags = (-1 == iSelItem) ? MF_GRAYED : MF_ENABLED;
  159. ::EnableMenuItem(hMenuTrack, IDM_DLGCALL_CALL,
  160. ((uFlags == MF_GRAYED) || !GetConfRoom()->IsNewCallAllowed()) ?
  161. MF_GRAYED : MF_ENABLED);
  162. ::EnableMenuItem(hMenuTrack, IDM_DLGCALL_PROPERTIES, uFlags);
  163. if (NULL != pIdMenu)
  164. {
  165. // Additional menu items
  166. while (0 != *pIdMenu)
  167. {
  168. int id = *pIdMenu++;
  169. if (-1 == id)
  170. {
  171. InsertMenu(hMenuTrack, (DWORD) -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
  172. }
  173. else
  174. {
  175. TCHAR sz[CCHMAXSZ];
  176. if (FLoadString(id, sz, CCHMAX(sz)))
  177. {
  178. UINT uf = MF_BYPOSITION | MF_STRING | uFlags;
  179. if (id >= IDM_DLGCALL_ALWAYS_ENABLED)
  180. {
  181. uf = (uf & ~MF_GRAYED) | MF_ENABLED;
  182. }
  183. InsertMenu(hMenuTrack, (DWORD) -1, uf, id, sz);
  184. }
  185. }
  186. }
  187. }
  188. // Check to see if we have "special" coordinates that signify
  189. // that we entered here as a result of a keyboard click
  190. // instead of a mouse click - and if so, get some default coords
  191. if ((0xFFFF == pt.x) && (0xFFFF == pt.y))
  192. {
  193. RECT rc;
  194. if ((-1 == iSelItem) ||
  195. (FALSE == ListView_GetItemRect(m_hwnd, iSelItem, &rc, LVIR_ICON)))
  196. {
  197. ::GetWindowRect(m_hwnd, &rc);
  198. pt.x = rc.left;
  199. pt.y = rc.top;
  200. }
  201. else
  202. {
  203. // Convert from client coords to screen coords
  204. ::MapWindowPoints(m_hwnd, NULL, (LPPOINT)&rc, 2);
  205. pt.x = rc.left + (RectWidth(rc) / 2);
  206. pt.y = rc.top + (RectHeight(rc) / 2);
  207. }
  208. }
  209. // Draw and track the "floating" popup
  210. ::TrackPopupMenu(hMenuTrack, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  211. pt.x, pt.y, 0, ::GetParent(m_hwnd), NULL);
  212. ::DestroyMenu(hMenu);
  213. }
  214. VOID CALV::OnRClick(POINT pt)
  215. {
  216. DoMenu(pt, m_pIdMenu);
  217. }
  218. VOID CALV::OnCommand(WPARAM wParam, LPARAM lParam)
  219. {
  220. WORD wCmd = LOWORD(wParam);
  221. switch (wCmd)
  222. {
  223. case IDM_DLGCALL_PROPERTIES:
  224. CmdProperties();
  225. break;
  226. case IDM_DLGCALL_SPEEDDIAL:
  227. CmdSpeedDial();
  228. break;
  229. default:
  230. break;
  231. }
  232. }
  233. /* C M D P R O P E R T I E S */
  234. /*-------------------------------------------------------------------------
  235. %%Function: CmdProperties
  236. -------------------------------------------------------------------------*/
  237. VOID CALV::CmdProperties(void)
  238. {
  239. TCHAR szName[CCHMAXSZ_NAME];
  240. TCHAR szAddr[CCHMAXSZ_ADDRESS];
  241. if (!GetSzName(szName, CCHMAX(szName)) ||
  242. !GetSzAddress(szAddr, CCHMAX(szAddr)))
  243. {
  244. return;
  245. }
  246. UPROPDLGENTRY rgProp[1] = {
  247. {IDS_UPROP_ADDRESS, szAddr},
  248. };
  249. CUserPropertiesDlg dlgUserProp(m_hwnd, IDI_LARGE);
  250. dlgUserProp.DoModal(rgProp, ARRAY_ELEMENTS(rgProp), szName, NULL);
  251. }
  252. /* C M D S P E E D D I A L */
  253. /*-------------------------------------------------------------------------
  254. %%Function: CmdSpeedDial
  255. -------------------------------------------------------------------------*/
  256. VOID CALV::CmdSpeedDial(void)
  257. {
  258. TCHAR szName[CCHMAXSZ_NAME];
  259. TCHAR szAddr[CCHMAXSZ_ADDRESS];
  260. if (!GetSzName(szName, CCHMAX(szName)) ||
  261. !GetSzAddress(szAddr, CCHMAX(szAddr)))
  262. {
  263. return;
  264. }
  265. FCreateSpeedDial(szName, szAddr);
  266. }
  267. /* C M D R E F R E S H */
  268. /*-------------------------------------------------------------------------
  269. %%Function: CmdRefresh
  270. -------------------------------------------------------------------------*/
  271. VOID CALV::CmdRefresh(void)
  272. {
  273. ClearItems();
  274. ShowItems(m_hwnd);
  275. }
  276. ///////////////////////////////////////////////////////////////////////
  277. // RAI routines
  278. /* C R E A T E R A I */
  279. /*-------------------------------------------------------------------------
  280. %%Function: CreateRai
  281. -------------------------------------------------------------------------*/
  282. RAI * CreateRai(LPCTSTR pszName, NM_ADDR_TYPE addrType, LPCTSTR pszAddr)
  283. {
  284. RAI * pRai = new RAI;
  285. LPTSTR psz = PszAlloc(pszAddr);
  286. if ((NULL == pRai) || (NULL == psz))
  287. {
  288. delete pRai;
  289. delete psz;
  290. return NULL;
  291. }
  292. lstrcpyn(pRai->szName, pszName, CCHMAX(pRai->szName));
  293. pRai->cItems = 1;
  294. pRai->rgDwStr[0].psz = psz;
  295. pRai->rgDwStr[0].dw = addrType;
  296. return pRai;
  297. }
  298. /* C L E A R R A I */
  299. /*-------------------------------------------------------------------------
  300. %%Function: ClearRai
  301. -------------------------------------------------------------------------*/
  302. VOID ClearRai(RAI ** ppRai)
  303. {
  304. if (NULL == *ppRai)
  305. return;
  306. for (int i = 0; i < (*ppRai)->cItems; i++)
  307. {
  308. delete (*ppRai)->rgDwStr[i].psz;
  309. }
  310. delete *ppRai;
  311. *ppRai = NULL;
  312. }
  313. /* D U P R A I */
  314. /*-------------------------------------------------------------------------
  315. %%Function: DupRai
  316. -------------------------------------------------------------------------*/
  317. RAI * DupRai(RAI * pRai)
  318. {
  319. if (NULL == pRai)
  320. return NULL;
  321. RAI * pRaiRet = (RAI *) new BYTE[sizeof(RAI) + (pRai->cItems-1)*sizeof(DWSTR)];
  322. if (NULL != pRaiRet)
  323. {
  324. lstrcpy(pRaiRet->szName, pRai->szName);
  325. pRaiRet->cItems = pRai->cItems;
  326. for (int i = 0; i < pRai->cItems; i++)
  327. {
  328. pRaiRet->rgDwStr[i].dw = pRai->rgDwStr[i].dw;
  329. pRaiRet->rgDwStr[i].psz = PszAlloc(pRai->rgDwStr[i].psz);
  330. }
  331. }
  332. return pRaiRet;
  333. }
  334. /* F E N A B L E D N M A D D R */
  335. /*-------------------------------------------------------------------------
  336. %%Function: FEnabledNmAddr
  337. -------------------------------------------------------------------------*/
  338. BOOL FEnabledNmAddr(DWORD dwAddrType)
  339. {
  340. switch (dwAddrType)
  341. {
  342. default:
  343. case NM_ADDR_ULS:
  344. // We only care about ULS addresses if
  345. // we are not in gatekeeper mode...
  346. return !g_fGkEnabled;
  347. case NM_ADDR_UNKNOWN:
  348. case NM_ADDR_IP:
  349. // We always care aobut these addresses
  350. return TRUE;
  351. case NM_ADDR_H323_GATEWAY:
  352. {
  353. return !g_fGkEnabled && g_fGatewayEnabled;
  354. }
  355. case NM_ADDR_ALIAS_ID:
  356. return g_fGkEnabled && !g_bGkPhoneNumberAddressing;
  357. case NM_ADDR_ALIAS_E164:
  358. return g_fGkEnabled && g_bGkPhoneNumberAddressing;
  359. case NM_ADDR_PSTN: // old, never enabled
  360. return FALSE;
  361. }
  362. }