Leaked source code of windows server 2003
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.

3062 lines
76 KiB

  1. // File: dlgcall.cpp
  2. #include "precomp.h"
  3. #include "resource.h"
  4. #include "help_ids.h"
  5. #include "dlgcall2.h"
  6. #include "dirutil.h"
  7. #include "mrulist2.h"
  8. #include "ldap.h"
  9. #include "wab.h"
  10. #include "calv.h"
  11. #include "speedial.h"
  12. #include "history.h"
  13. #include "dlgacd.h"
  14. #include "conf.h"
  15. #include "confroom.h"
  16. #include "confutil.h"
  17. #include "confpolicies.h"
  18. #include "cmd.h"
  19. // GUI constants for this dialog
  20. const UINT DX_BORDER = 6; // Standard spacing for Office dialogs
  21. const UINT DY_BORDER = 6; // Standard spacing for Office dialogs
  22. const UINT DY_COMBOBOX = 200; // Height of the dropped list
  23. const UINT DX_DLGCALL_MIN = 460;
  24. const UINT DY_DLGCALL_MIN = 400;
  25. const UINT DX_DLGCALL_DEFAULT = 800;
  26. const UINT DY_DLGCALL_DEFAULT = 600;
  27. void GetDefaultRect(const HWND hwndParent, RECT & rcRect, const int iDefaultWidth, const int iDefaultHeight);
  28. int GetPixelsPerChar(const HWND hwnd);
  29. const static struct _ColumnInfo
  30. {
  31. int iColumnLabelIds;
  32. int iMinColumnChars;
  33. } ciColumnInfo[ MAX_DIR_COLUMNS ] =
  34. {
  35. { IDS_DIR_COLUMN_EMAIL, 28 },
  36. { IDS_DIR_COLUMN_AUDIO, 0 },
  37. { IDS_DIR_COLUMN_VIDEO, 0 },
  38. { IDS_DIR_COLUMN_LAST_NAME, 16 },
  39. { IDS_DIR_COLUMN_FIRST_NAME, 14 },
  40. { IDS_DIR_COLUMN_LOCATION, 16 },
  41. { IDS_DIR_COLUMN_COMMENTS, 22 }
  42. };
  43. ///////////////////////////////////////////////////////////////////////////
  44. // Local Data
  45. static const DWORD _mpIdHelpDlgCall[] =
  46. {
  47. IDM_DLGCALL_DELETE_ILS, IDH_FINDSOMEONE_DELETE_ILS,
  48. IDM_DLGCALL_NEWWINDOW, IDH_FINDSOMEONE_BROWSER,
  49. IDM_DLGCALL_REFRESH, IDH_FINDSOMEONE_REFRESH,
  50. ID_TB_HELP, IDH_FINDSOMEONE_HELP,
  51. IDS_DLGCALL_EDIT_HDR, IDH_PLACECALL_NAME,
  52. IDE_DLGCALL_NAME, IDH_PLACECALL_NAME,
  53. IDC_DLGCALL_COMBO, IDH_PLACECALL_INFOSTORE,
  54. IDS_SECURITY_CHECKBOX, IDH_PLACECALL_SECURITY_CHKBX,
  55. IDL_DLGCALL_LIST, IDH_PLACECALL_LIST,
  56. IDL_DLGCALL_LISTOWNERDATA, IDH_PLACECALL_LIST,
  57. IDL_DLGCALL_ILS_LISTVIEW, IDH_PLACECALL_LIST,
  58. IDOK, IDH_PLACECALL_CALL,
  59. 0, 0
  60. };
  61. int g_cBusy = 0; // non-zero if busy connecting to server
  62. #ifdef nmDlgCallNormal
  63. const int NM_CALLDLG_DEFAULT = nmDlgCallNormal;
  64. const int NM_CALLDLG_NO_ILS_FILTER = nmDlgCallNoFilter;
  65. const int NM_CALLDLG_NO_ILS = nmDlgCallNoIls;
  66. const int NM_CALLDLG_NO_GAL = nmDlgCallNoGal;
  67. const int NM_CALLDLG_NO_WAB = nmDlgCallNoWab;
  68. const int NM_CALLDLG_NO_SPEEDDIAL = nmDlgCallNoSpeedDial;
  69. const int NM_CALLDLG_NO_HISTORY = nmDlgCallNoHistory;
  70. #endif /* old NM_CALL_DLG constants */
  71. // Dir list types:
  72. const UINT DLT_ULS = 0;
  73. const UINT DLT_IN_CALL_LOG = 1;
  74. const UINT DLT_OUT_CALL_LOG = 2;
  75. const UINT DLT_WAB = 3;
  76. struct DLTCOLUMNINFO
  77. {
  78. int nColumns; // number of columns
  79. int nIconColumns; // number of icon-only columns
  80. UINT uStringID; // string ID of first column
  81. LPTSTR pszRVOrder; // reg val to store column order
  82. LPTSTR pszRVWidths; // reg val to store column widths
  83. LPTSTR pszRVSortAscending; // reg val to store sort direction
  84. LPTSTR pszRVSortColumn; // reg val to store sort column
  85. };
  86. const DLTCOLUMNINFO g_rgDLColumnInfo[] =
  87. {
  88. { MAX_DIR_COLUMNS, 2, IDS_DIR_COLUMN_FIRST, // DLT_ULS
  89. &REGVAL_DIR_COLUMN_ORDER, &REGVAL_DIR_COLUMN_WIDTHS,
  90. &REGVAL_DIR_SORT_ASCENDING, &REGVAL_DIR_SORT_COLUMN },
  91. };
  92. CFindSomeone* CFindSomeone::s_pDlgCall= NULL;
  93. ///////////////////////////////////////////////////////////////////////////
  94. int StringCompare( const TCHAR * const psz1, const TCHAR * const psz2 );
  95. void UpdateSecurityCheck(CConfRoom *pConfRoom, HWND hDlg, UINT idCheck)
  96. {
  97. bool userAlterable, secure;
  98. pConfRoom->get_securitySettings( userAlterable, secure );
  99. EnableWindow( GetDlgItem(hDlg, idCheck), userAlterable );
  100. ::CheckDlgButton( hDlg, idCheck, secure? BST_CHECKED: BST_UNCHECKED );
  101. }
  102. /* C D L G C A L L */
  103. /*-------------------------------------------------------------------------
  104. %%Function: CFindSomeone
  105. -------------------------------------------------------------------------*/
  106. CFindSomeone::CFindSomeone(CConfRoom *pConfRoom):
  107. m_pAccel(NULL),
  108. m_dwOptions(0),
  109. m_hwndList(NULL),
  110. m_ilsListView(NULL),
  111. m_hwndCombo(NULL),
  112. m_hwndComboEdit(NULL),
  113. m_hwndEdit(NULL),
  114. m_webView( NULL ),
  115. m_WndOwnerDataListOldWndProc(NULL),
  116. m_fInEdit(FALSE),
  117. m_iSel(0),
  118. m_pMruServer(NULL),
  119. m_pUls(NULL),
  120. m_pSpeedDial(NULL),
  121. #if USE_GAL
  122. m_pGAL(NULL),
  123. #endif //#if USE_GAL
  124. m_pAlv(NULL),
  125. m_pWab(NULL),
  126. m_pHistory(NULL),
  127. m_pszDefault(NULL),
  128. m_pRai(NULL),
  129. m_pConfRoom(pConfRoom),
  130. m_bPlacedCall(false)
  131. {
  132. SetEmptySz(m_szAddress);
  133. SetEmptySz(m_szDirectory);
  134. // BUGBUG georgep: Why are we checking m_dwOptions? It was set to 0 above.
  135. if ((0 == (m_dwOptions & NM_CALLDLG_NO_WAB)) &&
  136. (NULL == CWAB::GetInstance()) )
  137. {
  138. m_pWab = new CWAB();
  139. }
  140. if (0 == (m_dwOptions & NM_CALLDLG_NO_ILS))
  141. {
  142. m_pMruServer = GetMruListServer();
  143. m_pUls = new CLDAP();
  144. }
  145. if (0 == (m_dwOptions & NM_CALLDLG_NO_SPEEDDIAL))
  146. {
  147. m_pSpeedDial = new CSPEEDDIAL();
  148. }
  149. #if USE_GAL
  150. if ((0 == (m_dwOptions & NM_CALLDLG_NO_GAL)) &&
  151. CGAL::FLoadMapiFns() )
  152. {
  153. m_pGAL = new CGAL();
  154. }
  155. #endif // USE_GAL
  156. if (0 == (m_dwOptions & NM_CALLDLG_NO_HISTORY))
  157. {
  158. m_pHistory = new CHISTORY();
  159. }
  160. // Load the small icon list
  161. m_himlIcon = ImageList_Create(DXP_ICON_SMALL, DYP_ICON_SMALL, ILC_MASK, 1, 0);
  162. if (NULL != m_himlIcon)
  163. {
  164. HBITMAP hBmp = ::LoadBitmap(::GetInstanceHandle(), MAKEINTRESOURCE(IDB_ICON_IMAGES));
  165. if (NULL != hBmp)
  166. {
  167. ImageList_AddMasked(m_himlIcon, hBmp, TOOLBAR_MASK_COLOR);
  168. ::DeleteObject(hBmp);
  169. }
  170. }
  171. m_pConfRoom->AddConferenceChangeHandler(this);
  172. }
  173. CFindSomeone::~CFindSomeone(void)
  174. {
  175. // Clear any existing data
  176. if (NULL != m_pAlv)
  177. {
  178. m_pAlv->ClearItems();
  179. }
  180. delete m_pMruServer;
  181. if (NULL != m_pWab)
  182. {
  183. m_pWab->Release();
  184. }
  185. if (NULL != m_pUls)
  186. {
  187. m_pUls->Release();
  188. }
  189. if (NULL != m_pSpeedDial)
  190. {
  191. m_pSpeedDial->Release();
  192. }
  193. if (NULL != m_himlIcon)
  194. {
  195. ImageList_Destroy(m_himlIcon);
  196. }
  197. #if USE_GAL
  198. if (NULL != m_pGAL)
  199. {
  200. m_pGAL->Release();
  201. }
  202. #endif // USE_GAL
  203. if (NULL != m_pHistory)
  204. {
  205. m_pHistory->Release();
  206. }
  207. ClearRai(&m_pRai);
  208. m_pConfRoom->RemoveConferenceChangeHandler(this);
  209. }
  210. //--------------------------------------------------------------------------//
  211. // CFindSomeone::findSomeone. //
  212. //--------------------------------------------------------------------------//
  213. void
  214. CFindSomeone::findSomeone(CConfRoom *pConfRoom)
  215. {
  216. if (NULL == s_pDlgCall)
  217. {
  218. s_pDlgCall = new CFindSomeone(pConfRoom);
  219. s_pDlgCall->doModeless();
  220. }
  221. if (NULL != s_pDlgCall)
  222. {
  223. HWND hwnd = s_pDlgCall->GetWindow();
  224. ::ShowWindow( hwnd, SW_RESTORE );
  225. ::SetForegroundWindow( hwnd );
  226. }
  227. } // End of CFindSomeone::findSomeone.
  228. //--------------------------------------------------------------------------//
  229. // CDlgCall::Destroy. //
  230. //--------------------------------------------------------------------------//
  231. void
  232. CFindSomeone::Destroy()
  233. {
  234. WARNING_OUT(("Entering CFindSomeone::Destroy( )..."));
  235. CFindSomeone * pDlgCall = s_pDlgCall;
  236. s_pDlgCall = NULL;
  237. if( pDlgCall != NULL )
  238. {
  239. if( pDlgCall->m_pUls != NULL )
  240. {
  241. // Stop the CLDAP thread from trying to interact with the FindSomeone
  242. // windows after we've already destroyed them...
  243. pDlgCall->m_pUls->CloseServer();
  244. }
  245. HWND hwnd = pDlgCall->GetWindow();
  246. if (NULL != hwnd)
  247. {
  248. WARNING_OUT(("CFindSomeone::Destroy( ): destroying windows..."));
  249. DestroyWindow(hwnd);
  250. }
  251. pDlgCall->Release();
  252. }
  253. WARNING_OUT(("Exiting CFindSomeone::Destroy( )..."));
  254. } // End of CDlgCall::Destroy.
  255. HWND CFindSomeone::GetHwndList()
  256. {
  257. return ( m_pAlv && m_pAlv->FOwnerData() ) ?
  258. m_hwndOwnerDataList : (m_pAlv == (CALV *) m_pUls)? m_ilsListView: m_hwndList;
  259. }
  260. RAI * CFindSomeone::GetAddrInfo()
  261. {
  262. return DupRai(m_pRai);
  263. }
  264. /* F M S G S P E C I A L */
  265. /*-------------------------------------------------------------------------
  266. %%Function: FMsgSpecial
  267. Return TRUE if this is a special message, not to be passed to IsDialogMessage
  268. -------------------------------------------------------------------------*/
  269. BOOL CFindSomeone::FMsgSpecial(MSG * pMsg)
  270. {
  271. switch (pMsg->message)
  272. {
  273. case WM_KEYDOWN:
  274. case WM_KEYUP:
  275. case WM_CHAR:
  276. if (VK_F5 == pMsg->wParam)
  277. return TRUE;
  278. if (VK_RETURN == pMsg->wParam)
  279. {
  280. if (m_hwndComboEdit == GetFocus())
  281. {
  282. return TRUE;
  283. }
  284. }
  285. break;
  286. default:
  287. break;
  288. }
  289. return FALSE;
  290. }
  291. /* D O M O D A L */
  292. /*-------------------------------------------------------------------------
  293. %%Function: DoModal
  294. -------------------------------------------------------------------------*/
  295. HRESULT
  296. CFindSomeone::doModeless(void)
  297. {
  298. #if 0
  299. HACCEL hAccel = LoadAccelerators(::GetInstanceHandle(), MAKEINTRESOURCE(IDA_DLGCALL));
  300. #endif
  301. HRESULT hr = CreateDlgCall(NULL);
  302. #if 0
  303. if (SUCCEEDED(hr) && (NULL != m_hwnd))
  304. {
  305. while (IsWindow(m_hwnd))
  306. {
  307. MSG msg;
  308. if (!::GetMessage(&msg, NULL, 0, 0))
  309. {
  310. // Don't eat the WM_QUIT
  311. PostQuitMessage(msg.wParam);
  312. break; // out of loop
  313. }
  314. if (FMsgSpecial(&msg) || !IsDialogMessage(m_hwnd, &msg))
  315. {
  316. if (FALSE == ::TranslateAccelerator(m_hwnd, hAccel, &msg))
  317. {
  318. ::TranslateMessage(&msg);
  319. ::DispatchMessage(&msg);
  320. }
  321. }
  322. }
  323. }
  324. #endif
  325. return hr;
  326. }
  327. // Determine the standard font size
  328. VOID CFindSomeone::CalcDyText(void)
  329. {
  330. m_dyText = 14; // default to something reasonable
  331. HWND hwnd = GetWindow();
  332. ASSERT(NULL != hwnd);
  333. HDC hdc = GetDC(hwnd);
  334. if (NULL == hdc)
  335. return;
  336. TEXTMETRIC tm;
  337. if (GetTextMetrics(hdc, &tm))
  338. {
  339. m_dyText = tm.tmHeight;
  340. }
  341. // Leave space for 4 n's (two on each side)
  342. TCHAR sz[MAX_PATH];
  343. const int cSpaceN = 4;
  344. for (int ich = 0; ich < cSpaceN; ich++)
  345. {
  346. sz[ich] = _T('n');
  347. }
  348. if (FLoadString( IDS_DLGCALL_CLOSE, &sz[cSpaceN], CCHMAX(sz)-cSpaceN))
  349. {
  350. HFONT hfont = SelectFont(hdc, ::GetDefaultFont());
  351. RECT rc;
  352. SetRect(&rc, 0, 0, 0, 0);
  353. m_dyButton = 2*DY_BORDER + DrawText(hdc, sz, -1, &rc, DT_CALCRECT);
  354. m_dxButton = rc.right;
  355. hfont = SelectFont(hdc, hfont);
  356. }
  357. ReleaseDC(hwnd, hdc);
  358. }
  359. HWND CreatIconButton(HWND hwndParent, int idTooltip, int idCmd, int idIcon)
  360. {
  361. HWND hwndButton = CreateButton( hwndParent, idTooltip, idCmd );
  362. if (NULL != hwndButton)
  363. {
  364. AddToolTip(hwndParent, hwndButton, idTooltip);
  365. SetWindowLong(hwndButton, GWL_STYLE, BS_PUSHBUTTON|BS_ICON|WS_VISIBLE|WS_CHILD|WS_TABSTOP);
  366. HANDLE hIcon = LoadImage(GetInstanceHandle(), MAKEINTRESOURCE(idIcon),
  367. IMAGE_ICON, 0, 0, 0);
  368. SendMessage(hwndButton, BM_SETIMAGE, IMAGE_ICON, reinterpret_cast<LPARAM>(hIcon));
  369. }
  370. return(hwndButton);
  371. }
  372. /* C R E A T E D L G C A L L */
  373. /*-------------------------------------------------------------------------
  374. %%Function: CreateDlgCall
  375. The order in which these windows is created is very important.
  376. See the Layout function and pay attention to the tab order
  377. -------------------------------------------------------------------------*/
  378. HRESULT CFindSomeone::CreateDlgCall(HWND hwndParent)
  379. {
  380. TCHAR sz[CCHMAXSZ];
  381. HRESULT hr = S_OK;
  382. if (NULL == m_himlIcon)
  383. return E_FAIL; // no pretty icons, don't bother trying to continue
  384. if (!FLoadString(IDS_DLGCALL_TITLE, sz, CCHMAX(sz)))
  385. return E_FAIL;
  386. // Get the window position
  387. PVOID pv;
  388. RECT rcDest; // left, right, width, height
  389. RegEntry re(DLGCALL_MRU_KEY, HKEY_CURRENT_USER);
  390. if (sizeof(rcDest) == re.GetBinary(REGVAL_DLGCALL_POSITION, &pv))
  391. {
  392. CopyMemory(&rcDest, pv, sizeof(rcDest));
  393. }
  394. else
  395. {
  396. GetDefaultRect( hwndParent, rcDest, DX_DLGCALL_DEFAULT, DY_DLGCALL_DEFAULT );
  397. rcDest.right -= rcDest.left;
  398. rcDest.bottom -= rcDest.top;
  399. }
  400. if (!CFrame::Create(
  401. hwndParent,
  402. sz,
  403. WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
  404. 0,
  405. rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
  406. GetInstanceHandle(),
  407. LoadIcon(GetInstanceHandle(), MAKEINTRESOURCE(IDI_WEBVIEW))
  408. ))
  409. {
  410. return E_OUTOFMEMORY;
  411. }
  412. HWND hwndThis = GetWindow();
  413. CalcDyText();
  414. //////////////////////////////////
  415. // Static text at the top
  416. HWND hwnd = CreateStaticText(hwndThis, IDS_DLGCALL_HDR);
  417. DWORD dwStyle = WS_CHILD | WS_BORDER | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP |
  418. WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBS_AUTOHSCROLL;
  419. // Either a complicated combo edit/listbox or a simple drop list
  420. if ((NULL != m_pUls) && m_pUls->FAvailable())
  421. {
  422. dwStyle |= (0 != (nmDlgCallNoServerEdit & m_dwOptions)) ?
  423. CBS_DROPDOWNLIST : CBS_DROPDOWN;
  424. }
  425. else
  426. {
  427. dwStyle |= CBS_DROPDOWNLIST;
  428. }
  429. m_hwndCombo = ::CreateWindowEx(0L, g_cszComboBoxEx, g_cszEmpty, dwStyle,
  430. 0, 0, DX_BORDER, DY_COMBOBOX,
  431. hwndThis, (HMENU) IDC_DLGCALL_COMBO,
  432. ::GetInstanceHandle(), NULL);
  433. if (NULL != m_hwndCombo)
  434. {
  435. // Set the icons
  436. ::SendMessage(m_hwndCombo, CBEM_SETIMAGELIST, 0, (LPARAM) m_himlIcon);
  437. // Set the font:
  438. ::SendMessage(m_hwndCombo, WM_SETFONT, (WPARAM) GetDefaultFont(), 0);
  439. // Limit the text
  440. ::SendMessage(m_hwndCombo, CB_LIMITTEXT, CCHMAXSZ_ADDRESS-1, 0L);
  441. // Set extended user interface
  442. ::SendMessage(m_hwndCombo, CB_SETEXTENDEDUI, 1, 0L);
  443. m_hwndComboEdit = (HWND) SendMessage(m_hwndCombo, CBEM_GETEDITCONTROL, 0, 0);
  444. if (NULL != m_hwndComboEdit)
  445. {
  446. // Add a tooltip to the combo box (actually, the edit control)
  447. AddToolTip(hwndThis, m_hwndComboEdit, IDS_DLGCALL_COMBO_TOOLTIP);
  448. }
  449. else
  450. {
  451. // Add a tooltip to the combo box
  452. AddToolTip(hwndThis, m_hwndCombo, IDS_DLGCALL_COMBO_TOOLTIP);
  453. }
  454. }
  455. CreatIconButton(hwndThis, IDS_TT_DELETE_ILS, IDM_DLGCALL_DELETE_ILS, IDI_DELETE);
  456. CreatIconButton(hwndThis, IDS_TT_NEWWINDOW , IDM_DLGCALL_NEWWINDOW , IDI_NEWHTMLWINDOW);
  457. CreatIconButton(hwndThis, IDS_TT_REFRESH , IDM_DLGCALL_REFRESH , IDI_REFRESH);
  458. CreatIconButton(hwndThis, IDS_TT_HELP , ID_TB_HELP , IDI_HELP);
  459. //////////////////////////////////
  460. // GroupBox
  461. m_hwndFrame = ::CreateWindowEx( 0, TEXT( "button" ), g_cszEmpty,
  462. WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | WS_GROUP | BS_GROUPBOX,
  463. 0, 0, 0, 0,
  464. hwndThis, (HMENU) -1,
  465. ::GetInstanceHandle(), NULL);
  466. //////////////////////////////////
  467. // Edit Control
  468. CreateStaticText(hwndThis, IDS_DLGCALL_EDIT_HDR);
  469. m_hwndEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE, g_cszEdit, g_cszEmpty,
  470. WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | WS_CLIPCHILDREN |
  471. ES_AUTOHSCROLL,
  472. 0, 0, 0, 0,
  473. hwndThis, (HMENU) IDE_DLGCALL_NAME,
  474. ::GetInstanceHandle(), NULL);
  475. if (NULL != m_hwndEdit)
  476. {
  477. // Set the font:
  478. ::SendMessage(m_hwndEdit, WM_SETFONT, (WPARAM) GetDefaultFont(), 0);
  479. // Limit the text
  480. ::SendMessage(m_hwndEdit, EM_LIMITTEXT, CCHMAXSZ_ADDRESS-1, 0L);
  481. // Add a tooltip to the edit control
  482. AddToolTip(hwndThis, m_hwndEdit, IDS_DLGCALL_EDIT_TOOLTIP);
  483. }
  484. ////////////////////////////////
  485. // Main Listbox
  486. m_hwndList = CreateWindowEx(WS_EX_CLIENTEDGE, g_cszListView, g_cszEmpty,
  487. WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_TABSTOP | WS_VISIBLE |
  488. LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS |
  489. LVS_SORTASCENDING | LVS_NOSORTHEADER,
  490. 0, 0, 0, 0,
  491. hwndThis, (HMENU) IDL_DLGCALL_LIST,
  492. ::GetInstanceHandle(), NULL);
  493. if (NULL != m_hwndList)
  494. {
  495. ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT);
  496. ListView_SetImageList(m_hwndList, m_himlIcon, LVSIL_SMALL);
  497. LV_COLUMN lvc;
  498. ClearStruct(&lvc);
  499. lvc.mask = LVCF_TEXT | LVCF_SUBITEM;
  500. lvc.pszText = sz;
  501. if (FLoadString(IDS_NAME, sz, CCHMAX(sz)))
  502. {
  503. lvc.iSubItem = 0;
  504. ListView_InsertColumn(m_hwndList, IDI_DLGCALL_NAME, &lvc);
  505. }
  506. if (FLoadString(IDS_ADDRESS, sz, CCHMAX(sz)))
  507. {
  508. lvc.iSubItem = 1;
  509. ListView_InsertColumn(m_hwndList, IDI_DLGCALL_ADDRESS, &lvc);
  510. }
  511. m_cVisible = ListView_GetCountPerPage(m_hwndList);
  512. }
  513. ////////////////////////////////
  514. // OwnerData Listbox
  515. m_hwndOwnerDataList = CreateWindowEx(WS_EX_CLIENTEDGE, g_cszListView, g_cszEmpty,
  516. WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_TABSTOP | WS_VISIBLE |
  517. LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS |
  518. LVS_SORTASCENDING | LVS_NOSORTHEADER | LVS_OWNERDATA,
  519. 0, 0, 0, 0,
  520. hwndThis, (HMENU) IDL_DLGCALL_LISTOWNERDATA,
  521. ::GetInstanceHandle(), NULL);
  522. if (NULL != m_hwndOwnerDataList)
  523. {
  524. ListView_SetExtendedListViewStyle(m_hwndOwnerDataList, LVS_EX_FULLROWSELECT);
  525. ListView_SetImageList(m_hwndOwnerDataList, m_himlIcon, LVSIL_SMALL);
  526. LV_COLUMN lvc;
  527. ClearStruct(&lvc);
  528. lvc.mask = LVCF_TEXT | LVCF_SUBITEM;
  529. lvc.pszText = sz;
  530. if (FLoadString(IDS_NAME, sz, CCHMAX(sz)))
  531. {
  532. lvc.iSubItem = 0;
  533. ListView_InsertColumn(m_hwndOwnerDataList, IDI_DLGCALL_NAME, &lvc);
  534. }
  535. if (FLoadString(IDS_ADDRESS, sz, CCHMAX(sz)))
  536. {
  537. lvc.iSubItem = 1;
  538. ListView_InsertColumn(m_hwndOwnerDataList, IDI_DLGCALL_ADDRESS, &lvc);
  539. }
  540. m_WndOwnerDataListOldWndProc = reinterpret_cast< WNDPROC >(GetWindowLongPtr(m_hwndOwnerDataList, GWLP_WNDPROC));
  541. SetWindowLongPtr(m_hwndOwnerDataList, GWLP_USERDATA, reinterpret_cast< LONG_PTR >( this ));
  542. SetWindowLongPtr(m_hwndOwnerDataList, GWLP_WNDPROC, reinterpret_cast< LONG_PTR >( OwnerDataListWndProc));
  543. }
  544. ////////////////////////////////
  545. // ILS Listbox
  546. m_ilsListView = CreateWindowEx( WS_EX_CLIENTEDGE,
  547. WC_LISTVIEW, // list view class
  548. TEXT( "" ), // no default text
  549. WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_TABSTOP |
  550. LVS_REPORT | LVS_SINGLESEL | LVS_AUTOARRANGE | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS,
  551. 0, 0,
  552. 0, 0,
  553. hwndThis,
  554. (HMENU) IDL_DLGCALL_ILS_LISTVIEW,
  555. ::GetInstanceHandle(),
  556. NULL );
  557. if( m_ilsListView != NULL )
  558. {
  559. InitColumns();
  560. // Associate the image list with the list view
  561. ListView_SetImageList( m_ilsListView, m_himlIcon, LVSIL_SMALL);
  562. // set the style to do drag and drop headers and full row select
  563. ListView_SetExtendedListViewStyle( m_ilsListView, ListView_GetExtendedListViewStyle( m_ilsListView ) |
  564. LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES );
  565. }
  566. TCHAR szWebDir[1024];
  567. CDirectoryManager::get_webDirectoryUrl(szWebDir, ARRAY_ELEMENTS(szWebDir));
  568. m_webView = CreateWindowEx( WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT,
  569. TEXT( "AtlAxWin" ),
  570. szWebDir,
  571. WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_TABSTOP,
  572. 0, 0,
  573. 0, 0,
  574. hwndThis,
  575. (HMENU) IDL_DLGCALL_WEB_VIEW,
  576. ::GetInstanceHandle(),
  577. NULL );
  578. //////////////////////////////////
  579. // Security Control
  580. FLoadString( IDS_SECURITY_CHECKBOX, sz, CCHMAX( sz ) );
  581. HWND securityCheckBox;
  582. securityCheckBox = ::CreateWindow(
  583. TEXT( "button" ),
  584. sz,
  585. WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_AUTOCHECKBOX | BS_MULTILINE | BS_TOP,
  586. 0, 0, 0, 0,
  587. hwndThis,
  588. (HMENU) IDS_SECURITY_CHECKBOX,
  589. ::GetInstanceHandle(),
  590. NULL );
  591. if( securityCheckBox != NULL )
  592. {
  593. // Set the font:
  594. ::SendMessage(securityCheckBox, WM_SETFONT, (WPARAM) GetDefaultFont(), 0);
  595. UpdateSecurityCheck(m_pConfRoom, hwndThis, IDS_SECURITY_CHECKBOX);
  596. }
  597. CreateButton( hwndThis, IDS_DLGCALL_CALL, IDOK );
  598. CreateButton( hwndThis, IDS_DLGCALL_CLOSE, IDCANCEL );
  599. // Finally, initialize the data in each list
  600. InitAlv();
  601. Layout();
  602. if( m_ilsListView != NULL )
  603. {
  604. LoadColumnInfo();
  605. }
  606. if (m_pConfRoom->FIsConferenceActive())
  607. {
  608. // Simulate a call started to get all the states right
  609. OnCallStarted();
  610. }
  611. ShowWindow(hwndThis, SW_SHOWNORMAL);
  612. ::EnableWindow(GetDlgItem(hwndThis, IDOK), FALSE);
  613. if( m_pAlv )
  614. {
  615. SetFocus(m_hwndEdit);
  616. if (!FEmptySz(m_pszDefault))
  617. {
  618. SetWindowText(m_hwndEdit, m_pszDefault);
  619. }
  620. }
  621. else
  622. {
  623. hr = E_FAIL;
  624. }
  625. return hr;
  626. }
  627. bool
  628. get_textRect
  629. (
  630. const HWND window,
  631. RECT & rect,
  632. const TCHAR * const measureText = NULL
  633. );
  634. //--------------------------------------------------------------------------//
  635. // get_textRect. //
  636. //--------------------------------------------------------------------------//
  637. bool
  638. get_textRect
  639. (
  640. const HWND window,
  641. RECT & rect,
  642. const TCHAR * const measureText
  643. ){
  644. HDC dc = GetDC( window );
  645. bool result = false;
  646. if( dc != NULL )
  647. {
  648. HFONT font = SelectFont( dc, ::GetDefaultFont() );
  649. if( measureText != NULL )
  650. {
  651. DrawText( dc, measureText, -1, &rect, DT_CALCRECT | DT_WORDBREAK );
  652. result = true;
  653. }
  654. else
  655. {
  656. int length;
  657. if( (length = ::SendMessage( window, WM_GETTEXTLENGTH, 0, 0 )) > 0 )
  658. {
  659. TCHAR * text = new TCHAR [ length + 1 ];
  660. if( text != NULL )
  661. {
  662. ::SendMessage( window, WM_GETTEXT, length + 1, (LPARAM) text );
  663. DrawText( dc, text, -1, &rect, DT_CALCRECT | DT_WORDBREAK );
  664. delete [] text;
  665. result = true;
  666. }
  667. }
  668. }
  669. SelectFont( dc, font );
  670. ReleaseDC( window, dc );
  671. }
  672. return( result );
  673. } // End of get_textRect.
  674. //--------------------------------------------------------------------------//
  675. // CFindSomeone::Layout. //
  676. //--------------------------------------------------------------------------//
  677. void
  678. CFindSomeone::Layout(void)
  679. {
  680. // BUGBUG georgep: Hard coded for now
  681. static const int IconButtonWidth = 24;
  682. static const int IconButtonHeight = 24;
  683. static const int idIconButtons[] =
  684. {
  685. IDM_DLGCALL_DELETE_ILS,
  686. IDM_DLGCALL_NEWWINDOW,
  687. IDM_DLGCALL_REFRESH,
  688. ID_TB_HELP,
  689. };
  690. static const int NumIconButtons = ARRAY_ELEMENTS(idIconButtons);
  691. HWND hwnd = GetWindow();
  692. HDWP hdwp = BeginDeferWindowPos(15);
  693. // Get client area (inside margin/border)...
  694. RECT rc;
  695. GetClientRect(hwnd, &rc);
  696. int clientWidth = rc.right - 2*DX_BORDER;
  697. int clientHeight = rc.bottom - (DY_BORDER + DY_BORDER + m_dyButton);
  698. int maxComboLabelWidth = (clientWidth - NumIconButtons*(DX_BORDER + IconButtonWidth)) / 2;
  699. HWND comboLabel = GetDlgItem( hwnd, IDS_DLGCALL_HDR );
  700. RECT comboRect;
  701. RECT comboLabelRect;
  702. GetWindowRect( m_hwndCombo, &comboRect );
  703. SetRect( &comboLabelRect, 0, 0, maxComboLabelWidth, 0 );
  704. get_textRect( comboLabel, comboLabelRect );
  705. int comboHeight = RectHeight( comboRect );
  706. int comboLabelWidth = RectWidth( comboLabelRect );
  707. int comboLabelHeight = RectHeight( comboLabelRect );
  708. int maxHeight = max( comboHeight, comboLabelHeight );
  709. int comboLabelLeft = DX_BORDER;
  710. int comboLabelTop = max( DY_BORDER, (DY_BORDER + ((maxHeight - comboLabelHeight) / 2)) );
  711. hdwp = DeferWindowPos(hdwp,
  712. comboLabel,
  713. NULL,
  714. comboLabelLeft,
  715. comboLabelTop,
  716. comboLabelWidth,
  717. comboLabelHeight,
  718. SWP_NOACTIVATE | SWP_NOZORDER );
  719. int comboLeft = comboLabelLeft + comboLabelWidth + DX_BORDER;
  720. int comboTop = max( DY_BORDER, (DY_BORDER + ((maxHeight - comboHeight) / 2)) );
  721. int comboWidth = clientWidth - (comboLabelLeft + comboLabelWidth
  722. + NumIconButtons*(DX_BORDER + IconButtonWidth) );
  723. hdwp = DeferWindowPos(hdwp,
  724. m_hwndCombo,
  725. NULL,
  726. comboLeft,
  727. comboTop,
  728. comboWidth,
  729. DY_COMBOBOX,
  730. SWP_NOACTIVATE | SWP_NOZORDER );
  731. {
  732. for (int i=0; i<NumIconButtons; ++i)
  733. {
  734. hdwp = DeferWindowPos(hdwp,
  735. GetDlgItem(hwnd, idIconButtons[i]),
  736. NULL,
  737. comboLeft + comboWidth + DX_BORDER + i*(IconButtonWidth+DX_BORDER),
  738. comboTop,
  739. IconButtonWidth,
  740. IconButtonHeight,
  741. SWP_NOACTIVATE | SWP_NOZORDER );
  742. }
  743. }
  744. int frameTop = maxHeight + DY_BORDER;
  745. hdwp = DeferWindowPos(hdwp,
  746. m_hwndFrame,
  747. NULL,
  748. DX_BORDER,
  749. frameTop,
  750. clientWidth,
  751. clientHeight - frameTop,
  752. SWP_NOACTIVATE | SWP_NOZORDER );
  753. // Add a little because groups draw inside their bounds
  754. frameTop += 2 * DY_BORDER;
  755. RECT editLabelRect;
  756. HWND editLabel = GetDlgItem( hwnd, IDS_DLGCALL_EDIT_HDR );
  757. int editLabelWidth = (clientWidth - (DX_BORDER * 6)) / 2;
  758. SetRect( &editLabelRect, 0, 0, editLabelWidth, 0 );
  759. get_textRect( editLabel, editLabelRect );
  760. int editLabelHeight = RectHeight( editLabelRect );
  761. int editLabelLeft = DY_BORDER * 3;
  762. int editLabelTop = frameTop + DY_BORDER;
  763. hdwp = DeferWindowPos(hdwp,
  764. editLabel,
  765. NULL,
  766. editLabelLeft,
  767. editLabelTop,
  768. editLabelWidth,
  769. editLabelHeight,
  770. SWP_NOACTIVATE | SWP_NOZORDER );
  771. int editTop = editLabelTop + editLabelHeight + DY_BORDER;
  772. // Edit Control
  773. hdwp = DeferWindowPos(hdwp,
  774. m_hwndEdit,
  775. NULL,
  776. editLabelLeft,
  777. editTop,
  778. editLabelWidth,
  779. comboHeight,
  780. SWP_NOACTIVATE | SWP_NOZORDER );
  781. int buttonTop = clientHeight - ((DY_BORDER * 3) / 2) - m_dyButton;
  782. int listViewLeft = 3 * DX_BORDER;
  783. int listViewTop = editTop + comboHeight + DY_BORDER;
  784. int listViewWidth = clientWidth - (DX_BORDER * 4);
  785. int listViewHeight = buttonTop - listViewTop - DY_BORDER;
  786. int columns = _GetCurListViewNumColumns();
  787. int columnWidth = listViewWidth / columns;
  788. // ListBox
  789. hdwp = DeferWindowPos(hdwp,
  790. m_hwndList,
  791. NULL,
  792. listViewLeft,
  793. listViewTop,
  794. listViewWidth,
  795. listViewHeight,
  796. SWP_NOACTIVATE | SWP_NOZORDER );
  797. hdwp = DeferWindowPos(hdwp,
  798. m_hwndOwnerDataList,
  799. NULL,
  800. listViewLeft,
  801. listViewTop,
  802. listViewWidth,
  803. listViewHeight,
  804. SWP_NOACTIVATE | SWP_NOZORDER );
  805. hdwp = DeferWindowPos(hdwp,
  806. m_ilsListView,
  807. NULL,
  808. listViewLeft,
  809. listViewTop,
  810. listViewWidth,
  811. listViewHeight,
  812. SWP_NOACTIVATE | SWP_NOZORDER );
  813. HWND hWndList = GetHwndList();
  814. if( hWndList != m_ilsListView )
  815. {
  816. for( int i = 0; i < columns; i++ )
  817. {
  818. ListView_SetColumnWidth( hWndList, i, columnWidth );
  819. }
  820. }
  821. InvalidateRect( ListView_GetHeader(hWndList), NULL, true );
  822. m_cVisible = ListView_GetCountPerPage(hWndList);
  823. {
  824. int securityWidth = editLabelWidth - GetSystemMetrics( SM_CXSMICON );
  825. HWND security = GetDlgItem( hwnd, IDS_SECURITY_CHECKBOX );
  826. RECT securityRect;
  827. SetRect( &securityRect, 0, 0, securityWidth, 0 );
  828. get_textRect( security, securityRect );
  829. // + 2 for the focus rect
  830. int securityHeight = RectHeight( securityRect ) + 2;
  831. int checkHeight = GetSystemMetrics(SM_CYMENUCHECK);
  832. securityHeight = max (securityHeight, checkHeight);
  833. hdwp = DeferWindowPos(hdwp,
  834. security,
  835. NULL,
  836. listViewLeft,
  837. buttonTop,
  838. securityWidth,
  839. securityHeight,
  840. SWP_NOACTIVATE | SWP_NOZORDER );
  841. }
  842. HWND callButton = GetDlgItem( hwnd, IDOK );
  843. hdwp = DeferWindowPos(hdwp,
  844. callButton,
  845. NULL,
  846. clientWidth - DX_BORDER - m_dxButton,
  847. buttonTop,
  848. m_dxButton,
  849. m_dyButton,
  850. SWP_NOACTIVATE | SWP_NOZORDER );
  851. hdwp = DeferWindowPos(hdwp,
  852. m_webView,
  853. NULL,
  854. DX_BORDER,
  855. frameTop,
  856. clientWidth,
  857. clientHeight - frameTop,
  858. SWP_NOACTIVATE | SWP_NOZORDER );
  859. // Center the close button at the bottom of the window
  860. HWND closeButton = GetDlgItem( hwnd, IDCANCEL );
  861. hdwp = DeferWindowPos(hdwp,
  862. closeButton,
  863. NULL,
  864. (clientWidth - m_dxButton) / 2,
  865. clientHeight + DY_BORDER,
  866. m_dxButton,
  867. m_dyButton,
  868. SWP_NOACTIVATE | SWP_NOZORDER );
  869. EndDeferWindowPos(hdwp);
  870. } // End of CFindSomeone::Layout.
  871. static BOOL IsInClient(HWND hwnd, POINT *ppt)
  872. {
  873. RECT rc;
  874. GetClientRect(hwnd, &rc);
  875. MapWindowPoints(hwnd, HWND_DESKTOP, (POINT *) &rc, 2);
  876. return(PtInRect(&rc, *ppt));
  877. }
  878. void CFindSomeone::OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
  879. {
  880. POINT pt = { xPos, yPos };
  881. if (IsInClient(GetHwndList(), &pt))
  882. {
  883. m_pAlv->OnRClick(pt);
  884. return;
  885. }
  886. if (IsInClient(GetWindow(), &pt))
  887. {
  888. DoHelpWhatsThis(reinterpret_cast<WPARAM>(hwndContext), _mpIdHelpDlgCall);
  889. return;
  890. }
  891. FORWARD_WM_CONTEXTMENU(hwnd, hwndContext, xPos, yPos, CFrame::ProcessMessage);
  892. }
  893. LRESULT CFindSomeone::ProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  894. {
  895. switch (uMsg)
  896. {
  897. HANDLE_MSG(hwnd, WM_COMMAND , OnCommand);
  898. HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);
  899. case WM_GETMINMAXINFO:
  900. {
  901. LPMINMAXINFO lpminmax = (LPMINMAXINFO) lParam;
  902. lpminmax->ptMinTrackSize.x = DX_DLGCALL_MIN;
  903. lpminmax->ptMinTrackSize.y = DY_DLGCALL_MIN;
  904. return 0;
  905. }
  906. case WM_DISPLAY_MSG:
  907. {
  908. DisplayMsgId(hwnd, (int) wParam);
  909. return 0;
  910. }
  911. case WM_CLOSE:
  912. Destroy();
  913. break;
  914. case WM_CREATE:
  915. {
  916. HACCEL hAccel = LoadAccelerators(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDA_DLGCALL));
  917. if (NULL != hAccel)
  918. {
  919. m_pAccel = new CTranslateAccelTable(hwnd, hAccel);
  920. if (NULL != m_pAccel)
  921. {
  922. AddTranslateAccelerator(m_pAccel);
  923. }
  924. }
  925. // Must be done AFTER adding the accelerator table
  926. AddModelessDlg(hwnd);
  927. break;
  928. }
  929. case WM_DESTROY:
  930. {
  931. if (NULL != m_pAccel)
  932. {
  933. RemoveTranslateAccelerator(m_pAccel);
  934. m_pAccel->Release();
  935. m_pAccel = NULL;
  936. }
  937. RemoveModelessDlg(hwnd);
  938. if (NULL != m_pAlv)
  939. {
  940. m_pAlv->ClearItems();
  941. m_pAlv->ClearHwnd();
  942. }
  943. RegEntry re(DLGCALL_MRU_KEY, HKEY_CURRENT_USER);
  944. // Save the window size/position
  945. RECT rc;
  946. if (GetWindowRect(hwnd, &rc))
  947. {
  948. rc.right -= rc.left;
  949. rc.bottom -= rc.top;
  950. re.SetValue(REGVAL_DLGCALL_POSITION, &rc, sizeof(rc));
  951. }
  952. // Save the selected view
  953. TCHAR szServer[CCHMAXSZ_SERVER];
  954. if (0 != GetWindowText(m_hwndComboEdit, szServer, CCHMAX(szServer)))
  955. {
  956. TRACE_OUT(("Saving last used directory is [%s]", szServer));
  957. re.SetValue(REGVAL_DLGCALL_DEFDIR, szServer);
  958. }
  959. StoreColumnInfo();
  960. return 0;
  961. }
  962. case WM_HELP:
  963. {
  964. DoHelp(lParam, _mpIdHelpDlgCall);
  965. break;
  966. }
  967. case WM_NOTIFY:
  968. {
  969. switch (wParam)
  970. {
  971. case IDL_DLGCALL_LIST:
  972. case IDL_DLGCALL_LISTOWNERDATA:
  973. case IDL_DLGCALL_ILS_LISTVIEW:
  974. return OnNotifyList(lParam);
  975. case IDC_DLGCALL_COMBO:
  976. OnNotifyCombo(lParam);
  977. break;
  978. default:
  979. break;
  980. }
  981. break;
  982. }
  983. case WM_SETTINGCHANGE:
  984. {
  985. WINDOWPLACEMENT wp;
  986. wp.length = sizeof(wp);
  987. if (!GetWindowPlacement(hwnd, &wp))
  988. break;
  989. switch (wp.showCmd)
  990. {
  991. case SW_NORMAL:
  992. case SW_RESTORE:
  993. {
  994. CalcDyText();
  995. Layout();
  996. break;
  997. }
  998. default:
  999. break;
  1000. }
  1001. break;
  1002. }
  1003. case WM_SETCURSOR:
  1004. {
  1005. if (0 == g_cBusy)
  1006. break;
  1007. ::SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
  1008. return TRUE;
  1009. }
  1010. case WM_SETFOCUS:
  1011. {
  1012. ::SetFocus(m_hwndEdit);
  1013. return 0;
  1014. }
  1015. default:
  1016. break;
  1017. }
  1018. return(CFrame::ProcessMessage(hwnd, uMsg, wParam, lParam));
  1019. }
  1020. /* O N N O T I F Y L I S T */
  1021. /*-------------------------------------------------------------------------
  1022. %%Function: OnNotifyList
  1023. -------------------------------------------------------------------------*/
  1024. LRESULT CFindSomeone::OnNotifyList(LPARAM lParam)
  1025. {
  1026. LPNMHDR pnmh = (LPNMHDR) lParam;
  1027. HWND hwnd = GetWindow();
  1028. switch (pnmh->code)
  1029. {
  1030. case NM_DBLCLK:
  1031. {
  1032. OnCommand(hwnd, IDOK, NULL, 0);
  1033. break;
  1034. }
  1035. case LVN_KEYDOWN:
  1036. {
  1037. LPNMLVKEYDOWN pkdn = (LPNMLVKEYDOWN) lParam;
  1038. switch (pkdn->wVKey)
  1039. {
  1040. case VK_F5:
  1041. OnCommand(hwnd, IDM_DLGCALL_REFRESH, NULL, 0);
  1042. break;
  1043. case VK_DELETE:
  1044. OnCommand(hwnd, IDM_DLGCALL_DELETE, NULL, 0);
  1045. break;
  1046. default:
  1047. break;
  1048. }
  1049. break;
  1050. }
  1051. case LVN_ITEMCHANGED:
  1052. {
  1053. CConfRoom *pConfRoom = GetConfRoom();
  1054. if (m_fInEdit || NULL == pConfRoom || !pConfRoom->IsNewCallAllowed())
  1055. break;
  1056. int iSel = m_pAlv->GetSelection();
  1057. BOOL fEnable = (-1 != iSel);
  1058. EnableWindow(GetDlgItem(hwnd, IDOK), fEnable);
  1059. break;
  1060. }
  1061. case LVN_GETDISPINFO:
  1062. {
  1063. LV_DISPINFO *lpdi = (LV_DISPINFO *)lParam;
  1064. if (lpdi->item.mask & LVIF_TEXT)
  1065. {
  1066. switch( lpdi->item.iSubItem )
  1067. {
  1068. case 0:
  1069. m_pAlv->OnListGetColumn1Data(lpdi->item.iItem, lpdi->item.cchTextMax, lpdi->item.pszText);
  1070. break;
  1071. case 1:
  1072. m_pAlv->OnListGetColumn2Data(lpdi->item.iItem, lpdi->item.cchTextMax, lpdi->item.pszText);
  1073. break;
  1074. case 2:
  1075. m_pAlv->OnListGetColumn3Data(lpdi->item.iItem, lpdi->item.cchTextMax, lpdi->item.pszText);
  1076. break;
  1077. }
  1078. }
  1079. if( lpdi->item.mask & LVIF_IMAGE )
  1080. {
  1081. lpdi->item.iImage = m_pAlv->OnListGetImageForItem( lpdi->item.iItem );
  1082. }
  1083. break;
  1084. }
  1085. case LVN_ODCACHEHINT:
  1086. {
  1087. LPNMLVCACHEHINT lpCacheHint = reinterpret_cast< LPNMLVCACHEHINT > (lParam);
  1088. m_pAlv->OnListCacheHint(lpCacheHint->iFrom, lpCacheHint->iTo);
  1089. break;
  1090. }
  1091. case LVN_ODFINDITEM:
  1092. {
  1093. LPNMLVFINDITEM lpFindItem = reinterpret_cast< LPNMLVFINDITEM > (lParam);
  1094. if (0 == (lpFindItem->lvfi.flags & (LVFI_PARTIAL | LVFI_STRING)))
  1095. break;
  1096. return m_pAlv->OnListFindItem(lpFindItem->lvfi.psz);
  1097. }
  1098. case LVN_COLUMNCLICK:
  1099. {
  1100. if( m_pAlv == m_pUls )
  1101. {
  1102. // The user clicked on one of the column headings - sort by
  1103. // this column.
  1104. TRACE_OUT(("CFindSomeone::OnNotify called (NM_COLUMNCLICK)"));
  1105. NM_LISTVIEW *pNm = (NM_LISTVIEW *)lParam;
  1106. ASSERT(pNm);
  1107. if (pNm->iSubItem == m_iSortColumn)
  1108. {
  1109. m_fSortAscending = !m_fSortAscending;
  1110. }
  1111. else if( pNm->iSubItem != -1 )
  1112. {
  1113. m_fSortAscending = TRUE;
  1114. }
  1115. if( pNm->iSubItem != -1 )
  1116. {
  1117. m_iSortColumn = pNm->iSubItem;
  1118. }
  1119. else
  1120. {
  1121. pNm->iSubItem = m_iSortColumn;
  1122. }
  1123. SendMessage( pNm->hdr.hwndFrom, WM_SETREDRAW, FALSE, 0 );
  1124. ListView_SortItems( pNm->hdr.hwndFrom,
  1125. CompareWrapper,
  1126. (LPARAM) this );
  1127. SendMessage( pNm->hdr.hwndFrom, WM_SETREDRAW, TRUE, 0 );
  1128. }
  1129. break;
  1130. }
  1131. case NM_CUSTOMDRAW:
  1132. {
  1133. return DoCustomDraw((LPNMLVCUSTOMDRAW)lParam);
  1134. }
  1135. default:
  1136. break;
  1137. }
  1138. return 0;
  1139. }
  1140. /* D O C U S T O M D R A W */
  1141. /*-------------------------------------------------------------------------
  1142. %%Function: DoCustomDraw
  1143. -------------------------------------------------------------------------*/
  1144. LRESULT CFindSomeone::DoCustomDraw(LPNMLVCUSTOMDRAW lplvcd)
  1145. {
  1146. switch (lplvcd->nmcd.dwDrawStage)
  1147. {
  1148. case CDDS_PREPAINT:
  1149. {
  1150. return CDRF_NOTIFYITEMDRAW;
  1151. }
  1152. case CDDS_ITEMPREPAINT:
  1153. {
  1154. if (!m_pAlv->IsItemBold(lplvcd->nmcd.dwItemSpec))
  1155. break;
  1156. //get the existing font
  1157. HFONT hFont = (HFONT)SendMessage(m_hwndOwnerDataList, WM_GETFONT, 0, 0);
  1158. if (NULL == hFont)
  1159. break;
  1160. LOGFONT lf;
  1161. if (0 == GetObject(hFont, sizeof(lf), &lf))
  1162. break;
  1163. lf.lfWeight = FW_BOLD;
  1164. hFont = CreateFontIndirect(&lf);
  1165. if (NULL == hFont)
  1166. break;
  1167. SelectObject(lplvcd->nmcd.hdc, hFont);
  1168. return CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT;
  1169. }
  1170. case CDDS_ITEMPOSTPAINT:
  1171. {
  1172. HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  1173. if (NULL != hFont)
  1174. {
  1175. //clean up stuff here
  1176. hFont = (HFONT)SelectObject(lplvcd->nmcd.hdc, hFont);
  1177. DeleteFont(hFont);
  1178. }
  1179. break;
  1180. }
  1181. default:
  1182. break;
  1183. }
  1184. return CDRF_DODEFAULT;
  1185. }
  1186. /* U P D A T E I L S S E R V E R */
  1187. /*-------------------------------------------------------------------------
  1188. %%Function: UpdateIlsServer
  1189. Update the current ILS server based on the text in the combo's edit control.
  1190. -------------------------------------------------------------------------*/
  1191. VOID CFindSomeone::UpdateIlsServer(void)
  1192. {
  1193. TCHAR szServer[CCHMAXSZ_SERVER];
  1194. if (0 == GetWindowText(m_hwndComboEdit, szServer, CCHMAX(szServer)))
  1195. return;
  1196. const TCHAR * const displayName = CDirectoryManager::get_displayName( szServer );
  1197. const TCHAR * const dnsName = CDirectoryManager::get_dnsName( szServer );
  1198. SetWindowText( m_hwndComboEdit, displayName );
  1199. int iSel = ::SendMessage(m_hwndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM) displayName );
  1200. if ((CB_ERR == iSel) && (NULL != m_pUls) && m_pUls->FAvailable())
  1201. {
  1202. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1203. //
  1204. // Assume this is an ILS server - and add it to the list ONLY if
  1205. // not prevented by policy.
  1206. //
  1207. if (!rePol.GetNumber(REGVAL_POL_NO_ADDING_NEW_ULS, DEFAULT_POL_NO_ADDING_NEW_ULS))
  1208. {
  1209. if (NULL != m_pMruServer)
  1210. {
  1211. if( m_pMruServer->AddNewEntry( dnsName ) )
  1212. {
  1213. iSel = AddAlvSz( m_pUls, displayName, m_iIlsFirst );
  1214. }
  1215. }
  1216. }
  1217. }
  1218. if (CB_ERR == iSel)
  1219. return;
  1220. if (NULL != m_pAlv)
  1221. {
  1222. m_pAlv->ClearItems();
  1223. }
  1224. if (iSel >= m_iIlsFirst)
  1225. {
  1226. if( NULL != m_pUls )
  1227. {
  1228. m_pAlv = m_pUls;
  1229. if( !CDirectoryManager::isWebDirectory( dnsName ) )
  1230. {
  1231. m_pUls->SetServer( dnsName );
  1232. // We have to send this twice so that we don't autocomplete..
  1233. SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSel, 0);
  1234. SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSel, 0);
  1235. }
  1236. }
  1237. }
  1238. ShowList(iSel);
  1239. }
  1240. LRESULT CFindSomeone::OnNotifyCombo(LPARAM lParam)
  1241. {
  1242. NMCOMBOBOXEX * pNmcbe = (NMCOMBOBOXEX*) lParam;
  1243. switch(pNmcbe->hdr.code)
  1244. {
  1245. case CBEN_ENDEDIT:
  1246. {
  1247. PNMCBEENDEDIT pnmcbee = (PNMCBEENDEDIT) lParam;
  1248. if (_T('\0') != pnmcbee->szText[0])
  1249. {
  1250. EndComboEdit(pnmcbee->iWhy);
  1251. }
  1252. break;
  1253. }
  1254. // NOTE: the IE 3.0 comctl32.dll sends us the wrong notification
  1255. // when running under NT. We handle it here, but if we are running
  1256. // on NT using the IE 4.0 comctl32.dll, it will be handled above.
  1257. case CBEN_ENDEDITW:
  1258. {
  1259. PNMCBEENDEDITW pnmcbee = (PNMCBEENDEDITW) lParam;
  1260. if (L'\0' != pnmcbee->szText[0])
  1261. {
  1262. EndComboEdit(pnmcbee->iWhy);
  1263. }
  1264. break;
  1265. }
  1266. default:
  1267. break;
  1268. }
  1269. return 0;
  1270. }
  1271. VOID CFindSomeone::EndComboEdit(int iWhy)
  1272. {
  1273. switch (iWhy)
  1274. {
  1275. case CBENF_RETURN:
  1276. {
  1277. if (SendMessage(m_hwndCombo, CB_GETDROPPEDSTATE, 0, 0))
  1278. {
  1279. // remove the dropdown
  1280. SendMessage(m_hwndCombo, CB_SHOWDROPDOWN, 0, 0);
  1281. }
  1282. UpdateIlsServer();
  1283. break;
  1284. }
  1285. case CBENF_KILLFOCUS:
  1286. {
  1287. // remove the dropdown
  1288. SendMessage(m_hwndCombo, CB_SHOWDROPDOWN, 0, 0);
  1289. break;
  1290. }
  1291. case CBENF_DROPDOWN:
  1292. default:
  1293. break;
  1294. }
  1295. }
  1296. static void DoAxMethod(HWND hwnd, LPWSTR szMethod)
  1297. {
  1298. IUnknown *pUnk;
  1299. if (SUCCEEDED(AtlAxGetControl(hwnd, &pUnk)))
  1300. {
  1301. CComPtr<IDispatch> spDispatch = com_cast<IDispatch>(pUnk);
  1302. if (spDispatch)
  1303. {
  1304. DISPID dispid;
  1305. if (SUCCEEDED(spDispatch->GetIDsOfNames(IID_NULL, &szMethod, 1,
  1306. LOCALE_USER_DEFAULT, &dispid)))
  1307. {
  1308. DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
  1309. HRESULT hr = spDispatch->Invoke(
  1310. dispid,
  1311. IID_NULL,
  1312. LOCALE_USER_DEFAULT,
  1313. DISPATCH_METHOD,
  1314. &dispparamsNoArgs, NULL, NULL, NULL);
  1315. }
  1316. }
  1317. pUnk->Release();
  1318. }
  1319. }
  1320. static void NewHtmlWindow(HWND hwnd)
  1321. {
  1322. IUnknown *pUnk;
  1323. if (SUCCEEDED(AtlAxGetControl(hwnd, &pUnk)))
  1324. {
  1325. CComPtr<IWebBrowser> spWeb = com_cast<IWebBrowser>(pUnk);
  1326. if (spWeb)
  1327. {
  1328. BSTR bstrLocation;
  1329. if (SUCCEEDED(spWeb->get_LocationURL(&bstrLocation)))
  1330. {
  1331. LPTSTR szName;
  1332. if (SUCCEEDED(BSTR_to_LPTSTR (&szName, bstrLocation)))
  1333. {
  1334. LaunchRedirWebPage(szName);
  1335. // Free resources
  1336. //
  1337. delete (szName);
  1338. }
  1339. SysFreeString(bstrLocation);
  1340. }
  1341. }
  1342. pUnk->Release();
  1343. }
  1344. }
  1345. /* O N C O M M A N D */
  1346. /*-------------------------------------------------------------------------
  1347. %%Function: OnCommand
  1348. -------------------------------------------------------------------------*/
  1349. void CFindSomeone::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  1350. {
  1351. ASSERT(NULL != hwnd);
  1352. switch (id)
  1353. {
  1354. case ID_TB_HELP:
  1355. FORWARD_WM_SYSCOMMAND(hwnd, SC_CONTEXTHELP, 0, 0, SendMessage);
  1356. break;
  1357. case IDM_DLGCALL_ENTER:
  1358. if (IsWindowActive(m_hwndCombo))
  1359. {
  1360. UpdateIlsServer();
  1361. }
  1362. else
  1363. {
  1364. HWND hwndFocus = GetFocus();
  1365. TCHAR szClass[20];
  1366. GetClassName(hwndFocus, szClass, ARRAY_ELEMENTS(szClass));
  1367. if (0 == lstrcmpi(szClass, TEXT("button"))
  1368. && BS_PUSHBUTTON == (GetWindowStyle(hwndFocus)&(BS_PUSHBUTTON|BS_CHECKBOX|BS_RADIOBUTTON)))
  1369. {
  1370. // Push the button
  1371. OnCommand(hwnd, GetDlgCtrlID(hwndFocus), hwndFocus, BN_CLICKED);
  1372. }
  1373. else if (IsWindowEnabled(GetDlgItem(hwnd, IDOK)))
  1374. {
  1375. // Try to complete the call
  1376. OnCommand(hwnd, IDOK, NULL, 0);
  1377. }
  1378. else
  1379. {
  1380. MessageBeep(MB_ICONHAND);
  1381. }
  1382. }
  1383. break;
  1384. case IDC_DLGCALL_COMBO:
  1385. {
  1386. switch (codeNotify)
  1387. {
  1388. case CBN_EDITCHANGE:
  1389. {
  1390. OnEditChangeDirectory();
  1391. break;
  1392. }
  1393. case CBN_KILLFOCUS:
  1394. {
  1395. int iSel = ::SendMessage(m_hwndCombo, CB_GETCURSEL, 0, 0);
  1396. if (CB_ERR == iSel)
  1397. {
  1398. UpdateIlsServer();
  1399. }
  1400. else if (iSel != m_iSel)
  1401. {
  1402. ShowList(iSel);
  1403. }
  1404. break;
  1405. }
  1406. case CBN_SELENDOK:
  1407. {
  1408. int iSel = ::SendMessage(m_hwndCombo, CB_GETCURSEL, 0, 0);
  1409. // We have to send this so that we don't autocomplete..
  1410. SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSel, 0);
  1411. ShowList(iSel);
  1412. break;
  1413. }
  1414. default:
  1415. break;
  1416. } /* switch (HIWORD(wParam)) */
  1417. break;
  1418. }
  1419. case IDM_DLGCALL_CALL:
  1420. case IDOK:
  1421. {
  1422. CConfRoom *pConfRoom = GetConfRoom();
  1423. if (NULL == pConfRoom || !pConfRoom->IsNewCallAllowed())
  1424. {
  1425. WARNING_OUT(("Meeting settings prevent outgoing calls"));
  1426. break;
  1427. }
  1428. if (SUCCEEDED(HrGetSelection()))
  1429. {
  1430. onCall();
  1431. }
  1432. else
  1433. {
  1434. if( !hasValidUserInfo( m_pRai ) )
  1435. {
  1436. DisplayMsgErr( hwnd, IDS_NO_CALL_LOG_INFO );
  1437. }
  1438. else
  1439. {
  1440. TCHAR szName[CCHMAXSZ_NAME];
  1441. GetEditText(szName, CCHMAX(szName));
  1442. DisplayMsgErr(hwnd, IDS_ERR_CALLTO, szName);
  1443. }
  1444. }
  1445. break;
  1446. }
  1447. case IDCANCEL:
  1448. {
  1449. PostMessage( hwnd, WM_CLOSE, 0, 0 );
  1450. break;
  1451. }
  1452. case IDE_DLGCALL_NAME:
  1453. {
  1454. switch (codeNotify)
  1455. {
  1456. case EN_CHANGE:
  1457. {
  1458. TCHAR sz[CCHMAXSZ];
  1459. sz[0] = _T('\0');
  1460. GetWindowText(m_hwndEdit, sz, CCHMAX(sz));
  1461. int iSel = CFindSomeone::FindSzBySortedColumn(sz);
  1462. if (-1 != iSel)
  1463. {
  1464. HWND hwndCurr = GetHwndList();
  1465. // Select the item found
  1466. ListView_SetItemState(hwndCurr, iSel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1467. int iTop = ListView_GetTopIndex(hwndCurr);
  1468. int cDiff = (iSel - iTop);
  1469. if ((cDiff < 0) || (cDiff > m_cVisible))
  1470. {
  1471. // Scroll the item into view
  1472. RECT rc;
  1473. ListView_GetItemRect(hwndCurr, iSel, &rc, LVIR_BOUNDS);
  1474. ListView_Scroll(hwndCurr, 0, cDiff * (rc.bottom - rc.top));
  1475. }
  1476. }
  1477. break;
  1478. }
  1479. default:
  1480. break;
  1481. } /* switch (HIWORD(wParam)) */
  1482. break;
  1483. }
  1484. case IDM_DLGCALL_NEWWINDOW:
  1485. NewHtmlWindow(m_webView);
  1486. break;
  1487. case IDM_DLGCALL_REFRESH:
  1488. if (IsWindowVisible(m_webView))
  1489. {
  1490. DoAxMethod(m_webView, L"Refresh");
  1491. break;
  1492. }
  1493. // Fall through
  1494. case IDM_DLGCALL_PROPERTIES:
  1495. case IDM_DLGCALL_DELETE:
  1496. case IDM_DLGCALL_SPEEDDIAL:
  1497. case IDM_DLGCALL_WAB:
  1498. case IDM_DLGCALL_STOP:
  1499. {
  1500. if (NULL != m_pAlv)
  1501. {
  1502. m_pAlv->OnCommand(GET_WM_COMMAND_MPS(id, hwndCtl, codeNotify));
  1503. }
  1504. break;
  1505. }
  1506. case IDM_DLGCALL_DELETE_ILS:
  1507. OnDeleteIlsServer();
  1508. break;
  1509. default:
  1510. break;
  1511. }
  1512. }
  1513. int CFindSomeone::GetEditText(LPTSTR psz, int cchMax)
  1514. {
  1515. ASSERT(NULL != m_hwndEdit);
  1516. int cch = GetWindowText(m_hwndEdit, psz, cchMax);
  1517. return TrimSz(psz);
  1518. }
  1519. HRESULT CFindSomeone::HrGetSelection(void)
  1520. {
  1521. HRESULT result = E_FAIL;
  1522. // Check if we have a selection
  1523. if( ListView_GetNextItem( GetHwndList(), -1, LVNI_ALL | LVNI_SELECTED ) != -1 )
  1524. {
  1525. m_pRai = m_pAlv->GetAddrInfo();
  1526. if( hasValidUserInfo( m_pRai ) )
  1527. {
  1528. result = S_OK;
  1529. }
  1530. }
  1531. return( result );
  1532. } // End of CFindSomeone::HrGetSelection.
  1533. /* F I N D S Z */
  1534. /*-------------------------------------------------------------------------
  1535. %%Function: FindSz
  1536. First the item that matches at least the first part of the string
  1537. from the current list.
  1538. -------------------------------------------------------------------------*/
  1539. int CFindSomeone::FindSz(LPCTSTR psz)
  1540. {
  1541. LV_FINDINFO lvfi;
  1542. ClearStruct(&lvfi);
  1543. lvfi.flags = LVFI_PARTIAL;
  1544. lvfi.psz = (LPTSTR) psz;
  1545. return ListView_FindItem(GetHwndList(), -1, &lvfi);
  1546. }
  1547. //--------------------------------------------------------------------------//
  1548. // CFindSomeone::FindSzBySortedColumn. //
  1549. //--------------------------------------------------------------------------//
  1550. int CFindSomeone::FindSzBySortedColumn(LPCTSTR psz)
  1551. {
  1552. ASSERT( psz != NULL );
  1553. TCHAR pszColumnText[ MAX_PATH ];
  1554. HWND hwndList = GetHwndList();
  1555. bool bSorted = hwndList == m_ilsListView;
  1556. int iSearchColumn = bSorted ? m_iSortColumn : 0;
  1557. int iStart = 0;
  1558. int iEnd = ListView_GetItemCount( hwndList ) - 1;
  1559. int iMid = iEnd / 2;
  1560. int iCompareLength = lstrlen( psz );
  1561. int iResult = -1;
  1562. bool bAscending = (m_fSortAscending != FALSE);
  1563. if( iEnd > 0 )
  1564. {
  1565. if( bSorted && ((iSearchColumn == COLUMN_INDEX_AUDIO) || (iSearchColumn == COLUMN_INDEX_VIDEO) ))
  1566. {
  1567. bSorted = false;
  1568. // The list is sorted by av capabilities.... perform a linear search on the first (unsorted) text column...
  1569. int iColumnOrder[ MAX_DIR_COLUMNS ];
  1570. if( ListView_GetColumnOrderArray( m_ilsListView, g_rgDLColumnInfo[ DLT_ULS ].nColumns, iColumnOrder ) )
  1571. {
  1572. if( (iColumnOrder[ 0 ] == COLUMN_INDEX_AUDIO) || (iColumnOrder[ 0 ] == COLUMN_INDEX_VIDEO) )
  1573. {
  1574. if( (iColumnOrder[ 1 ] == COLUMN_INDEX_AUDIO) || (iColumnOrder[ 1 ] == COLUMN_INDEX_VIDEO) )
  1575. {
  1576. iSearchColumn = 2;
  1577. }
  1578. else
  1579. {
  1580. iSearchColumn = 1;
  1581. }
  1582. }
  1583. else
  1584. {
  1585. iSearchColumn = 0;
  1586. }
  1587. iSearchColumn = iColumnOrder[iSearchColumn];
  1588. }
  1589. }
  1590. if (!bSorted)
  1591. {
  1592. // Do a linear search
  1593. for( int nn = 0; nn <= iEnd; nn++ )
  1594. {
  1595. ListView_GetItemText( hwndList, nn, iSearchColumn, pszColumnText, CCHMAX( pszColumnText ) );
  1596. if( iCompareLength < CCHMAX( pszColumnText ) - 1 )
  1597. {
  1598. pszColumnText[ iCompareLength ] = '\0'; // Only compare iCompareLength characters...
  1599. }
  1600. if( StringCompare( psz, pszColumnText ) == 0 )
  1601. {
  1602. iResult = nn;
  1603. break;
  1604. }
  1605. }
  1606. }
  1607. else
  1608. {
  1609. while( iStart <= iEnd )
  1610. {
  1611. pszColumnText[ 0 ] = '\0';
  1612. ListView_GetItemText( hwndList, iMid, iSearchColumn, pszColumnText, CCHMAX( pszColumnText ) );
  1613. if( iCompareLength < CCHMAX( pszColumnText ) - 1 )
  1614. {
  1615. pszColumnText[ iCompareLength ] = '\0'; // Only compare iCompareLength characters...
  1616. }
  1617. int iCompareResult = StringCompare( psz, pszColumnText );
  1618. bool pszIsLess = (iCompareResult <= 0);
  1619. if( iCompareResult == 0 )
  1620. {
  1621. // We've found a match but we will keep going because there may be more than one
  1622. // and we want to find the "first" one...
  1623. iResult = iMid;
  1624. }
  1625. else
  1626. {
  1627. if( !bAscending )
  1628. {
  1629. pszIsLess = !pszIsLess;
  1630. }
  1631. }
  1632. if( pszIsLess )
  1633. {
  1634. iEnd = iMid - 1;
  1635. }
  1636. else
  1637. {
  1638. iStart = iMid + 1;
  1639. }
  1640. iMid = iStart + ((iEnd - iStart) / 2);
  1641. }
  1642. }
  1643. }
  1644. return( iResult );
  1645. } // End of CFindSomeone::FindSzBySortedColumn.
  1646. VOID CFindSomeone::OnEditChangeDirectory(void)
  1647. {
  1648. if (m_fInEdit)
  1649. return;
  1650. TCHAR szEdit[CCHMAXSZ_ADDRESS];
  1651. TCHAR szBuff[CCHMAXSZ_ADDRESS];
  1652. szEdit[0] = _T('\0');
  1653. int cch = GetWindowText(m_hwndCombo, szEdit, CCHMAX(szEdit));
  1654. CharUpperBuff(szEdit, CCHMAX(szEdit));
  1655. if (0 == cch)
  1656. return;
  1657. // Check if anything changed
  1658. PTCHAR pchSrc = m_szDirectory;
  1659. PTCHAR pchDest = szEdit;
  1660. while ((_T('\0') != *pchSrc) && (*pchSrc == *pchDest))
  1661. {
  1662. // REVIEW: not DBCS safe
  1663. pchSrc++;
  1664. pchDest++;
  1665. }
  1666. if (_T('\0') == *pchDest)
  1667. {
  1668. lstrcpy(m_szDirectory, szEdit);
  1669. return; // quick exit - nothing to do
  1670. }
  1671. if (-1 == FindSzCombo(m_hwndCombo, szEdit, szBuff))
  1672. return;
  1673. m_fInEdit = TRUE;
  1674. AutoCompleteCombo(m_hwndCombo, &szBuff[cch]);
  1675. lstrcpyn(m_szDirectory, szBuff, cch+1);
  1676. CharUpperBuff(m_szDirectory, CCHMAX(m_szDirectory));
  1677. m_fInEdit = FALSE;
  1678. }
  1679. /* I N I T A L V */
  1680. /*-------------------------------------------------------------------------
  1681. %%Function: InitAlv
  1682. -------------------------------------------------------------------------*/
  1683. VOID CFindSomeone::InitAlv(void)
  1684. {
  1685. int iSelDefault = LB_ERR;
  1686. ASSERT( NULL == m_pAlv );
  1687. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  1688. bool bGkEnabled = CALLING_MODE_GATEKEEPER == reConf.GetNumber(REGVAL_CALLING_MODE, CALLING_MODE_DIRECT );
  1689. #if USE_GAL
  1690. // Add each of the view items to the list
  1691. if ((NULL != m_pGAL) && m_pGAL->FAvailable())
  1692. {
  1693. AddAlv(m_pGAL);
  1694. if( !m_pAlv )
  1695. {
  1696. m_pAlv = m_pGAL;
  1697. }
  1698. }
  1699. #endif // #if USE_GAL
  1700. if((!bGkEnabled) && (NULL != m_pSpeedDial) && m_pSpeedDial->FAvailable())
  1701. {
  1702. AddAlv(m_pSpeedDial);
  1703. if( !m_pAlv )
  1704. {
  1705. m_pAlv = m_pSpeedDial;
  1706. }
  1707. }
  1708. if ( (!bGkEnabled) && ( NULL != m_pHistory) && m_pHistory->FAvailable())
  1709. {
  1710. AddAlv(m_pHistory);
  1711. if( !m_pAlv )
  1712. {
  1713. m_pAlv = m_pHistory;
  1714. }
  1715. }
  1716. if ((NULL != m_pWab) && m_pWab->FAvailable())
  1717. {
  1718. AddAlv(m_pWab);
  1719. if( !m_pAlv )
  1720. {
  1721. m_pAlv = m_pWab;
  1722. }
  1723. }
  1724. m_iIlsFirst = ::SendMessage(m_hwndCombo, CB_GETCOUNT, 0, 0);
  1725. // Add the list of ILS servers
  1726. if (bGkEnabled)
  1727. {
  1728. // If there is a customized Web View, we will show it in GK mode as
  1729. // well as in ILS mode
  1730. if ((NULL != m_pUls) && ConfPolicies::GetWebDirInfo())
  1731. {
  1732. AddAlvSz( m_pUls, CDirectoryManager::get_displayName( CDirectoryManager::get_webDirectoryIls() ));
  1733. }
  1734. }
  1735. else
  1736. {
  1737. if((NULL != m_pUls) && m_pUls->FAvailable() && (NULL != m_pMruServer) && !_IsDirectoryServicePolicyDisabled())
  1738. {
  1739. m_pAlv = m_pUls;
  1740. for( int i = m_pMruServer->GetNumEntries() - 1; i >= 0; i-- )
  1741. {
  1742. AddAlvSz( m_pUls, CDirectoryManager::get_displayName( m_pMruServer->GetNameEntry( i ) ) );
  1743. }
  1744. }
  1745. }
  1746. iSelDefault = CB_ERR;
  1747. if( m_pAlv )
  1748. {
  1749. // We know that there is at lest one directory server in the combobox
  1750. // Get the user's last selection
  1751. RegEntry reMru(DLGCALL_MRU_KEY, HKEY_CURRENT_USER);
  1752. LPTSTR psz = reMru.GetString(REGVAL_DLGCALL_DEFDIR);
  1753. if (!FEmptySz(psz))
  1754. {
  1755. TRACE_OUT(("Last directory was [%s]",psz));
  1756. iSelDefault = ::SendMessage(m_hwndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM) psz);
  1757. }
  1758. else
  1759. {
  1760. // This may be the first time, and there is no last use one in the registry
  1761. TCHAR szDirectoryName[CCHMAXSZ];
  1762. if( m_pAlv )
  1763. {
  1764. if( m_pAlv != m_pUls )
  1765. {
  1766. m_pAlv->GetName(szDirectoryName, CCHMAX(szDirectoryName));
  1767. iSelDefault = ::SendMessage(m_hwndCombo, CB_FINDSTRINGEXACT, (WPARAM) -1, (LPARAM) szDirectoryName);
  1768. }
  1769. else if( m_pMruServer->GetNumEntries() > 0 )
  1770. {
  1771. iSelDefault = m_iIlsFirst;
  1772. }
  1773. }
  1774. }
  1775. iSelDefault = (CB_ERR != iSelDefault) ? iSelDefault : 0;
  1776. ShowList(iSelDefault);
  1777. // We have to send this twice so that we don't autocomplete..
  1778. SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSelDefault, 0);
  1779. SendMessage(m_hwndCombo, CB_SETCURSEL, (WPARAM) iSelDefault, 0);
  1780. }
  1781. else
  1782. {
  1783. // The user has no directory services set up
  1784. DisplayMsgErr( NULL, IDS_NO_DIRECTORY_SERVICES_OR_ADDRESS_BOOKS );
  1785. }
  1786. }
  1787. bool CFindSomeone::_IsDirectoryServicePolicyDisabled()
  1788. {
  1789. RegEntry rePol(POLICIES_KEY, HKEY_CURRENT_USER);
  1790. return rePol.GetNumber( REGVAL_POL_NO_DIRECTORY_SERVICES, DEFAULT_POL_NO_DIRECTORY_SERVICES ) ? true : false;
  1791. }
  1792. int CFindSomeone::AddAlv(CALV * pAlv)
  1793. {
  1794. TCHAR sz[CCHMAXSZ];
  1795. pAlv->GetName(sz, CCHMAX(sz));
  1796. return AddAlvSz(pAlv, sz);
  1797. }
  1798. int CFindSomeone::AddAlvSz(CALV * pAlv, LPCTSTR psz, int cbIndex)
  1799. {
  1800. ASSERT(NULL != pAlv);
  1801. ASSERT(NULL != m_hwndCombo);
  1802. COMBOBOXEXITEM cbi;
  1803. ClearStruct(&cbi);
  1804. cbi.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;
  1805. cbi.iItem = cbIndex;
  1806. cbi.iImage = pAlv->GetIconId(psz);
  1807. cbi.iSelectedImage = cbi.iImage;
  1808. cbi.pszText = (LPTSTR) psz;
  1809. cbi.cchTextMax = lstrlen(cbi.pszText);
  1810. int iIndex = ::SendMessage(m_hwndCombo, CBEM_INSERTITEM, 0, (LPARAM) &cbi);
  1811. if (CB_ERR != iIndex)
  1812. {
  1813. ::SendMessage(m_hwndCombo, CB_SETITEMDATA, iIndex, (LPARAM) pAlv);
  1814. }
  1815. return iIndex;
  1816. }
  1817. /* S H O W L I S T */
  1818. /*-------------------------------------------------------------------------
  1819. %%Function: ShowList
  1820. -------------------------------------------------------------------------*/
  1821. VOID CFindSomeone::ShowList(int iSel)
  1822. {
  1823. HWND hwnd = GetWindow();
  1824. if (CB_ERR == iSel)
  1825. return;
  1826. m_iSel = iSel;
  1827. BOOL bPrevListWasOwnerData = m_pAlv->FOwnerData();
  1828. int nColsPrevListView = _GetCurListViewNumColumns();
  1829. BOOL bPrevChangedNumCols = FALSE;
  1830. // Clear any existing data
  1831. if (NULL != m_pAlv)
  1832. {
  1833. m_pAlv->ClearItems();
  1834. if( nColsPrevListView != _GetCurListViewNumColumns() )
  1835. {
  1836. bPrevChangedNumCols = TRUE;
  1837. }
  1838. }
  1839. // Get the new selection
  1840. m_pAlv = (CALV *) ::SendMessage(m_hwndCombo, CB_GETITEMDATA, iSel, 0);
  1841. ASSERT(m_pAlv != NULL);
  1842. ASSERT(m_pAlv != (CALV *) -1);
  1843. BOOL bCurListIsOwnerData = m_pAlv->FOwnerData();
  1844. bool webDir = false;
  1845. TCHAR szServer[CCHMAXSZ_SERVER];
  1846. szServer[0] = 0;
  1847. if (m_pAlv == m_pUls)
  1848. {
  1849. COMBOBOXEXITEM cbi;
  1850. ClearStruct(&cbi);
  1851. cbi.mask = CBEIF_TEXT;
  1852. cbi.iItem = iSel;
  1853. cbi.pszText = szServer;
  1854. cbi.cchTextMax = ARRAY_ELEMENTS(szServer);
  1855. ::SendMessage(m_hwndCombo, CBEM_GETITEM, iSel, (LPARAM)&cbi);
  1856. TRACE_OUT(("CBEM_GETITEM got %s for text", szServer));
  1857. webDir = CDirectoryManager::isWebDirectory( szServer );
  1858. }
  1859. // Show or hide all windows between HELP and CANCEL
  1860. HWND start = GetDlgItem(hwnd, ID_TB_HELP);
  1861. HWND end = GetDlgItem(hwnd, IDCANCEL);
  1862. if (NULL != start)
  1863. {
  1864. UINT uShow = webDir ? SW_HIDE : SW_SHOW;
  1865. for (HWND child=::GetWindow(start, GW_HWNDNEXT);
  1866. child!=NULL && child!=end; child=::GetWindow(child, GW_HWNDNEXT))
  1867. {
  1868. ShowWindow(child, uShow);
  1869. }
  1870. ShowWindow(m_webView, SW_HIDE+SW_SHOW-uShow);
  1871. }
  1872. EnableWindow(GetDlgItem(hwnd, IDM_DLGCALL_NEWWINDOW), webDir);
  1873. EnableWindow( GetDlgItem( hwnd, IDM_DLGCALL_DELETE_ILS ), FALSE );
  1874. if (m_pAlv == m_pUls)
  1875. {
  1876. ::ShowWindow( m_hwndOwnerDataList, SW_HIDE );
  1877. ::ShowWindow( m_hwndList, SW_HIDE );
  1878. if( webDir )
  1879. {
  1880. ::SetFocus( m_webView );
  1881. }
  1882. else
  1883. {
  1884. m_pUls->SetServer( CDirectoryManager::get_dnsName( szServer ) );
  1885. m_pAlv->ShowItems(GetHwndList());
  1886. ::SetFocus( m_ilsListView );
  1887. RegEntry rePol( POLICIES_KEY, HKEY_CURRENT_USER );
  1888. if (!rePol.GetNumber(REGVAL_POL_NO_ADDING_NEW_ULS, DEFAULT_POL_NO_ADDING_NEW_ULS))
  1889. {
  1890. EnableWindow( GetDlgItem( hwnd, IDM_DLGCALL_DELETE_ILS ), TRUE );
  1891. }
  1892. }
  1893. }
  1894. else
  1895. {
  1896. if( m_ilsListView != NULL )
  1897. {
  1898. ::ShowWindow( m_ilsListView, SW_HIDE );
  1899. ::ShowWindow( m_webView, SW_HIDE );
  1900. m_pUls->CacheServerData();
  1901. }
  1902. if (m_pAlv->FOwnerData())
  1903. {
  1904. ::ShowWindow(m_hwndList, SW_HIDE);
  1905. }
  1906. else
  1907. {
  1908. ::ShowWindow(m_hwndOwnerDataList, SW_HIDE);
  1909. }
  1910. m_pAlv->ShowItems(GetHwndList());
  1911. ::SetFocus( GetHwndList() );
  1912. }
  1913. if( bPrevChangedNumCols || ( bCurListIsOwnerData != bPrevListWasOwnerData ) || ( nColsPrevListView != _GetCurListViewNumColumns() ) )
  1914. {
  1915. Layout();
  1916. }
  1917. }
  1918. int CFindSomeone::_GetCurListViewNumColumns()
  1919. {
  1920. int nListViewColumns = DEFAULT_NUM_LISTVIEW_COLUMNS;
  1921. HWND hListViewHeader = NULL;
  1922. HWND hWndList = GetHwndList();
  1923. if( hWndList )
  1924. {
  1925. hListViewHeader = ListView_GetHeader( hWndList );
  1926. if( hListViewHeader )
  1927. {
  1928. nListViewColumns = Header_GetItemCount( hListViewHeader );
  1929. }
  1930. }
  1931. return nListViewColumns;
  1932. }
  1933. /* D L G C A L L S E T H E A D E R */
  1934. /*-------------------------------------------------------------------------
  1935. %%Function: DlgCallSetHeader
  1936. Set the listbox header text for the "address" / "email" / "status" field.
  1937. -------------------------------------------------------------------------*/
  1938. VOID DlgCallSetHeader(HWND hwndList, int ids)
  1939. {
  1940. HWND hwnd = ListView_GetHeader(hwndList);
  1941. if (NULL == hwnd)
  1942. return;
  1943. TCHAR sz[CCHMAXSZ];
  1944. if (!FLoadString(ids, sz, CCHMAX(sz)))
  1945. return;
  1946. HDITEM hdItem;
  1947. ClearStruct(&hdItem);
  1948. hdItem.mask = HDI_TEXT; // | HDI_IMAGE; hdItem.iImage = II_ASCENDING;
  1949. hdItem.pszText = sz;
  1950. hdItem.cchTextMax = lstrlen(hdItem.pszText);
  1951. Header_SetItem(hwnd, IDI_DLGCALL_ADDRESS, &hdItem);
  1952. }
  1953. /* D L G C A L L A D D I T E M */
  1954. /*-------------------------------------------------------------------------
  1955. %%Function: DlgCallAddItem
  1956. Add the name and address to the list, returning the position.
  1957. -------------------------------------------------------------------------*/
  1958. int DlgCallAddItem(HWND hwndList, LPCTSTR pszName, LPCTSTR pszAddress, int iImage, LPARAM lParam, int iItem, LPCTSTR pszComment)
  1959. {
  1960. LV_ITEM lvItem;
  1961. ClearStruct(&lvItem);
  1962. lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  1963. lvItem.iItem = iItem;
  1964. lvItem.lParam = lParam;
  1965. lvItem.iImage = iImage;
  1966. lvItem.pszText = (LPTSTR) pszName;
  1967. lvItem.cchTextMax = lstrlen(lvItem.pszText);
  1968. int iPos = ListView_InsertItem(hwndList, &lvItem);
  1969. if (-1 != iPos)
  1970. {
  1971. ListView_SetItemText(hwndList, iPos, IDI_DLGCALL_ADDRESS, (LPTSTR) pszAddress);
  1972. if( pszComment )
  1973. {
  1974. ListView_SetItemText(hwndList, iPos, IDI_DLGCALL_COMMENT, (LPTSTR) pszComment);
  1975. }
  1976. }
  1977. return iPos;
  1978. }
  1979. /* C A L L T O S Z */
  1980. /*-------------------------------------------------------------------------
  1981. %%Function: CallToSz
  1982. Call an address using "CallTo:"
  1983. -------------------------------------------------------------------------*/
  1984. HRESULT CallToSz(LPCTSTR pcszAddress)
  1985. {
  1986. #ifdef DEBUG
  1987. RegEntry re(DEBUG_KEY, HKEY_LOCAL_MACHINE);
  1988. if (0 != re.GetNumber(REGVAL_DBG_FAKE_CALLTO, DEFAULT_DBG_FAKE_CALLTO))
  1989. {
  1990. MessageBox(NULL, pcszAddress, "Called", MB_OK);
  1991. return S_OK;
  1992. }
  1993. #endif /* DEBUG */
  1994. if (FEmptySz(pcszAddress))
  1995. return E_INVALIDARG;
  1996. TCHAR sz[MAX_PATH];
  1997. lstrcpy(sz, g_cszCallTo);
  1998. int cch = lstrlen(sz);
  1999. if (CCHMAX(sz) <= (cch + lstrlen(pcszAddress)))
  2000. return E_INVALIDARG; // the address won't fit
  2001. lstrcpy(&sz[cch], pcszAddress);
  2002. HINSTANCE hInst = ShellExecute(NULL, NULL, sz, NULL, NULL, SW_SHOWNORMAL);
  2003. return ((INT_PTR)hInst > 32) ? S_OK : E_FAIL;
  2004. }
  2005. //--------------------------------------------------------------------------//
  2006. // GetMruListServer. //
  2007. //--------------------------------------------------------------------------//
  2008. CMRUList *
  2009. GetMruListServer(void)
  2010. {
  2011. CMRUList * pMruList = new CMRUList;
  2012. if( pMruList != NULL )
  2013. {
  2014. pMruList->Load( DIR_MRU_KEY );
  2015. if( CDirectoryManager::isWebDirectoryEnabled() )
  2016. {
  2017. // Make sure the web directory is in the list...
  2018. pMruList->AppendEntry( CDirectoryManager::get_webDirectoryIls() );
  2019. }
  2020. const TCHAR * const defaultServer = CDirectoryManager::get_defaultServer();
  2021. if( lstrlen( defaultServer ) > 0 )
  2022. {
  2023. // Make sure the default server name is in the list and at the top...
  2024. pMruList->AddNewEntry( defaultServer );
  2025. }
  2026. }
  2027. return( pMruList );
  2028. } // End of GetMruListServer.
  2029. // The only purpose for this function is to avoid scrollbar tracking of the data
  2030. /* static */
  2031. LRESULT CALLBACK CFindSomeone::OwnerDataListWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  2032. {
  2033. CFindSomeone* pThis = reinterpret_cast< CFindSomeone* >( GetWindowLongPtr( hwnd, GWLP_USERDATA ) );
  2034. WNDPROC lpPrevWndFunc = pThis->m_WndOwnerDataListOldWndProc;
  2035. bool bUserDroppedScrollSlider = false;
  2036. if (WM_VSCROLL == uMsg)
  2037. {
  2038. switch (LOWORD(wParam))
  2039. {
  2040. case SB_THUMBTRACK:
  2041. // don't track
  2042. return FALSE;
  2043. case SB_THUMBPOSITION:
  2044. bUserDroppedScrollSlider = true;
  2045. // fake a final SB_THUMBTRACK notification
  2046. CallWindowProc(lpPrevWndFunc, hwnd, uMsg, MAKEWPARAM(SB_THUMBTRACK, HIWORD(wParam)), lParam);
  2047. break;
  2048. default:
  2049. break;
  2050. }
  2051. }
  2052. LRESULT lRet = CallWindowProc(lpPrevWndFunc, hwnd, uMsg, wParam, lParam);
  2053. if( bUserDroppedScrollSlider )
  2054. {
  2055. ListView_SetItemState(hwnd, GetScrollPos( hwnd, SB_VERT ), LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  2056. }
  2057. return lRet;
  2058. }
  2059. //--------------------------------------------------------------------------//
  2060. //--------------------------------------------------------------------------//
  2061. // copied from 2.11 dirlist.cpp. //
  2062. //--------------------------------------------------------------------------//
  2063. //--------------------------------------------------------------------------//
  2064. //--------------------------------------------------------------------------//
  2065. // CFindSomeone::InitColumns. //
  2066. //--------------------------------------------------------------------------//
  2067. BOOL CFindSomeone::InitColumns(void)
  2068. {
  2069. BOOL bRet = FALSE;
  2070. if (NULL != m_ilsListView)
  2071. {
  2072. // Remove all columns:
  2073. // NOTE: we could optimize by removing only extras and changing the rest
  2074. while( ListView_DeleteColumn( m_ilsListView, 0 ) ){};
  2075. // Now initialize the columns we will need
  2076. // Initialize the LV_COLUMN structure
  2077. // the mask specifies that the .fmt, .ex, width, and .subitem members
  2078. // of the structure are valid,
  2079. LV_COLUMN lvC; // List View Column structure
  2080. TCHAR szText[256]; // place to store some text
  2081. lvC.pszText = szText;
  2082. lvC.fmt = LVCFMT_LEFT; // left align the column
  2083. // Add the columns.
  2084. for (int index = 0; index < g_rgDLColumnInfo[DLT_ULS].nColumns; index++)
  2085. {
  2086. HD_ITEM hdi;
  2087. switch( index )
  2088. {
  2089. case COLUMN_INDEX_AUDIO:
  2090. hdi.iImage = II_AUDIO_COLUMN_HEADER;
  2091. lvC.mask = LVCF_SUBITEM;
  2092. break;
  2093. case COLUMN_INDEX_VIDEO:
  2094. hdi.iImage = II_VIDEO_COLUMN_HEADER;
  2095. lvC.mask = LVCF_SUBITEM;
  2096. break;
  2097. default:
  2098. hdi.iImage = -1;
  2099. lvC.mask = LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM;
  2100. LoadString( ::GetInstanceHandle(),
  2101. ciColumnInfo[ index ].iColumnLabelIds,
  2102. szText,
  2103. CCHMAX(szText));
  2104. break;
  2105. }
  2106. lvC.iSubItem = index;
  2107. if( ListView_InsertColumn( m_ilsListView, index, &lvC ) == -1 )
  2108. {
  2109. WARNING_OUT(("Could not insert column %d in list view", index));
  2110. }
  2111. else if( hdi.iImage != -1 )
  2112. {
  2113. hdi.mask = HDI_IMAGE | HDI_FORMAT;
  2114. hdi.fmt = HDF_IMAGE;
  2115. Header_SetItem( ListView_GetHeader( m_ilsListView ), index, &hdi );
  2116. }
  2117. }
  2118. Header_SetImageList( ListView_GetHeader( m_ilsListView ), m_himlIcon );
  2119. bRet = TRUE;
  2120. }
  2121. // ISSUE: do we want to persist this data?
  2122. m_fSortAscending = TRUE;
  2123. m_iSortColumn = COLUMN_INDEX_LAST_NAME;
  2124. return bRet;
  2125. }
  2126. //--------------------------------------------------------------------------//
  2127. // CFindSomeone::LoadColumnInfo. //
  2128. //--------------------------------------------------------------------------//
  2129. BOOL
  2130. CFindSomeone::LoadColumnInfo(void)
  2131. {
  2132. RegEntry re(UI_KEY, HKEY_CURRENT_USER);
  2133. // load column info from registry:
  2134. LPLONG plColumns = NULL;
  2135. DWORD dwLength = re.GetBinary( g_rgDLColumnInfo[DLT_ULS].pszRVWidths,
  2136. (LPVOID*) &plColumns);
  2137. if (dwLength == (sizeof(LONG) * g_rgDLColumnInfo[DLT_ULS].nColumns))
  2138. {
  2139. // get width of each column
  2140. for (int i = 0; i < g_rgDLColumnInfo[DLT_ULS].nColumns; i++)
  2141. {
  2142. m_alColumns[i] = plColumns[i];
  2143. ListView_SetColumnWidth(m_ilsListView, i, m_alColumns[i]);
  2144. }
  2145. }
  2146. else
  2147. {
  2148. int iMinColumnPixels[ MAX_DIR_COLUMNS ];
  2149. int iPixelsPerChar = GetPixelsPerChar( m_ilsListView );
  2150. int ii;
  2151. // Loop through all the columns setting their minimum widths...
  2152. for( ii = 0; ii < g_rgDLColumnInfo[ DLT_ULS ].nColumns; ii++ )
  2153. {
  2154. if( (ii == COLUMN_INDEX_AUDIO) || (ii == COLUMN_INDEX_VIDEO) )
  2155. {
  2156. // We use a 16x16 icon, plus add 7 pixels for padding.
  2157. // There's also padding built into the icons to make them look more centered....
  2158. // The column header icons are aligned left and the column icons are aligned right...
  2159. iMinColumnPixels[ ii ] = 23;
  2160. }
  2161. else
  2162. {
  2163. iMinColumnPixels[ ii ] = ciColumnInfo[ ii ].iMinColumnChars * iPixelsPerChar;
  2164. }
  2165. }
  2166. // Loop through all but the last column setting each columns to it's minimum width...
  2167. for( ii = 0; ii < g_rgDLColumnInfo[ DLT_ULS ].nColumns - 1; ii++ )
  2168. {
  2169. ListView_SetColumnWidth( m_ilsListView, ii, iMinColumnPixels[ ii ] );
  2170. m_alColumns[ ii ] = ListView_GetColumnWidth( m_ilsListView, ii );
  2171. }
  2172. // The last column gets the rest...
  2173. int iLastColoumnIndex = g_rgDLColumnInfo[ DLT_ULS ].nColumns - 1;
  2174. ListView_SetColumnWidth( m_ilsListView, iLastColoumnIndex, LVSCW_AUTOSIZE_USEHEADER );
  2175. m_alColumns[ iLastColoumnIndex ] = ListView_GetColumnWidth( m_ilsListView, iLastColoumnIndex );
  2176. if( m_alColumns[ iLastColoumnIndex ] < iMinColumnPixels[ iLastColoumnIndex ] )
  2177. {
  2178. ListView_SetColumnWidth( m_ilsListView, iLastColoumnIndex, iMinColumnPixels[ iLastColoumnIndex ] );
  2179. m_alColumns[ iLastColoumnIndex ] = ListView_GetColumnWidth( m_ilsListView, iLastColoumnIndex );
  2180. }
  2181. }
  2182. // set column order
  2183. LPLONG plColumnOrder = NULL;
  2184. dwLength = re.GetBinary( g_rgDLColumnInfo[DLT_ULS].pszRVOrder,
  2185. (LPVOID*) &plColumnOrder);
  2186. if (dwLength == (sizeof(LONG) * g_rgDLColumnInfo[DLT_ULS].nColumns))
  2187. {
  2188. ListView_SetColumnOrderArray( m_ilsListView,
  2189. g_rgDLColumnInfo[DLT_ULS].nColumns,
  2190. plColumnOrder);
  2191. // load the sort column and direction
  2192. m_iSortColumn = re.GetNumber(g_rgDLColumnInfo[DLT_ULS].pszRVSortColumn, COLUMN_INDEX_LAST_NAME );
  2193. ASSERT(m_iSortColumn < g_rgDLColumnInfo[DLT_ULS].nColumns);
  2194. m_fSortAscending = re.GetNumber(g_rgDLColumnInfo[DLT_ULS].pszRVSortAscending, TRUE);
  2195. }
  2196. else
  2197. {
  2198. const static int iDefaultColumnOrder[] = { COLUMN_INDEX_AUDIO, COLUMN_INDEX_VIDEO, COLUMN_INDEX_LAST_NAME, COLUMN_INDEX_FIRST_NAME, COLUMN_INDEX_ADDRESS, COLUMN_INDEX_LOCATION, COLUMN_INDEX_COMMENTS };
  2199. ListView_SetColumnOrderArray( m_ilsListView, ARRAY_ELEMENTS( iDefaultColumnOrder ), iDefaultColumnOrder );
  2200. }
  2201. return TRUE;
  2202. }
  2203. //--------------------------------------------------------------------------//
  2204. // CFindSomeone::CompareWrapper. //
  2205. //--------------------------------------------------------------------------//
  2206. int
  2207. CALLBACK
  2208. CFindSomeone::CompareWrapper
  2209. (
  2210. LPARAM param1,
  2211. LPARAM param2,
  2212. LPARAM This
  2213. ){
  2214. return( ((CFindSomeone *) This)->DirListViewCompareProc( param1, param2 ) );
  2215. } // End of CFindSomeone::CompareWrapper.
  2216. //--------------------------------------------------------------------------//
  2217. // CFindSomeone::DirListViewCompareProc. //
  2218. //--------------------------------------------------------------------------//
  2219. int
  2220. CFindSomeone::DirListViewCompareProc
  2221. (
  2222. LPARAM param1,
  2223. LPARAM param2
  2224. ){
  2225. LV_ITEM lvi;
  2226. int result;
  2227. if( (m_iSortColumn == COLUMN_INDEX_AUDIO) || (m_iSortColumn == COLUMN_INDEX_VIDEO) )
  2228. {
  2229. lvi.mask = LVIF_IMAGE;
  2230. lvi.iItem = LParamToPos( param1 );
  2231. lvi.iSubItem = m_iSortColumn;
  2232. ListView_GetItem( m_ilsListView, &lvi );
  2233. int iImage1 = lvi.iImage;
  2234. lvi.iItem = LParamToPos( param2 );
  2235. ListView_GetItem( m_ilsListView, &lvi );
  2236. result = lvi.iImage - iImage1;
  2237. }
  2238. else
  2239. {
  2240. // BUGBUG: need better constant for max size
  2241. TCHAR szText1[ MAX_PATH ];
  2242. TCHAR szText2[ MAX_PATH ];
  2243. lvi.mask = LVIF_TEXT;
  2244. lvi.iItem = LParamToPos( param1 );
  2245. lvi.iSubItem = m_iSortColumn;
  2246. lvi.pszText = szText1;
  2247. lvi.cchTextMax = CCHMAX( szText1 );
  2248. ListView_GetItem( m_ilsListView, &lvi );
  2249. lvi.iItem = LParamToPos( param2 );
  2250. lvi.pszText = szText2;
  2251. ListView_GetItem( m_ilsListView, &lvi );
  2252. result = StringCompare( szText1, szText2 );
  2253. }
  2254. if( !m_fSortAscending )
  2255. {
  2256. result = -result;
  2257. }
  2258. return( result );
  2259. }
  2260. //--------------------------------------------------------------------------//
  2261. // CFindSomeone::LParamToPos. //
  2262. //--------------------------------------------------------------------------//
  2263. int CFindSomeone::LParamToPos(LPARAM lParam)
  2264. {
  2265. LV_FINDINFO lvF;
  2266. lvF.flags = LVFI_PARAM;
  2267. lvF.lParam = lParam;
  2268. return( ListView_FindItem( m_ilsListView, -1, &lvF ) ); // Note: retuns -1 on failure...
  2269. }
  2270. //--------------------------------------------------------------------------//
  2271. // CFindSomeone::StoreColumnInfo. //
  2272. //--------------------------------------------------------------------------//
  2273. void
  2274. CFindSomeone::StoreColumnInfo(void)
  2275. {
  2276. if( IsWindow( m_ilsListView ) )
  2277. {
  2278. RegEntry re( UI_KEY, HKEY_CURRENT_USER );
  2279. DWORD dwStyle = ::GetWindowLong( m_ilsListView, GWL_STYLE );
  2280. if( (dwStyle & LVS_TYPEMASK) == LVS_REPORT )
  2281. {
  2282. // get width of each column
  2283. for( int i = 0; i < g_rgDLColumnInfo[ DLT_ULS ].nColumns; i++ )
  2284. {
  2285. m_alColumns[ i ] = ListView_GetColumnWidth( m_ilsListView, i );
  2286. }
  2287. }
  2288. // save this back to registry
  2289. re.SetValue( g_rgDLColumnInfo[ DLT_ULS ].pszRVWidths,
  2290. (LPVOID) m_alColumns,
  2291. sizeof( LONG ) * g_rgDLColumnInfo[ DLT_ULS ].nColumns );
  2292. int anColumnOrder[MAX_DIR_COLUMNS];
  2293. if( ListView_GetColumnOrderArray( m_ilsListView,
  2294. g_rgDLColumnInfo[ DLT_ULS ].nColumns,
  2295. anColumnOrder ) )
  2296. {
  2297. // save the column order to registry
  2298. re.SetValue( g_rgDLColumnInfo[ DLT_ULS ].pszRVOrder,
  2299. (LPVOID) anColumnOrder,
  2300. sizeof( LONG ) * g_rgDLColumnInfo[ DLT_ULS ].nColumns );
  2301. }
  2302. // save the sort column and direction
  2303. re.SetValue(g_rgDLColumnInfo[ DLT_ULS ].pszRVSortColumn, m_iSortColumn);
  2304. re.SetValue(g_rgDLColumnInfo[ DLT_ULS ].pszRVSortAscending, m_fSortAscending);
  2305. }
  2306. } // End of CFindSomeone::StoreColumnInfo.
  2307. //--------------------------------------------------------------------------//
  2308. // CFindSomeone::onCall. //
  2309. //--------------------------------------------------------------------------//
  2310. void
  2311. CFindSomeone::onCall(void)
  2312. {
  2313. if( m_pRai != NULL )
  2314. {
  2315. const bool secure = (IsDlgButtonChecked( GetWindow(), IDS_SECURITY_CHECKBOX ) == BST_CHECKED);
  2316. const NM_ADDR_TYPE nmType = static_cast<NM_ADDR_TYPE>(m_pRai->rgDwStr[ 0 ].dw);
  2317. g_pCCallto->Callto( m_pRai->rgDwStr[ 0 ].psz, // pointer to the callto url to try to place the call with...
  2318. m_pRai->szName, // pointer to the display name to use...
  2319. nmType, // callto type to resolve this callto as...
  2320. true, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
  2321. &secure, // security preference, NULL for none. must be "compatible" with secure param if present...
  2322. false, // whether or not save in mru...
  2323. true, // whether or not to perform user interaction on errors...
  2324. GetWindow(), // if bUIEnabled is true this is the window to parent error/status windows to...
  2325. NULL ); // out pointer to INmCall * to receive INmCall * generated by placing call...
  2326. }
  2327. } // End of CFindSomeone::onCall.
  2328. //--------------------------------------------------------------------------//
  2329. // CFindSomeone::OnDeleteIlsServer. //
  2330. //--------------------------------------------------------------------------//
  2331. void CFindSomeone::OnDeleteIlsServer(void)
  2332. {
  2333. if( m_pMruServer != NULL )
  2334. {
  2335. int iSelectionIndex = ::SendMessage( m_hwndCombo, CB_GETCURSEL, 0, 0 );
  2336. if( iSelectionIndex != CB_ERR )
  2337. {
  2338. int iLength = ::SendMessage( m_hwndCombo, CB_GETLBTEXTLEN, iSelectionIndex, 0 );
  2339. TCHAR * pszIls = new TCHAR [ iLength + 1 ];
  2340. if( pszIls != NULL )
  2341. {
  2342. if( ::SendMessage( m_hwndCombo, CB_GETLBTEXT, iSelectionIndex, (LPARAM) pszIls ) != CB_ERR )
  2343. {
  2344. HWND hwndDialog = s_pDlgCall->GetWindow();
  2345. USES_RES2T
  2346. TCHAR res1[RES_CH_MAX];
  2347. TCHAR res2[RES_CH_MAX];
  2348. RES2T( IDS_MSGBOX_TITLE );
  2349. COPY_RES2T(res2)
  2350. // First make sure this directory server isn't their default server....
  2351. if( lstrcmpi( pszIls, CDirectoryManager::get_defaultServer() ) == 0 )
  2352. {
  2353. RES2T( IDS_DLGCALL_CANT_DELETE_DEFAULT_ILS );
  2354. COPY_RES2T(res1);
  2355. ::MessageBox( hwndDialog, res1, res2, MB_SETFOREGROUND | MB_OK | MB_ICONEXCLAMATION );
  2356. }
  2357. else
  2358. {
  2359. // Next make them confirm they want to do this...
  2360. if( ::MessageBox( hwndDialog, RES2T( IDS_DLGCALL_CONFIRM_DELETE_ILS ), res2, MB_SETFOREGROUND | MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 ) == IDYES )
  2361. {
  2362. if( m_pMruServer->DeleteEntry( pszIls ) )
  2363. {
  2364. m_pMruServer->Save();
  2365. int iCount = ::SendMessage( m_hwndCombo, CB_DELETESTRING, iSelectionIndex, 0 );
  2366. if( iCount <= iSelectionIndex )
  2367. {
  2368. iSelectionIndex--;
  2369. }
  2370. ::SendMessage( m_hwndCombo, CB_SETCURSEL, iSelectionIndex, 0 );
  2371. ShowList( iSelectionIndex );
  2372. }
  2373. }
  2374. }
  2375. }
  2376. delete [] pszIls;
  2377. }
  2378. }
  2379. }
  2380. } // End of CFindSomeone::OnDeleteIlsServer.
  2381. void CFindSomeone::OnCallStarted()
  2382. {
  2383. HWND hwnd = GetWindow();
  2384. m_secure = ::IsDlgButtonChecked( hwnd, IDS_SECURITY_CHECKBOX ) != 0;
  2385. UpdateSecurityCheck(m_pConfRoom, hwnd, IDS_SECURITY_CHECKBOX);
  2386. // BUGBUG georgep: We get notified before the actual conference state
  2387. // changes, so we need to disable manually
  2388. ::EnableWindow( GetDlgItem(hwnd, IDS_SECURITY_CHECKBOX), FALSE );
  2389. }
  2390. void CFindSomeone::OnCallEnded()
  2391. {
  2392. HWND hwnd = GetWindow();
  2393. UpdateSecurityCheck(m_pConfRoom, hwnd, IDS_SECURITY_CHECKBOX);
  2394. ::CheckDlgButton( hwnd, IDS_SECURITY_CHECKBOX, m_secure );
  2395. }
  2396. //--------------------------------------------------------------------------//
  2397. // StringCompare. //
  2398. //--------------------------------------------------------------------------//
  2399. int StringCompare( const TCHAR * const psz1, const TCHAR * const psz2 )
  2400. {
  2401. ASSERT( psz1 != NULL );
  2402. ASSERT( psz2 != NULL );
  2403. int iResult = CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, psz1, -1, psz2, -1 );
  2404. ASSERT( iResult != 0);
  2405. if( iResult == CSTR_LESS_THAN )
  2406. {
  2407. iResult = -1;
  2408. }
  2409. else if( iResult == CSTR_GREATER_THAN )
  2410. {
  2411. iResult = 1;
  2412. }
  2413. else
  2414. {
  2415. iResult = 0;
  2416. }
  2417. return( iResult );
  2418. } // End of StringCompare.
  2419. //--------------------------------------------------------------------------//
  2420. // GetDefaultRect. //
  2421. //--------------------------------------------------------------------------//
  2422. void GetDefaultRect(const HWND hwndParent, RECT & rcRect, const int iDefaultWidth, const int iDefaultHeight)
  2423. {
  2424. RECT rcWorkArea;
  2425. bool bResizeAndCenter = true;
  2426. if( !SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWorkArea, 0 ) )
  2427. {
  2428. SetRect( &rcWorkArea, 0, 0, GetSystemMetrics( SM_CXSCREEN ) - 1, GetSystemMetrics( SM_CYSCREEN ) - 1 );
  2429. }
  2430. if( IsWindow( hwndParent ) )
  2431. {
  2432. GetWindowRect( hwndParent, &rcRect );
  2433. rcRect.left += DX_BORDER;
  2434. rcRect.top += DY_BORDER + GetSystemMetrics( SM_CYCAPTION );
  2435. rcRect.right = rcRect.left + iDefaultWidth;
  2436. rcRect.bottom = rcRect.top + iDefaultHeight;
  2437. if( (rcRect.left >= rcWorkArea.left) && (rcRect.top >= rcWorkArea.top) &&
  2438. (rcRect.right <= rcWorkArea.right) && (rcRect.bottom <= rcWorkArea.bottom) )
  2439. {
  2440. bResizeAndCenter = false;
  2441. }
  2442. }
  2443. if( bResizeAndCenter )
  2444. {
  2445. int iWidth = rcWorkArea.right - rcWorkArea.left;
  2446. if( iWidth > iDefaultWidth )
  2447. {
  2448. iWidth -= iDefaultWidth;
  2449. iWidth /= 2;
  2450. rcWorkArea.left += iWidth;
  2451. rcWorkArea.right = rcWorkArea.left + iDefaultWidth;
  2452. }
  2453. else
  2454. {
  2455. iWidth = (rcWorkArea.right - rcWorkArea.left) / 10;
  2456. rcWorkArea.left += iWidth;
  2457. rcWorkArea.right -= iWidth;
  2458. }
  2459. int iHeight = rcWorkArea.bottom - rcWorkArea.top;
  2460. if( iHeight > iDefaultHeight )
  2461. {
  2462. iHeight -= iDefaultHeight;
  2463. iHeight /= 2;
  2464. rcWorkArea.top += iHeight;
  2465. rcWorkArea.bottom = rcWorkArea.top + iDefaultHeight;
  2466. }
  2467. else
  2468. {
  2469. iHeight = (rcWorkArea.bottom - rcWorkArea.top) / 10;
  2470. rcWorkArea.top += iHeight;
  2471. rcWorkArea.bottom -= iHeight;
  2472. }
  2473. rcRect = rcWorkArea;
  2474. }
  2475. } // End of GetDefaultRect.
  2476. //--------------------------------------------------------------------------//
  2477. // GetPixelsPerChar. //
  2478. //--------------------------------------------------------------------------//
  2479. int GetPixelsPerChar(const HWND hwnd)
  2480. {
  2481. int iPixels = 10;
  2482. if( IsWindow( hwnd ) )
  2483. {
  2484. HDC hDC;
  2485. if( (hDC = GetDC( hwnd )) != NULL )
  2486. {
  2487. HFONT hFont;
  2488. if( (hFont = (HFONT) SendMessage( hwnd, WM_GETFONT, 0, 0 )) != NULL )
  2489. {
  2490. hFont = (HFONT) SelectObject( hDC, hFont );
  2491. TEXTMETRIC tmMetrics;
  2492. GetTextMetrics( hDC, &tmMetrics );
  2493. iPixels = tmMetrics.tmAveCharWidth;
  2494. SelectObject( hDC, hFont );
  2495. }
  2496. ReleaseDC( hwnd, hDC );
  2497. }
  2498. }
  2499. return( iPixels );
  2500. } // End of GetPixelsPerChar.