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.

681 lines
24 KiB

  1. //--------------------------------------------------------------------------//
  2. // Header Files. //
  3. //--------------------------------------------------------------------------//
  4. #include "precomp.h"
  5. #include "resource.h"
  6. #include "help_ids.h"
  7. #include "dlgcall2.h"
  8. #include "mrulist2.h"
  9. #include "dlgacd.h"
  10. #include "dlgCall2.h"
  11. #include "calv.h"
  12. #include "dirutil.h"
  13. #include "callto.h"
  14. #include "conf.h"
  15. #include "confroom.h"
  16. #include "confpolicies.h"
  17. extern void UpdateSecurityCheck(CConfRoom *pConfRoom, HWND hDlg, UINT idCheck);
  18. //--------------------------------------------------------------------------//
  19. // CDlgAcd::CDlgAcd. //
  20. //--------------------------------------------------------------------------//
  21. CDlgAcd::CDlgAcd(CConfRoom *pConfRoom):
  22. m_hwnd( NULL ),
  23. m_nameCombo( NULL ),
  24. m_addressTypeCombo( NULL ),
  25. m_pRai( NULL ),
  26. m_mruRai( NULL ),
  27. m_pConfRoom( pConfRoom ),
  28. m_secure( false )
  29. {
  30. // Ensure the common controls are loaded...
  31. INITCOMMONCONTROLSEX icc;
  32. icc.dwSize = sizeof(icc);
  33. icc.dwICC = ICC_WIN95_CLASSES | ICC_COOL_CLASSES | ICC_USEREX_CLASSES;
  34. InitCommonControlsEx( &icc );
  35. } // End of CDlgAcd::CDlgAcd.
  36. //--------------------------------------------------------------------------//
  37. // CDlgAcd::~CDlgAcd. //
  38. //--------------------------------------------------------------------------//
  39. CDlgAcd::~CDlgAcd()
  40. {
  41. ClearRai( &m_mruRai );
  42. } // End of CDlgAcd::~CDlgAcd.
  43. //--------------------------------------------------------------------------//
  44. // CDlgAcd::doModal. //
  45. //--------------------------------------------------------------------------//
  46. INT_PTR CDlgAcd::doModal
  47. (
  48. HWND parent,
  49. RichAddressInfo * rai,
  50. bool & secure
  51. ){
  52. INT_PTR result;
  53. m_pRai = rai;
  54. m_secure = secure;
  55. result = DialogBoxParam( ::GetInstanceHandle(),
  56. MAKEINTRESOURCE( IDD_ACD ),
  57. parent,
  58. DlgProcAcd,
  59. (LPARAM) this );
  60. secure = m_secure;
  61. return( result );
  62. } // End of CDlgAcd::doModal.
  63. //--------------------------------------------------------------------------//
  64. // CDlgAcd::DlgProcAcd. //
  65. //--------------------------------------------------------------------------//
  66. INT_PTR
  67. CALLBACK
  68. CDlgAcd::DlgProcAcd
  69. (
  70. HWND dialog,
  71. UINT message,
  72. WPARAM wParam,
  73. LPARAM lParam
  74. ){
  75. static const DWORD helpIDMap[] =
  76. {
  77. IDC_STATIC_ADDRESS, IDH_GENERAL_GENERAL,
  78. IDB_ACD_ADDRESS, IDH_PLACECALL_TO_TEXT,
  79. IDL_ACD_ADDRESS, IDH_PLACECALL_TO_TEXT,
  80. IDC_ACD_USING_STATIC, IDH_PLACECALL_USING,
  81. IDL_ACD_ADDR_TYPE, IDH_PLACECALL_USING,
  82. IDC_SECURE_CALL, IDH_PLACECALL_SECURITY_CHKBX,
  83. IDC_ACD_DIRECTORY, IDH_PLACECALL_TO,
  84. IDOK, IDH_PLACECALL_CALL,
  85. 0, 0
  86. };
  87. bool result = false;
  88. switch( message )
  89. {
  90. case WM_INITDIALOG:
  91. {
  92. ASSERT(NULL != lParam);
  93. ::SetWindowLongPtr( dialog, DWLP_USER, lParam );
  94. result = ((CDlgAcd *) lParam)->onInitDialog( dialog );
  95. }
  96. break;
  97. case WM_COMMAND:
  98. {
  99. CDlgAcd * acd = (CDlgAcd *) ::GetWindowLongPtr( dialog, DWLP_USER );
  100. if( acd != NULL )
  101. {
  102. result = acd->onCommand( LOWORD( wParam ), HIWORD( wParam ) );
  103. }
  104. }
  105. break;
  106. case WM_CONTEXTMENU:
  107. {
  108. DoHelpWhatsThis( wParam, helpIDMap );
  109. }
  110. break;
  111. case WM_HELP:
  112. {
  113. DoHelp( lParam, helpIDMap );
  114. }
  115. break;
  116. }
  117. return( (BOOL) result );
  118. } // End of CDlgAcd::DlgProcAcd.
  119. //--------------------------------------------------------------------------//
  120. // CDlgAcd::onInitDialog. //
  121. //--------------------------------------------------------------------------//
  122. bool
  123. CDlgAcd::onInitDialog
  124. (
  125. HWND dialog
  126. ){
  127. m_hwnd = dialog;
  128. UpdateSecurityCheck(m_pConfRoom, m_hwnd, IDC_SECURE_CALL);
  129. HICON directoryIcon = LoadIcon( ::GetInstanceHandle(), MAKEINTRESOURCE( IDI_DIRECTORY ) );
  130. if( directoryIcon != NULL )
  131. {
  132. ::SendDlgItemMessage( dialog, IDC_ACD_DIRECTORY, BM_SETIMAGE, IMAGE_ICON, (LPARAM) directoryIcon );
  133. }
  134. m_nameCombo = GetDlgItem( m_hwnd, IDL_ACD_ADDRESS );
  135. m_addressTypeCombo = GetDlgItem( m_hwnd, IDL_ACD_ADDR_TYPE );
  136. ComboBox_LimitText( m_nameCombo, CCHMAXSZ_ADDRESS - 1 );
  137. fillCallMruList();
  138. fillAddressTypesList();
  139. ::SendMessage( m_nameCombo, EM_LIMITTEXT, CCallto::s_iMaxAddressLength, 0 );
  140. if( hasValidUserInfo( m_pRai ) )
  141. {
  142. ::SetWindowText( m_nameCombo, m_pRai->szName );
  143. ::SendMessage( m_addressTypeCombo, CB_SETCURSEL, m_pRai->rgDwStr[ 0 ].dw, 0 );
  144. }
  145. else
  146. {
  147. ::SendMessage( m_addressTypeCombo, CB_SETCURSEL, 0, 0 );
  148. }
  149. CenterWindow( m_hwnd, ::GetParent( m_hwnd ) );
  150. if (m_pConfRoom->FIsConferenceActive())
  151. {
  152. // Simulate a call started to get all the states right
  153. OnCallStarted();
  154. }
  155. return( true ); // Default focus...
  156. } // End of CDlgAcd::onInitDialog.
  157. //--------------------------------------------------------------------------//
  158. // CDlgAcd::fillCallMruList. //
  159. //--------------------------------------------------------------------------//
  160. void
  161. CDlgAcd::fillCallMruList(void)
  162. {
  163. ASSERT(NULL != m_nameCombo);
  164. COMBOBOXEXITEM cbi;
  165. ClearStruct( &cbi );
  166. cbi.mask = CBEIF_TEXT;
  167. cbi.iItem = -1; // Always insert at the end...
  168. HRESULT result = S_OK;
  169. for( int nn = 0; result == S_OK; nn++ )
  170. {
  171. RichAddressInfo * rai;
  172. if( (result = m_callMruList.GetAddress( nn, &rai )) == S_OK )
  173. {
  174. cbi.pszText = rai->szName;
  175. cbi.cchTextMax = lstrlen( cbi.pszText );
  176. int index = (int)::SendMessage( m_nameCombo, CBEM_INSERTITEM, 0, (LPARAM) &cbi );
  177. if( index != CB_ERR )
  178. {
  179. ::SendMessage( m_nameCombo, CB_SETITEMDATA, index, nn );
  180. }
  181. else
  182. {
  183. result = S_FALSE;
  184. }
  185. ClearRai( &rai );
  186. }
  187. }
  188. } // End of CDlgAcd::fillCallMruList.
  189. //--------------------------------------------------------------------------//
  190. // CDlgAcd::fillAddressTypesList. //
  191. //--------------------------------------------------------------------------//
  192. void
  193. CDlgAcd::fillAddressTypesList(void)
  194. {
  195. using namespace ConfPolicies;
  196. enum CallMode
  197. {
  198. CM_GK = 0x0001, // GateKeeper
  199. CM_GW = 0x0002, // Gateway
  200. CM_NoGate = 0x0004, // Neither
  201. } ;
  202. static const struct
  203. {
  204. LPARAM dwCallType;
  205. UINT idTitle;
  206. UINT uCallMode;
  207. } s_mpCtIds[] =
  208. {
  209. { NM_ADDR_UNKNOWN, IDS_ACD_CT_AUTOMATIC, CM_GK|CM_GW|CM_NoGate },
  210. { NM_ADDR_MACHINENAME, IDS_ACD_CT_IP, CM_GW|CM_NoGate },
  211. { NM_ADDR_ULS, IDS_ACD_CT_ILS, CM_GW|CM_NoGate },
  212. { NM_ADDR_ALIAS_E164, IDS_ACD_CT_PHONE, CM_GK|CM_GW },
  213. { NM_ADDR_ALIAS_ID, IDS_ACD_CT_ALIAS, CM_GK },
  214. } ;
  215. HWND combo = GetDlgItem( m_hwnd, IDL_ACD_ADDR_TYPE );
  216. if( combo != NULL )
  217. {
  218. UINT uCallType = CM_NoGate;
  219. if (CallingMode_GateKeeper == GetCallingMode())
  220. {
  221. uCallType = CM_GK;
  222. }
  223. else
  224. {
  225. RegEntry reConf(CONFERENCING_KEY, HKEY_CURRENT_USER);
  226. if (reConf.GetNumber( REGVAL_USE_H323_GATEWAY ) != 0)
  227. {
  228. uCallType = CM_GW;
  229. }
  230. }
  231. for( int nn = 0; nn < ARRAY_ELEMENTS(s_mpCtIds); nn++ )
  232. {
  233. if (0 == (uCallType & s_mpCtIds[nn].uCallMode))
  234. {
  235. continue;
  236. }
  237. TCHAR sz[ CCHMAXSZ_NAME ];
  238. if( FLoadString( s_mpCtIds[ nn ].idTitle, sz, CCHMAX( sz ) ) )
  239. {
  240. int index = (int)::SendMessage( combo, CB_INSERTSTRING, -1, (LPARAM) sz );
  241. if( index != CB_ERR )
  242. {
  243. ::SendMessage( combo, CB_SETITEMDATA, index, s_mpCtIds[ nn ].dwCallType );
  244. }
  245. }
  246. }
  247. }
  248. } // End of CDlgAcd::fillAddressTypesList.
  249. //--------------------------------------------------------------------------//
  250. // CDlgAcd::onCommand. //
  251. //--------------------------------------------------------------------------//
  252. bool
  253. CDlgAcd::onCommand
  254. (
  255. int command,
  256. int notification
  257. ){
  258. ASSERT(NULL != m_hwnd);
  259. bool result = false;
  260. switch( command )
  261. {
  262. case IDC_SECURE_CALL:
  263. {
  264. m_secure = (IsDlgButtonChecked( m_hwnd, IDC_SECURE_CALL ) == BST_CHECKED);
  265. }
  266. break;
  267. case IDL_ACD_ADDRESS:
  268. {
  269. if( notification == CBN_EDITCHANGE )
  270. {
  271. onEditChange();
  272. }
  273. else if( notification == CBN_SELCHANGE )
  274. {
  275. int iSel = (int)::SendMessage( m_nameCombo, CB_GETCURSEL, 0, 0 );
  276. if (iSel >= 0)
  277. {
  278. onMruSelect( iSel );
  279. }
  280. }
  281. }
  282. break;
  283. case IDL_ACD_ADDR_TYPE:
  284. if (CBN_SELCHANGE == notification)
  285. {
  286. // Pretend like the user just typed in the edit control
  287. onEditChange();
  288. }
  289. break;
  290. case IDC_ACD_DIRECTORY:
  291. {
  292. CFindSomeone::findSomeone(m_pConfRoom);
  293. ::EndDialog( m_hwnd, IDCANCEL );
  294. }
  295. break;
  296. case IDOK:
  297. {
  298. if( m_mruRai != NULL )
  299. {
  300. lstrcpy( m_pRai->szName, m_mruRai->szName );
  301. m_pRai->cItems = m_mruRai->cItems;
  302. for( int nn = 0; nn < m_mruRai->cItems; nn++ )
  303. {
  304. m_pRai->rgDwStr[ nn ].dw = m_mruRai->rgDwStr[ nn ].dw;
  305. m_pRai->rgDwStr[ nn ].psz = PszAlloc( m_mruRai->rgDwStr[ nn ].psz );
  306. }
  307. }
  308. else
  309. {
  310. int type = (int)::SendMessage( m_addressTypeCombo, CB_GETCURSEL, 0, 0 );
  311. type = (int)((type == CB_ERR)? NM_ADDR_UNKNOWN: ComboBox_GetItemData(m_addressTypeCombo, type));
  312. ::SendMessage( GetDlgItem( m_hwnd, IDL_ACD_ADDRESS), WM_GETTEXT, CCHMAX( m_pRai->szName ), (LPARAM) m_pRai->szName );
  313. if( (type == NM_ADDR_UNKNOWN) && bCanCallAsPhoneNumber( m_pRai->szName ) )
  314. {
  315. type = NM_ADDR_ALIAS_E164;
  316. }
  317. m_pRai->cItems = 1;
  318. m_pRai->rgDwStr[ 0 ].dw = type;
  319. m_pRai->rgDwStr[ 0 ].psz = PszAlloc( m_pRai->szName );
  320. }
  321. ::EndDialog( m_hwnd, IDOK );
  322. result = true;
  323. }
  324. break;
  325. case IDCANCEL:
  326. {
  327. ::EndDialog( m_hwnd, IDCANCEL );
  328. result = true;
  329. }
  330. break;
  331. }
  332. return( result );
  333. } // End of CDlgAcd::onCommand.
  334. //--------------------------------------------------------------------------//
  335. // CDlgAcd::onEditChange. //
  336. //--------------------------------------------------------------------------//
  337. void
  338. CDlgAcd::onEditChange(void)
  339. {
  340. TCHAR szEdit[ CCHMAXSZ_ADDRESS ];
  341. int cch = get_editText( szEdit, CCHMAX( szEdit ) );
  342. EnableWindow( GetDlgItem( m_hwnd, IDOK ), (cch > 0) );
  343. ClearRai( &m_mruRai );
  344. } // End of CDlgAcd::onEditChange.
  345. //--------------------------------------------------------------------------//
  346. // CDlgAcd::onMruSelect. //
  347. //--------------------------------------------------------------------------//
  348. void
  349. CDlgAcd::onMruSelect
  350. (
  351. int selection
  352. ){
  353. int mruIndex = (int)::SendMessage( m_nameCombo, CB_GETITEMDATA, selection, 0 );
  354. HRESULT result;
  355. RichAddressInfo * rai;
  356. if( (result = m_callMruList.GetAddress( mruIndex, &rai )) == S_OK )
  357. {
  358. ::SetWindowText( m_nameCombo, rai->szName );
  359. DWORD dwType = rai->rgDwStr[ 0 ].dw;
  360. // HACKHACK georgep: We know Automatic is at index 0
  361. for (int typeIndex=ComboBox_GetCount(m_addressTypeCombo)-1; typeIndex>0; --typeIndex)
  362. {
  363. if (static_cast<DWORD>(ComboBox_GetItemData(m_addressTypeCombo, typeIndex))
  364. == dwType)
  365. {
  366. break;
  367. }
  368. }
  369. ComboBox_SetCurSel(m_addressTypeCombo, typeIndex);
  370. m_mruRai = rai;
  371. }
  372. } // End of CDlgAcd::onMruSelect.
  373. //--------------------------------------------------------------------------//
  374. // CDlgAcd::newCall. //
  375. //--------------------------------------------------------------------------//
  376. void
  377. CDlgAcd::newCall
  378. (
  379. HWND parentWindow,
  380. CConfRoom * pConfRoom
  381. ){
  382. CDlgAcd placeCall(pConfRoom);
  383. RichAddressInfo rai;
  384. bool userAlterable;
  385. bool secure;
  386. pConfRoom->AddConferenceChangeHandler(&placeCall);
  387. pConfRoom->get_securitySettings( userAlterable, secure );
  388. rai.szName[ 0 ] = '\0';
  389. rai.cItems = 0;
  390. if( placeCall.doModal( parentWindow, &rai, secure ) == IDOK )
  391. {
  392. NM_ADDR_TYPE nmType = static_cast<NM_ADDR_TYPE>(rai.rgDwStr[ 0 ].dw);
  393. g_pCCallto->Callto( rai.szName, // pointer to the callto url to try to place the call with...
  394. NULL, // pointer to the display name to use...
  395. nmType, // callto type to resolve this callto as...
  396. true, // the pszCallto parameter is to be interpreted as a pre-unescaped addressing component vs a full callto...
  397. &secure, // security preference, NULL for none. must be "compatible" with secure param if present...
  398. true, // whether or not save in mru...
  399. true, // whether or not to perform user interaction on errors...
  400. parentWindow, // if bUIEnabled is true this is the window to parent error/status windows to...
  401. NULL ); // out pointer to INmCall * to receive INmCall * generated by placing call...
  402. for( int nn = 0; nn < rai.cItems; nn++ )
  403. {
  404. delete [] rai.rgDwStr[ nn ].psz;
  405. }
  406. }
  407. pConfRoom->RemoveConferenceChangeHandler(&placeCall);
  408. } // End of CDlgAcd::newCall.
  409. //--------------------------------------------------------------------------//
  410. // CDlgAcd::get_editText. //
  411. //--------------------------------------------------------------------------//
  412. int
  413. CDlgAcd::get_editText
  414. (
  415. LPTSTR psz,
  416. int cchMax
  417. ){
  418. ASSERT(NULL != m_nameCombo);
  419. SetEmptySz( psz );
  420. GetWindowText( m_nameCombo, psz, cchMax );
  421. return( TrimSz( psz ) );
  422. } // End of get_editText.
  423. void CDlgAcd::OnCallStarted()
  424. {
  425. UpdateSecurityCheck(m_pConfRoom, m_hwnd, IDC_SECURE_CALL);
  426. // BUGBUG georgep: We get notified before the actual conference state
  427. // changes, so we need to disable manually
  428. ::EnableWindow( GetDlgItem(m_hwnd, IDC_SECURE_CALL), FALSE );
  429. }
  430. void CDlgAcd::OnCallEnded()
  431. {
  432. UpdateSecurityCheck(m_pConfRoom, m_hwnd, IDC_SECURE_CALL);
  433. ::CheckDlgButton( m_hwnd, IDC_SECURE_CALL, m_secure );
  434. }
  435. //--------------------------------------------------------------------------//
  436. // CEnumMRU::CEnumMRU. //
  437. //--------------------------------------------------------------------------//
  438. CEnumMRU::CEnumMRU():
  439. RefCount( NULL )
  440. {
  441. } // CEnumMRU::CEnumMRU.
  442. //--------------------------------------------------------------------------//
  443. // CEnumMRU::AddRef. //
  444. //--------------------------------------------------------------------------//
  445. ULONG
  446. STDMETHODCALLTYPE
  447. CEnumMRU::AddRef(void)
  448. {
  449. return( RefCount::AddRef() );
  450. } // CEnumMRU::AddRef.
  451. //--------------------------------------------------------------------------//
  452. // CEnumMRU::Release. //
  453. //--------------------------------------------------------------------------//
  454. ULONG
  455. STDMETHODCALLTYPE
  456. CEnumMRU::Release(void)
  457. {
  458. return( RefCount::Release() );
  459. } // CEnumMRU::Release.
  460. //--------------------------------------------------------------------------//
  461. // CEnumMRU::GetAddress. //
  462. //--------------------------------------------------------------------------//
  463. HRESULT
  464. STDMETHODCALLTYPE
  465. CEnumMRU::GetAddress
  466. (
  467. long index,
  468. RichAddressInfo ** ppAddr
  469. ){
  470. HRESULT result = S_FALSE;
  471. if( GetNumEntries() <= index )
  472. {
  473. result = S_FALSE;
  474. }
  475. else
  476. {
  477. // HACKHACK georgep: Just using the Address as the display name. We
  478. // should clean this up later so we are not taking up extra memory and
  479. // registry space
  480. *ppAddr = CreateRai( GetString( index, ACD_ADDR ), (NM_ADDR_TYPE) GetDWORD( index, ACD_TYPE ), GetString( index, ACD_ADDR ) );
  481. result = (*ppAddr == NULL)? E_OUTOFMEMORY: S_OK;
  482. }
  483. return( result );
  484. } // CEnumMRU::GetAddress.
  485. //--------------------------------------------------------------------------//
  486. // CEnumMRU::GetRecentAddresses. //
  487. //--------------------------------------------------------------------------//
  488. HRESULT
  489. CEnumMRU::GetRecentAddresses
  490. (
  491. IEnumRichAddressInfo ** ppEnum
  492. ){
  493. *ppEnum = new CEnumMRU();
  494. return( (*ppEnum == NULL)? E_OUTOFMEMORY: S_OK );
  495. } // End of CEnumMRU::GetRecentAddresses.
  496. //--------------------------------------------------------------------------//
  497. // CEnumMRU::FreeAddress. //
  498. //--------------------------------------------------------------------------//
  499. HRESULT
  500. CEnumMRU::FreeAddress
  501. (
  502. RichAddressInfo ** ppAddr
  503. ){
  504. ClearRai( ppAddr );
  505. return( S_OK );
  506. } // End of CEnumMRU::FreeAddress.
  507. //--------------------------------------------------------------------------//
  508. // CEnumMRU::CopyAddress. //
  509. //--------------------------------------------------------------------------//
  510. HRESULT
  511. CEnumMRU::CopyAddress
  512. (
  513. RichAddressInfo * pAddrIn,
  514. RichAddressInfo ** ppAddrOut
  515. ){
  516. *ppAddrOut = DupRai( pAddrIn );
  517. return( (*ppAddrOut == NULL)? E_OUTOFMEMORY: S_OK );
  518. } // End of CEnumMRU::CopyAddress.
  519. CAcdMru::CAcdMru() :
  520. CMRUList2( _rgMruCall, CENTRYMAX_MRUCALL )
  521. {
  522. }
  523. int CAcdMru::CompareEntry(int iItem, PMRUE pEntry)
  524. {
  525. ASSERT(NULL != pEntry);
  526. int iRet = 0;
  527. LPCTSTR psz1 = GetString(iItem, ACD_ADDR);
  528. LPCTSTR psz2 = GetString(pEntry, ACD_ADDR);
  529. ASSERT(NULL != psz1 && NULL != psz2);
  530. return(lstrcmpi(psz1, psz2));
  531. }