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.

940 lines
29 KiB

  1. // baprop.cpp
  2. // WAB & Messenger integration to OE
  3. // Created 06/23/98 by YST
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "pch.hxx"
  7. #include "badata.h"
  8. #include "baprop.h"
  9. #include "bllist.h"
  10. #include "baui.h"
  11. #include "shlwapip.h"
  12. #include "demand.h"
  13. #include "mailnews.h"
  14. #include "menuutil.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[]=__FILE__;
  18. #define new DEBUG_NEW
  19. #endif
  20. #define MAX_SUMMARY_ID 13
  21. #define Msgr_Index 0
  22. extern ULONG MsgrPropTags[];
  23. extern ULONG PR_MSGR_DEF_ID;
  24. static TCHAR szDefault[CCHMAX_STRINGRES]; // TEXT(" (default)");
  25. static TCHAR szPending[CCHMAX_STRINGRES]; // TEXT(" (Pending...)");
  26. const LPTSTR szDomainSeparator = TEXT("@");
  27. const LPTSTR szSMTP = TEXT("SMTP");
  28. #define PROP_ERROR(prop) (PROP_TYPE(prop.ulPropTag) == PT_ERROR)
  29. static int nDefault = -1;
  30. static HFONT hBold = NULL;
  31. static HFONT hNormal = NULL;
  32. static CMsgrList *s_pMsgrList = NULL;
  33. static SizedSPropTagArray(1, pTagProp)=
  34. {
  35. 1,
  36. {
  37. PR_EMAIL_ADDRESS,
  38. }
  39. };
  40. ///$$/////////////////////////////////////////////////////////////////////////
  41. //
  42. // AddCBEmailItem - Adds an email address to the personal tab list view
  43. //
  44. // lpszAddrType can be NULL in which case a default one of type SMTP will be used
  45. //
  46. //////////////////////////////////////////////////////////////////////////////
  47. void AddCBEmailItem(HWND hWndCB,
  48. LPTSTR lpszEmailAddress,
  49. BOOL fDefault,
  50. LPTSTR lpszPendName)
  51. {
  52. TCHAR szBuf[CCHMAX_STRINGRES];
  53. TCHAR szTmp[CCHMAX_STRINGRES];
  54. LV_ITEM lvi = {0};
  55. UINT nSim = 0;
  56. int index = -1;
  57. StrCpyN(szTmp, lpszEmailAddress, ARRAYSIZE(szTmp));
  58. // TCHAR *pch = StrStr(CharUpper(szTmp), szHotMail);
  59. // if(pch != NULL)
  60. nSim = lstrlen(szTmp); //(UINT) (pch - szTmp + 1);
  61. Assert(nSim < CCHMAX_STRINGRES);
  62. if(nSim > 0)
  63. {
  64. if(nSim > (CCHMAX_STRINGRES - strlen(szDefault) - 2))
  65. {
  66. nSim = CCHMAX_STRINGRES - strlen(szDefault) - 2;
  67. StrCpyN(szBuf, lpszEmailAddress, nSim);
  68. szBuf[nSim] = '\0';
  69. }
  70. else
  71. StrCpyN(szBuf, lpszEmailAddress, ARRAYSIZE(szBuf));
  72. if(fDefault)
  73. {
  74. if(s_pMsgrList)
  75. {
  76. if(s_pMsgrList->FindAndDeleteUser(lpszEmailAddress, FALSE /*fDelete*/) == S_OK)
  77. StrCatBuff(szBuf, szDefault, ARRAYSIZE(szBuf));
  78. else if(!lstrcmpi(lpszPendName, lpszEmailAddress))
  79. StrCatBuff(szBuf, szPending, ARRAYSIZE(szBuf));
  80. }
  81. }
  82. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  83. lvi.iImage = IMAGE_EMPTY;
  84. lvi.pszText = szBuf;
  85. lvi.cchTextMax = 256; //nSim;
  86. lvi.iItem = ListView_GetItemCount(hWndCB);
  87. lvi.iSubItem = 0;
  88. lvi.lParam = fDefault;
  89. index = ListView_InsertItem(hWndCB, &lvi);
  90. if(fDefault)
  91. nDefault = index;
  92. }
  93. return;
  94. }
  95. const static HELPMAP g_rgCtxWabExt[] =
  96. {
  97. {IDC_MSGR_ID_EDIT, IDH_WAB_ONLINE_ADDNEW},
  98. {IDC_MSGR_ADD, IDH_WAB_ONLINE_ADD},
  99. {IDC_MSGR_BUTTON_SETDEFAULT, IDH_WAB_ONLINE_SETAS},
  100. {IDC_SEND_INSTANT_MESSAGE, IDH_WAB_ONLINE_SENDIM},
  101. {IDC_USER_NAME, IDH_WAB_ONLINE_LIST},
  102. {idcStatic1, IDH_NEWS_COMM_GROUPBOX},
  103. {idcStatic2, IDH_NEWS_COMM_GROUPBOX},
  104. {idcStatic3, IDH_NEWS_COMM_GROUPBOX},
  105. {idcStatic4, IDH_NEWS_COMM_GROUPBOX},
  106. {idcStatic5, IDH_NEWS_COMM_GROUPBOX},
  107. {idcStatic6, IDH_NEWS_COMM_GROUPBOX},
  108. {idcStatic7, IDH_NEWS_COMM_GROUPBOX},
  109. {0, 0}
  110. };
  111. INT_PTR CALLBACK WabExtDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  112. {
  113. LPWABEXTDISPLAY lpWED = (LPWABEXTDISPLAY) GetWindowLongPtr(hDlg, DWLP_USER);
  114. DWORD dwError = 0;
  115. HIMAGELIST himl = NULL;
  116. switch (msg)
  117. {
  118. case WM_INITDIALOG:
  119. {
  120. PROPSHEETPAGE * pps = (PROPSHEETPAGE *) lParam;
  121. LPWABEXTDISPLAY * lppWED = (LPWABEXTDISPLAY *) pps->lParam;
  122. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  123. // Add two columns to the listview
  124. LVCOLUMN lvc;
  125. RECT rc;
  126. HWND ctlList = GetDlgItem(hDlg, IDC_USER_NAME);
  127. s_pMsgrList = OE_OpenMsgrList();
  128. // one column
  129. lvc.mask = LVCF_FMT | LVCF_WIDTH;
  130. lvc.fmt = LVCFMT_LEFT;
  131. lvc.iSubItem = 0;
  132. GetWindowRect(ctlList,&rc);
  133. lvc.cx = rc.right - rc.left - 20; //TBD
  134. ListView_InsertColumn(ctlList, 0, &lvc);
  135. if(lppWED)
  136. {
  137. SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM)*lppWED);
  138. lpWED = *lppWED;
  139. }
  140. InitFonts();
  141. AthLoadString(idsBADefault, szDefault, ARRAYSIZE(szDefault));
  142. AthLoadString(idsBADispStatus, szPending, ARRAYSIZE(szPending));
  143. // ListView_SetExtendedListViewStyle(ctlList, LVS_EX_FULLROWSELECT);
  144. himl = ImageList_LoadImage(g_hLocRes, MAKEINTRESOURCE(idbAddrBookHot), 18, 0,
  145. RGB(255, 0, 255), IMAGE_BITMAP,
  146. LR_LOADMAP3DCOLORS | LR_CREATEDIBSECTION);
  147. ListView_SetImageList(ctlList, himl, LVSIL_SMALL);
  148. AddAccountsToList(hDlg, lpWED);
  149. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_ADD),FALSE);
  150. }
  151. break;
  152. case WM_CONTEXTMENU:
  153. case WM_HELP:
  154. return OnContextHelp(hDlg, msg, wParam, lParam, g_rgCtxWabExt);
  155. break;
  156. case WM_COMMAND:
  157. {
  158. switch(HIWORD(wParam)) // Notification code
  159. {
  160. case EN_CHANGE:
  161. {
  162. if(LOWORD(wParam) == IDC_MSGR_ID_EDIT)
  163. {
  164. if(GetWindowTextLength(GetDlgItem(hDlg, IDC_MSGR_ID_EDIT)) > 0)
  165. {
  166. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_ADD),TRUE);
  167. SendMessage(GetParent(hDlg), DM_SETDEFID, IDC_MSGR_ADD, 0);
  168. }
  169. else
  170. {
  171. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_ADD),FALSE);
  172. SendMessage(GetParent(hDlg), DM_SETDEFID, IDOK, 0);
  173. }
  174. }
  175. break;
  176. }
  177. }
  178. switch(LOWORD(wParam)) // commands
  179. {
  180. case IDC_MSGR_BUTTON_SETDEFAULT:
  181. SetAsDefault(hDlg, lpWED);
  182. break;
  183. case IDC_MSGR_ADD:
  184. AddMsgrId(hDlg, lpWED);
  185. break;
  186. case IDC_SEND_INSTANT_MESSAGE:
  187. WabSendIMsg(hDlg, lpWED);
  188. break;
  189. default:
  190. break;
  191. }
  192. }
  193. break;
  194. case WM_NOTIFY:
  195. {
  196. switch (((NMHDR FAR *) lParam)->code)
  197. {
  198. case PSN_APPLY:
  199. ::SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE);
  200. DeleteFonts();
  201. if(s_pMsgrList)
  202. OE_CloseMsgrList(s_pMsgrList);
  203. break;
  204. case PSN_SETACTIVE:
  205. ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_USER_NAME));
  206. AddAccountsToList(hDlg, lpWED);
  207. break;
  208. case PSN_KILLACTIVE:
  209. AddMsgrId(hDlg, lpWED);
  210. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
  211. return 1;
  212. break;
  213. case PSN_RESET:
  214. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
  215. DeleteFonts();
  216. if(s_pMsgrList)
  217. OE_CloseMsgrList(s_pMsgrList);
  218. break;
  219. case LVN_ITEMCHANGED:
  220. {
  221. int nItem = ListView_GetNextItem(::GetDlgItem(hDlg, IDC_USER_NAME), -1, LVIS_SELECTED);
  222. if((nItem != nDefault) && (nItem > -1))
  223. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_BUTTON_SETDEFAULT),TRUE);
  224. else
  225. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_BUTTON_SETDEFAULT),FALSE);
  226. if(WabIsItemOnline(hDlg, nItem))
  227. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),TRUE);
  228. else
  229. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),FALSE);
  230. }
  231. break;
  232. case NM_CUSTOMDRAW:
  233. switch(wParam)
  234. {
  235. case IDC_USER_NAME:
  236. {
  237. NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
  238. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  239. if(pnmcd->dwDrawStage==CDDS_PREPAINT)
  240. {
  241. SetLastError(0);
  242. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
  243. dwError = GetLastError();
  244. return TRUE;
  245. }
  246. else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
  247. {
  248. if(pnmcd->lItemlParam)
  249. {
  250. SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, hBold);
  251. SetLastError(0);
  252. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
  253. dwError = GetLastError();
  254. return TRUE;
  255. }
  256. else
  257. {
  258. SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, hNormal);
  259. SetLastError(0);
  260. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
  261. dwError = GetLastError();
  262. return TRUE;
  263. }
  264. }
  265. SetLastError(0);
  266. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
  267. dwError = GetLastError();
  268. return TRUE;
  269. }
  270. break;
  271. default:
  272. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
  273. return TRUE;
  274. break;
  275. }
  276. break;
  277. }
  278. }
  279. break;
  280. }
  281. return FALSE;
  282. }
  283. void AddAccountsToList(HWND hDlg, LPWABEXTDISPLAY lpWED, LPTSTR lpszPendName)
  284. {
  285. // LPWABEXTDISPLAY lpWED = (LPWABEXTDISPLAY) GetWindowLongPtr(hDlg, DWLP_USER);
  286. ULONG ulcPropCount = 0;
  287. LPSPropValue lpPropArray = NULL;
  288. ULONG i = 0;
  289. LPSPropValue lpPropEmail = NULL;
  290. LPSPropValue lpPropAddrType = NULL;
  291. LPSPropValue lpPropMVEmail = NULL;
  292. LPSPropValue lpPropMVAddrType = NULL;
  293. LPSPropValue lpPropDefaultIndex = NULL;
  294. LPSPropValue lpMsgrDevId = NULL;
  295. HWND ctlList = GetDlgItem(hDlg, IDC_USER_NAME);
  296. Assert(ctlList);
  297. Assert(PR_MSGR_DEF_ID);
  298. nDefault = -1;
  299. if(!lpWED)
  300. {
  301. Assert(FALSE);
  302. return;
  303. }
  304. if(!HR_FAILED(lpWED->lpPropObj->GetProps(NULL, 0,
  305. &ulcPropCount,
  306. &lpPropArray)))
  307. {
  308. if(ulcPropCount && lpPropArray)
  309. {
  310. for(i = 0; i < ulcPropCount; i++)
  311. {
  312. switch(lpPropArray[i].ulPropTag)
  313. {
  314. case PR_EMAIL_ADDRESS:
  315. lpPropEmail = &(lpPropArray[i]);
  316. break;
  317. case PR_ADDRTYPE:
  318. lpPropAddrType = &(lpPropArray[i]);
  319. break;
  320. case PR_CONTACT_EMAIL_ADDRESSES:
  321. lpPropMVEmail = &(lpPropArray[i]);
  322. break;
  323. case PR_CONTACT_ADDRTYPES:
  324. lpPropMVAddrType = &(lpPropArray[i]);
  325. break;
  326. case PR_CONTACT_DEFAULT_ADDRESS_INDEX:
  327. lpPropDefaultIndex = &(lpPropArray[i]);
  328. break;
  329. default:
  330. if(lpPropArray[i].ulPropTag == PR_MSGR_DEF_ID)
  331. lpMsgrDevId = &(lpPropArray[i]);
  332. break;
  333. }
  334. }
  335. if(!lpPropEmail && !lpPropMVEmail)
  336. goto Error;
  337. if(lpPropMVEmail)
  338. {
  339. // we have a multiple emails
  340. //Assume, if this is present, so is MVAddrType, and defaultindex
  341. for(i = 0; i < lpPropMVEmail->Value.MVSZ.cValues; i++)
  342. {
  343. AddCBEmailItem(ctlList,
  344. lpPropMVEmail->Value.MVSZ.LPPSZ[i],
  345. (lpMsgrDevId ?
  346. ((!lstrcmpi(lpPropMVEmail->Value.MVSZ.LPPSZ[i], lpMsgrDevId->Value.LPSZ)) ? TRUE : FALSE) : FALSE), lpszPendName);
  347. }
  348. }
  349. else
  350. {
  351. // we dont have multi-valued props yet - lets use the
  352. // single valued ones and tag a change so that the record is
  353. // updated ...
  354. AddCBEmailItem(ctlList,
  355. lpPropEmail->Value.LPSZ,
  356. (lpMsgrDevId ?
  357. ((!lstrcmpi(lpPropEmail->Value.LPSZ, lpMsgrDevId->Value.LPSZ)) ? TRUE : FALSE) : FALSE), lpszPendName);
  358. }
  359. }
  360. }
  361. Error:
  362. if(nDefault == -1)
  363. {
  364. if(ListView_GetItemCount(ctlList) > 0) // We have as min 1 item
  365. {
  366. // Select default item
  367. ListView_SetItemState(ctlList, 0,
  368. LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  369. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_BUTTON_SETDEFAULT),TRUE);
  370. // Enable "SendInstant Message only when contact is Online
  371. if(WabIsItemOnline(hDlg, 0))
  372. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),TRUE);
  373. else
  374. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),FALSE);
  375. }
  376. else
  377. {
  378. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),FALSE);
  379. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_BUTTON_SETDEFAULT),FALSE);
  380. }
  381. }
  382. else
  383. {
  384. // Select default item
  385. ListView_SetItemState(ctlList, nDefault,
  386. LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  387. EnableWindow(GetDlgItem(hDlg,IDC_MSGR_BUTTON_SETDEFAULT),FALSE);
  388. // Enable "SendInstant Message only when contact is Online
  389. if(WabIsItemOnline(hDlg, nDefault))
  390. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),TRUE);
  391. else
  392. EnableWindow(GetDlgItem(hDlg,IDC_SEND_INSTANT_MESSAGE),FALSE);
  393. }
  394. if(lpPropArray)
  395. lpWED->lpWABObject->FreeBuffer(lpPropArray);
  396. return;
  397. }
  398. // Set selected email address as default for Messenger
  399. void SetAsDefault(HWND hDlg, LPWABEXTDISPLAY lpWED)
  400. {
  401. HWND ctlList = ::GetDlgItem(hDlg, IDC_USER_NAME);
  402. TCHAR szName[CCHMAX_STRINGRES];
  403. Assert(ctlList);
  404. int iItem = ListView_GetNextItem(ctlList, -1, LVIS_SELECTED);
  405. if(iItem == -1)
  406. return;
  407. ListView_GetItemText(ctlList, iItem, 0,szName, CCHMAX_STRINGRES - 1);
  408. if(StrStr(szName, szDefault)) // already default
  409. return;
  410. SetDefaultID(szName, hDlg, lpWED);
  411. }
  412. // Add Messanger ID to list
  413. #define NOT_FOUND ((ULONG) -1)
  414. void AddMsgrId(HWND hDlg, LPWABEXTDISPLAY lpWED)
  415. {
  416. HWND hwndEdit = ::GetDlgItem(hDlg, IDC_MSGR_ID_EDIT);
  417. LPSPropValue lpPropArray = NULL;
  418. ULONG ulcPropCount = 0;
  419. ULONG i = 0;
  420. ULONG nMVEmailAddress = NOT_FOUND, nMVAddrTypes = NOT_FOUND, nEmailAddress = NOT_FOUND;
  421. ULONG nAddrType = NOT_FOUND, nDefaultIndex = NOT_FOUND;
  422. TCHAR szName[CCHMAX_STRINGRES];
  423. HRESULT hr = S_OK;
  424. if(!::GetWindowText(hwndEdit, szName, CCHMAX_STRINGRES - 1))
  425. return;
  426. TCHAR *pch = NULL;
  427. if(!AsciiTrimSpaces(szName))
  428. {
  429. AthMessageBoxW(hDlg, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsBAErrExtChars),
  430. NULL, MB_OK | MB_ICONSTOP);
  431. ::SetWindowText(hwndEdit, "");
  432. ::SetFocus(hwndEdit);
  433. return;
  434. }
  435. int nLen = lstrlen(szName);
  436. if(nLen <= 0)
  437. goto exi;
  438. nLen = lstrlen(szSMTP);
  439. if(nLen <= 0)
  440. goto exi;
  441. // Create a return prop array to pass back to the WAB
  442. if(HR_FAILED(lpWED->lpPropObj->GetProps(NULL, 0,
  443. &ulcPropCount,
  444. &lpPropArray)))
  445. return;
  446. if(ulcPropCount && lpPropArray)
  447. {
  448. for(i = 0; i < ulcPropCount; i++)
  449. {
  450. switch(lpPropArray[i].ulPropTag)
  451. {
  452. case PR_EMAIL_ADDRESS:
  453. nEmailAddress = i;
  454. break;
  455. case PR_ADDRTYPE:
  456. nAddrType = i;
  457. break;
  458. case PR_CONTACT_EMAIL_ADDRESSES:
  459. nMVEmailAddress = i;
  460. break;
  461. case PR_CONTACT_ADDRTYPES:
  462. nMVAddrTypes = i;
  463. break;
  464. case PR_CONTACT_DEFAULT_ADDRESS_INDEX:
  465. nDefaultIndex = i;
  466. break;
  467. }
  468. }
  469. // if no e-mail address, just add the given prop as e-mail address and in mv e-mail addresses
  470. if(nEmailAddress == NOT_FOUND)
  471. {
  472. SPropValue spv[5];
  473. spv[0].ulPropTag = PR_EMAIL_ADDRESS;
  474. spv[0].Value.LPSZ = szName;
  475. spv[1].ulPropTag = PR_ADDRTYPE;
  476. spv[1].Value.LPSZ = szSMTP;
  477. spv[2].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
  478. spv[2].Value.MVSZ.cValues = 1;
  479. spv[2].Value.MVSZ.LPPSZ = (char **) LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR));
  480. if(spv[2].Value.MVSZ.LPPSZ)
  481. spv[2].Value.MVSZ.LPPSZ[0] = szName;
  482. spv[3].ulPropTag = PR_CONTACT_ADDRTYPES;
  483. spv[3].Value.MVSZ.cValues = 1;
  484. spv[3].Value.MVSZ.LPPSZ = (char **) LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR));
  485. if(spv[3].Value.MVSZ.LPPSZ)
  486. spv[3].Value.MVSZ.LPPSZ[0] = szSMTP;
  487. spv[4].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
  488. spv[4].Value.l = 0;
  489. hr = lpWED->lpPropObj->SetProps(5, (LPSPropValue)&spv, NULL);
  490. if(spv[2].Value.MVSZ.LPPSZ)
  491. LocalFree(spv[2].Value.MVSZ.LPPSZ);
  492. if(spv[3].Value.MVSZ.LPPSZ)
  493. LocalFree(spv[3].Value.MVSZ.LPPSZ);
  494. }
  495. else if(nMVEmailAddress == NOT_FOUND)
  496. {
  497. // we have an e-mail address but no contact-email-addresses
  498. // so we will need to create the contact e-mail addresses
  499. SPropValue spv[3];
  500. spv[0].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
  501. spv[0].Value.MVSZ.cValues = 2;
  502. spv[0].Value.MVSZ.LPPSZ = (char **) LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*2);
  503. if(spv[0].Value.MVSZ.LPPSZ)
  504. {
  505. spv[0].Value.MVSZ.LPPSZ[0] = lpPropArray[nEmailAddress].Value.LPSZ;
  506. spv[0].Value.MVSZ.LPPSZ[1] = szName;
  507. }
  508. spv[1].ulPropTag = PR_CONTACT_ADDRTYPES;
  509. spv[1].Value.MVSZ.cValues = 2;
  510. spv[1].Value.MVSZ.LPPSZ = (char **) LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*2);
  511. if(spv[1].Value.MVSZ.LPPSZ)
  512. {
  513. spv[1].Value.MVSZ.LPPSZ[0] = (nAddrType == NOT_FOUND) ? (LPTSTR)szSMTP : lpPropArray[nAddrType].Value.LPSZ;
  514. spv[1].Value.MVSZ.LPPSZ[1] = szSMTP;
  515. }
  516. spv[2].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
  517. spv[2].Value.l = 0;
  518. hr = lpWED->lpPropObj->SetProps(3, (LPSPropValue)&spv, NULL);
  519. if(spv[0].Value.MVSZ.LPPSZ)
  520. LocalFree(spv[0].Value.MVSZ.LPPSZ);
  521. if(spv[1].Value.MVSZ.LPPSZ)
  522. LocalFree(spv[1].Value.MVSZ.LPPSZ);
  523. }
  524. else
  525. {
  526. // tag on the new props to the end of the existing contact_address_types
  527. if(HR_FAILED(hr = AddPropToMVPString(lpWED, lpPropArray,ulcPropCount, nMVEmailAddress, szName)))
  528. goto exi;
  529. if(HR_FAILED(hr = AddPropToMVPString(lpWED, lpPropArray, ulcPropCount, nMVAddrTypes, szSMTP)))
  530. goto exi;
  531. hr = lpWED->lpPropObj->SetProps(ulcPropCount, lpPropArray, NULL);
  532. }
  533. // Set this new data on the object
  534. //
  535. if(SUCCEEDED(hr))
  536. {
  537. lpWED->fDataChanged = TRUE;
  538. if(nDefault == -1)
  539. SetDefaultID(szName, hDlg, lpWED);
  540. else
  541. {
  542. // just refresh list, which will add buddy.6
  543. ListView_DeleteAllItems(::GetDlgItem(hDlg, IDC_USER_NAME));
  544. AddAccountsToList(hDlg, lpWED);
  545. }
  546. ::SetWindowText(hwndEdit, "");
  547. }
  548. }
  549. exi:
  550. if(lpPropArray)
  551. lpWED->lpWABObject->FreeBuffer(lpPropArray);
  552. }
  553. //Set default ID in WAB
  554. void SetDefaultID(TCHAR *szName, HWND hDlg, LPWABEXTDISPLAY lpWED)
  555. {
  556. ULONG ulcPropCount = 0;
  557. LPSPropValue lpPropArray = NULL;
  558. SCODE sc = 0;
  559. if(s_pMsgrList)
  560. {
  561. s_pMsgrList->AddUser(szName); // Always ignore result
  562. }
  563. else
  564. return;
  565. // Create a return prop array to pass back to the WAB
  566. int nLen = lstrlen(szName);
  567. sc = lpWED->lpWABObject->AllocateBuffer(sizeof(SPropValue),
  568. (LPVOID *)&lpPropArray);
  569. if (sc!=S_OK)
  570. goto out;
  571. if(nLen)
  572. {
  573. lpPropArray[Msgr_Index].ulPropTag = MsgrPropTags[Msgr_Index];
  574. sc = lpWED->lpWABObject->AllocateMore(nLen+1, lpPropArray,
  575. (LPVOID *)&(lpPropArray[Msgr_Index].Value.LPSZ));
  576. if (sc!=S_OK)
  577. goto out;
  578. StrCpyN(lpPropArray[Msgr_Index].Value.LPSZ, szName, nLen+1);
  579. }
  580. // Set this new data on the object
  581. //
  582. if(HR_FAILED(lpWED->lpPropObj->SetProps( 1, lpPropArray, NULL)))
  583. goto out;
  584. lpWED->fDataChanged = TRUE;
  585. ListView_DeleteAllItems(::GetDlgItem(hDlg, IDC_USER_NAME));
  586. AddAccountsToList(hDlg, lpWED, szName);
  587. out:
  588. if(lpPropArray)
  589. lpWED->lpWABObject->FreeBuffer(lpPropArray);
  590. }
  591. //$$//////////////////////////////////////////////////////////////////////////////
  592. //
  593. // TrimSpaces - strips a string of leading and trailing blanks
  594. //
  595. // szBuf - pointer to buffer containing the string we want to strip spaces off.
  596. // Also, check that characters are ASCII
  597. //
  598. ////////////////////////////////////////////////////////////////////////////////
  599. BOOL AsciiTrimSpaces(TCHAR * szBuf)
  600. {
  601. register LPTSTR lpTemp = szBuf;
  602. DWORD cchBuf = lstrlen(szBuf)+1;
  603. if(!szBuf || !lstrlen(szBuf))
  604. return FALSE;
  605. // Trim leading spaces
  606. while (IsSpace(lpTemp)) {
  607. lpTemp = CharNext(lpTemp);
  608. }
  609. if (lpTemp != szBuf) {
  610. // Leading spaces to trim
  611. StrCpyN(szBuf, lpTemp, cchBuf);
  612. lpTemp = szBuf;
  613. }
  614. if (*lpTemp == '\0') {
  615. // empty string
  616. return(TRUE);
  617. }
  618. // Move to the end
  619. lpTemp += lstrlen(lpTemp);
  620. lpTemp--;
  621. // Walk backwards, triming spaces
  622. while (IsSpace(lpTemp) && lpTemp > szBuf) {
  623. *lpTemp = '\0';
  624. lpTemp = CharPrev(szBuf, lpTemp);
  625. }
  626. lpTemp = szBuf;
  627. while (*lpTemp)
  628. {
  629. // Internet addresses only allow pure ASCII. No high bits!
  630. if (*lpTemp & 0x80)
  631. return(FALSE);
  632. lpTemp++;
  633. }
  634. return(TRUE);
  635. }
  636. /***************************************************************************
  637. Name : AddPropToMVPString
  638. Purpose : Add a property to a multi-valued binary property in a prop array
  639. Parameters: lpaProps -> array of properties
  640. cProps = number of props in lpaProps
  641. uPropTag = property tag for MVP
  642. index = index in lpaProps of MVP
  643. lpszNew -> new data string
  644. Returns : HRESULT
  645. Comment : Find the size of the existing MVP
  646. Add in the size of the new entry
  647. allocate new space
  648. copy old to new
  649. free old
  650. copy new entry
  651. point prop array LPSZ to the new space
  652. increment cValues
  653. Note: The new MVP memory is AllocMore'd onto the lpaProps
  654. allocation. We will unlink the pointer to the old MVP array,
  655. but this will be cleaned up when the prop array is freed.
  656. ***************************************************************************/
  657. HRESULT AddPropToMVPString(
  658. LPWABEXTDISPLAY lpWED,
  659. LPSPropValue lpaProps,
  660. DWORD cProps,
  661. DWORD index,
  662. LPTSTR lpszNew) {
  663. #ifdef UNICODE
  664. SWStringArray UNALIGNED * lprgszOld = NULL; // old SString array
  665. #else
  666. SLPSTRArray UNALIGNED * lprgszOld = NULL; // old SString array
  667. #endif
  668. LPTSTR *lppszNew = NULL; // new prop array
  669. LPTSTR *lppszOld = NULL; // old prop array
  670. ULONG cbMVP = 0;
  671. ULONG cExisting = 0;
  672. LPBYTE lpNewTemp = NULL;
  673. HRESULT hResult = hrSuccess;
  674. SCODE sc = SUCCESS_SUCCESS;
  675. ULONG i;
  676. ULONG cbNew;
  677. if (lpszNew) {
  678. cbNew = lstrlen(lpszNew) + 1;
  679. } else {
  680. cbNew = 0;
  681. }
  682. // Find the size of any existing MVP entries
  683. if (PROP_ERROR(lpaProps[index])) {
  684. // Un-ERROR the property tag
  685. lpaProps[index].ulPropTag = PROP_TAG(PT_MV_TSTRING, PROP_ID(lpaProps[index].ulPropTag));
  686. } else {
  687. // point to the structure in the prop array.
  688. lprgszOld = &(lpaProps[index].Value.MVSZ);
  689. lppszOld = lprgszOld->LPPSZ;
  690. cExisting = lprgszOld->cValues;
  691. cbMVP = cExisting * sizeof(LPTSTR);
  692. }
  693. // cbMVP now contains the current size of the MVP
  694. cbMVP += sizeof(LPTSTR); // room in the MVP for another string pointer
  695. // Allocate room for new MVP array
  696. if (sc = lpWED->lpWABObject->AllocateMore(cbMVP, lpaProps, (LPVOID *)&lppszNew)) {
  697. DebugTrace("AddPropToMVPString allocation (%u) failed %x\n", cbMVP, sc);
  698. hResult = ResultFromScode(sc);
  699. return(hResult);
  700. }
  701. // If there are properties there already, copy them to our new MVP
  702. for (i = 0; i < cExisting; i++) {
  703. // Copy this property value to the MVP
  704. lppszNew[i] = lppszOld[i];
  705. }
  706. // Add the new property value
  707. // Allocate room for it
  708. if (cbNew) {
  709. if (sc = lpWED->lpWABObject->AllocateMore(cbNew, lpaProps, (LPVOID *)&(lppszNew[i]))) {
  710. DebugTrace("AddPropToMVPBin allocation (%u) failed %x\n", cbNew, sc);
  711. hResult = ResultFromScode(sc);
  712. return(hResult);
  713. }
  714. StrCpyN(lppszNew[i], lpszNew, cbNew);
  715. lpaProps[index].Value.MVSZ.LPPSZ= lppszNew;
  716. lpaProps[index].Value.MVSZ.cValues = cExisting + 1;
  717. } else {
  718. lppszNew[i] = NULL;
  719. }
  720. return(hResult);
  721. }
  722. // this function check if selected item is online
  723. BOOL WabIsItemOnline(HWND hDlg, int nItem)
  724. {
  725. TCHAR szName[CCHMAX_STRINGRES];
  726. TCHAR *pch = NULL;
  727. if(nItem < 0)
  728. return(FALSE);
  729. HWND ctlList = ::GetDlgItem(hDlg, IDC_USER_NAME);
  730. Assert(ctlList);
  731. ListView_GetItemText(ctlList, nItem, 0,szName, CCHMAX_STRINGRES - 1);
  732. // Remove "(default)"
  733. pch = StrStr(szName, szDefault);
  734. if(pch != NULL)
  735. szName[pch - szName] = '\0';
  736. if(s_pMsgrList)
  737. {
  738. return(s_pMsgrList->IsContactOnline(szName, s_pMsgrList->GetFirstMsgrItem()));
  739. }
  740. return(FALSE);
  741. }
  742. // Send instant message to selected item
  743. void WabSendIMsg(HWND hDlg, LPWABEXTDISPLAY lpWED)
  744. {
  745. TCHAR szName[CCHMAX_STRINGRES];
  746. TCHAR *pch = NULL;
  747. HWND ctlList = ::GetDlgItem(hDlg, IDC_USER_NAME);
  748. Assert(ctlList);
  749. int iItem = ListView_GetNextItem(ctlList, -1, LVIS_SELECTED);
  750. if(iItem == -1)
  751. return;
  752. ListView_GetItemText(ctlList, iItem, 0,szName, CCHMAX_STRINGRES - 1);
  753. // Remove "(default)"
  754. pch = StrStr(szName, szDefault);
  755. if(pch != NULL)
  756. szName[pch - szName] = '\0';
  757. if(s_pMsgrList)
  758. {
  759. s_pMsgrList->SendInstMessage(szName);
  760. }
  761. }
  762. BOOL InitFonts(void)
  763. {
  764. LOGFONT lf;
  765. // Create the font
  766. if(SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0))
  767. {
  768. if(!hNormal)
  769. hNormal = CreateFontIndirect(&lf);
  770. lf.lfWeight = (lf.lfWeight < 700) ? 700 : 1000;
  771. if(!hBold)
  772. hBold = CreateFontIndirect(&lf);
  773. }
  774. return(TRUE);
  775. }
  776. void DeleteFonts(void)
  777. {
  778. if(hNormal)
  779. {
  780. DeleteObject(hNormal);
  781. hNormal = NULL;
  782. }
  783. if(hBold)
  784. {
  785. DeleteObject(hBold);
  786. hBold = NULL;
  787. }
  788. }