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.

4319 lines
128 KiB

  1. // baui.cpp : Implementation of CIEMsgAb
  2. // Messenger integration to OE
  3. // Created 04/20/98 by YST
  4. // #define YST 1
  5. #include "pch.hxx"
  6. #include <windowsx.h>
  7. #include "msoert.h"
  8. #include "basicim2.h"
  9. #include "shlwapi.h"
  10. #include "bactrl.h"
  11. #include "baprop.h"
  12. #include "baui.h"
  13. #include "bllist.h"
  14. #include <wabapi.h>
  15. #include "shlwapip.h"
  16. #include "clutil.h"
  17. #include <mapi.h>
  18. #include "hotlinks.h"
  19. static CAddressBookData * st_pAddrBook = NULL;
  20. #define MAX_MENUSTR 256
  21. //
  22. // Pseudoclass for the variable-sized OLECMDTEXT structure.
  23. // You need to declare it as a class (and not a BYTE buffer that is
  24. // suitable cast) because BYTE buffers are not guaranteed to be aligned.
  25. //
  26. template <int n>
  27. class OLECMDTEXTV : public OLECMDTEXT {
  28. WCHAR wszBuf[n-1]; // "-1" because OLECMDTEXT includes 1 wchar
  29. };
  30. #ifdef DEBUG
  31. DWORD dwDOUTLevel = 0;
  32. #endif
  33. HRESULT DropOnMailRecipient(IDataObject *pdtobj, DWORD grfKeyState);
  34. STDAPI OESimulateDrop(IDropTarget *pdrop, IDataObject *pdtobj, DWORD grfKeyState,
  35. const POINTL *ppt, DWORD *pdwEffect);
  36. typedef enum _tagGetPropertyIDs
  37. {
  38. TBEX_BUTTONTEXT = 100, // VT_BSTR
  39. TBEX_TOOLTIPTEXT = 101, // VT_BSTR
  40. TBEX_GRAYICON = 102, // HICON as a VT_BYREF
  41. TBEX_HOTICON = 103, // HICON as a VT_BYREF
  42. TBEX_GRAYICONSM = 104, // HICON as a VT_BYREF
  43. TBEX_HOTICONSM = 105, // HICON as a VT_BYREF
  44. TBEX_DEFAULTVISIBLE = 106, // VT_BOOL
  45. TMEX_MENUTEXT = 200, // VT_BSTR
  46. TMEX_STATUSBARTEXT = 201, // VT_BSTR
  47. TMEX_CUSTOM_MENU = 202, // VT_BSTR
  48. } GETPROPERTYIDS;
  49. static const int BA_SortOrder[] =
  50. {
  51. BIMSTATE_ONLINE,
  52. BIMSTATE_BE_RIGHT_BACK,
  53. BIMSTATE_OUT_TO_LUNCH,
  54. BIMSTATE_IDLE,
  55. BIMSTATE_AWAY,
  56. BIMSTATE_ON_THE_PHONE,
  57. BIMSTATE_BUSY,
  58. BIMSTATE_INVISIBLE,
  59. BIMSTATE_OFFLINE,
  60. BIMSTATE_UNKNOWN
  61. };
  62. // Create control
  63. HRESULT CreateIEMsgAbCtrl(IIEMsgAb **ppIEMsgAb)
  64. {
  65. HRESULT hr;
  66. IUnknown *pUnknown;
  67. TraceCall("CreateMessageList");
  68. // Get the class factory for the MessageList object
  69. IClassFactory *pFactory = NULL;
  70. hr = _Module.GetClassObject(CLSID_IEMsgAb, IID_IClassFactory,
  71. (LPVOID *) &pFactory);
  72. // If we got the factory, then get an object pointer from it
  73. if (SUCCEEDED(hr))
  74. {
  75. hr = pFactory->CreateInstance(NULL, IID_IUnknown,
  76. (LPVOID *) &pUnknown);
  77. if (SUCCEEDED(hr))
  78. {
  79. hr = pUnknown->QueryInterface(IID_IIEMsgAb, (LPVOID *) ppIEMsgAb);
  80. pUnknown->Release();
  81. }
  82. pFactory->Release();
  83. }
  84. return (hr);
  85. }
  86. /////////////////////////////////////////////////////////////////////////////
  87. // CIEMsgAb
  88. CIEMsgAb::CIEMsgAb():m_ctlList(_T("SysListView32"), this, 1)
  89. {
  90. m_bWindowOnly = TRUE;
  91. m_pDataObject = 0;
  92. m_cf = 0;
  93. m_hwndParent = NULL;
  94. m_pFolderBar = NULL;
  95. m_pObjSite = NULL;
  96. m_nSortType = HIWORD(DwGetOptions());
  97. m_pCMsgrList = NULL;
  98. m_himl = NULL;
  99. m_fLogged = FALSE;
  100. m_dwFontCacheCookie = 0;
  101. m_nChCount = 0;
  102. m_lpWED = NULL;
  103. m_lpWEDContext = NULL;
  104. m_lpPropObj = NULL;
  105. m_szOnline = NULL;
  106. // m_szInvisible = NULL;
  107. m_szBusy = NULL;
  108. m_szBack = NULL;
  109. m_szAway = NULL;
  110. m_szOnPhone = NULL;
  111. m_szLunch = NULL;
  112. m_szOffline = NULL;
  113. m_szIdle = NULL;
  114. m_szEmptyList = NULL;
  115. m_szMsgrEmptyList = NULL;
  116. m_szLeftBr = NULL;
  117. m_szRightBr = NULL;
  118. m_fNoRemove = FALSE;
  119. m_delItem = 0;
  120. m_dwHideMessenger = DwGetMessStatus();
  121. m_dwDisableMessenger = DwGetDisableMessenger();
  122. WORD wShow = LOWORD(DwGetOptions());
  123. m_fShowAllContacts = FALSE;
  124. m_fShowOnlineContacts = FALSE;
  125. m_fShowOfflineContacts = FALSE;
  126. m_fShowEmailContacts = FALSE;
  127. m_fShowOthersContacts = FALSE;
  128. if(wShow == 0)
  129. m_fShowAllContacts = TRUE;
  130. else if (wShow == 1)
  131. m_fShowOfflineContacts = TRUE;
  132. else
  133. m_fShowOnlineContacts = TRUE;
  134. m_fWAB = TRUE;
  135. // Initialize the applicaiton
  136. #ifdef LATER
  137. g_pInstance->DllAddRef();
  138. #endif
  139. // Raid-32933: OE: MSIMN.EXE doesn't always exit
  140. // g_pInstance->CoIncrementInit();
  141. // LATER this is temporary hack for resources!!!
  142. _ASSERT(g_hLocRes);
  143. // g_hLocRes = g_hInst; //_Module.GetResourceInstance();
  144. }
  145. CIEMsgAb::~CIEMsgAb()
  146. {
  147. // #ifdef TEST
  148. SafeRelease(m_pObjSite);
  149. // #endif
  150. // unregister from Msgr list
  151. if(m_pCMsgrList)
  152. {
  153. m_pCMsgrList->UnRegisterUIWnd(m_hWnd);
  154. OE_CloseMsgrList(m_pCMsgrList);
  155. m_pCMsgrList = NULL;
  156. }
  157. SafeMemFree(m_szOnline);
  158. // SafeMemFree(m_szInvisible);
  159. SafeMemFree(m_szBusy);
  160. SafeMemFree(m_szBack);
  161. SafeMemFree(m_szAway);
  162. SafeMemFree(m_szOnPhone);
  163. SafeMemFree(m_szLunch);
  164. SafeMemFree(m_szOffline);
  165. SafeMemFree(m_szIdle);
  166. SafeMemFree(m_szMsgrEmptyList);
  167. SafeMemFree(m_szEmptyList);
  168. SafeMemFree(m_szLeftBr);
  169. SafeMemFree(m_szRightBr);
  170. // Raid-32933: OE: MSIMN.EXE doesn't always exit
  171. // g_pInstance->CoDecrementInit();
  172. #ifdef LATER
  173. g_pInstance->DllRelease();
  174. #endif
  175. }
  176. LRESULT CIEMsgAb::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  177. {
  178. WORD wShow;
  179. if(m_fShowOnlineContacts)
  180. wShow = 2;
  181. else if(m_fShowOfflineContacts)
  182. wShow = 1;
  183. else
  184. wShow = 0;
  185. DwSetOptions((DWORD) MAKELONG(wShow, m_nSortType));
  186. // KillTimer(IDT_PANETIMER);
  187. if(m_delItem != 0)
  188. m_fNoRemove = TRUE;
  189. // else
  190. // m_fNoRemove = FALSE;
  191. m_delItem = ListView_GetItemCount(m_ctlList);
  192. #ifdef LATER
  193. if (m_dwFontCacheCookie && g_lpIFontCache)
  194. {
  195. IConnectionPoint *pConnection = NULL;
  196. if (SUCCEEDED(g_lpIFontCache->QueryInterface(IID_IConnectionPoint, (LPVOID *) &pConnection)))
  197. {
  198. pConnection->Unadvise(m_dwFontCacheCookie);
  199. pConnection->Release();
  200. }
  201. }
  202. m_cAddrBook.Unadvise();
  203. #endif
  204. // RevokeDragDrop(m_hWnd);
  205. if (m_himl != NULL)
  206. ImageList_Destroy(m_himl);
  207. return 0;
  208. }
  209. HRESULT CIEMsgAb::OnDraw(ATL_DRAWINFO& di)
  210. {
  211. RECT& rc = *(RECT*)di.prcBounds;
  212. #if 0
  213. int patGray[4];
  214. HBITMAP hbm;
  215. HBRUSH hbr;
  216. COLORREF cFg;
  217. COLORREF cBkg;
  218. // Initialize the pattern
  219. patGray[0] = 0x005500AA;
  220. patGray[1] = 0x005500AA;
  221. patGray[2] = 0x005500AA;
  222. patGray[3] = 0x005500AA;
  223. // Create a bitmap from the pattern
  224. hbm = CreateBitmap(8, 8, 1, 1, (LPSTR)patGray);
  225. if ((HBITMAP) NULL != hbm)
  226. {
  227. hbr = CreatePatternBrush(hbm);
  228. if (hbr)
  229. {
  230. // Select the right colors into the DC
  231. cFg = SetTextColor(di.hdcDraw, GetSysColor(COLOR_3DFACE));
  232. cBkg = SetBkColor(di.hdcDraw, RGB(255, 255, 255));
  233. // Fill the rectangle
  234. FillRect(di.hdcDraw, &rc, hbr);
  235. SetTextColor(di.hdcDraw, cFg);
  236. SetBkColor(di.hdcDraw, cBkg);
  237. DeleteObject(hbr);
  238. }
  239. DeleteObject(hbm);
  240. }
  241. #endif
  242. // Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
  243. return S_OK;
  244. }
  245. LRESULT CIEMsgAb::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  246. {
  247. // Define a bogus rectangle for the controls. They will get resized in
  248. // our size handler.
  249. RECT rcPos = {0, 0, 100, 100};
  250. WCHAR sz[CCHMAX_STRINGRES];
  251. // Create the various controls
  252. m_ctlList.Create(m_hWnd, rcPos, _T("Outlook Express Address Book ListView"),
  253. WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
  254. LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS /* | LVS_SORTASCENDING*/);
  255. if(m_ctlList.m_hWnd == NULL)
  256. {
  257. DWORD dwErr = GetLastError();
  258. Assert(FALSE);
  259. }
  260. ListView_SetUnicodeFormat(m_ctlList, TRUE);
  261. ListView_SetExtendedListViewStyleEx(m_ctlList, LVS_EX_INFOTIP | LVS_EX_LABELTIP, LVS_EX_INFOTIP | LVS_EX_LABELTIP);
  262. // Image List
  263. Assert(m_himl == NULL);
  264. m_himl = ImageList_LoadImage(g_hLocRes, MAKEINTRESOURCE(idbAddrBookHot), 16, 0,
  265. RGB(255, 0, 255), IMAGE_BITMAP,
  266. LR_LOADMAP3DCOLORS | LR_CREATEDIBSECTION);
  267. ListView_SetImageList(m_ctlList, m_himl, LVSIL_SMALL);
  268. LVCOLUMN lvc;
  269. lvc.mask = LVCF_SUBITEM;
  270. lvc.iSubItem = 0;
  271. ListView_InsertColumn(m_ctlList, 0, &lvc);
  272. #ifdef LATER
  273. m_ctlList.SendMessage(WM_SETFONT, NULL, 0);
  274. SetListViewFont(m_ctlList, GetListViewCharset(), TRUE);
  275. if (g_lpIFontCache)
  276. {
  277. IConnectionPoint *pConnection = NULL;
  278. if (SUCCEEDED(g_lpIFontCache->QueryInterface(IID_IConnectionPoint, (LPVOID *) &pConnection)))
  279. {
  280. pConnection->Advise((IUnknown *)(IFontCacheNotify *) this, &m_dwFontCacheCookie);
  281. pConnection->Release();
  282. }
  283. }
  284. #endif
  285. if(!m_dwHideMessenger && !m_dwDisableMessenger)
  286. {
  287. // Msgr Initialization
  288. m_pCMsgrList = OE_OpenMsgrList();
  289. // Register our control for Msgr list
  290. if(m_pCMsgrList)
  291. {
  292. m_pCMsgrList->RegisterUIWnd(m_hWnd);
  293. if(m_pCMsgrList->IsLocalOnline())
  294. {
  295. m_fLogged = TRUE;
  296. FillMsgrList();
  297. }
  298. }
  299. }
  300. // Initialize the address book object too
  301. m_fWAB = CheckForWAB();
  302. if(m_fWAB)
  303. {
  304. HRESULT hr = m_cAddrBook.OpenWabFile(m_fWAB);
  305. if(hr == S_OK) // && m_fShowAllContacts)
  306. m_cAddrBook.LoadWabContents(m_ctlList, this);
  307. }
  308. else
  309. { if(m_fShowAllContacts)
  310. {
  311. // Bug 23934. We show only online/offline contacts if we use Outlook
  312. m_fShowAllContacts = FALSE;
  313. m_fShowOnlineContacts = FALSE;
  314. m_fShowOfflineContacts = TRUE;
  315. }
  316. }
  317. st_pAddrBook = &m_cAddrBook;
  318. // Sort and Select the first item
  319. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  320. ListView_SetItemState(m_ctlList, 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  321. // Add the tooltip
  322. // Load Tooltip strings
  323. if(AthLoadString(idsBAOnline, sz, ARRAYSIZE(sz)))
  324. {
  325. ULONG cchSize = lstrlenW(sz) + 1;
  326. if(MemAlloc((LPVOID *) &m_szOnline, cchSize * sizeof(WCHAR)))
  327. StrCpyNW(m_szOnline, sz, cchSize);
  328. }
  329. if(AthLoadString(idsBABusy, sz, ARRAYSIZE(sz)))
  330. {
  331. ULONG cchSize = lstrlenW(sz) + 1;
  332. if(MemAlloc((LPVOID *) &m_szBusy, cchSize*sizeof(WCHAR)))
  333. StrCpyNW(m_szBusy, sz, cchSize);
  334. }
  335. if(AthLoadString(idsBABack, sz, ARRAYSIZE(sz)))
  336. {
  337. ULONG cchSize = lstrlenW(sz) + 1;
  338. if(MemAlloc((LPVOID *) &m_szBack, cchSize*sizeof(WCHAR)))
  339. StrCpyNW(m_szBack, sz, cchSize);
  340. }
  341. if(AthLoadString(idsBAAway, sz, ARRAYSIZE(sz)))
  342. {
  343. ULONG cchSize = lstrlenW(sz) + 1;
  344. if(MemAlloc((LPVOID *) &m_szAway, cchSize*sizeof(WCHAR)))
  345. StrCpyNW(m_szAway, sz, cchSize);
  346. }
  347. if(AthLoadString(idsBAOnPhone, sz, ARRAYSIZE(sz)))
  348. {
  349. ULONG cchSize = lstrlenW(sz) + 1;
  350. if(MemAlloc((LPVOID *) &m_szOnPhone, cchSize*sizeof(WCHAR)))
  351. StrCpyNW(m_szOnPhone, sz, cchSize);
  352. }
  353. if(AthLoadString(idsBALunch, sz, ARRAYSIZE(sz)))
  354. {
  355. ULONG cchSize = lstrlenW(sz) + 1;
  356. if(MemAlloc((LPVOID *) &m_szLunch, cchSize*sizeof(WCHAR)))
  357. StrCpyNW(m_szLunch, sz, cchSize);
  358. }
  359. if(AthLoadString(idsBAOffline, sz, ARRAYSIZE(sz)))
  360. {
  361. ULONG cchSize = lstrlenW(sz) + 1;
  362. if(MemAlloc((LPVOID *) &m_szOffline, cchSize*sizeof(WCHAR)))
  363. StrCpyNW(m_szOffline, sz, cchSize);
  364. }
  365. if(AthLoadString(idsBAIdle, sz, ARRAYSIZE(sz)))
  366. {
  367. ULONG cchSize = lstrlenW(sz) + 1;
  368. if(MemAlloc((LPVOID *) &m_szIdle, cchSize*sizeof(WCHAR)))
  369. StrCpyNW(m_szIdle, sz, cchSize);
  370. }
  371. if(AthLoadString(idsMsgrEmptyList, sz, ARRAYSIZE(sz)))
  372. {
  373. ULONG cchSize = lstrlenW(sz) + 1;
  374. if(MemAlloc((LPVOID *) &m_szEmptyList, cchSize*sizeof(WCHAR)))
  375. StrCpyNW(m_szEmptyList, sz, cchSize);
  376. }
  377. if(AthLoadString(idsMSNEmptyList, sz, ARRAYSIZE(sz)))
  378. {
  379. ULONG cchSize = lstrlenW(sz) + 1;
  380. if(MemAlloc((LPVOID *) &m_szMsgrEmptyList, cchSize*sizeof(WCHAR)))
  381. StrCpyNW(m_szMsgrEmptyList, sz, cchSize);
  382. }
  383. if(AthLoadString(idsLeftBr, sz, ARRAYSIZE(sz)))
  384. {
  385. ULONG cchSize = lstrlenW(sz) + 1;
  386. if(MemAlloc((LPVOID *) &m_szLeftBr, cchSize*sizeof(WCHAR)))
  387. StrCpyNW(m_szLeftBr, sz, cchSize);
  388. }
  389. if(AthLoadString(idsRightBr, sz, ARRAYSIZE(sz)))
  390. {
  391. ULONG cchSize = lstrlenW(sz) + 1;
  392. if(MemAlloc((LPVOID *) &m_szRightBr, cchSize*sizeof(WCHAR)))
  393. StrCpyNW(m_szRightBr, sz, cchSize);
  394. }
  395. m_ctlList.SetFocus();
  396. // Register ourselves as a drop target
  397. // RegisterDragDrop(m_hWnd, (IDropTarget *) this);
  398. // Update the size of the listview columns
  399. _AutosizeColumns();
  400. if(ListView_GetItemCount(m_ctlList) > 0)
  401. m_cEmptyList.Hide();
  402. else
  403. m_cEmptyList.Show(m_ctlList, (LPWSTR) (m_fShowAllContacts ? m_szEmptyList : m_szMsgrEmptyList));
  404. // SetTimer(IDT_PANETIMER, ELAPSE_MOUSEOVERCHECK, NULL);
  405. // Finished
  406. return (0);
  407. }
  408. LRESULT CIEMsgAb::OnSetFocus(UINT nMsg , WPARAM wParam , LPARAM lParam , BOOL& bHandled )
  409. {
  410. CComControlBase::OnSetFocus(nMsg, wParam, lParam, bHandled);
  411. m_ctlList.SetFocus();
  412. #ifdef TEST
  413. if (m_pObjSite)
  414. {
  415. m_pObjSite->OnFocusChangeIS((IInputObject*) this, TRUE);
  416. }
  417. #endif //TEST
  418. return 0;
  419. }
  420. LRESULT CIEMsgAb::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  421. {
  422. RECT rc;
  423. DWORD width = LOWORD(lParam);
  424. DWORD height = HIWORD(lParam);
  425. // Position the listview to fill the entire area
  426. RECT rcList;
  427. rcList.left = 0;
  428. rcList.top = 0;
  429. rcList.right = width;
  430. rcList.bottom = height;
  431. m_ctlList.SetWindowPos(NULL, &rcList, SWP_NOACTIVATE | SWP_NOZORDER);
  432. // Update the size of the listview columns
  433. _AutosizeColumns();
  434. // bHandled = FALSE;
  435. return (0);
  436. }
  437. void CIEMsgAb::_AutosizeColumns(void)
  438. {
  439. RECT rcList;
  440. m_ctlList.GetClientRect(&rcList);
  441. ListView_SetColumnWidth(m_ctlList, 0, rcList.right - 5);
  442. }
  443. #ifdef LATER
  444. //
  445. // FUNCTION: CMessageList::OnPreFontChange()
  446. //
  447. // PURPOSE: Get's hit by the Font Cache before it changes the fonts we're
  448. // using. In response we tell the ListView to dump any custom
  449. // font's it's using.
  450. //
  451. STDMETHODIMP CIEMsgAb::OnPreFontChange(void)
  452. {
  453. m_ctlList.SendMessage(WM_SETFONT, 0, 0);
  454. return (S_OK);
  455. }
  456. //
  457. // FUNCTION: CMessageList::OnPostFontChange()
  458. //
  459. // PURPOSE: Get's hit by the Font Cache after it updates the font's we're
  460. // using. In response, we set the new font for the current charset.
  461. //
  462. STDMETHODIMP CIEMsgAb::OnPostFontChange(void)
  463. {
  464. SetListViewFont(m_ctlList, GetListViewCharset(), TRUE);
  465. return (S_OK);
  466. }
  467. #endif
  468. LRESULT CIEMsgAb::CmdSetOnline(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  469. {
  470. LPMABENTRY pEntry = GetSelectedEntry();
  471. if(!pEntry || (pEntry->tag == LPARAM_MENTRY) || !m_pCMsgrList)
  472. return S_FALSE;
  473. // m_cAddrBook.SetDefaultMsgrID(pEntry->lpSB, pEntry->pchWABID);
  474. if(m_pCMsgrList && (PromptToGoOnline() == S_OK) )
  475. m_pCMsgrList->AddUser(pEntry->pchWABID);
  476. return S_OK;
  477. }
  478. LRESULT CIEMsgAb::CmdNewOnlineContact(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  479. {
  480. if(m_pCMsgrList)
  481. {
  482. if(PromptToGoOnline() == S_OK)
  483. m_pCMsgrList->NewOnlineContact();
  484. }
  485. return S_OK;
  486. }
  487. LRESULT CIEMsgAb::CmdNewContact(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  488. {
  489. // Tell the WAB to bring up it's new contact UI
  490. HRESULT hr = S_OK;
  491. if(!m_cAddrBook.fIsWabLoaded())
  492. {
  493. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  494. goto exit;
  495. }
  496. if(FAILED(hr = m_cAddrBook.NewContact(m_hWnd)))
  497. goto exit;
  498. _ReloadListview();
  499. exit:
  500. return (hr);
  501. }
  502. LRESULT CIEMsgAb::NewInstantMessage(LPMABENTRY pEntry)
  503. {
  504. if(((INT_PTR) pEntry) == -1)
  505. return(m_pCMsgrList->SendInstMessage(NULL));
  506. else if(m_pCMsgrList)
  507. {
  508. if(PromptToGoOnline() == S_OK)
  509. return(m_pCMsgrList->SendInstMessage(pEntry->lpMsgrInfo->pchID));
  510. }
  511. return(S_OK);
  512. }
  513. LRESULT CIEMsgAb::CmdDialPhone(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  514. {
  515. return(CallPhone(NULL, FALSE));
  516. }
  517. LRESULT CIEMsgAb::CmdHomePhone(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  518. {
  519. LPMABENTRY pEntry = GetSelectedEntry();
  520. if(!pEntry || !(pEntry->lpPhones))
  521. {
  522. Assert(FALSE);
  523. return(E_FAIL);
  524. }
  525. return(CallPhone(pEntry->lpPhones->pchHomePhone, (pEntry->tag == LPARAM_MENTRY)));
  526. }
  527. LRESULT CIEMsgAb::CmdWorkPhone(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  528. {
  529. LPMABENTRY pEntry = GetSelectedEntry();
  530. if(!pEntry || !(pEntry->lpPhones))
  531. {
  532. Assert(FALSE);
  533. return(E_FAIL);
  534. }
  535. return(CallPhone(pEntry->lpPhones->pchWorkPhone, (pEntry->tag == LPARAM_MENTRY)));
  536. }
  537. LRESULT CIEMsgAb::CmdMobilePhone(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  538. {
  539. LPMABENTRY pEntry = GetSelectedEntry();
  540. if(!pEntry || !(pEntry->lpPhones))
  541. {
  542. Assert(FALSE);
  543. return(E_FAIL);
  544. }
  545. return(CallPhone(pEntry->lpPhones->pchMobilePhone, (pEntry->tag == LPARAM_MENTRY)));
  546. }
  547. LRESULT CIEMsgAb::CmdIPPhone(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  548. {
  549. LPMABENTRY pEntry = GetSelectedEntry();
  550. if(!pEntry || !(pEntry->lpPhones))
  551. {
  552. Assert(FALSE);
  553. return(E_FAIL);
  554. }
  555. return(CallPhone(pEntry->lpPhones->pchIPPhone, (pEntry->tag == LPARAM_MENTRY)));
  556. }
  557. LRESULT CIEMsgAb::CallPhone(WCHAR *wszPhone, BOOL fMessengerContact)
  558. {
  559. WCHAR wszTmp[MAX_PATH] ={0};
  560. if((lstrlenW(wszPhone) + 5) >= MAX_PATH)
  561. return(E_FAIL);
  562. if(!(!m_pCMsgrList || !m_pCMsgrList->IsLocalOnline()))
  563. {
  564. // Use Messenger API
  565. if(fMessengerContact)
  566. {
  567. StrCpyNW(wszTmp, L"+", ARRAYSIZE(wszTmp));
  568. StrCatBuffW(wszTmp, wszPhone, ARRAYSIZE(wszTmp));
  569. }
  570. else
  571. StrCpyNW(wszTmp, wszPhone, ARRAYSIZE(wszTmp));
  572. if(SUCCEEDED(m_pCMsgrList->LaunchPhoneUI(wszTmp)))
  573. return(S_OK);
  574. }
  575. Assert(IsTelInstalled());
  576. StrCpyNW(wszTmp, L"Tel:", ARRAYSIZE(wszTmp));
  577. if(wszPhone)
  578. {
  579. StrCatBuffW(wszTmp, wszPhone, ARRAYSIZE(wszTmp));
  580. }
  581. SHELLEXECUTEINFOW ExecInfo;
  582. ExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
  583. ExecInfo.nShow = SW_SHOWNORMAL;
  584. ExecInfo.fMask = 0;
  585. ExecInfo.hwnd = m_hWnd;
  586. ExecInfo.lpDirectory = NULL;
  587. ExecInfo.lpParameters = NULL;
  588. ExecInfo.lpVerb = L"open";
  589. ExecInfo.lpFile = wszTmp;
  590. if(!ShellExecuteExW(&ExecInfo))
  591. {
  592. WCHAR wszMsg[CCHMAX_STRINGRES];
  593. WCHAR wszTitle[CCHMAX_STRINGRES];
  594. if(!AthLoadString(idsAthena, wszTitle, ARRAYSIZE(wszTitle)))
  595. wszTitle[0] = L'\0';
  596. if(!AthLoadString(idsTelFail, wszMsg, ARRAYSIZE(wszMsg)))
  597. wszMsg[0] = L'\0';
  598. MessageBoxW(NULL, wszMsg, wszTitle, MB_OK | MB_ICONSTOP);
  599. }
  600. return(S_OK);
  601. }
  602. LRESULT CIEMsgAb::CmdNewEmaile(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  603. {
  604. LVITEM lvi;
  605. LPMABENTRY pEntry;
  606. LPRECIPLIST lpList = NULL;
  607. LPRECIPLIST lpListNext = lpList;
  608. ULONG nRecipCount = 0;
  609. TCHAR szBuf[MAX_PATH];
  610. HRESULT hr = S_OK;
  611. // Loop through the selected items
  612. lvi.mask = LVIF_PARAM;
  613. lvi.iItem = -1;
  614. lvi.iSubItem = 0;
  615. while (-1 != (lvi.iItem = ListView_GetNextItem(m_ctlList, lvi.iItem, LVIS_SELECTED)))
  616. {
  617. // We need to get the entry ID from the item
  618. ListView_GetItem(m_ctlList, &lvi);
  619. // Tell the data source to add this person to the message
  620. pEntry = (LPMABENTRY) lvi.lParam;
  621. Assert(pEntry);
  622. if(pEntry->tag == LPARAM_MABENTRY || pEntry->tag == LPARAM_ABENTRY)
  623. {
  624. // m_cAddrBook.AddRecipient(pAddrTableW, pEntry->lpSB, FALSE);
  625. lpListNext = AddTeimToRecipList(lpListNext, pEntry->pchWABID, pEntry->pchWABName, pEntry->lpSB);
  626. if(!lpList)
  627. lpList = lpListNext;
  628. nRecipCount++;
  629. }
  630. /* else if(pEntry->tag == LPARAM_ABGRPENTRY)
  631. m_cAddrBook.AddRecipient(pAddrTableW, pEntry->lpSB, TRUE);*/
  632. else if(pEntry->tag == LPARAM_MENTRY)
  633. {
  634. Assert(pEntry->lpMsgrInfo);
  635. lpListNext = AddTeimToRecipList(lpListNext, pEntry->lpMsgrInfo->pchID, pEntry->lpMsgrInfo->pchMsgrName, NULL);
  636. if(!lpList)
  637. lpList = lpListNext;
  638. nRecipCount++;
  639. }
  640. else
  641. Assert(FALSE);
  642. }
  643. if(nRecipCount)
  644. hr = HrStartMailThread( m_hWnd, nRecipCount,
  645. lpList, // HrSendMail frees lpList so dont reuse
  646. CheckForOutlookExpress(szBuf, ARRAYSIZE(szBuf)));
  647. return (hr);
  648. }
  649. LRESULT CIEMsgAb::CmdNewIMsg(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  650. {
  651. return(CmdNewMessage(wNotifyCode, ID_SEND_INSTANT_MESSAGE, hWndCtl, bHandled));
  652. }
  653. LRESULT CIEMsgAb::CmdNewMessage(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  654. {
  655. LVITEM lvi;
  656. LPMABENTRY pEntry;
  657. pEntry = GetEntryForSendInstMsg();
  658. if(wID == ID_SEND_INSTANT_MESSAGE)
  659. {
  660. if(pEntry)
  661. return(NewInstantMessage(pEntry));
  662. else
  663. {
  664. Assert(FALSE);
  665. return(-1);
  666. }
  667. }
  668. else if((((INT_PTR) pEntry) != -1) && pEntry)
  669. return(NewInstantMessage(pEntry));
  670. else
  671. return(CmdNewEmaile(wNotifyCode, wID, hWndCtl, bHandled));
  672. }
  673. // Exec for Properties command
  674. LRESULT CIEMsgAb::CmdProperties(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  675. {
  676. HRESULT hr = S_OK;
  677. LPMABENTRY pEntry = GetSelectedEntry();
  678. if(pEntry)
  679. {
  680. if(pEntry->tag == LPARAM_MABENTRY || pEntry->tag == LPARAM_ABENTRY || pEntry->tag == LPARAM_ABGRPENTRY)
  681. {
  682. if(!m_cAddrBook.fIsWabLoaded())
  683. {
  684. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  685. return(hr);
  686. }
  687. m_cAddrBook.ShowDetails(m_hWnd, pEntry->lpSB);
  688. }
  689. }
  690. _ReloadListview();
  691. return (0);
  692. }
  693. LRESULT CIEMsgAb::NotifyDeleteItem(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  694. {
  695. NMLISTVIEW *pnmlv = (NMLISTVIEW *) pnmh;
  696. LVITEM lvi;
  697. lvi.mask = LVIF_PARAM;
  698. lvi.iItem = pnmlv->iItem;
  699. lvi.iSubItem = 0;
  700. ListView_GetItem(m_ctlList, &lvi);
  701. LPMABENTRY pEntry = (LPMABENTRY) lvi.lParam;
  702. if(pEntry->tag == LPARAM_MABENTRY || pEntry->tag == LPARAM_ABENTRY || pEntry->tag == LPARAM_ABGRPENTRY)
  703. {
  704. Assert(m_cAddrBook.fIsWabLoaded());
  705. m_cAddrBook.FreeListViewItem(pEntry->lpSB);
  706. }
  707. RemoveBlabEntry(pEntry);
  708. if(m_delItem > 0)
  709. m_delItem--;
  710. else
  711. Assert(FALSE);
  712. return (0);
  713. }
  714. LRESULT CIEMsgAb::NotifyItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  715. {
  716. ULONG uChanged;
  717. NMLISTVIEW *pnmlv = (NMLISTVIEW *) pnmh;
  718. if (pnmlv->uChanged & LVIF_STATE)
  719. {
  720. uChanged = pnmlv->uNewState ^ pnmlv->uOldState;
  721. if (uChanged & LVIS_SELECTED)
  722. _EnableCommands();
  723. }
  724. return (0);
  725. }
  726. // Sort compare
  727. int CALLBACK BA_Sort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  728. {
  729. LPMABENTRY pEntry1 = (LPMABENTRY) lParam1;
  730. LPMABENTRY pEntry2 = (LPMABENTRY) lParam2;
  731. WCHAR pchName1[MAXNAME];
  732. WCHAR pchName2[MAXNAME];
  733. int nIndex1 = 0;
  734. int nIndex2 = 0 ;
  735. if(!(pEntry1->lpMsgrInfo))
  736. {
  737. nIndex1 = sizeof(BA_SortOrder)/sizeof(int);
  738. if(pEntry1->tag == LPARAM_ABGRPENTRY)
  739. nIndex1++;
  740. }
  741. else
  742. {
  743. while((pEntry1->lpMsgrInfo) && (BA_SortOrder[nIndex1] != pEntry1->lpMsgrInfo->nStatus) && (BA_SortOrder[nIndex1] != BIMSTATE_UNKNOWN))
  744. nIndex1++;
  745. }
  746. if(!(pEntry2->lpMsgrInfo))
  747. {
  748. nIndex2 = sizeof(BA_SortOrder)/sizeof(int);
  749. if(pEntry2->tag == LPARAM_ABGRPENTRY)
  750. nIndex2++;
  751. }
  752. else
  753. {
  754. while((BA_SortOrder[nIndex2] != pEntry2->lpMsgrInfo->nStatus) && (BA_SortOrder[nIndex2] != BIMSTATE_UNKNOWN))
  755. nIndex2++;
  756. }
  757. if(pEntry1->tag == LPARAM_MENTRY) // if no AB entry
  758. StrCpyNW(pchName1, pEntry1->lpMsgrInfo->pchMsgrName, ARRAYSIZE(pchName1));
  759. else
  760. StrCpyNW(pchName1, pEntry1->pchWABName, ARRAYSIZE(pchName1));
  761. // st_pAddrBook->GetDisplayName(pEntry1->lpSB, pchName1);
  762. pchName1[ARRAYSIZE(pchName1) - 1] = L'\0';
  763. if(pEntry2->tag == LPARAM_MENTRY) // if no AB entry
  764. StrCpyNW(pchName2, pEntry2->lpMsgrInfo->pchMsgrName, ARRAYSIZE(pchName2));
  765. else
  766. StrCpyNW(pchName2, pEntry2->pchWABName, ARRAYSIZE(pchName2));
  767. // st_pAddrBook->GetDisplayName(pEntry2->lpSB, pchName2);
  768. pchName2[ARRAYSIZE(pchName2) - 1] = L'\0';
  769. switch(lParamSort)
  770. {
  771. case BASORT_NAME_ACSEND:
  772. return(lstrcmpiW(pchName1, pchName2));
  773. case BASORT_NAME_DESCEND:
  774. return(lstrcmpiW(pchName2, pchName1));
  775. default:
  776. if((pEntry1->lpMsgrInfo) && (pEntry2->lpMsgrInfo) && (pEntry1->lpMsgrInfo->nStatus == pEntry2->lpMsgrInfo->nStatus))
  777. {
  778. if(lParamSort == BASORT_STATUS_ACSEND)
  779. return(lstrcmpiW(pchName1, pchName2));
  780. else
  781. return(lstrcmpiW(pchName2, pchName1));
  782. }
  783. else
  784. {
  785. if(lParamSort == BASORT_STATUS_ACSEND)
  786. return(nIndex1 - nIndex2);
  787. else
  788. return(nIndex2 - nIndex1);
  789. }
  790. }
  791. Assert(FALSE);
  792. return(0);
  793. }
  794. void CIEMsgAb::_EnableCommands(void)
  795. {
  796. #ifdef LATER
  797. if(g_pBrowser)
  798. g_pBrowser->UpdateToolbar();
  799. #endif
  800. }
  801. LRESULT CIEMsgAb::NotifyItemActivate(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  802. {
  803. return (SendMessage(WM_COMMAND, ID_SEND_INSTANT_MESSAGE2, 0));
  804. }
  805. // GETDISPLAYINFO notification message
  806. LRESULT CIEMsgAb::NotifyGetDisplayInfo(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  807. {
  808. LV_DISPINFOW * plvdi = (LV_DISPINFOW *)pnmh;
  809. LRESULT hr;
  810. if(plvdi->item.lParam)
  811. {
  812. LPMABENTRY pEntry = (LPMABENTRY) plvdi->item.lParam;
  813. LPMABENTRY pFindEntry = NULL;
  814. if (plvdi->item.mask & LVIF_IMAGE)
  815. {
  816. if((hr = SetUserIcon(pEntry, (pEntry->lpMsgrInfo ? pEntry->lpMsgrInfo->nStatus : BIMSTATE_OFFLINE), &(plvdi->item.iImage) ) ) != S_OK)
  817. return(hr);
  818. }
  819. if (plvdi->item.mask & LVIF_TEXT)
  820. {
  821. if(pEntry->tag == LPARAM_ABENTRY || pEntry->tag == LPARAM_ABGRPENTRY)
  822. {
  823. // if((hr = m_cAddrBook.GetDisplayName(pEntry->lpSB, plvdi->item.pszText)) != S_OK)
  824. // return(hr);
  825. Assert(pEntry->pchWABName);
  826. StrCpyNW(plvdi->item.pszText, pEntry->pchWABName, plvdi->item.cchTextMax - 1);
  827. plvdi->item.pszText[plvdi->item.cchTextMax - 1] = L'\0';
  828. }
  829. else if(pEntry->tag == LPARAM_MABENTRY || pEntry->tag == LPARAM_MENTRY)
  830. {
  831. #ifdef LATER
  832. if(pEntry->tag == LPARAM_MENTRY && (pEntry->lpMsgrInfo->nStatus == BIMSTATE_ONLINE) &&
  833. lstrcmpiW(pEntry->lpMsgrInfo->pchMsgrName, pEntry->lpMsgrInfo->pchID) && m_fWAB)
  834. {
  835. StrCpyN(plvdi->item.pszText, pEntry->lpMsgrInfo->pchMsgrName, plvdi->item.cchTextMax - 1);
  836. plvdi->item.pszText[plvdi->item.cchTextMax - 1] = L'\0';
  837. // Don't need redraw now, do it later
  838. hr = MAPI_E_COLLISION; // m_cAddrBook.AutoAddContact(pEntry->lpMsgrInfo->pchMsgrName, pEntry->lpMsgrInfo->pchID);
  839. if(hr == MAPI_E_COLLISION) // already have a contact in AB
  840. {
  841. int Index = -1;
  842. WCHAR *pchID = NULL;
  843. ULONG cchSize = lstrlenW(pEntry->lpMsgrInfo->pchID) + 1;
  844. if(MemAlloc((LPVOID *) &pchID, cchSize * sizeof(WCHAR)))
  845. {
  846. StrCpyN(pchID, pEntry->lpMsgrInfo->pchID, cchSize);
  847. do
  848. {
  849. pFindEntry = FindUserEmail(pchID, &Index, FALSE);
  850. }while((pFindEntry != NULL) && (pFindEntry->tag == LPARAM_MENTRY));
  851. if(pFindEntry != NULL)
  852. {
  853. hr = m_cAddrBook.SetDefaultMsgrID(pFindEntry->lpSB, pchID);
  854. if(hr == S_OK)
  855. _ReloadListview();
  856. }
  857. MemFree(pchID);
  858. }
  859. }
  860. //if we not found...
  861. if(hr != S_OK)
  862. {
  863. hr = m_cAddrBook.AutoAddContact(pEntry->lpMsgrInfo->pchMsgrName, pEntry->lpMsgrInfo->pchID);
  864. if(hr == S_OK)
  865. _ReloadListview();
  866. }
  867. }
  868. else
  869. {
  870. #endif //LATER
  871. StrCpyNW(plvdi->item.pszText, pEntry->lpMsgrInfo->pchMsgrName, plvdi->item.cchTextMax - 1);
  872. plvdi->item.pszText[plvdi->item.cchTextMax - 1] = L'\0';
  873. // plvdi->item.pszText = pEntry->lpMsgrInfo->pchMsgrName;
  874. // }
  875. }
  876. else // Unknown tag
  877. Assert(FALSE);
  878. }
  879. }
  880. return S_OK;
  881. }
  882. LRESULT CIEMsgAb::NotifyGetInfoTip(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  883. {
  884. NMLVGETINFOTIPW *plvgit = (NMLVGETINFOTIPW *) pnmh;
  885. LVITEM lvi;
  886. lvi.mask = LVIF_PARAM;
  887. lvi.iItem = plvgit->iItem;
  888. lvi.iSubItem = plvgit->iSubItem;
  889. ListView_GetItem(m_ctlList, &lvi);
  890. LPMABENTRY pEntry = (LPMABENTRY) lvi.lParam;
  891. if (pEntry->lpMsgrInfo != NULL)
  892. {
  893. StrCpyNW(plvgit->pszText, pEntry->lpMsgrInfo->pchMsgrName, plvgit->cchTextMax);
  894. StrCatBuffW(plvgit->pszText, m_szLeftBr, plvgit->cchTextMax);
  895. StrCatBuffW(plvgit->pszText, pEntry->lpMsgrInfo->pchID, plvgit->cchTextMax);
  896. StrCatBuffW(plvgit->pszText, m_szRightBr, plvgit->cchTextMax);
  897. LPCWSTR szStatus;
  898. switch(pEntry->lpMsgrInfo->nStatus)
  899. {
  900. case BIMSTATE_ONLINE:
  901. szStatus = m_szOnline;
  902. break;
  903. case BIMSTATE_BUSY:
  904. szStatus = m_szBusy;
  905. break;
  906. case BIMSTATE_BE_RIGHT_BACK:
  907. szStatus = m_szBack;
  908. break;
  909. case BIMSTATE_IDLE:
  910. szStatus = m_szIdle;
  911. break;
  912. case BIMSTATE_AWAY:
  913. szStatus = m_szAway;
  914. break;
  915. case BIMSTATE_ON_THE_PHONE:
  916. szStatus = m_szOnPhone;
  917. break;
  918. case BIMSTATE_OUT_TO_LUNCH:
  919. szStatus = m_szLunch;
  920. break;
  921. default:
  922. szStatus = m_szOffline;
  923. break;
  924. }
  925. StrCatBuffW(plvgit->pszText, szStatus, plvgit->cchTextMax);
  926. }
  927. else if (plvgit->dwFlags & LVGIT_UNFOLDED)
  928. {
  929. // If this is not a messenger item and the text
  930. // isn't truncated do not display a tooltip.
  931. plvgit->pszText[0] = L'\0';
  932. }
  933. return 0;
  934. }
  935. LRESULT CIEMsgAb::SetUserIcon(LPMABENTRY pEntry, int nStatus, int * pImage)
  936. {
  937. switch(pEntry->tag)
  938. {
  939. case LPARAM_MENTRY:
  940. case LPARAM_MABENTRY:
  941. {
  942. switch(nStatus)
  943. {
  944. case BIMSTATE_ONLINE:
  945. *pImage = IMAGE_ONLINE;
  946. break;
  947. case BIMSTATE_INVISIBLE:
  948. *pImage = IMAGE_STOPSIGN;
  949. break;
  950. case BIMSTATE_BUSY:
  951. *pImage = IMAGE_STOPSIGN;
  952. break;
  953. case BIMSTATE_BE_RIGHT_BACK:
  954. *pImage = IMAGE_CLOCKSIGN; // IMAGE_BE_RIGHT_BACK;
  955. break;
  956. case BIMSTATE_IDLE:
  957. *pImage = IMAGE_CLOCKSIGN; // IMAGE_IDLE;
  958. break;
  959. case BIMSTATE_AWAY:
  960. *pImage = IMAGE_CLOCKSIGN; // IMAGE_AWAY;
  961. break;
  962. case BIMSTATE_ON_THE_PHONE:
  963. *pImage = IMAGE_STOPSIGN; // IMAGE_ON_THE_PHONE;
  964. break;
  965. case BIMSTATE_OUT_TO_LUNCH:
  966. *pImage = IMAGE_CLOCKSIGN; // IMAGE_OUT_TO_LUNCH;
  967. break;
  968. default:
  969. *pImage = IMAGE_OFFLINE;
  970. break;
  971. }
  972. }
  973. break;
  974. case LPARAM_ABGRPENTRY:
  975. // WAB group
  976. *pImage = IMAGE_DISTRIBUTION_LIST;
  977. break;
  978. default:
  979. // Not a buddy...
  980. if(pEntry->fCertificate)
  981. *pImage = IMAGE_CERT;
  982. else
  983. *pImage = IMAGE_NEW_MESSAGE;
  984. break;
  985. }
  986. return(S_OK);
  987. }
  988. // Return MAB entry for first selected item
  989. LPMABENTRY CIEMsgAb::GetSelectedEntry()
  990. {
  991. LVITEM lvi;
  992. // Get the focused item
  993. lvi.iItem = ListView_GetNextItem(m_ctlList, -1, LVNI_SELECTED | LVNI_FOCUSED);
  994. // Get the lParam for that item
  995. if (lvi.iItem != -1)
  996. {
  997. lvi.iSubItem = 0;
  998. lvi.mask = LVIF_PARAM;
  999. if(ListView_GetItem(m_ctlList, &lvi))
  1000. return((LPMABENTRY) lvi.lParam);
  1001. }
  1002. return(NULL); // unscucces
  1003. }
  1004. /*
  1005. LRESULT CIEMsgAb::CmdMsgrOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1006. {
  1007. return(m_pCMsgrList->LaunchOptionsUI()); // (MOPTDLG_GENERAL_PAGE);
  1008. }
  1009. */
  1010. // Check entry for possibility to send Instant message
  1011. LPMABENTRY CIEMsgAb::GetEntryForSendInstMsg(LPMABENTRY pEntry)
  1012. {
  1013. if(!IsMessengerInstalled())
  1014. return(NULL);
  1015. if(ListView_GetSelectedCount(m_ctlList) == 1)
  1016. {
  1017. if(!pEntry) // if we don'y have pEntry yet then get it
  1018. pEntry = GetSelectedEntry();
  1019. if(pEntry && (pEntry->tag == LPARAM_MABENTRY || pEntry->tag == LPARAM_MENTRY) &&
  1020. (pEntry->lpMsgrInfo->nStatus != BIMSTATE_OFFLINE) && (pEntry->lpMsgrInfo->nStatus != BIMSTATE_INVISIBLE) &&
  1021. !(m_pCMsgrList->IsLocalName(pEntry->lpMsgrInfo->pchID)))
  1022. return(pEntry);
  1023. }
  1024. #ifdef NEED
  1025. if(m_pCMsgrList)
  1026. {
  1027. if(m_pCMsgrList->IsLocalOnline() && (m_pCMsgrList->GetCount() > 0))
  1028. return(NULL); // should be /*return((LPMABENTRY) -1);*/ - temporary disabled (YST)
  1029. }
  1030. #endif
  1031. return(NULL);
  1032. }
  1033. // Display right-mouse click (context) menu
  1034. LRESULT CIEMsgAb::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1035. {
  1036. LPMABENTRY pEntry;
  1037. HMENU hPopup = 0;
  1038. HWND hwndHeader;
  1039. int id = 0;
  1040. POINT pt = { (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam) };
  1041. int n = -1;
  1042. // Figure out if this came from the keyboard or not
  1043. if (lParam == -1)
  1044. {
  1045. Assert((HWND) wParam == m_ctlList);
  1046. int i = ListView_GetFirstSel(m_ctlList);
  1047. if (i == -1)
  1048. return (0);
  1049. ListView_GetItemPosition(m_ctlList, i, &pt);
  1050. m_ctlList.ClientToScreen(&pt);
  1051. }
  1052. LVHITTESTINFO lvhti;
  1053. lvhti.pt = pt;
  1054. m_ctlList.ScreenToClient(&lvhti.pt);
  1055. ListView_HitTest(m_ctlList, &lvhti);
  1056. if (lvhti.iItem == -1)
  1057. return (0);
  1058. // Load the context menu
  1059. hPopup = LoadPopupMenu(IDR_BA_POPUP);
  1060. if (!hPopup)
  1061. goto exit;
  1062. pEntry = GetSelectedEntry();
  1063. pEntry = GetEntryForSendInstMsg(pEntry);
  1064. if(pEntry)
  1065. SetMenuDefaultItem(hPopup, ID_SEND_INSTANT_MESSAGE, FALSE);
  1066. else
  1067. SetMenuDefaultItem(hPopup, ID_SEND_MESSAGE, FALSE);
  1068. if (!m_pCMsgrList)
  1069. {
  1070. DeleteMenu(hPopup, ID_SEND_INSTANT_MESSAGE, MF_BYCOMMAND);
  1071. DeleteMenu(hPopup, ID_SET_ONLINE_CONTACT, MF_BYCOMMAND);
  1072. DeleteMenu(hPopup, ID_NEW_ONLINE_CONTACT, MF_BYCOMMAND);
  1073. }
  1074. MenuUtil_EnablePopupMenu(hPopup, this);
  1075. TrackPopupMenuEx(hPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  1076. pt.x, pt.y, m_hWnd, NULL);
  1077. exit:
  1078. if (hPopup)
  1079. DestroyMenu(hPopup);
  1080. return (0);
  1081. }
  1082. //
  1083. // FUNCTION: CIEMsgAb::DragEnter()
  1084. //
  1085. // PURPOSE: This get's called when the user starts dragging an object
  1086. // over our target area.
  1087. //
  1088. // PARAMETERS:
  1089. // <in> pDataObject - Pointer to the data object being dragged
  1090. // <in> grfKeyState - Pointer to the current key states
  1091. // <in> pt - Point in screen coordinates of the mouse
  1092. // <out> pdwEffect - Where we return whether this is a valid place for
  1093. // pDataObject to be dropped and if so what type of
  1094. // drop.
  1095. //
  1096. // RETURN VALUE:
  1097. // S_OK - The function succeeded.
  1098. //
  1099. STDMETHODIMP CIEMsgAb::DragEnter(IDataObject* pDataObject, DWORD grfKeyState,
  1100. POINTL pt, DWORD* pdwEffect)
  1101. {
  1102. IEnumFORMATETC *pEnum;
  1103. FORMATETC fe;
  1104. ULONG celtFetched;
  1105. // Verify we got this
  1106. if (!pDataObject)
  1107. return (S_OK);
  1108. // Init
  1109. ZeroMemory(&fe, sizeof(FORMATETC));
  1110. // Set the default return value to be failure
  1111. *pdwEffect = DROPEFFECT_NONE;
  1112. // Get the FORMATETC enumerator for this data object
  1113. if (SUCCEEDED(pDataObject->EnumFormatEtc(DATADIR_GET, &pEnum)))
  1114. {
  1115. // Walk through the data types to see if we can find the ones we're
  1116. // interested in.
  1117. pEnum->Reset();
  1118. while (S_OK == pEnum->Next(1, &fe, &celtFetched))
  1119. {
  1120. Assert(celtFetched == 1);
  1121. #ifdef LATER
  1122. // The only format we care about is CF_INETMSG
  1123. if ((fe.cfFormat == CF_INETMSG) /*|| (fe.cfFormat == CF_OEMESSAGES)*/)
  1124. {
  1125. *pdwEffect = DROPEFFECT_COPY;
  1126. break;
  1127. }
  1128. #endif
  1129. }
  1130. pEnum->Release();
  1131. }
  1132. // We we're going to allow the drop, then keep a copy of the data object
  1133. if (*pdwEffect != DROPEFFECT_NONE)
  1134. {
  1135. m_pDataObject = pDataObject;
  1136. m_pDataObject->AddRef();
  1137. m_cf = fe.cfFormat;
  1138. m_fRight = (grfKeyState & MK_RBUTTON);
  1139. }
  1140. return (S_OK);
  1141. }
  1142. //
  1143. // FUNCTION: CIEMsgAb::DragOver()
  1144. //
  1145. // PURPOSE: This is called as the user drags an object over our target.
  1146. // If we allow this object to be dropped on us, then we will have
  1147. // a pointer in m_pDataObject.
  1148. //
  1149. // PARAMETERS:
  1150. // <in> grfKeyState - Pointer to the current key states
  1151. // <in> pt - Point in screen coordinates of the mouse
  1152. // <out> pdwEffect - Where we return whether this is a valid place for
  1153. // pDataObject to be dropped and if so what type of
  1154. // drop.
  1155. //
  1156. // RETURN VALUE:
  1157. // S_OK - The function succeeded.
  1158. //
  1159. STDMETHODIMP CIEMsgAb::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
  1160. {
  1161. // If we didn't cache a data object in IDropTarget::DragEnter(), we
  1162. // blow this off.
  1163. if (NULL == m_pDataObject)
  1164. {
  1165. *pdwEffect = DROPEFFECT_NONE;
  1166. return (S_OK);
  1167. }
  1168. // We always do a copy
  1169. *pdwEffect = DROPEFFECT_COPY;
  1170. return (S_OK);
  1171. }
  1172. //
  1173. // FUNCTION: CIEMsgAb::DragLeave()
  1174. //
  1175. // PURPOSE: Allows us to release any stored data we have from a successful
  1176. // DragEnter()
  1177. //
  1178. // RETURN VALUE:
  1179. // S_OK - Everything is groovy
  1180. //
  1181. STDMETHODIMP CIEMsgAb::DragLeave(void)
  1182. {
  1183. // Free everything up at this point.
  1184. if (NULL != m_pDataObject)
  1185. {
  1186. m_pDataObject->Release();
  1187. m_pDataObject = 0;
  1188. m_cf = 0;
  1189. }
  1190. return (S_OK);
  1191. }
  1192. //
  1193. // FUNCTION: CIEMsgAb::Drop()
  1194. //
  1195. // PURPOSE: The user has let go of the object over our target. If we
  1196. // can accept this object we will already have the pDataObject
  1197. // stored in m_pDataObject.
  1198. //
  1199. // PARAMETERS:
  1200. // <in> pDataObject - Pointer to the data object being dragged
  1201. // <in> grfKeyState - Pointer to the current key states
  1202. // <in> pt - Point in screen coordinates of the mouse
  1203. // <out> pdwEffect - Where we return whether this is a valid place for
  1204. // pDataObject to be dropped and if so what type of
  1205. // drop.
  1206. //
  1207. // RETURN VALUE:
  1208. // S_OK - Everything worked OK
  1209. //
  1210. STDMETHODIMP CIEMsgAb::Drop(IDataObject* pDataObject, DWORD grfKeyState,
  1211. POINTL pt, DWORD* pdwEffect)
  1212. {
  1213. HRESULT hr = S_OK;
  1214. #ifdef LATER
  1215. FORMATETC fe;
  1216. STGMEDIUM stm;
  1217. IMimeMessage *pMessage = 0;
  1218. // Get the stream from the DataObject
  1219. ZeroMemory(&stm, sizeof(STGMEDIUM));
  1220. SETDefFormatEtc(fe, CF_INETMSG, TYMED_ISTREAM);
  1221. if (FAILED(hr = pDataObject->GetData(&fe, &stm)))
  1222. goto exit;
  1223. // Create a new message object
  1224. if (FAILED(hr = HrCreateMessage(&pMessage)))
  1225. goto exit;
  1226. // Load the message from the stream
  1227. if (FAILED(hr = pMessage->Load(stm.pstm)))
  1228. goto exit;
  1229. // If this was a right-drag, then we bring up a context menu etc.
  1230. if (m_fRight)
  1231. _DoDropMenu(pt, pMessage);
  1232. else
  1233. _DoDropMessage(pMessage);
  1234. exit:
  1235. ReleaseStgMedium(&stm);
  1236. SafeRelease(pMessage);
  1237. m_pDataObject->Release();
  1238. m_pDataObject = 0;
  1239. m_cf = 0;
  1240. #endif
  1241. return (hr);
  1242. }
  1243. HRESULT CIEMsgAb::_DoDropMessage(LPMIMEMESSAGE pMessage)
  1244. {
  1245. HRESULT hr;
  1246. #ifdef LATER
  1247. ADDRESSLIST addrList = { 0 };
  1248. ULONG i;
  1249. SECSTATE secState = {0};
  1250. BOOL fSignTrusted = FALSE;
  1251. if(FAILED(hr = HandleSecurity(m_hWnd, pMessage)))
  1252. return hr;
  1253. if (IsSecure(pMessage) && SUCCEEDED(HrGetSecurityState(pMessage, &secState, NULL)))
  1254. {
  1255. fSignTrusted = !!IsSignTrusted(&secState);
  1256. CleanupSECSTATE(&secState);
  1257. }
  1258. // Get the address list from the message
  1259. hr = pMessage->GetAddressTypes(IAT_FROM | IAT_SENDER, IAP_FRIENDLYW | IAP_EMAIL | IAP_ADRTYPE, &addrList);
  1260. if (FAILED(hr))
  1261. goto exit;
  1262. // Loop through the addresses
  1263. for (i = 0; i < addrList.cAdrs; i++)
  1264. {
  1265. if(!m_cAddrBook.fIsWabLoaded())
  1266. {
  1267. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  1268. return(hr);
  1269. }
  1270. m_cAddrBook.AddAddress(addrList.prgAdr[i].pszFriendlyW, addrList.prgAdr[i].pszEmail);
  1271. #ifdef DEAD
  1272. TCHAR *pch = StrStr(CharUpper(addrList.prgAdr[i].pszEmail), szHotMail);
  1273. if((pch != NULL) && m_pCMsgrList)
  1274. m_pCMsgrList->AddUser(addrList.prgAdr[i].pszEmail);
  1275. #endif // DEAD
  1276. }
  1277. if(fSignTrusted)
  1278. {
  1279. FILETIME ftNull = {0};
  1280. HrAddSenderCertToWab(NULL, pMessage, NULL, NULL, NULL, ftNull, WFF_CREATE);
  1281. }
  1282. #ifdef NEEDED
  1283. // Reload the table
  1284. _ReloadListview();
  1285. #endif
  1286. exit:
  1287. #endif
  1288. return (S_OK);
  1289. }
  1290. HRESULT CIEMsgAb::_DoDropMenu(POINTL pt, LPMIMEMESSAGE pMessage)
  1291. {
  1292. HRESULT hr = S_OK;
  1293. #ifdef LATER
  1294. ADDRESSLIST addrList = { 0 };
  1295. ULONG i;
  1296. HMENU hPopup = 0, hSubMenu = 0;
  1297. UINT id = 0;
  1298. BOOL fReload = FALSE;
  1299. SECSTATE secState = {0};
  1300. BOOL fSignTrusted = FALSE;
  1301. // Get the address list from the message
  1302. if(FAILED(hr = HandleSecurity(m_hWnd, pMessage)))
  1303. return hr;
  1304. if (IsSecure(pMessage) && SUCCEEDED(HrGetSecurityState(pMessage, &secState, NULL)))
  1305. {
  1306. fSignTrusted = !!IsSignTrusted(&secState);
  1307. CleanupSECSTATE(&secState);
  1308. }
  1309. hr = pMessage->GetAddressTypes(IAT_KNOWN, IAP_FRIENDLYW | IAP_EMAIL | IAP_ADRTYPE, &addrList);
  1310. if (FAILED(hr))
  1311. goto exit;
  1312. // Load the context menu
  1313. hPopup = LoadPopupMenu(IDR_BA_DRAGDROP_POPUP);
  1314. if (!hPopup)
  1315. goto exit;
  1316. // Bold the "Save All" item
  1317. MENUITEMINFO mii;
  1318. mii.cbSize = sizeof(mii);
  1319. mii.fMask = MIIM_STATE;
  1320. if (GetMenuItemInfo(hPopup, ID_SAVE_ALL, FALSE, &mii))
  1321. {
  1322. mii.fState |= MFS_DEFAULT;
  1323. SetMenuItemInfo(hPopup, ID_SAVE_ALL, FALSE, &mii);
  1324. }
  1325. // Create the "Save >" item
  1326. hSubMenu = CreatePopupMenu();
  1327. // Loop through the addresses
  1328. for (i = 0; i < addrList.cAdrs; i++)
  1329. {
  1330. AppendMenuWrapW(hSubMenu, MF_STRING | MF_ENABLED, ID_SAVE_ADDRESS_FIRST + i, addrList.prgAdr[i].pszFriendlyW);
  1331. }
  1332. mii.fMask = MIIM_SUBMENU;
  1333. mii.hSubMenu = hSubMenu;
  1334. SetMenuItemInfo(hPopup, ID_SAVE, FALSE, &mii);
  1335. id = TrackPopupMenuEx(hPopup, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  1336. pt.x, pt.y, m_hWnd, NULL);
  1337. if (id == ID_SAVE_ALL_ADDRESSES)
  1338. {
  1339. for (i = 0; i < addrList.cAdrs; i++)
  1340. {
  1341. m_cAddrBook.AddAddress(addrList.prgAdr[i].pszFriendlyW, addrList.prgAdr[i].pszEmail);
  1342. }
  1343. fReload = TRUE;
  1344. }
  1345. else if (id >= ID_SAVE_ADDRESS_FIRST && id < ID_SAVE_ADDRESS_LAST)
  1346. {
  1347. m_cAddrBook.AddAddress(addrList.prgAdr[id - ID_SAVE_ADDRESS_FIRST].pszFriendlyW,
  1348. addrList.prgAdr[id - ID_SAVE_ADDRESS_FIRST].pszEmail);
  1349. fReload = TRUE;
  1350. }
  1351. if(fSignTrusted)
  1352. {
  1353. FILETIME ftNull = {0};
  1354. HrAddSenderCertToWab(NULL, pMessage, NULL, NULL, NULL, ftNull, WFF_CREATE);
  1355. }
  1356. if (fReload)
  1357. {
  1358. // Reload the table
  1359. _ReloadListview();
  1360. }
  1361. exit:
  1362. if (hSubMenu)
  1363. DestroyMenu(hSubMenu);
  1364. if (hPopup)
  1365. DestroyMenu(hPopup);
  1366. #endif
  1367. return (S_OK);
  1368. }
  1369. LRESULT CIEMsgAb::CmdDelete(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1370. {
  1371. HRESULT hr = S_OK;
  1372. LVITEM lvi;
  1373. ENTRYLIST rList;
  1374. ULONG cValues;
  1375. SBinary UNALIGNED *pEntryId;
  1376. BOOL fConfirm = TRUE;
  1377. TCHAR szText[CCHMAX_STRINGRES + MAXNAME];
  1378. WCHAR wszBuff[CCHMAX_STRINGRES];
  1379. if(m_delItem > 0)
  1380. {
  1381. MessageBeep(MB_OK);
  1382. return(S_OK);
  1383. }
  1384. if(m_fNoRemove)
  1385. m_fNoRemove = FALSE;
  1386. lvi.mask = LVIF_PARAM;
  1387. lvi.iSubItem = 0;
  1388. lvi.iItem = -1;
  1389. // Figure out how many items are selected
  1390. cValues = ListView_GetSelectedCount(m_ctlList);
  1391. m_delItem = cValues;
  1392. if (cValues != 1)
  1393. {
  1394. // Remove only Msgr entry
  1395. #ifdef LATER
  1396. AthLoadString(idsBADelMultiple, wszBuff, ARRAYSIZE(wszBuff));
  1397. wnsprintf(szText, ARRAYSIZE(szText), wszBuff, cValues);
  1398. if(IDNO == AthMessageBoxW(NULL, MAKEINTRESOURCE(idsAthena), MAKEINTRESOURCE(idsAthena),
  1399. NULL, MB_YESNO | MB_ICONEXCLAMATION))
  1400. {
  1401. return (0);
  1402. }
  1403. else
  1404. #endif // LATER
  1405. if(m_fNoRemove)
  1406. {
  1407. MessageBeep(MB_OK);
  1408. return(S_OK);
  1409. }
  1410. else
  1411. fConfirm = FALSE;
  1412. // Assert(FALSE);
  1413. // return (0);
  1414. }
  1415. while(cValues > 0)
  1416. {
  1417. lvi.iItem = ListView_GetNextItem(m_ctlList, lvi.iItem, LVNI_SELECTED);
  1418. if(lvi.iItem < 0)
  1419. {
  1420. ErrBeep:
  1421. MessageBeep(MB_OK);
  1422. return(S_OK);
  1423. }
  1424. // Get the item from the ListView
  1425. if(ListView_GetItem(m_ctlList, &lvi) == FALSE)
  1426. goto ErrBeep;
  1427. // Check buddy state
  1428. LPMABENTRY pEntry = (LPMABENTRY) lvi.lParam;
  1429. if(pEntry->tag == LPARAM_MENTRY)
  1430. {
  1431. if(m_pCMsgrList && m_pCMsgrList->IsLocalOnline())
  1432. {
  1433. // Remove only Msgr entry
  1434. if(fConfirm)
  1435. {
  1436. #ifdef LATER
  1437. AthLoadString(idsBADelBLEntry, wszBuff, ARRAYSIZE(wszBuff));
  1438. wnsprintf(szText, ARRAYSIZE(szTExt), wszBuff, pEntry->lpMsgrInfo->pchMsgrName);
  1439. if(IDNO == AthMessageBox(m_hWnd, MAKEINTRESOURCE(idsAthena), szText,
  1440. NULL, MB_YESNO | MB_ICONEXCLAMATION))
  1441. {
  1442. m_delItem = 0;
  1443. return (0);
  1444. }
  1445. else if(m_fNoRemove)
  1446. goto ErrBeep;
  1447. #endif // LATER
  1448. }
  1449. if(pEntry->lpMsgrInfo)
  1450. {
  1451. m_delItem--;
  1452. hr = m_pCMsgrList->FindAndDeleteUser(pEntry->lpMsgrInfo->pchID, TRUE /* fDelete*/);
  1453. }
  1454. else
  1455. {
  1456. m_delItem = 0;
  1457. return(S_OK);
  1458. }
  1459. }
  1460. else
  1461. goto ErrBeep;
  1462. }
  1463. else if(pEntry->tag == LPARAM_MABENTRY)
  1464. {
  1465. int nID = IDNO;
  1466. if(fConfirm)
  1467. {
  1468. #ifdef LATER
  1469. AthLoadString(idsBADelBLABEntry, wszBuff, ARRAYSIZE(wszBuff));
  1470. wnsprintf(szText, ARRAYSIZE(szText), wszBuff, pEntry->pchWABName);
  1471. nID = AthMessageBox(m_hWnd, MAKEINTRESOURCE(idsAthena), szText,
  1472. NULL, MB_YESNOCANCEL | MB_ICONEXCLAMATION);
  1473. #endif // LATER
  1474. }
  1475. if(((nID == IDYES) || !fConfirm) && !m_fNoRemove)
  1476. {
  1477. if(m_pCMsgrList && m_pCMsgrList->IsLocalOnline())
  1478. {
  1479. // Remove only Msgr & AB entry
  1480. if(pEntry->lpMsgrInfo)
  1481. hr = m_pCMsgrList->FindAndDeleteUser(pEntry->lpMsgrInfo->pchID, TRUE /* fDelete*/);
  1482. else
  1483. {
  1484. m_delItem = 0;
  1485. return(S_OK);
  1486. }
  1487. // Allocate a structure big enough for all of 'em
  1488. if (MemAlloc((LPVOID *) &(rList.lpbin), sizeof(SBinary)))
  1489. {
  1490. rList.cValues = 0;
  1491. pEntryId = rList.lpbin;
  1492. *pEntryId = *(pEntry->lpSB);
  1493. pEntryId++;
  1494. rList.cValues = 1;
  1495. // Tell the WAB to delete 'em
  1496. m_nChCount++; // increase count of our notification messages from WAB
  1497. if(!m_cAddrBook.fIsWabLoaded())
  1498. {
  1499. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  1500. return(hr);
  1501. }
  1502. m_cAddrBook.DeleteItems(&rList);
  1503. // Free our array
  1504. MemFree(rList.lpbin);
  1505. }
  1506. // m_delItem++;
  1507. ListView_DeleteItem(m_ctlList, lvi.iItem);
  1508. lvi.iItem--;
  1509. ListView_SetItemState(m_ctlList, ((lvi.iItem >= 0) ? lvi.iItem : 0), LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  1510. }
  1511. else
  1512. MessageBeep(MB_OK);
  1513. }
  1514. else if((nID == IDNO) && !m_fNoRemove)
  1515. {
  1516. // Remove only Msgr entry
  1517. m_delItem--;
  1518. hr = m_pCMsgrList->FindAndDeleteUser(pEntry->lpMsgrInfo->pchID, TRUE /* fDelete*/);
  1519. }
  1520. else
  1521. {
  1522. // Remove nothing
  1523. m_delItem--;
  1524. hr = S_OK;
  1525. }
  1526. }
  1527. else
  1528. {
  1529. // remove AN entry (group or contact)
  1530. if(fConfirm)
  1531. {
  1532. #ifdef LATER
  1533. AthLoadString(idsBADelABEntry, wszBuff, ARRAYSIZE(wszBuff));
  1534. wnsprintf(szText, ARRAYSIZE(szText), wszBuff, pEntry->pchWABName);
  1535. if(IDNO == AthMessageBox(m_hWnd, MAKEINTRESOURCE(idsAthena), szText,
  1536. NULL, MB_YESNO | MB_ICONEXCLAMATION))
  1537. {
  1538. m_delItem = 0;
  1539. return(0);
  1540. }
  1541. else if(m_fNoRemove)
  1542. goto ErrBeep;
  1543. #endif // LATER
  1544. }
  1545. // Allocate a structure big enough for all of 'em
  1546. if(pEntry->lpSB)
  1547. {
  1548. if (MemAlloc((LPVOID *) &(rList.lpbin), sizeof(SBinary)))
  1549. {
  1550. rList.cValues = 0;
  1551. pEntryId = rList.lpbin;
  1552. *pEntryId = *(pEntry->lpSB);
  1553. pEntryId++;
  1554. rList.cValues = 1;
  1555. // Tell the WAB to delete 'em
  1556. m_nChCount++; // increase count of our notification messages from WAB
  1557. if(!m_cAddrBook.fIsWabLoaded())
  1558. {
  1559. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  1560. return(hr);
  1561. }
  1562. m_cAddrBook.DeleteItems(&rList);
  1563. // Free our array
  1564. MemFree(rList.lpbin);
  1565. }
  1566. }
  1567. // m_delItem++;
  1568. ListView_DeleteItem(m_ctlList, lvi.iItem);
  1569. lvi.iItem--;
  1570. }
  1571. cValues--;
  1572. }
  1573. if(ListView_GetItemCount(m_ctlList) > 0)
  1574. {
  1575. m_cEmptyList.Hide();
  1576. ListView_SetItemState(m_ctlList, ((lvi.iItem >= 0) ? lvi.iItem : 0), LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  1577. }
  1578. else
  1579. m_cEmptyList.Show(m_ctlList, (LPWSTR) (m_fShowAllContacts ? m_szEmptyList : m_szMsgrEmptyList));
  1580. _ReloadListview();
  1581. return (hr);
  1582. }
  1583. STDMETHODIMP CIEMsgAb::get_InstMsg(BOOL * pVal)
  1584. {
  1585. *pVal = (GetEntryForSendInstMsg() != NULL);
  1586. return S_OK;
  1587. }
  1588. /* STDMETHODIMP CIEMsgAb::put_InstMsg(BOOL newVal)
  1589. {
  1590. return S_OK;
  1591. } */
  1592. STDMETHODIMP CIEMsgAb::HasFocusIO()
  1593. {
  1594. if (GetFocus() == m_ctlList)
  1595. return S_OK;
  1596. else
  1597. return S_FALSE;
  1598. }
  1599. STDMETHODIMP CIEMsgAb::TranslateAcceleratorIO(LPMSG pMsg)
  1600. {
  1601. if(!pMsg)
  1602. goto SNDMsg;
  1603. #ifdef NEED
  1604. if ((pMsg->message == WM_SYSKEYDOWN) && (pMsg->wParam == ((int) 'D')))
  1605. return(S_FALSE);
  1606. #endif
  1607. if (pMsg->message != WM_KEYDOWN)
  1608. goto SNDMsg;
  1609. if (! (pMsg->wParam == VK_TAB || pMsg->wParam == VK_F6))
  1610. goto SNDMsg;
  1611. m_ctlList.SendMessage(WM_KILLFOCUS, (WPARAM) NULL, (LPARAM) 0);
  1612. return S_OK;
  1613. SNDMsg:
  1614. ::TranslateMessage(pMsg);
  1615. ::DispatchMessage(pMsg);
  1616. // m_ctlList.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
  1617. return (S_OK);
  1618. }
  1619. STDMETHODIMP CIEMsgAb::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
  1620. {
  1621. if (!m_pObjSite)
  1622. return E_FAIL;
  1623. if (!IsWindow(m_hWnd))
  1624. {
  1625. IOleWindow *pOleWnd;
  1626. if (SUCCEEDED(m_pObjSite->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWnd)))
  1627. {
  1628. if(SUCCEEDED(pOleWnd->GetWindow(&m_hwndParent)))
  1629. {
  1630. //Will be resized by parent
  1631. RECT rect = {0};
  1632. m_hWnd = CreateControlWindow(m_hwndParent, rect);
  1633. if (!m_hWnd)
  1634. return E_FAIL;
  1635. }
  1636. }
  1637. pOleWnd->Release();
  1638. }
  1639. if (fActivate)
  1640. {
  1641. m_ctlList.SetFocus();
  1642. }
  1643. m_pObjSite->OnFocusChangeIS((IInputObject*) this, fActivate);
  1644. return (S_OK);
  1645. }
  1646. STDMETHODIMP CIEMsgAb::SetSite(IUnknown *punksite)
  1647. {
  1648. //If we already have a site, we release it
  1649. SafeRelease(m_pObjSite);
  1650. IInputObjectSite *pObjSite;
  1651. if ((punksite) && (SUCCEEDED(punksite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&pObjSite))))
  1652. {
  1653. m_pObjSite = pObjSite;
  1654. // IOleWindow* pOleWindow;
  1655. // if(SUCCEEDED(punksite->QueryInterface(IID_IOleWindowe, (LPVOID*)&pOleWindow))))
  1656. return S_OK;
  1657. }
  1658. return E_FAIL;
  1659. }
  1660. STDMETHODIMP CIEMsgAb::GetSite(REFIID riid, LPVOID *ppvSite)
  1661. {
  1662. return E_NOTIMPL;
  1663. }
  1664. HRESULT CIEMsgAb::RegisterFlyOut(CFolderBar *pFolderBar)
  1665. {
  1666. #ifdef LATER
  1667. Assert(m_pFolderBar == NULL);
  1668. m_pFolderBar = pFolderBar;
  1669. m_pFolderBar->AddRef();
  1670. #endif
  1671. return S_OK;
  1672. }
  1673. HRESULT CIEMsgAb::RevokeFlyOut(void)
  1674. {
  1675. #ifdef LATER
  1676. if (m_pFolderBar)
  1677. {
  1678. m_pFolderBar->Release();
  1679. m_pFolderBar = NULL;
  1680. }
  1681. #endif
  1682. return S_OK;
  1683. }
  1684. void CIEMsgAb::_ReloadListview(void)
  1685. {
  1686. // Kill timer first
  1687. // KillTimer(IDT_PANETIMER);
  1688. // Turn off redrawing
  1689. if(m_delItem != 0)
  1690. m_fNoRemove = TRUE;
  1691. // else
  1692. // m_fNoRemove = FALSE;
  1693. m_delItem = ListView_GetItemCount(m_ctlList);
  1694. SetWindowRedraw(m_ctlList, FALSE);
  1695. int index = ListView_GetNextItem(m_ctlList, -1, LVIS_SELECTED | LVIS_FOCUSED);
  1696. if(index == -1)
  1697. index = 0;
  1698. // Delete everything and reload
  1699. SideAssert(ListView_DeleteAllItems(m_ctlList));
  1700. if(m_pCMsgrList && m_pCMsgrList->IsLocalOnline())
  1701. {
  1702. m_fLogged = TRUE;
  1703. FillMsgrList(); // User list reload
  1704. }
  1705. if(m_fShowAllContacts)
  1706. {
  1707. if(!m_cAddrBook.fIsWabLoaded())
  1708. {
  1709. if(FAILED(m_cAddrBook.OpenWabFile(m_fWAB)))
  1710. return;
  1711. }
  1712. m_cAddrBook.LoadWabContents(m_ctlList, this);
  1713. }
  1714. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  1715. ListView_SetItemState(m_ctlList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1716. ListView_EnsureVisible(m_ctlList, index, FALSE);
  1717. SetWindowRedraw(m_ctlList, TRUE);
  1718. // Invalidate(TRUE); //
  1719. if(ListView_GetItemCount(m_ctlList) > 0)
  1720. m_cEmptyList.Hide();
  1721. else
  1722. m_cEmptyList.Show(m_ctlList, (LPWSTR) (m_fShowAllContacts ? m_szEmptyList : m_szMsgrEmptyList));
  1723. UpdateWindow(/*m_ctlList*/);
  1724. // SetTimer(IDT_PANETIMER, ELAPSE_MOUSEOVERCHECK, NULL);
  1725. return;
  1726. }
  1727. ULONG STDMETHODCALLTYPE CIEMsgAb::OnNotify(ULONG cNotif, LPNOTIFICATION pNotifications)
  1728. {
  1729. // Well something changed in WAB, but we don't know what. We should reload.
  1730. // Sometimes these changes from us and we should ignore it.
  1731. if(m_nChCount > 0)
  1732. m_nChCount--;
  1733. else
  1734. _ReloadListview();
  1735. return (0);
  1736. }
  1737. LRESULT CIEMsgAb::CmdFind(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1738. {
  1739. HRESULT hr = S_OK;
  1740. if(!m_cAddrBook.fIsWabLoaded())
  1741. {
  1742. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  1743. return(hr);
  1744. }
  1745. m_cAddrBook.Find(m_hWnd);
  1746. return (0);
  1747. }
  1748. LRESULT CIEMsgAb::CmdNewGroup(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1749. {
  1750. HRESULT hr = S_OK;
  1751. if(!m_cAddrBook.fIsWabLoaded())
  1752. {
  1753. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  1754. return(hr);
  1755. }
  1756. m_cAddrBook.NewGroup(m_hWnd);
  1757. _ReloadListview();
  1758. return (0);
  1759. }
  1760. LRESULT CIEMsgAb::CmdIEMsgAb(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1761. {
  1762. HRESULT hr = S_OK;
  1763. if(!m_cAddrBook.fIsWabLoaded())
  1764. {
  1765. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  1766. return(hr);
  1767. }
  1768. m_cAddrBook.AddressBook(m_hWnd);
  1769. return (0);
  1770. }
  1771. void CIEMsgAb::AddMsgrListItem(LPMINFO lpMsgrInfo)
  1772. {
  1773. LV_ITEMW lvItem;
  1774. m_cEmptyList.Hide(); // m,ust be sure that empty mesage is hide
  1775. lvItem.iItem = ListView_GetItemCount(m_ctlList);
  1776. lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
  1777. lvItem.lParam = (LPARAM) AddBlabEntry(LPARAM_MENTRY, NULL, lpMsgrInfo, NULL, NULL, FALSE);
  1778. lvItem.iSubItem = 0;
  1779. lvItem.pszText = LPSTR_TEXTCALLBACKW;
  1780. lvItem.iImage = I_IMAGECALLBACK;
  1781. // SetUserIcon(LPARAM_MENTRY, lpMsgrInfo->nStatus, &(lvItem.iImage));
  1782. ::SendMessage(m_ctlList, LVM_INSERTITEMW, 0, ((LPARAM) &lvItem));
  1783. return;
  1784. }
  1785. HRESULT CIEMsgAb::FillMsgrList()
  1786. {
  1787. LPMINFO pEntry = NULL;
  1788. if(!m_pCMsgrList)
  1789. {
  1790. // Assert(FALSE); // Possible situation. See Bug 31262
  1791. return(S_OK);
  1792. }
  1793. pEntry = m_pCMsgrList->GetFirstMsgrItem();
  1794. while(pEntry)
  1795. {
  1796. // if(m_fShowAllContacts || ((pEntry->nStatus != BIMSTATE_OFFLINE) && (pEntry->nStatus != BIMSTATE_INVISIBLE) &&
  1797. // !(m_pCMsgrList->IsLocalName(pEntry->pchID) )))
  1798. if(m_fShowAllContacts)
  1799. AddMsgrListItem(pEntry);
  1800. else if((m_fShowOnlineContacts || m_fShowOfflineContacts) && ((pEntry->nStatus != BIMSTATE_OFFLINE) && (pEntry->nStatus != BIMSTATE_INVISIBLE) &&
  1801. !(m_pCMsgrList->IsLocalName(pEntry->pchID))))
  1802. AddMsgrListItem(pEntry);
  1803. else if(m_fShowOfflineContacts && (((pEntry->nStatus == BIMSTATE_OFFLINE) || (pEntry->nStatus == BIMSTATE_INVISIBLE)) &&
  1804. !(m_pCMsgrList->IsLocalName(pEntry->pchID))))
  1805. AddMsgrListItem(pEntry);
  1806. pEntry = m_pCMsgrList->GetNextMsgrItem(pEntry);
  1807. }
  1808. return S_OK;
  1809. }
  1810. // Add BLAB table entry
  1811. LPMABENTRY CIEMsgAb::AddBlabEntry(MABENUM tag, LPSBinary lpSB, LPMINFO lpMsgrInfo, WCHAR *pchMail, WCHAR *pchDisplayName, BOOL fCert, LPPNONEENTRIES lpPhs)
  1812. {
  1813. WCHAR szName[MAXNAME];
  1814. LPMABENTRY pEntry = NULL;
  1815. WCHAR *pchName = NULL;
  1816. int nLen = 0;
  1817. if (!MemAlloc((LPVOID *) &pEntry, sizeof(mabEntry)))
  1818. return(NULL);
  1819. pEntry->tag = tag;
  1820. pEntry->lpSB = lpSB;
  1821. pEntry->pchWABName = NULL;
  1822. pEntry->pchWABID = NULL;
  1823. pEntry->fCertificate = fCert;
  1824. pEntry->lpPhones = NULL;
  1825. if(lpSB != NULL)
  1826. {
  1827. if(!pchDisplayName)
  1828. {
  1829. if(!m_cAddrBook.fIsWabLoaded())
  1830. {
  1831. if(FAILED(m_cAddrBook.OpenWabFile(m_fWAB)))
  1832. return(NULL);
  1833. }
  1834. m_cAddrBook.GetDisplayName(pEntry->lpSB, szName, ARRAYSIZE(szName));
  1835. pchName = szName;
  1836. }
  1837. else
  1838. pchName = pchDisplayName;
  1839. if(pchName)
  1840. {
  1841. ULONG cchSize = lstrlenW(pchName) + 1;
  1842. if (!MemAlloc((LPVOID *) &(pEntry->pchWABName), cchSize * sizeof(WCHAR) ))
  1843. {
  1844. MemFree(pEntry);
  1845. return(NULL);
  1846. }
  1847. StrCpyNW(pEntry->pchWABName, pchName, cchSize);
  1848. }
  1849. if(pchMail != NULL)
  1850. {
  1851. ULONG cchSize = lstrlenW(pchMail) + 1;
  1852. if (MemAlloc((LPVOID *) &(pEntry->pchWABID), cchSize * sizeof(WCHAR) ))
  1853. StrCpyNW(pEntry->pchWABID, pchMail, cchSize);
  1854. }
  1855. }
  1856. if(lpMsgrInfo && MemAlloc((LPVOID *) &(pEntry->lpMsgrInfo), sizeof(struct _tag_OEMsgrInfo)))
  1857. {
  1858. pEntry->lpMsgrInfo->nStatus = lpMsgrInfo->nStatus;
  1859. pEntry->lpMsgrInfo->pPrev = NULL;
  1860. pEntry->lpMsgrInfo->pNext = NULL;
  1861. if(lpMsgrInfo->pchMsgrName && MemAlloc((LPVOID *) &(pEntry->lpMsgrInfo->pchMsgrName), (lstrlenW(lpMsgrInfo->pchMsgrName) + 1)*sizeof(WCHAR)))
  1862. StrCpyNW(pEntry->lpMsgrInfo->pchMsgrName, lpMsgrInfo->pchMsgrName, lstrlenW(lpMsgrInfo->pchMsgrName) + 1);
  1863. else
  1864. pEntry->lpMsgrInfo->pchMsgrName = NULL;
  1865. if(lpMsgrInfo->pchID && MemAlloc((LPVOID *) &(pEntry->lpMsgrInfo->pchID), (lstrlenW(lpMsgrInfo->pchID) + 1)*sizeof(WCHAR)))
  1866. StrCpyNW(pEntry->lpMsgrInfo->pchID, lpMsgrInfo->pchID, lstrlenW(lpMsgrInfo->pchID) + 1);
  1867. else
  1868. pEntry->lpMsgrInfo->pchID = NULL;
  1869. if((lpMsgrInfo->pchWorkPhone || lpMsgrInfo->pchHomePhone || lpMsgrInfo->pchMobilePhone) && MemAlloc((LPVOID *) &(pEntry->lpPhones), sizeof(PNONEENTRIES)))
  1870. {
  1871. if(lpMsgrInfo->pchHomePhone && MemAlloc((LPVOID *) &(pEntry->lpPhones->pchHomePhone), (lstrlenW(lpMsgrInfo->pchHomePhone) + 1)*sizeof(WCHAR)))
  1872. StrCpyNW(pEntry->lpPhones->pchHomePhone, lpMsgrInfo->pchHomePhone, lstrlenW(lpMsgrInfo->pchHomePhone) + 1);
  1873. else
  1874. pEntry->lpPhones->pchHomePhone = NULL;
  1875. if(lpMsgrInfo->pchWorkPhone && MemAlloc((LPVOID *) &(pEntry->lpPhones->pchWorkPhone), (lstrlenW(lpMsgrInfo->pchWorkPhone) + 1)*sizeof(WCHAR)))
  1876. StrCpyNW(pEntry->lpPhones->pchWorkPhone, lpMsgrInfo->pchWorkPhone, lstrlenW(lpMsgrInfo->pchWorkPhone) + 1);
  1877. else
  1878. pEntry->lpPhones->pchWorkPhone = NULL;
  1879. if(lpMsgrInfo->pchMobilePhone && MemAlloc((LPVOID *) &(pEntry->lpPhones->pchMobilePhone), (lstrlenW(lpMsgrInfo->pchMobilePhone) + 1)*sizeof(WCHAR)))
  1880. StrCpyNW(pEntry->lpPhones->pchMobilePhone, lpMsgrInfo->pchMobilePhone, lstrlenW(lpMsgrInfo->pchMobilePhone) + 1);
  1881. else
  1882. pEntry->lpPhones->pchMobilePhone = NULL;
  1883. pEntry->lpPhones->pchIPPhone = NULL;
  1884. return(pEntry);
  1885. }
  1886. }
  1887. else
  1888. pEntry->lpMsgrInfo = NULL;
  1889. // Add information about pfones
  1890. if(lpPhs && MemAlloc((LPVOID *) &(pEntry->lpPhones), sizeof(PNONEENTRIES)))
  1891. {
  1892. if(lpPhs->pchHomePhone && (nLen = lstrlenW(lpPhs->pchHomePhone)))
  1893. {
  1894. if(MemAlloc((LPVOID *) &(pEntry->lpPhones->pchHomePhone), (nLen + 1)*sizeof(WCHAR)))
  1895. StrCpyNW(pEntry->lpPhones->pchHomePhone, lpPhs->pchHomePhone, nLen + 1);
  1896. else
  1897. pEntry->lpPhones->pchHomePhone = NULL;
  1898. }
  1899. else
  1900. pEntry->lpPhones->pchHomePhone = NULL;
  1901. if(lpPhs->pchWorkPhone && (nLen = lstrlenW(lpPhs->pchWorkPhone)))
  1902. {
  1903. if(MemAlloc((LPVOID *) &(pEntry->lpPhones->pchWorkPhone), (nLen + 1)*sizeof(WCHAR)))
  1904. StrCpyNW(pEntry->lpPhones->pchWorkPhone, lpPhs->pchWorkPhone, nLen + 1);
  1905. else
  1906. pEntry->lpPhones->pchWorkPhone = NULL;
  1907. }
  1908. else
  1909. pEntry->lpPhones->pchWorkPhone = NULL;
  1910. if(lpPhs->pchMobilePhone && (nLen = lstrlenW(lpPhs->pchMobilePhone)))
  1911. {
  1912. if(MemAlloc((LPVOID *) &(pEntry->lpPhones->pchMobilePhone), (nLen + 1)*sizeof(WCHAR)))
  1913. StrCpyNW(pEntry->lpPhones->pchMobilePhone, lpPhs->pchMobilePhone, nLen + 1);
  1914. else
  1915. pEntry->lpPhones->pchMobilePhone = NULL;
  1916. }
  1917. else
  1918. pEntry->lpPhones->pchMobilePhone = NULL;
  1919. if(lpPhs->pchIPPhone && (nLen = lstrlenW(lpPhs->pchIPPhone)))
  1920. {
  1921. if(MemAlloc((LPVOID *) &(pEntry->lpPhones->pchIPPhone), (nLen + 1)*sizeof(WCHAR)))
  1922. StrCpyNW(pEntry->lpPhones->pchIPPhone, lpPhs->pchIPPhone, nLen + 1);
  1923. else
  1924. pEntry->lpPhones->pchIPPhone = NULL;
  1925. }
  1926. else
  1927. pEntry->lpPhones->pchIPPhone = NULL;
  1928. }
  1929. return(pEntry);
  1930. }
  1931. void CIEMsgAb::RemoveMsgrInfo(LPMINFO lpMsgrInfo)
  1932. {
  1933. SafeMemFree(lpMsgrInfo->pchMsgrName);
  1934. SafeMemFree(lpMsgrInfo->pchID);
  1935. SafeMemFree(lpMsgrInfo);
  1936. }
  1937. // Remove BLAB table entry
  1938. void CIEMsgAb::RemoveBlabEntry(LPMABENTRY lpEntry)
  1939. {
  1940. if(lpEntry == NULL)
  1941. return;
  1942. if(lpEntry->pchWABName)
  1943. MemFree(lpEntry->pchWABName);
  1944. if(lpEntry->pchWABID)
  1945. MemFree(lpEntry->pchWABID);
  1946. if(lpEntry->lpPhones)
  1947. {
  1948. if(lpEntry->lpPhones->pchHomePhone)
  1949. MemFree(lpEntry->lpPhones->pchHomePhone);
  1950. if(lpEntry->lpPhones->pchWorkPhone)
  1951. MemFree(lpEntry->lpPhones->pchWorkPhone);
  1952. if(lpEntry->lpPhones->pchMobilePhone)
  1953. MemFree(lpEntry->lpPhones->pchMobilePhone);
  1954. if(lpEntry->lpPhones->pchIPPhone)
  1955. MemFree(lpEntry->lpPhones->pchIPPhone);
  1956. MemFree(lpEntry->lpPhones);
  1957. }
  1958. if(lpEntry->lpMsgrInfo)
  1959. {
  1960. RemoveMsgrInfo(lpEntry->lpMsgrInfo);
  1961. lpEntry->lpMsgrInfo = NULL;
  1962. }
  1963. MemFree(lpEntry);
  1964. lpEntry = NULL;
  1965. return;
  1966. }
  1967. // This function check buddy and if we have AB entry then set LPARAM_MABENTRY tag
  1968. void CIEMsgAb::CheckAndAddAbEntry(LPSBinary lpSB, WCHAR *pchEmail, WCHAR *pchDisplayName, DWORD nFlag, LPPNONEENTRIES pPhEnries)
  1969. {
  1970. WCHAR szName[MAXNAME];
  1971. LPMABENTRY pEntry = NULL;
  1972. LV_ITEMW lvItem;
  1973. lvItem.iItem = ListView_GetItemCount(m_ctlList);
  1974. lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
  1975. lvItem.iSubItem = 0;
  1976. lvItem.pszText = LPSTR_TEXTCALLBACKW;
  1977. lvItem.iImage = I_IMAGECALLBACK;
  1978. m_cEmptyList.Hide(); // must be sure that empty mesage is hide
  1979. if(!(nFlag & MAB_BUDDY))
  1980. {
  1981. if(m_fShowAllContacts || (m_fShowEmailContacts && pchEmail) || (m_fShowOthersContacts && (pchEmail == NULL)))
  1982. {
  1983. lvItem.lParam = (LPARAM) AddBlabEntry((nFlag & MAB_GROUP) ? LPARAM_ABGRPENTRY : LPARAM_ABENTRY, lpSB, NULL, pchEmail,
  1984. pchDisplayName, (nFlag & MAB_CERT), pPhEnries);
  1985. // SetUserIcon(LPARAM_ABGRPENTRY, 0, &(lvItem.iImage));
  1986. ::SendMessage(m_ctlList, LVM_INSERTITEMW, 0, ((LPARAM) &lvItem));
  1987. // ListView_InsertItem(m_ctlList, &lvItem);
  1988. }
  1989. return;
  1990. }
  1991. if(pchEmail)
  1992. pEntry = FindUserEmail(pchEmail, NULL, TRUE);
  1993. if(pEntry) // buddy found
  1994. {
  1995. // if we already linked this budyy to AN entry, add new list item)
  1996. if(pEntry->tag == LPARAM_MABENTRY)
  1997. {
  1998. lvItem.lParam = (LPARAM) AddBlabEntry(LPARAM_MABENTRY, lpSB, pEntry->lpMsgrInfo, pchEmail, pchDisplayName, (nFlag & MAB_CERT), pPhEnries);
  1999. // SetUserIcon(LPARAM_MABENTRY, pEntry->lpMsgrInfo->nStatus, &(lvItem.iImage));
  2000. ListView_InsertItem(m_ctlList, &lvItem);
  2001. }
  2002. else if(pEntry->tag == LPARAM_MENTRY) // buddy was not linked to AB entry
  2003. {
  2004. pEntry->tag = LPARAM_MABENTRY;
  2005. pEntry->lpSB = lpSB;
  2006. Assert(lpSB);
  2007. if(!m_cAddrBook.fIsWabLoaded())
  2008. {
  2009. if(FAILED(m_cAddrBook.OpenWabFile(m_fWAB)))
  2010. return;
  2011. }
  2012. m_cAddrBook.GetDisplayName(pEntry->lpSB, szName, ARRAYSIZE(szName));
  2013. pEntry->pchWABName = NULL;
  2014. pEntry->pchWABID = NULL;
  2015. ULONG cchSize = lstrlenW(szName) + 1;
  2016. if (MemAlloc((LPVOID *) &(pEntry->pchWABName), cchSize*sizeof(WCHAR) ))
  2017. StrCpyNW(pEntry->pchWABName, szName, cchSize);
  2018. cchSize = lstrlenW(pchEmail) + 1;
  2019. if(MemAlloc((LPVOID *) &(pEntry->pchWABID), cchSize*sizeof(WCHAR) ))
  2020. StrCpyNW(pEntry->pchWABID, pchEmail, cchSize);
  2021. }
  2022. else
  2023. Assert(FALSE); // something strange
  2024. }
  2025. else // buddy not found, simple AB entry
  2026. {
  2027. if(m_fShowAllContacts || (m_fShowEmailContacts && pchEmail) || (m_fShowOthersContacts && (pchEmail == NULL)))
  2028. {
  2029. lvItem.lParam = (LPARAM) AddBlabEntry(LPARAM_ABENTRY, lpSB, NULL, pchEmail, pchDisplayName, (nFlag & MAB_CERT), pPhEnries);
  2030. // SetUserIcon(LPARAM_ABENTRY, 0, &(lvItem.iImage));
  2031. ListView_InsertItem(m_ctlList, &lvItem);
  2032. }
  2033. }
  2034. }
  2035. LPMABENTRY CIEMsgAb::FindUserEmail(WCHAR *pchEmail, int *pIndex, BOOL fMsgrOnly)
  2036. {
  2037. LPMABENTRY pEntry = NULL;
  2038. LVITEMW lvi;
  2039. lvi.mask = LVIF_PARAM;
  2040. if(pIndex != NULL)
  2041. lvi.iItem = *pIndex;
  2042. else
  2043. lvi.iItem = -1;
  2044. lvi.iSubItem = 0;
  2045. while((lvi.iItem = ListView_GetNextItem(m_ctlList, lvi.iItem, LVNI_ALL)) != -1)
  2046. {
  2047. ListView_GetItem(m_ctlList, &lvi);
  2048. pEntry = (LPMABENTRY) lvi.lParam;
  2049. if(pEntry)
  2050. {
  2051. if(fMsgrOnly)
  2052. {
  2053. if(pEntry->lpMsgrInfo)
  2054. {
  2055. if((pEntry->lpMsgrInfo)->pchID)
  2056. {
  2057. if(!lstrcmpiW((pEntry->lpMsgrInfo)->pchID, pchEmail))
  2058. {
  2059. if(pIndex != NULL)
  2060. *pIndex = lvi.iItem;
  2061. return(pEntry);
  2062. }
  2063. }
  2064. }
  2065. }
  2066. else
  2067. {
  2068. if(pEntry->pchWABID)
  2069. {
  2070. if(!lstrcmpiW(pEntry->pchWABID, pchEmail))
  2071. {
  2072. if(pIndex != NULL)
  2073. *pIndex = lvi.iItem;
  2074. return(pEntry);
  2075. }
  2076. }
  2077. if(pEntry->lpSB)
  2078. {
  2079. Assert(m_cAddrBook.fIsWabLoaded());
  2080. if(m_cAddrBook.CheckEmailAddr(pEntry->lpSB, pchEmail))
  2081. {
  2082. if(pIndex != NULL)
  2083. *pIndex = lvi.iItem;
  2084. return(pEntry);
  2085. }
  2086. }
  2087. }
  2088. }
  2089. }
  2090. return(NULL);
  2091. }
  2092. // messenger want shutown. release messenger object
  2093. HRESULT CIEMsgAb::OnMsgrShutDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2094. {
  2095. if(m_pCMsgrList)
  2096. {
  2097. m_pCMsgrList->UnRegisterUIWnd(m_hWnd);
  2098. OE_CloseMsgrList(m_pCMsgrList);
  2099. m_pCMsgrList = NULL;
  2100. }
  2101. m_dwHideMessenger = 1;
  2102. m_dwDisableMessenger = 1;
  2103. _ReloadListview();
  2104. ::SendMessage(m_hwndParent, WM_MSGR_LOGRESULT, 0, 0);
  2105. return(S_OK);
  2106. }
  2107. // Set new buddy status (online/ofline/etc. and redraw list view entry)
  2108. HRESULT CIEMsgAb::OnUserStateChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2109. {
  2110. HRESULT hr = S_OK;
  2111. LPMABENTRY pEntry = NULL;
  2112. int index = -1;
  2113. BOOL fNeedRefresh = m_fShowOnlineContacts ;
  2114. if(fNeedRefresh)
  2115. {
  2116. m_fShowOfflineContacts = TRUE;
  2117. m_fShowOnlineContacts = FALSE;
  2118. _ReloadListview();
  2119. }
  2120. while((pEntry = FindUserEmail((LPWSTR) lParam, &index, TRUE)) != NULL)
  2121. {
  2122. pEntry->lpMsgrInfo->nStatus = (int) wParam;
  2123. ListView_RedrawItems(m_ctlList, index, index+1);
  2124. }
  2125. if(fNeedRefresh)
  2126. {
  2127. m_fShowOfflineContacts = FALSE;
  2128. m_fShowOnlineContacts = TRUE;
  2129. _ReloadListview();
  2130. }
  2131. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  2132. return(hr);
  2133. }
  2134. // Message: buddy was removed
  2135. HRESULT CIEMsgAb::OnUserRemoved(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2136. {
  2137. HRESULT hr = S_OK;
  2138. int index = -1;
  2139. LPMABENTRY pEntry = NULL;
  2140. while((pEntry = FindUserEmail((LPWSTR) lParam, &index, TRUE)) != NULL)
  2141. {
  2142. // Not removed yet
  2143. if(pEntry->tag == LPARAM_MABENTRY)
  2144. {
  2145. Assert(pEntry->lpMsgrInfo);
  2146. if(pEntry->lpMsgrInfo)
  2147. {
  2148. RemoveMsgrInfo(pEntry->lpMsgrInfo);
  2149. pEntry->lpMsgrInfo = NULL;
  2150. }
  2151. pEntry->tag = LPARAM_ABENTRY;
  2152. ListView_RedrawItems(m_ctlList, index, index+1);
  2153. }
  2154. else if(pEntry->tag == LPARAM_MENTRY)
  2155. {
  2156. int index1 = ListView_GetNextItem(m_ctlList, -1, LVIS_SELECTED | LVIS_FOCUSED);
  2157. m_delItem++;
  2158. ListView_DeleteItem(m_ctlList, index);
  2159. if(index == index1)
  2160. {
  2161. index1--;
  2162. ListView_SetItemState(m_ctlList, ((index1 >= 0) ? index1 : 0), LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
  2163. }
  2164. }
  2165. else
  2166. index++;
  2167. }
  2168. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  2169. if(ListView_GetItemCount(m_ctlList) > 0)
  2170. m_cEmptyList.Hide();
  2171. else
  2172. m_cEmptyList.Show(m_ctlList, (LPWSTR) (m_fShowAllContacts ? m_szEmptyList : m_szMsgrEmptyList));
  2173. return(hr);
  2174. }
  2175. // Event User was added => add buddy to our list.
  2176. HRESULT CIEMsgAb::OnUserAdded(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2177. {
  2178. LPMINFO pEntry = (LPMINFO) lParam;
  2179. if(m_fShowAllContacts)
  2180. AddMsgrListItem(pEntry);
  2181. else if((m_fShowOnlineContacts || m_fShowOfflineContacts) && ((pEntry->nStatus != BIMSTATE_OFFLINE) && (pEntry->nStatus != BIMSTATE_INVISIBLE) &&
  2182. !(m_pCMsgrList->IsLocalName(pEntry->pchID))))
  2183. AddMsgrListItem(pEntry);
  2184. else if(m_fShowOfflineContacts && (((pEntry->nStatus == BIMSTATE_OFFLINE) || (pEntry->nStatus == BIMSTATE_INVISIBLE)) &&
  2185. !(m_pCMsgrList->IsLocalName(pEntry->pchID))))
  2186. AddMsgrListItem(pEntry);
  2187. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  2188. return(S_OK);
  2189. }
  2190. HRESULT CIEMsgAb::OnUserNameChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2191. {
  2192. HRESULT hr = S_OK;
  2193. #ifdef NEEDED
  2194. LPMINFO pItem = (LPMINFO) lParam;
  2195. LPMABENTRY pEntry = NULL;
  2196. int index = -1;
  2197. while((pEntry = FindUserEmail(pItem->pchID, &index, TRUE)) != NULL)
  2198. {
  2199. if((pEntry->tag == LPARAM_MENTRY) && lstrcmpi(pItem->pchID, pItem->pchMsgrName))
  2200. {
  2201. hr = m_cAddrBook.AutoAddContact(pItem->pchMsgrName, pItem->pchID);
  2202. // _ReloadListview();
  2203. }
  2204. ListView_RedrawItems(m_ctlList, index, index+1);
  2205. }
  2206. #endif
  2207. _ReloadListview();
  2208. return(hr);
  2209. }
  2210. HRESULT CIEMsgAb::OnUserLogoffEvent(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2211. {
  2212. HRESULT hr = S_OK;
  2213. ::SendMessage(m_hwndParent, nMsg, wParam, lParam);
  2214. if(!m_fLogged)
  2215. return S_OK;
  2216. else
  2217. m_fLogged = FALSE;
  2218. SetWindowRedraw(m_ctlList, FALSE);
  2219. int index = ListView_GetNextItem(m_ctlList, -1, LVIS_SELECTED | LVIS_FOCUSED);
  2220. // Delete everything and reload
  2221. if(m_delItem != 0)
  2222. m_fNoRemove = TRUE;
  2223. // else
  2224. // m_fNoRemove = FALSE;
  2225. m_delItem = ListView_GetItemCount(m_ctlList);
  2226. ListView_DeleteAllItems(m_ctlList);
  2227. // FillMsgrList(); // User list reload
  2228. if(m_fShowAllContacts)
  2229. {
  2230. if(!m_cAddrBook.fIsWabLoaded())
  2231. {
  2232. if(FAILED(hr = m_cAddrBook.OpenWabFile(m_fWAB)))
  2233. return(hr);
  2234. }
  2235. m_cAddrBook.LoadWabContents(m_ctlList, this);
  2236. }
  2237. ListView_SetItemState(m_ctlList, index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  2238. SetWindowRedraw(m_ctlList, TRUE);
  2239. if(ListView_GetItemCount(m_ctlList) > 0)
  2240. m_cEmptyList.Hide();
  2241. else
  2242. m_cEmptyList.Show(m_ctlList, (LPWSTR) (m_fShowAllContacts ? m_szEmptyList : m_szMsgrEmptyList));
  2243. UpdateWindow(/*m_ctlList*/);
  2244. return S_OK;
  2245. }
  2246. HRESULT CIEMsgAb::OnLocalStateChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2247. {
  2248. ::SendMessage(m_hwndParent, nMsg, wParam, lParam);
  2249. return S_OK;
  2250. }
  2251. HRESULT CIEMsgAb::OnUserLogResultEvent(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2252. {
  2253. ::SendMessage(m_hwndParent, nMsg, wParam, lParam);
  2254. _ReloadListview();
  2255. if(SUCCEEDED(lParam))
  2256. {
  2257. m_fLogged = TRUE;
  2258. }
  2259. return S_OK;
  2260. }
  2261. LRESULT CIEMsgAb::NotifyKillFocus(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  2262. {
  2263. HRESULT hres = E_FAIL;
  2264. if (m_pObjSite != NULL)
  2265. {
  2266. IInputObjectSite *pis;
  2267. hres = m_pObjSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&pis);
  2268. if (SUCCEEDED(hres))
  2269. {
  2270. hres = pis->OnFocusChangeIS((IInputObject*) this, FALSE);
  2271. pis->Release();
  2272. }
  2273. }
  2274. return (hres);
  2275. }
  2276. LRESULT CIEMsgAb::NotifySetFocus(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  2277. {
  2278. // #ifdef LATER
  2279. // UnkOnFocusChangeIS(m_pObjSite, (IInputObject*) this, TRUE);
  2280. // #endif
  2281. HRESULT hres = S_OK;
  2282. /* if (m_pObjSite != NULL)
  2283. {
  2284. IInputObjectSite *pis;
  2285. hres = m_pObjSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&pis);
  2286. if (SUCCEEDED(hres))
  2287. {
  2288. hres = pis->OnFocusChangeIS((IInputObject*) this, TRUE);
  2289. pis->Release();
  2290. }
  2291. }*/
  2292. return (hres);
  2293. }
  2294. HRESULT STDMETHODCALLTYPE CIEMsgAb::QueryStatus(const GUID *pguidCmdGroup,
  2295. ULONG cCmds, OLECMD *prgCmds,
  2296. OLECMDTEXT *pCmdText)
  2297. {
  2298. int nEnable;
  2299. HRESULT hr;
  2300. DWORD cSelected = ListView_GetSelectedCount(m_ctlList);
  2301. UINT id;
  2302. BIMSTATE State;
  2303. // Loop through all the commands in the array
  2304. for ( ; cCmds > 0; cCmds--, prgCmds++)
  2305. {
  2306. // Only look at commands that don't have OLECMDF_SUPPORTED;
  2307. if (prgCmds->cmdf == 0)
  2308. {
  2309. switch (prgCmds->cmdID)
  2310. {
  2311. case ID_HIDE_IM:
  2312. if(m_dwHideMessenger)
  2313. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2314. else if(!m_dwDisableMessenger)
  2315. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2316. else
  2317. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2318. break;
  2319. case ID_SHOW_IM:
  2320. if(m_dwHideMessenger)
  2321. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2322. else if(!m_dwDisableMessenger)
  2323. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2324. else
  2325. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2326. break;
  2327. // These commands are enabled if and only if one item is selected
  2328. case ID_DELETE_CONTACT:
  2329. if (cSelected > 0)
  2330. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2331. break;
  2332. case ID_FIND_PEOPLE:
  2333. case ID_ADDRESS_BOOK:
  2334. if(m_fWAB)
  2335. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2336. else
  2337. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2338. break;
  2339. case ID_SEND_MESSAGE:
  2340. if((HasFocusIO() == S_OK) && cSelected >= 1)
  2341. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2342. break;
  2343. case ID_SEND_INSTANT_MESSAGE2:
  2344. {
  2345. if (cSelected == 1)
  2346. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2347. else if(m_dwHideMessenger)
  2348. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2349. else
  2350. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2351. break;
  2352. }
  2353. case ID_SORT_BY_STATUS:
  2354. if(!IsMessengerInstalled())
  2355. {
  2356. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2357. break;
  2358. }
  2359. else
  2360. if(ListView_GetItemCount(m_ctlList) > 1)
  2361. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2362. else
  2363. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2364. if((m_nSortType == BASORT_STATUS_ACSEND) || (m_nSortType == BASORT_STATUS_DESCEND))
  2365. prgCmds->cmdf |= OLECMDF_NINCHED;
  2366. break;
  2367. case ID_SORT_BY_NAME:
  2368. if(!IsMessengerInstalled())
  2369. {
  2370. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2371. break;
  2372. }
  2373. else if(ListView_GetItemCount(m_ctlList) > 1)
  2374. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2375. else
  2376. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2377. if((m_nSortType == BASORT_NAME_ACSEND) || (m_nSortType == BASORT_NAME_DESCEND))
  2378. prgCmds->cmdf |= OLECMDF_NINCHED;
  2379. break;
  2380. // These commands are always enabled
  2381. case ID_POPUP_NEW_ACCOUNT:
  2382. case ID_NEW_HOTMAIL_ACCOUNT:
  2383. case ID_NEW_ATT_ACCOUNT:
  2384. case ID_NEW_CONTACT:
  2385. case ID_POPUP_MESSENGER:
  2386. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2387. break;
  2388. case ID_SET_ONLINE_CONTACT:
  2389. {
  2390. if(m_dwHideMessenger)
  2391. {
  2392. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2393. break;
  2394. }
  2395. else if(cSelected != 1)
  2396. {
  2397. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2398. break;
  2399. }
  2400. LPMABENTRY pEntry = GetSelectedEntry();
  2401. if(!pEntry && m_pCMsgrList)
  2402. {
  2403. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2404. break;
  2405. }
  2406. else if(pEntry && pEntry->tag != LPARAM_ABENTRY)
  2407. {
  2408. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2409. break;
  2410. }
  2411. }
  2412. case ID_NEW_ONLINE_CONTACT:
  2413. if(m_pCMsgrList)
  2414. {
  2415. if(m_pCMsgrList->IsLocalOnline())
  2416. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2417. else
  2418. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2419. }
  2420. else if(m_dwHideMessenger)
  2421. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2422. else
  2423. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2424. break;
  2425. // Properties is only enabled if the input focus is in the
  2426. // list view. Otherwise, we don't mark it as supported at all.
  2427. case ID_PROPERTIES:
  2428. {
  2429. LPMABENTRY pEntry = GetSelectedEntry();
  2430. if(pEntry && pEntry->tag != LPARAM_MENTRY)
  2431. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2432. else
  2433. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2434. break;
  2435. }
  2436. case ID_VIEW_ONLINE:
  2437. if(m_fShowOnlineContacts)
  2438. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED | OLECMDF_NINCHED;
  2439. else
  2440. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED ;
  2441. break;
  2442. case ID_VIEW_ONANDOFFLINE:
  2443. if(m_fShowOfflineContacts)
  2444. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED | OLECMDF_NINCHED;
  2445. else
  2446. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED ;
  2447. break;
  2448. case ID_VIEW_ALL:
  2449. if(m_fShowAllContacts)
  2450. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED | OLECMDF_NINCHED;
  2451. else
  2452. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED ;
  2453. break;
  2454. case ID_MESSENGER_OPTIONS:
  2455. if(m_dwHideMessenger)
  2456. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2457. else if (!m_pCMsgrList)
  2458. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2459. else
  2460. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2461. break;
  2462. case ID_CALL:
  2463. case ID_DIAL_PHONE_NUMBER:
  2464. if((ListView_GetItemCount(m_ctlList) < 1) || (!IsTelInstalled())) // && (!m_pCMsgrList || !m_pCMsgrList->IsLocalOnline())))
  2465. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2466. else
  2467. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2468. break;
  2469. case ID_HOME_PHONE:
  2470. case ID_WORK_PHONE:
  2471. case ID_MOBILE_PHONE:
  2472. case ID_IP_PHONE:
  2473. if(_FillPhoneNumber(prgCmds->cmdID, pCmdText))
  2474. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2475. else
  2476. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2477. break;
  2478. case SEP_PHONE:
  2479. {
  2480. LPMABENTRY pEntry = GetSelectedEntry();
  2481. if(pEntry && pEntry->lpPhones && (pEntry->lpPhones->pchIPPhone || pEntry->lpPhones->pchMobilePhone || pEntry->lpPhones->pchWorkPhone || pEntry->lpPhones->pchHomePhone))
  2482. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2483. else
  2484. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2485. }
  2486. break;
  2487. // These depend on whether
  2488. case ID_LOGIN_MESSENGER:
  2489. case ID_LOGOFF_MESSENGER:
  2490. case ID_MESSENGER_ONLINE:
  2491. case ID_MESSENGER_INVISIBLE:
  2492. case ID_MESSENGER_BUSY:
  2493. case ID_MESSENGER_BACK:
  2494. case ID_MESSENGER_AWAY:
  2495. case ID_MESSENGER_ON_PHONE:
  2496. case ID_MESSENGER_LUNCH:
  2497. case ID_POPUP_MESSENGER_STATUS:
  2498. {
  2499. // If messenger isn't installed, then none of these commands will
  2500. // be enabled.
  2501. if(m_dwHideMessenger)
  2502. {
  2503. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2504. break;
  2505. }
  2506. else if (!m_pCMsgrList)
  2507. {
  2508. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2509. break;
  2510. }
  2511. if (FAILED(m_pCMsgrList->GetLocalState(&State)))
  2512. State = BIMSTATE_UNKNOWN;
  2513. // Convert the online state to a command ID
  2514. switch (State)
  2515. {
  2516. case BIMSTATE_ONLINE:
  2517. case BIMSTATE_IDLE:
  2518. id = ID_MESSENGER_ONLINE;
  2519. break;
  2520. case BIMSTATE_INVISIBLE:
  2521. id = ID_MESSENGER_INVISIBLE;
  2522. break;
  2523. case BIMSTATE_BUSY:
  2524. id = ID_MESSENGER_BUSY;
  2525. break;
  2526. case BIMSTATE_BE_RIGHT_BACK:
  2527. id = ID_MESSENGER_BACK;
  2528. break;
  2529. case BIMSTATE_AWAY:
  2530. id = ID_MESSENGER_AWAY;
  2531. break;
  2532. case BIMSTATE_ON_THE_PHONE:
  2533. id = ID_MESSENGER_ON_PHONE;
  2534. break;
  2535. case BIMSTATE_OUT_TO_LUNCH:
  2536. id = ID_MESSENGER_LUNCH;
  2537. break;
  2538. default:
  2539. id = 0xffff;
  2540. }
  2541. // Logon is handled a bit seperatly
  2542. if (prgCmds->cmdID == ID_LOGIN_MESSENGER)
  2543. {
  2544. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2545. if (id == 0xffff)
  2546. prgCmds->cmdf |= OLECMDF_ENABLED;
  2547. }
  2548. else if (prgCmds->cmdID == ID_LOGOFF_MESSENGER)
  2549. {
  2550. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2551. if (id != 0xffff)
  2552. prgCmds->cmdf |= OLECMDF_ENABLED;
  2553. }
  2554. else
  2555. {
  2556. // For all other commands, if we in a known state
  2557. // then the command is enabled.
  2558. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2559. if (id != 0xffff)
  2560. prgCmds->cmdf = OLECMDF_ENABLED;
  2561. // If the command is the same as our state, it should be checked
  2562. if (id == prgCmds->cmdID)
  2563. prgCmds->cmdf |= OLECMDF_NINCHED;
  2564. }
  2565. }
  2566. break;
  2567. case ID_SEND_INSTANT_MESSAGE:
  2568. {
  2569. if(m_dwHideMessenger)
  2570. prgCmds->cmdf = OLECMDF_INVISIBLE;
  2571. else if (GetEntryForSendInstMsg())
  2572. prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  2573. else
  2574. prgCmds->cmdf = OLECMDF_SUPPORTED;
  2575. break;
  2576. }
  2577. }
  2578. }
  2579. }
  2580. return S_OK;
  2581. }
  2582. HRESULT STDMETHODCALLTYPE CIEMsgAb::Exec(const GUID *pguidCmdGroup,
  2583. DWORD nCmdID,
  2584. DWORD nCmdExecOpt,
  2585. VARIANTARG *pvaIn,
  2586. VARIANTARG *pvaOut)
  2587. {
  2588. HRESULT hr = OLECMDERR_E_NOTSUPPORTED;
  2589. BOOL bHandled = 0;
  2590. BIMSTATE State = BIMSTATE_UNKNOWN;
  2591. switch (nCmdID)
  2592. {
  2593. case ID_HIDE_IM:
  2594. Assert(!m_dwHideMessenger && !m_dwDisableMessenger)
  2595. m_dwDisableMessenger = 1;
  2596. DwSetDisableMessenger(m_dwDisableMessenger);
  2597. if(m_pCMsgrList)
  2598. {
  2599. m_pCMsgrList->UnRegisterUIWnd(m_hWnd);
  2600. OE_CloseMsgrList(m_pCMsgrList);
  2601. m_pCMsgrList = NULL;
  2602. _ReloadListview();
  2603. }
  2604. ::SendMessage(m_hwndParent, WM_MSGR_LOGRESULT, 0, 0);
  2605. break;
  2606. case ID_SHOW_IM:
  2607. Assert(!m_dwHideMessenger && m_dwDisableMessenger)
  2608. m_dwDisableMessenger = 0;
  2609. DwSetDisableMessenger(m_dwDisableMessenger);
  2610. if(!m_pCMsgrList)
  2611. {
  2612. m_pCMsgrList = OE_OpenMsgrList();
  2613. // Register our control for Msgr list
  2614. if(m_pCMsgrList)
  2615. {
  2616. m_pCMsgrList->RegisterUIWnd(m_hWnd);
  2617. if(m_pCMsgrList->IsLocalOnline())
  2618. {
  2619. m_fLogged = TRUE;
  2620. FillMsgrList();
  2621. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  2622. }
  2623. }
  2624. }
  2625. ::SendMessage(m_hwndParent, WM_MSGR_LOGRESULT, 0, 0);
  2626. break;
  2627. case ID_SHOWALLCONTACT:
  2628. if(m_fShowAllContacts)
  2629. {
  2630. m_fShowAllContacts = FALSE;
  2631. m_fShowOnlineContacts = TRUE;
  2632. m_fShowOfflineContacts = FALSE;
  2633. }
  2634. else if(m_fShowOnlineContacts)
  2635. {
  2636. m_fShowAllContacts = FALSE;
  2637. m_fShowOnlineContacts = FALSE;
  2638. m_fShowOfflineContacts = TRUE;
  2639. }
  2640. else if(m_fShowOfflineContacts)
  2641. {
  2642. m_fShowAllContacts = TRUE;
  2643. m_fShowOnlineContacts = FALSE;
  2644. m_fShowOfflineContacts = FALSE;
  2645. }
  2646. _ReloadListview();
  2647. break;
  2648. case ID_VIEW_ONLINE:
  2649. m_fShowAllContacts = FALSE;
  2650. m_fShowOfflineContacts = FALSE;
  2651. m_fShowOnlineContacts = TRUE;
  2652. _ReloadListview();
  2653. break;
  2654. case ID_VIEW_ONANDOFFLINE:
  2655. m_fShowAllContacts = FALSE;
  2656. m_fShowOnlineContacts = FALSE;
  2657. m_fShowOfflineContacts = TRUE;
  2658. _ReloadListview();
  2659. break;
  2660. case ID_VIEW_ALL:
  2661. m_fShowAllContacts = TRUE;
  2662. m_fShowOnlineContacts = FALSE;
  2663. m_fShowOfflineContacts = FALSE;
  2664. _ReloadListview();
  2665. break;
  2666. case ID_DIAL_PHONE_NUMBER:
  2667. CallPhone(NULL, FALSE);
  2668. break;
  2669. case ID_HOME_PHONE:
  2670. case ID_WORK_PHONE:
  2671. case ID_MOBILE_PHONE:
  2672. case ID_IP_PHONE:
  2673. {
  2674. LPMABENTRY pEntry = GetSelectedEntry();
  2675. if(!pEntry || !(pEntry->lpPhones))
  2676. {
  2677. Assert(FALSE);
  2678. break;
  2679. }
  2680. switch(nCmdID)
  2681. {
  2682. case ID_HOME_PHONE:
  2683. CallPhone(pEntry->lpPhones->pchHomePhone, (pEntry->tag == LPARAM_MENTRY));
  2684. break;
  2685. case ID_WORK_PHONE:
  2686. CallPhone(pEntry->lpPhones->pchWorkPhone, (pEntry->tag == LPARAM_MENTRY));
  2687. break;
  2688. case ID_MOBILE_PHONE:
  2689. CallPhone(pEntry->lpPhones->pchMobilePhone, (pEntry->tag == LPARAM_MENTRY));
  2690. break;
  2691. case ID_IP_PHONE:
  2692. CallPhone(pEntry->lpPhones->pchIPPhone, (pEntry->tag == LPARAM_MENTRY));
  2693. break;
  2694. }
  2695. }
  2696. break;
  2697. case ID_SEND_INSTANT_MESSAGE2:
  2698. CmdNewMessage(HIWORD(nCmdID), ID_SEND_INSTANT_MESSAGE2, m_ctlList, bHandled);
  2699. hr = S_OK;
  2700. break;
  2701. case ID_DELETE_CONTACT:
  2702. hr = (HRESULT) CmdDelete(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2703. break;
  2704. case ID_NEW_CONTACT:
  2705. // if(HasFocusIO() == S_OK)
  2706. CmdNewContact(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2707. hr = S_OK;
  2708. break;
  2709. case ID_SET_ONLINE_CONTACT:
  2710. CmdSetOnline(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2711. hr = S_OK;
  2712. break;
  2713. case ID_NEW_ONLINE_CONTACT:
  2714. CmdNewOnlineContact(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2715. hr = S_OK;
  2716. break;
  2717. case ID_PROPERTIES:
  2718. CmdProperties(0, 0, m_ctlList, bHandled);
  2719. hr = S_OK;
  2720. break;
  2721. #ifdef GEORGEH
  2722. case ID_NEW_MSG_DEFAULT:
  2723. if(HasFocusIO() == S_OK)
  2724. hr = CmdNewMessage(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2725. break;
  2726. #endif // GEORGEH
  2727. case ID_FIND_PEOPLE:
  2728. case ID_ADDRESS_BOOK:
  2729. {
  2730. WCHAR wszWABExePath[MAX_PATH];
  2731. if(S_OK == HrLoadPathWABEXE(wszWABExePath, sizeof(wszWABExePath)/sizeof(wszWABExePath[0])))
  2732. {
  2733. SHELLEXECUTEINFOW ExecInfo;
  2734. ExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
  2735. ExecInfo.nShow = SW_SHOWNORMAL;
  2736. ExecInfo.fMask = 0;
  2737. ExecInfo.hwnd = NULL;
  2738. ExecInfo.lpDirectory = NULL;
  2739. ExecInfo.lpParameters = ((nCmdID == ID_FIND_PEOPLE) ? L"/find" : L"");
  2740. ExecInfo.lpVerb = L"open";
  2741. ExecInfo.lpFile = wszWABExePath;
  2742. ShellExecuteExW(&ExecInfo);
  2743. // ShellExecuteW(NULL, L"open", wszWABExePath,
  2744. // ((nCmdID == ID_FIND_PEOPLE) ? L"/find" : L""),
  2745. // "", SW_SHOWNORMAL);
  2746. }
  2747. break;
  2748. }
  2749. case ID_SEND_MESSAGE:
  2750. if(HasFocusIO() == S_OK)
  2751. hr = (HRESULT) CmdNewEmaile(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2752. break;
  2753. case ID_SEND_INSTANT_MESSAGE:
  2754. // Assert(m_pCMsgrList);
  2755. CmdNewIMsg(HIWORD(nCmdID), LOWORD(nCmdID), m_ctlList, bHandled);
  2756. hr = S_OK;
  2757. break;
  2758. case ID_MESSENGER_OPTIONS:
  2759. if(m_pCMsgrList)
  2760. hr = m_pCMsgrList->LaunchOptionsUI(); //CmdMsgrOptions();
  2761. break;
  2762. case ID_MESSENGER_ONLINE:
  2763. if(m_pCMsgrList)
  2764. hr = m_pCMsgrList->SetLocalState(BIMSTATE_ONLINE);
  2765. break;
  2766. case ID_MESSENGER_INVISIBLE:
  2767. if(m_pCMsgrList)
  2768. hr = m_pCMsgrList->SetLocalState(BIMSTATE_INVISIBLE);
  2769. break;
  2770. case ID_MESSENGER_BUSY:
  2771. if(m_pCMsgrList)
  2772. hr = m_pCMsgrList->SetLocalState(BIMSTATE_BUSY);
  2773. break;
  2774. case ID_MESSENGER_BACK:
  2775. if(m_pCMsgrList)
  2776. hr = m_pCMsgrList->SetLocalState(BIMSTATE_BE_RIGHT_BACK);
  2777. break;
  2778. case ID_MESSENGER_AWAY:
  2779. if(m_pCMsgrList)
  2780. hr = m_pCMsgrList->SetLocalState(BIMSTATE_AWAY);
  2781. break;
  2782. case ID_MESSENGER_ON_PHONE:
  2783. if(m_pCMsgrList)
  2784. hr = m_pCMsgrList->SetLocalState(BIMSTATE_ON_THE_PHONE);
  2785. break;
  2786. case ID_MESSENGER_LUNCH:
  2787. if(m_pCMsgrList)
  2788. hr = m_pCMsgrList->SetLocalState(BIMSTATE_OUT_TO_LUNCH);
  2789. break;
  2790. case ID_LOGIN_MESSENGER:
  2791. if(m_pCMsgrList)
  2792. {
  2793. if(!m_pCMsgrList->IsLocalOnline())
  2794. {
  2795. if(PromptToGoOnline() == S_OK)
  2796. m_pCMsgrList->UserLogon();
  2797. }
  2798. hr = S_OK;
  2799. }
  2800. break;
  2801. case ID_LOGOFF_MESSENGER:
  2802. Assert(m_pCMsgrList);
  2803. if(m_pCMsgrList)
  2804. m_pCMsgrList->UserLogoff();
  2805. hr = S_OK;
  2806. break;
  2807. case ID_SORT_BY_NAME:
  2808. m_nSortType = BASORT_NAME_ACSEND;
  2809. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  2810. break;
  2811. case ID_SORT_BY_STATUS:
  2812. m_nSortType = BASORT_STATUS_ACSEND;
  2813. ListView_SortItems(m_ctlList, BA_Sort, m_nSortType);
  2814. break;
  2815. default:
  2816. break;
  2817. }
  2818. return hr;
  2819. }
  2820. // fill a phone number for menu
  2821. BOOL CIEMsgAb::_FillPhoneNumber(UINT Id, OLECMDTEXT *pcmdText)
  2822. {
  2823. LPMABENTRY pEntry = GetSelectedEntry();
  2824. WCHAR szTmp[CCHMAX_STRINGRES];
  2825. WCHAR * pch = NULL;
  2826. TCHAR * pchStr = NULL;
  2827. if(!pEntry || !(pEntry->lpPhones))
  2828. {
  2829. err:
  2830. pcmdText->cwBuf = 0;
  2831. return(FALSE);
  2832. }
  2833. szTmp[0] = L'\0';
  2834. switch(Id)
  2835. {
  2836. case ID_HOME_PHONE:
  2837. pch = pEntry->lpPhones->pchHomePhone;
  2838. AthLoadString(idsHome, szTmp, ARRAYSIZE(szTmp));
  2839. break;
  2840. case ID_WORK_PHONE:
  2841. pch = pEntry->lpPhones->pchWorkPhone;
  2842. AthLoadString(idsWork, szTmp, ARRAYSIZE(szTmp));
  2843. break;
  2844. case ID_MOBILE_PHONE:
  2845. pch = pEntry->lpPhones->pchMobilePhone;
  2846. AthLoadString(idsMobile, szTmp, ARRAYSIZE(szTmp));
  2847. break;
  2848. case ID_IP_PHONE:
  2849. pch = pEntry->lpPhones->pchIPPhone;
  2850. AthLoadString(idsIPPhone, szTmp, ARRAYSIZE(szTmp));
  2851. break;
  2852. default:
  2853. pch = NULL;
  2854. Assert(FALSE);
  2855. break;
  2856. }
  2857. if(!pch)
  2858. goto err;
  2859. if(pcmdText->cmdtextf == OLECMDTEXTF_NONE)
  2860. return(TRUE);
  2861. pcmdText->cwBuf = (lstrlenW(pch) + 2 + lstrlenW(szTmp));
  2862. if(pcmdText->cwBuf > MAX_MENUSTR)
  2863. Assert(FALSE);
  2864. else
  2865. {
  2866. #ifdef NEW
  2867. if(!MultiByteToWideChar(GetACP(), 0, pch, -1, pcmdText->rgwz, pcmdText->cwBuf))
  2868. {
  2869. Assert(FALSE);
  2870. pcmdText->cwBuf = 0;
  2871. }
  2872. #else
  2873. pchStr = ((TCHAR *)(pcmdText->rgwz));
  2874. LPTSTR pchTmpA = LPTSTRfromBstr(pch);
  2875. StrCpyN(pchStr, pchTmpA, ARRAYSIZE(pcmdText->rgwz));
  2876. MemFree(pchTmpA);
  2877. LPTSTR pchA = LPTSTRfromBstr(szTmp);
  2878. StrCatBuff(pchStr, pchA, ARRAYSIZE(pcmdText->rgwz));
  2879. MemFree(pchA);
  2880. pcmdText->cwActual = lstrlen(pchStr) + 1;
  2881. #endif
  2882. }
  2883. /* else
  2884. goto err; */
  2885. return(TRUE);
  2886. }
  2887. STDMETHODIMP CIEMsgAb::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  2888. {
  2889. #ifdef LATER
  2890. TCHAR sz[CCHMAX_STRINGRES];
  2891. if(m_lpWED->fReadOnly)
  2892. return NOERROR;
  2893. PROPSHEETPAGE psp;
  2894. // hinstApp = g_hInst;
  2895. psp.dwSize = sizeof(psp); // no extra data
  2896. psp.dwFlags = PSP_USEREFPARENT | PSP_USETITLE ;
  2897. psp.hInstance = g_hLocRes;
  2898. psp.lParam = (LPARAM) &(m_lpWED);
  2899. psp.pcRefParent = (UINT *)&(m_cRefThisDll);
  2900. psp.pszTemplate = MAKEINTRESOURCE(iddWabExt);
  2901. psp.pfnDlgProc = WabExtDlgProc;
  2902. psp.pszTitle = AthLoadString(idsWABExtTitle, sz, ARRAYSIZE(sz)); // Title for your tab AthLoadString(idsWABExtTitle, sz, ARRAYSIZE(sz))
  2903. m_hPage1 = ::CreatePropertySheetPage(&psp);
  2904. if (m_hPage1)
  2905. {
  2906. if (!lpfnAddPage(m_hPage1, lParam))
  2907. ::DestroyPropertySheetPage(m_hPage1);
  2908. }
  2909. return NOERROR;
  2910. #else
  2911. return E_NOTIMPL;
  2912. #endif
  2913. }
  2914. STDMETHODIMP CIEMsgAb::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam)
  2915. {
  2916. Assert(FALSE);
  2917. return E_NOTIMPL;
  2918. }
  2919. STDMETHODIMP CIEMsgAb::Initialize(LPWABEXTDISPLAY lpWABExtDisplay)
  2920. {
  2921. if (lpWABExtDisplay == NULL)
  2922. {
  2923. TRACE("CIEMsgAb::Initialize() no data object");
  2924. return E_FAIL;
  2925. }
  2926. if(st_pAddrBook == NULL)
  2927. {
  2928. TRACE("CIEMsgAb::Initialize() - run from not OE - no st_pAddrbook");
  2929. return E_FAIL;
  2930. }
  2931. if (!m_dwHideMessenger && !m_dwDisableMessenger)
  2932. {
  2933. if(!m_pCMsgrList)
  2934. {
  2935. m_pCMsgrList = OE_OpenMsgrList();
  2936. if(!m_pCMsgrList)
  2937. {
  2938. TRACE("CIEMsgAb::Initialize() - Messeneger not installed");
  2939. return E_FAIL;
  2940. }
  2941. }
  2942. }
  2943. // However if this is a context menu extension, we need to hang
  2944. // onto the propobj till such time as InvokeCommand is called ..
  2945. // At this point just AddRef the propobj - this will ensure that the
  2946. // data in the lpAdrList remains valid till we release the propobj..
  2947. // When we get another ContextMenu initiation, we can release the
  2948. // older cached propobj - if we dont get another initiation, we
  2949. // release the cached object at shutdown time
  2950. if(lpWABExtDisplay->ulFlags & WAB_CONTEXT_ADRLIST) // this means a IContextMenu operation is occuring
  2951. {
  2952. if(m_lpPropObj)
  2953. {
  2954. m_lpPropObj->Release();
  2955. m_lpPropObj = NULL;
  2956. }
  2957. m_lpPropObj = lpWABExtDisplay->lpPropObj;
  2958. m_lpPropObj->AddRef();
  2959. m_lpWEDContext = lpWABExtDisplay;
  2960. }
  2961. else
  2962. {
  2963. // For property sheet extensions, the lpWABExtDisplay will
  2964. // exist for the life of the property sheets ..
  2965. m_lpWED = lpWABExtDisplay;
  2966. }
  2967. return S_OK;
  2968. }
  2969. HRESULT CIEMsgAb::PromptToGoOnline()
  2970. {
  2971. HRESULT hr = S_OK;
  2972. #ifdef LATER
  2973. if (g_pConMan->IsGlobalOffline())
  2974. {
  2975. if (IDYES == AthMessageBoxW(m_hwndParent, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsErrWorkingOffline),
  2976. 0, MB_YESNO | MB_ICONEXCLAMATION ))
  2977. {
  2978. g_pConMan->SetGlobalOffline(FALSE);
  2979. hr = S_OK;
  2980. }
  2981. else
  2982. {
  2983. hr = S_FALSE;
  2984. }
  2985. }
  2986. else
  2987. hr = S_OK;
  2988. #endif
  2989. return hr;
  2990. }
  2991. HRESULT CIEMsgAb::ResizeChildWindows(LPCRECT prcPos)
  2992. {
  2993. RECT rc;
  2994. // Get the size of the outer window
  2995. if (!prcPos)
  2996. {
  2997. GetClientRect(&rc);
  2998. rc.right = rc.right - rc.left;
  2999. rc.bottom = rc.bottom - rc.top;
  3000. }
  3001. else
  3002. {
  3003. rc.top = 0;
  3004. rc.left = 0;
  3005. rc.right = prcPos->right - prcPos->left;
  3006. rc.bottom = prcPos->bottom - prcPos->top;
  3007. }
  3008. #if 0
  3009. // If we have to reserve room for the status bar and menu bar, do it
  3010. if (m_fStatusBar)
  3011. rc.bottom -= m_cyStatusBar;
  3012. if (m_fMenuBar)
  3013. rc.top += m_cyMenuBar;
  3014. #endif
  3015. // Move the ListView into the right place
  3016. /* ::SetWindowPos(m_ctlList.m_hWnd, NULL, rc.top, rc.left,
  3017. rc.right, rc.bottom, SWP_NOZORDER | SWP_NOACTIVATE); */
  3018. return S_OK;
  3019. }
  3020. ///////////////////////////////////////////////////////////////////////////
  3021. //
  3022. // IDeskBand implementation
  3023. //
  3024. ///////////////////////////////////////////////////////////////////////////
  3025. //
  3026. // CIEMsgAb::GetBandInfo()
  3027. //
  3028. ///////////////////////////////////////////////////////////////////////////
  3029. #define MIN_SIZE_X 50
  3030. #define MIN_SIZE_Y 50
  3031. STDMETHODIMP CIEMsgAb::GetBandInfo(DWORD dwBandID,
  3032. DWORD dwViewMode,
  3033. DESKBANDINFO* pdbi)
  3034. {
  3035. if (pdbi)
  3036. {
  3037. // _dwBandID = dwBandID;
  3038. // _dwViewMode = dwViewMode;
  3039. if (pdbi->dwMask & DBIM_MINSIZE)
  3040. {
  3041. pdbi->ptMinSize.x = MIN_SIZE_X;
  3042. pdbi->ptMinSize.y = MIN_SIZE_Y;
  3043. }
  3044. if (pdbi->dwMask & DBIM_MAXSIZE)
  3045. {
  3046. pdbi->ptMaxSize.x = -1;
  3047. pdbi->ptMaxSize.y = -1;
  3048. }
  3049. if (pdbi->dwMask & DBIM_INTEGRAL)
  3050. {
  3051. pdbi->ptIntegral.x = 1;
  3052. pdbi->ptIntegral.y = 1;
  3053. }
  3054. if (pdbi->dwMask & DBIM_ACTUAL)
  3055. {
  3056. pdbi->ptActual.x = 0;
  3057. pdbi->ptActual.y = 0;
  3058. }
  3059. if (pdbi->dwMask & DBIM_TITLE)
  3060. {
  3061. StrCpyNW(pdbi->wszTitle, L"WebBand Search", ARRAYSIZE(pdbi->wszTitle));
  3062. }
  3063. if (pdbi->dwMask & DBIM_MODEFLAGS)
  3064. pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
  3065. if (pdbi->dwMask & DBIM_BKCOLOR)
  3066. {
  3067. // Use the default background color by removing this flag.
  3068. pdbi->dwMask &= ~DBIM_BKCOLOR;
  3069. }
  3070. return S_OK;
  3071. }
  3072. return E_INVALIDARG;
  3073. }
  3074. ///////////////////////////////////////////////////////////////////////////
  3075. //
  3076. // IDockingWindow Methods
  3077. //
  3078. ///////////////////////////////////////////////////////////////////////////
  3079. //
  3080. // CIEMsgAb::ShowDW()
  3081. //
  3082. ///////////////////////////////////////////////////////////////////////////
  3083. STDMETHODIMP CIEMsgAb::ShowDW(BOOL fShow)
  3084. {
  3085. if (m_hWnd)
  3086. {
  3087. //
  3088. // Hide or show the window depending on
  3089. // the value of the fShow parameter.
  3090. //
  3091. if (fShow)
  3092. ::ShowWindow(m_hWnd, SW_SHOW);
  3093. else
  3094. ::ShowWindow(m_hWnd, SW_HIDE);
  3095. }
  3096. return S_OK;
  3097. }
  3098. ///////////////////////////////////////////////////////////////////////////
  3099. //
  3100. // CIEMsgAb::CloseDW()
  3101. //
  3102. ///////////////////////////////////////////////////////////////////////////
  3103. STDMETHODIMP CIEMsgAb::CloseDW(DWORD dwReserved)
  3104. {
  3105. ShowDW(FALSE);
  3106. // Assert(FALSE);
  3107. if (IsWindow(m_hWnd))
  3108. ::DestroyWindow(m_hWnd);
  3109. m_hWnd = NULL;
  3110. return S_OK;
  3111. }
  3112. ///////////////////////////////////////////////////////////////////////////
  3113. //
  3114. // CIEMsgAb::ResizeBorderDW()
  3115. //
  3116. ///////////////////////////////////////////////////////////////////////////
  3117. STDMETHODIMP CIEMsgAb::ResizeBorderDW(LPCRECT prcBorder, IUnknown* punkToolbarSite,
  3118. BOOL fReserved)
  3119. {
  3120. // This method is never called for Band Objects.
  3121. return E_NOTIMPL;
  3122. }
  3123. ///////////////////////////////////////////////////////////////////////////
  3124. //
  3125. // IOleWindow Methods
  3126. //
  3127. ///////////////////////////////////////////////////////////////////////////
  3128. //
  3129. // CIEMsgAb::GetWindow()
  3130. //
  3131. ///////////////////////////////////////////////////////////////////////////
  3132. STDMETHODIMP CIEMsgAb::GetWindow(HWND *phwnd)
  3133. {
  3134. *phwnd = m_hWnd;
  3135. return S_OK;
  3136. }
  3137. ///////////////////////////////////////////////////////////////////////////
  3138. //
  3139. // CIEMsgAb::ContextSensitiveHelp()
  3140. //
  3141. ///////////////////////////////////////////////////////////////////////////
  3142. STDMETHODIMP CIEMsgAb::ContextSensitiveHelp(BOOL fEnterMode)
  3143. {
  3144. return E_NOTIMPL;
  3145. }
  3146. STDMETHODIMP CIEMsgAb::Init (REFGUID refguid)
  3147. {
  3148. return S_OK;
  3149. }
  3150. STDMETHODIMP CIEMsgAb::GetProperty(SHORT iPropID, VARIANTARG * pvarProperty)
  3151. {
  3152. HRESULT hr = S_OK;
  3153. switch (iPropID)
  3154. {
  3155. case TBEX_BUTTONTEXT:
  3156. if (pvarProperty)
  3157. {
  3158. pvarProperty->vt = VT_BSTR;
  3159. pvarProperty->bstrVal = SysAllocString(L"YST Button");
  3160. if (NULL == pvarProperty->bstrVal)
  3161. hr = E_OUTOFMEMORY;
  3162. }
  3163. break;
  3164. case TBEX_GRAYICON:
  3165. hr = E_NOTIMPL; // hr = _GetIcon(TEXT("Icon"), 20, 20, _hIcon, pvarProperty);
  3166. break;
  3167. case TBEX_GRAYICONSM:
  3168. hr = E_NOTIMPL; // hr = _GetIcon(TEXT("Icon"), 16, 16, _hIconSm, pvarProperty);
  3169. break;
  3170. case TBEX_HOTICON:
  3171. hr = E_NOTIMPL; // hr = _GetIcon(TEXT("HotIcon"), 20, 20, _hHotIcon, pvarProperty);
  3172. break;
  3173. case TBEX_HOTICONSM:
  3174. hr = E_NOTIMPL; //hr = _GetIcon(TEXT("HotIcon"), 16, 16, _hHotIcon, pvarProperty);
  3175. break;
  3176. case TBEX_DEFAULTVISIBLE:
  3177. if (pvarProperty)
  3178. {
  3179. // BOOL fVisible = _RegGetBoolValue(L"Default Visible", FALSE);
  3180. pvarProperty->vt = VT_BOOL;
  3181. pvarProperty->boolVal = VARIANT_TRUE;
  3182. }
  3183. break;
  3184. case TMEX_CUSTOM_MENU:
  3185. {
  3186. if (pvarProperty != NULL)
  3187. {
  3188. pvarProperty->vt = VT_BSTR;
  3189. pvarProperty->bstrVal = SysAllocString(L"YST test");
  3190. if (pvarProperty->bstrVal == NULL)
  3191. {
  3192. hr = E_OUTOFMEMORY;
  3193. }
  3194. }
  3195. }
  3196. break;
  3197. case TMEX_MENUTEXT:
  3198. if (pvarProperty)
  3199. {
  3200. pvarProperty->vt = VT_BSTR;
  3201. pvarProperty->bstrVal = SysAllocString(L"YST test 1");
  3202. if (NULL == pvarProperty->bstrVal)
  3203. hr = E_OUTOFMEMORY;
  3204. }
  3205. break;
  3206. case TMEX_STATUSBARTEXT:
  3207. if (pvarProperty)
  3208. {
  3209. pvarProperty->vt = VT_BSTR;
  3210. pvarProperty->bstrVal = SysAllocString(L"YST test 2");
  3211. if (NULL == pvarProperty->bstrVal)
  3212. hr = E_OUTOFMEMORY;
  3213. }
  3214. break;
  3215. default:
  3216. hr = E_NOTIMPL;
  3217. }
  3218. return hr;
  3219. }
  3220. // --------------------------------------------------------------------------------
  3221. // AthLoadString
  3222. // --------------------------------------------------------------------------------
  3223. LPSTR ANSI_AthLoadString(UINT id, TCHAR* sz, int cch)
  3224. {
  3225. LPSTR szT;
  3226. if (sz == NULL)
  3227. {
  3228. if (!MemAlloc((LPVOID*)&szT, CCHMAX_STRINGRES))
  3229. return(NULL);
  3230. cch = CCHMAX_STRINGRES;
  3231. }
  3232. else
  3233. szT = sz;
  3234. if(g_hLocRes)
  3235. {
  3236. cch = LoadString(g_hLocRes, id, szT, cch);
  3237. Assert(cch > 0);
  3238. if (cch == 0)
  3239. {
  3240. if (sz == NULL)
  3241. MemFree(szT);
  3242. szT = NULL;
  3243. }
  3244. }
  3245. else
  3246. {
  3247. if (sz == NULL)
  3248. MemFree(szT);
  3249. szT = NULL;
  3250. }
  3251. return(szT);
  3252. }
  3253. // --------------------------------------------------------------------------------
  3254. // AthLoadString
  3255. // --------------------------------------------------------------------------------
  3256. LPWSTR AthLoadString(UINT id, LPWSTR sz, int cch)
  3257. {
  3258. LPWSTR szT;
  3259. if (sz == NULL)
  3260. {
  3261. if (!MemAlloc((LPVOID*)&szT, CCHMAX_STRINGRES*sizeof(WCHAR)))
  3262. return(NULL);
  3263. cch = CCHMAX_STRINGRES;
  3264. }
  3265. else
  3266. szT = sz;
  3267. if(g_hLocRes)
  3268. {
  3269. cch = LoadStringW(g_hLocRes, id, szT, cch);
  3270. Assert(cch > 0);
  3271. if (cch == 0)
  3272. {
  3273. if (sz == NULL)
  3274. MemFree(szT);
  3275. szT = NULL;
  3276. }
  3277. }
  3278. else
  3279. {
  3280. if (sz == NULL)
  3281. MemFree(szT);
  3282. szT = NULL;
  3283. }
  3284. return(szT);
  3285. }
  3286. //
  3287. // REVIEW: We need this function because current version of USER.EXE does
  3288. // not support pop-up only menu.
  3289. //
  3290. HMENU LoadPopupMenu(UINT id)
  3291. {
  3292. HMENU hmenuParent = LoadMenuW(g_hLocRes, MAKEINTRESOURCEW(id));
  3293. if (hmenuParent) {
  3294. HMENU hpopup = GetSubMenu(hmenuParent, 0);
  3295. RemoveMenu(hmenuParent, 0, MF_BYPOSITION);
  3296. DestroyMenu(hmenuParent);
  3297. return hpopup;
  3298. }
  3299. return NULL;
  3300. }
  3301. void MenuUtil_BuildMenuIDList(HMENU hMenu, OLECMD **prgCmds, ULONG *pcStart, ULONG *pcCmds)
  3302. {
  3303. ULONG cItems = 0;
  3304. MENUITEMINFO mii;
  3305. if(!IsMenu(hMenu))
  3306. return;
  3307. // Start by getting the count of items on this menu
  3308. cItems = GetMenuItemCount(hMenu);
  3309. if (!cItems)
  3310. return;
  3311. // Realloc the array to be cItems elements bigger
  3312. if (!MemRealloc((LPVOID *) prgCmds, sizeof(OLECMD) * (cItems + (*pcCmds))))
  3313. return;
  3314. *pcCmds += cItems;
  3315. // Walk this menu and add our items to it
  3316. mii.cbSize = sizeof(MENUITEMINFO);
  3317. mii.fMask = MIIM_ID | MIIM_SUBMENU;
  3318. for (ULONG i = 0; i < cItems; i++)
  3319. {
  3320. if (GetMenuItemInfo(hMenu, i, TRUE, &mii))
  3321. {
  3322. // Make sure this isn't a separator
  3323. if (mii.wID != -1 && mii.wID != 0)
  3324. {
  3325. // Add the ID to our array
  3326. (*prgCmds)[*pcStart].cmdID = mii.wID;
  3327. (*prgCmds)[*pcStart].cmdf = 0;
  3328. (*pcStart)++;
  3329. // See if we need to recurse
  3330. if (mii.hSubMenu)
  3331. {
  3332. MenuUtil_BuildMenuIDList(mii.hSubMenu, prgCmds, pcStart, pcCmds);
  3333. }
  3334. }
  3335. }
  3336. }
  3337. return;
  3338. }
  3339. //
  3340. // FUNCTION: MenuUtil_EnablePopupMenu()
  3341. //
  3342. // PURPOSE: Walks the given menu and takes care of enabling and
  3343. // disabling each item via the provided commnand target.
  3344. //
  3345. // PARAMETERS:
  3346. // [in] hPopup
  3347. // [in] *pTarget
  3348. //
  3349. HRESULT MenuUtil_EnablePopupMenu(HMENU hPopup, CIEMsgAb *pTarget)
  3350. {
  3351. HRESULT hr = S_OK;
  3352. int i;
  3353. int cItems;
  3354. OLECMD *rgCmds = NULL;
  3355. ULONG cStart = 0;
  3356. ULONG cCmds = 0;
  3357. MENUITEMINFO mii = {0};
  3358. OLECMDTEXT CmdText;
  3359. OLECMDTEXTV<MAX_MENUSTR> CmdNewText;
  3360. Assert(hPopup && pTarget);
  3361. // Build the array of menu ids
  3362. MenuUtil_BuildMenuIDList(hPopup, &rgCmds, &cCmds, &cStart);
  3363. // Ask our parent for the state of the commands
  3364. CmdText.cmdtextf = OLECMDTEXTF_NONE;
  3365. if (SUCCEEDED(hr = pTarget->QueryStatus(NULL, cCmds, rgCmds, &CmdText)))
  3366. {
  3367. mii.cbSize = sizeof(MENUITEMINFO);
  3368. // Now loop through the menu and apply the state
  3369. for (i = 0; i < (int) cCmds; i++)
  3370. {
  3371. BOOL f;
  3372. CmdNewText.cwBuf = 0;
  3373. if(rgCmds[i].cmdf & OLECMDF_INVISIBLE)
  3374. RemoveMenu(hPopup, rgCmds[i].cmdID, MF_BYCOMMAND);
  3375. else
  3376. {
  3377. // The default thing we're going to update is the state
  3378. mii.fMask = MIIM_STATE;
  3379. // Enabled or Disabled
  3380. if (rgCmds[i].cmdf & OLECMDF_ENABLED)
  3381. {
  3382. mii.fState = MFS_ENABLED;
  3383. }
  3384. else
  3385. mii.fState = MFS_GRAYED;
  3386. // Checked?
  3387. if (rgCmds[i].cmdf & OLECMDF_LATCHED)
  3388. mii.fState |= MFS_CHECKED;
  3389. if(mii.fState == MFS_ENABLED)
  3390. {
  3391. // special for phones
  3392. if((rgCmds[i].cmdID > ID_DIAL_PHONE_NUMBER) && (rgCmds[i].cmdID < ID_DIAL_PHONE_LAST))
  3393. {
  3394. OLECMD Cmd[1];
  3395. Cmd[0].cmdf = 0;
  3396. Cmd[0].cmdID = rgCmds[i].cmdID;
  3397. CmdNewText.cmdtextf = OLECMDTEXTF_NAME;
  3398. if (SUCCEEDED(hr = pTarget->QueryStatus(NULL, 1, Cmd, &CmdNewText)))
  3399. {
  3400. if(CmdNewText.cwBuf)
  3401. {
  3402. mii.fType = MFT_STRING;
  3403. mii.fMask |= MIIM_TYPE;
  3404. mii.dwTypeData = ((LPSTR) CmdNewText.rgwz);
  3405. mii.cch = CmdNewText.cwBuf;
  3406. }
  3407. else
  3408. {
  3409. mii.dwTypeData = NULL;
  3410. mii.cch = 0;
  3411. }
  3412. }
  3413. }
  3414. }
  3415. // Set the item state
  3416. f = SetMenuItemInfo(hPopup, rgCmds[i].cmdID, FALSE, &mii);
  3417. // if(CmdNewText.cwBuf)
  3418. // MemFree(&(CmdNewText.rgwz[0]));
  3419. // Radio Check?
  3420. if ((rgCmds[i].cmdf & OLECMDF_NINCHED) && rgCmds[i].cmdID != (-1))
  3421. {
  3422. CheckMenuRadioItem(hPopup, rgCmds[i].cmdID, rgCmds[i].cmdID, rgCmds[i].cmdID, MF_BYCOMMAND);
  3423. // mii.fMask |= MIIM_TYPE;
  3424. // mii.fType = MFT_RADIOCHECK;
  3425. // mii.fState |= MFS_CHECKED;
  3426. }
  3427. // Assert(f);
  3428. }
  3429. }
  3430. }
  3431. SafeMemFree(rgCmds);
  3432. return (hr);
  3433. }
  3434. HRESULT CEmptyList::Show(HWND hwndList, LPWSTR pszString)
  3435. {
  3436. // We're already doing a window
  3437. if (m_hwndList)
  3438. {
  3439. Hide();
  3440. }
  3441. // Keep a copy of the listview window handle
  3442. m_hwndList = hwndList;
  3443. if(MemAlloc((LPVOID *) &m_pwszString, (lstrlenW(pszString) + 1)*sizeof(WCHAR)))
  3444. StrCpyNW(m_pwszString, pszString, lstrlenW(pszString) + 1);
  3445. // Get the header window handle from the listview
  3446. m_hwndHeader = ListView_GetHeader(m_hwndList);
  3447. // Save our this pointer on the listview window
  3448. SetProp(m_hwndList, _T("EmptyListClass"), (HANDLE) this);
  3449. // Subclass the listview so we can steal sizing messages
  3450. if (!m_pfnWndProc)
  3451. m_pfnWndProc = SubclassWindow(m_hwndList, SubclassWndProc);
  3452. // Create our window on top
  3453. if (!m_hwndBlocker)
  3454. {
  3455. m_hwndBlocker = CreateWindow(_T("Button"), _T("Blocker"),
  3456. WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | BS_OWNERDRAW /*| ES_MULTILINE | ES_READONLY*/,
  3457. 0, 0, 0, 0, m_hwndList, (HMENU) NULL, g_hLocRes, NULL);
  3458. Assert(m_hwndBlocker);
  3459. }
  3460. // Set the font for the blocker
  3461. if(!m_hFont)
  3462. {
  3463. LOGFONT lf;
  3464. // Figure out which font to use
  3465. SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, FALSE);
  3466. // Create the fonts
  3467. m_hFont = CreateFontIndirect(&lf);
  3468. }
  3469. // Show the silly thing
  3470. if(m_hFont)
  3471. {
  3472. SendMessageW(m_hwndBlocker, WM_SETFONT, (WPARAM) m_hFont, MAKELPARAM(TRUE, 0));
  3473. }
  3474. // SetWindowTextW(m_hwndBlocker, m_pwszString);
  3475. // Position the blocker
  3476. RECT rcList = {0};
  3477. RECT rcHead = {0};
  3478. GetClientRect(m_hwndList, &rcList);
  3479. if(m_hwndHeader)
  3480. GetClientRect(m_hwndHeader, &rcHead);
  3481. SetWindowPos(m_hwndBlocker, 0, 0, rcHead.bottom, rcList.right,
  3482. rcList.bottom - rcHead.bottom, SWP_NOACTIVATE | SWP_NOZORDER);
  3483. ShowWindow(m_hwndBlocker, SW_SHOW);
  3484. return (S_OK);
  3485. }
  3486. HRESULT CEmptyList::Hide(void)
  3487. {
  3488. // Verify we have the blocker up first
  3489. if (m_pfnWndProc)
  3490. {
  3491. // Hide the window
  3492. ShowWindow(m_hwndBlocker, SW_HIDE);
  3493. // Unsubclass the window
  3494. SubclassWindow(m_hwndList, m_pfnWndProc);
  3495. // Delete the property
  3496. RemoveProp(m_hwndList, _T("EmptyListClass"));
  3497. // Free the string
  3498. SafeMemFree(m_pwszString);
  3499. // NULL everything out
  3500. m_pfnWndProc = 0;
  3501. m_hwndList = 0;
  3502. }
  3503. return (S_OK);
  3504. }
  3505. CEmptyList::~CEmptyList()
  3506. {
  3507. if(m_hFont)
  3508. DeleteObject(m_hFont);
  3509. if (IsWindow(m_hwndBlocker))
  3510. DestroyWindow(m_hwndBlocker);
  3511. SafeMemFree(m_pwszString);
  3512. if (NULL != m_hbrBack)
  3513. DeleteObject(m_hbrBack);
  3514. }
  3515. LRESULT CEmptyList::SubclassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3516. {
  3517. CEmptyList* pThis = (CEmptyList *) GetProp(hwnd, _T("EmptyListClass"));
  3518. Assert(pThis);
  3519. switch (uMsg)
  3520. {
  3521. case WM_DRAWITEM:
  3522. if (pThis && IsWindow(pThis->m_hwndBlocker))
  3523. {
  3524. LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT) lParam;
  3525. RECT rc = pdis->rcItem;
  3526. WCHAR wszStr[RESSTRMAX];
  3527. HBRUSH hbr3DFace = NULL;
  3528. hbr3DFace = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  3529. FillRect(pdis->hDC, &(pdis->rcItem), hbr3DFace);
  3530. SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW));
  3531. DeleteObject(hbr3DFace);
  3532. // Position the blocker
  3533. RECT rcList = {0};
  3534. RECT rcHead = {0};
  3535. GetClientRect(pThis->m_hwndList, &rcList);
  3536. if(pThis->m_hwndHeader)
  3537. GetClientRect(pThis->m_hwndHeader, &rcHead);
  3538. SetWindowPos(pThis->m_hwndBlocker, 0, 0, rcHead.bottom, rcList.right,
  3539. rcList.bottom - rcHead.bottom, SWP_NOACTIVATE | SWP_NOZORDER);
  3540. SelectFont(pdis->hDC, pThis->m_hFont);
  3541. rc.left = 0;
  3542. rc.top = rcHead.bottom;
  3543. rc.right = rcList.right;
  3544. rc.bottom = rcList.bottom - rcHead.bottom;
  3545. hbr3DFace = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  3546. FillRect(pdis->hDC, &(pdis->rcItem), hbr3DFace);
  3547. SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW));
  3548. DeleteObject(hbr3DFace);
  3549. DrawTextW(pdis->hDC, pThis->m_pwszString, -1, &rc, DT_WORDBREAK | DT_VCENTER | DT_CENTER );
  3550. return(0);
  3551. }
  3552. break;
  3553. case WM_SIZE:
  3554. if (pThis && IsWindow(pThis->m_hwndBlocker))
  3555. {
  3556. RECT rcHeader = {0};
  3557. GetClientRect(pThis->m_hwndHeader, &rcHeader);
  3558. SetWindowPos(pThis->m_hwndBlocker, 0, 0, 0, LOWORD(lParam),
  3559. HIWORD(lParam) - rcHeader.bottom,
  3560. SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
  3561. InvalidateRect(pThis->m_hwndBlocker, NULL, FALSE);
  3562. }
  3563. break;
  3564. case WM_CTLCOLORSTATIC:
  3565. if ((HWND) lParam == pThis->m_hwndBlocker)
  3566. {
  3567. if (!pThis->m_hbrBack)
  3568. {
  3569. pThis->m_hbrBack = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  3570. }
  3571. SetBkColor((HDC) wParam, GetSysColor(COLOR_WINDOW));
  3572. return (LRESULT) pThis->m_hbrBack;
  3573. }
  3574. break;
  3575. case WM_SYSCOLORCHANGE:
  3576. if (pThis)
  3577. {
  3578. DeleteObject(pThis->m_hbrBack);
  3579. pThis->m_hbrBack = 0;
  3580. SendMessage(pThis->m_hwndBlocker, uMsg, wParam, lParam);
  3581. }
  3582. break;
  3583. case WM_WININICHANGE:
  3584. case WM_FONTCHANGE:
  3585. if (pThis)
  3586. {
  3587. LRESULT lResult = CallWindowProc(pThis->m_pfnWndProc, hwnd, uMsg, wParam, lParam);
  3588. SendMessage(pThis->m_hwndBlocker, uMsg, wParam, lParam);
  3589. // HFONT hf = (HFONT) SendMessage(pThis->m_hwndList, WM_GETFONT, 0, 0);
  3590. // SendMessage(pThis->m_hwndBlocker, WM_SETFONT, (WPARAM) hf, MAKELPARAM(TRUE, 0));
  3591. return (lResult);
  3592. }
  3593. case WM_DESTROY:
  3594. {
  3595. if (pThis)
  3596. {
  3597. WNDPROC pfn = pThis->m_pfnWndProc;
  3598. pThis->Hide();
  3599. return (CallWindowProc(pfn, hwnd, uMsg, wParam, lParam));
  3600. }
  3601. }
  3602. break;
  3603. }
  3604. return (CallWindowProc(pThis->m_pfnWndProc, hwnd, uMsg, wParam, lParam));
  3605. }
  3606. extern "C" const GUID CLSID_MailRecipient;
  3607. HRESULT DropOnMailRecipient(IDataObject *pdtobj, DWORD grfKeyState)
  3608. {
  3609. IDropTarget *pdrop;
  3610. HRESULT hres = CoCreateInstance(CLSID_MailRecipient,
  3611. NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
  3612. IID_IDropTarget, (void **) &pdrop);
  3613. if (SUCCEEDED(hres))
  3614. {
  3615. hres = OESimulateDrop(pdrop, pdtobj, grfKeyState, NULL, NULL);
  3616. pdrop->Release();
  3617. }
  3618. return hres;
  3619. }
  3620. STDAPI OESimulateDrop(IDropTarget *pdrop, IDataObject *pdtobj, DWORD grfKeyState,
  3621. const POINTL *ppt, DWORD *pdwEffect)
  3622. {
  3623. POINTL pt;
  3624. DWORD dwEffect;
  3625. if (!ppt)
  3626. {
  3627. ppt = &pt;
  3628. pt.x = 0;
  3629. pt.y = 0;
  3630. }
  3631. if (!pdwEffect)
  3632. {
  3633. pdwEffect = &dwEffect;
  3634. dwEffect = DROPEFFECT_LINK | DROPEFFECT_MOVE | DROPEFFECT_COPY;
  3635. }
  3636. DWORD dwEffectSave = *pdwEffect; // drag enter returns the default effect
  3637. HRESULT hr = pdrop->DragEnter(pdtobj, grfKeyState, *ppt, pdwEffect);
  3638. if (*pdwEffect)
  3639. {
  3640. *pdwEffect = dwEffectSave; // do Drop with the full set of bits
  3641. hr = pdrop->Drop(pdtobj, grfKeyState, *ppt, pdwEffect);
  3642. }
  3643. else
  3644. {
  3645. pdrop->DragLeave();
  3646. hr = S_FALSE; // HACK? S_FALSE DragEnter said no
  3647. }
  3648. return hr;
  3649. }