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.

4172 lines
124 KiB

  1. /*
  2. * browser.cpp
  3. *
  4. * Purpose:
  5. * Implements a browser object
  6. *
  7. * Owner:
  8. * EricAn
  9. *
  10. * Copyright (C) Microsoft Corp. 1996
  11. */
  12. #include "pch.hxx"
  13. #include "bodybar.h"
  14. #include "browser.h"
  15. #include <shellapi.h>
  16. #include "resource.h"
  17. #include "options.h"
  18. #include "ipab.h"
  19. #include "inetcfg.h"
  20. #include "acctutil.h"
  21. #include "mailutil.h"
  22. #include "impapi.h"
  23. #include "menuutil.h"
  24. #include "ourguid.h"
  25. #include "thormsgs.h"
  26. #include "error.h"
  27. #include "fonts.h"
  28. #include "treeview.h"
  29. #include "goptions.h"
  30. #include "strconst.h"
  31. #include "note.h"
  32. #include "tbbands.h"
  33. #include "statbar.h"
  34. #include "newfldr.h"
  35. #include "conman.h"
  36. #include "acctutil.h"
  37. #include "spoolapi.h"
  38. #include "statnery.h"
  39. #include "inpobj.h"
  40. #include "fldbar.h"
  41. #include "layout.h"
  42. #include "htmlhelp.h"
  43. #include "shared.h"
  44. #include "mailutil.h"
  45. #include <shlwapi.h>
  46. #include "shlwapip.h"
  47. #include "instance.h"
  48. #include "ruleutil.h"
  49. #include "envfact.h"
  50. #include "storutil.h"
  51. #include "finder.h"
  52. #include "demand.h"
  53. #include "multiusr.h"
  54. #include "menures.h"
  55. #include "store.h"
  56. #include "subscr.h"
  57. #include "outbar.h"
  58. #include "navpane.h"
  59. #include "msostd.h"
  60. #include "inetreg.h"
  61. #include "mapiutil.h"
  62. #include "adbar.h"
  63. #include <mirror.h>
  64. #define MAX_SIZE_EXT_STR 128
  65. ASSERTDATA
  66. /////////////////////////////////////////////////////////////////////////////
  67. //
  68. // Defines
  69. //
  70. #define CBM_POSTCREATE (WM_USER + 4000)
  71. #define TIME_TO_CLEAR_NEWMSGSTATUS (20*1000) // 20 seconds
  72. #define TIMER_CLEAR_STATUS 1003
  73. /////////////////////////////////////////////////////////////////////////////
  74. //
  75. // Macros
  76. //
  77. #define CBDOUT(x) DOUTL(DOUT_LEVEL4, x)
  78. /////////////////////////////////////////////////////////////////////////////
  79. //
  80. // Global Data
  81. //
  82. static const TCHAR s_szCallClient[] = TEXT("Internet Call");
  83. static const TCHAR s_szMailClient[] = TEXT("Mail");
  84. static const TCHAR s_szNewsClient[] = TEXT("News");
  85. static HACCEL s_hAccelBrowser = NULL;
  86. static s_fQuickShutdown = FALSE;
  87. enum {
  88. IMAGE_STATBAR_BLANK,
  89. IMAGE_STATBAR_WARNING,
  90. IMAGE_STATBAR_SPOOLER
  91. };
  92. /////////////////////////////////////////////////////////////////////////////
  93. //
  94. // Prototypes
  95. //
  96. //
  97. // FUNCTION: ShellUtil_IsRegisteredClient()
  98. //
  99. // PURPOSE: Returns whether the specified client type is handled.
  100. //
  101. BOOL ShellUtil_IsRegisteredClient(LPCTSTR pszClient)
  102. {
  103. LONG cbSize = 0;
  104. TCHAR szKey[MAX_PATH];
  105. wnsprintf(szKey, ARRAYSIZE(szKey), c_szPathFileFmt, c_szRegPathClients, pszClient);
  106. return (RegQueryValue(HKEY_LOCAL_MACHINE, szKey, NULL, &cbSize) == ERROR_SUCCESS) &&
  107. (cbSize > 1);
  108. }
  109. //
  110. // FUNCTION: ShellUtil_RunIndirectRegCommand()
  111. //
  112. // PURPOSE: find the default value under HKLM\Software\Clients\pszClient
  113. // tack on shell\open\command
  114. // then runreg that
  115. //
  116. void ShellUtil_RunClientRegCommand(HWND hwnd, LPCTSTR pszClient)
  117. {
  118. TCHAR szDefApp[MAX_PATH], szExpanded[MAX_PATH];
  119. TCHAR szKey[MAX_PATH];
  120. DWORD cbSize = sizeof(szDefApp);
  121. DWORD dwType;
  122. wnsprintf(szKey, ARRAYSIZE(szKey), c_szPathFileFmt, c_szRegPathClients, pszClient);
  123. if (RegQueryValueEx(HKEY_LOCAL_MACHINE, szKey, 0, NULL, (LPBYTE)szDefApp, &cbSize) == ERROR_SUCCESS)
  124. {
  125. TCHAR szFullKey[MAX_PATH];
  126. // tack on shell\open\command
  127. wnsprintf(szFullKey, ARRAYSIZE(szFullKey), TEXT("%s\\%s\\shell\\open\\command"), szKey, szDefApp);
  128. cbSize = sizeof(szDefApp);
  129. if (RegQueryValueEx(HKEY_LOCAL_MACHINE, szFullKey, 0, &dwType, (LPBYTE)szDefApp, &cbSize) == ERROR_SUCCESS)
  130. {
  131. LPSTR pszArgs;
  132. SHELLEXECUTEINFO ExecInfo;
  133. pszArgs = PathGetArgs(szDefApp);
  134. PathRemoveArgs(szDefApp);
  135. PathUnquoteSpaces(szDefApp);
  136. if (REG_EXPAND_SZ == dwType)
  137. {
  138. ExpandEnvironmentStrings(szDefApp, szExpanded, ARRAYSIZE(szExpanded));
  139. ExecInfo.lpFile = szExpanded;
  140. }
  141. else
  142. ExecInfo.lpFile = szDefApp;
  143. ExecInfo.hwnd = hwnd;
  144. ExecInfo.lpVerb = NULL;
  145. ExecInfo.lpParameters = pszArgs;
  146. ExecInfo.lpDirectory = NULL;
  147. ExecInfo.nShow = SW_SHOWNORMAL;
  148. ExecInfo.fMask = 0;
  149. ExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
  150. ShellExecuteEx(&ExecInfo);
  151. }
  152. }
  153. }
  154. /////////////////////////////////////////////////////////////////////////
  155. //
  156. // Constructors, Destructors, and Initialization
  157. //
  158. CBrowser::CBrowser()
  159. {
  160. m_cRef = 1;
  161. m_hwnd = NULL;
  162. m_pView = NULL;
  163. m_pViewCT = NULL;
  164. m_hwndInner = NULL;
  165. m_ftSel = FOLDER_TYPESMAX;
  166. m_idSelected = FOLDERID_INVALID;
  167. m_fPainted = FALSE;
  168. m_hIconPhone = 0;
  169. m_hIconError = 0;
  170. m_hIconAthena = 0;
  171. m_hIconOffline = 0;
  172. m_hIcon = 0;
  173. m_hIconSm = 0;
  174. m_pTreeView = NULL;
  175. m_pStatus = NULL;
  176. m_pCoolbar = NULL;
  177. m_pBodyBar = NULL;
  178. m_pFolderBar = NULL;
  179. m_hwndLastFocus = NULL;
  180. m_fInternal = 0;
  181. *m_szName = 0;
  182. ZeroMemory(m_rgTBar, sizeof(m_rgTBar));
  183. m_itbLastFocus = ITB_NONE;
  184. m_cAcctMenu = 0;
  185. m_pAcctMenu = NULL;
  186. m_fAnimate = FALSE;
  187. m_hMenuLanguage = NULL;
  188. m_pDocObj = NULL;
  189. CoIncrementInit("CBrowser::CBrowser", MSOEAPI_START_SHOWERRORS, NULL, NULL);
  190. m_fEnvMenuInited = FALSE;
  191. m_fRebuildAccountMenu = TRUE;
  192. m_fInitNewAcctMenu = FALSE;
  193. m_hMenu = NULL;
  194. ZeroMemory(&m_hlDisabled, sizeof(HWNDLIST));
  195. m_dwIdentCookie = 0;
  196. m_fSwitchIsLogout = FALSE;
  197. m_fNoModifyAccts = FALSE;
  198. m_pAdBar = NULL;
  199. }
  200. CBrowser::~CBrowser()
  201. {
  202. Assert(NULL == m_pView);
  203. Assert(NULL == m_pViewCT);
  204. SafeRelease(m_pTreeView);
  205. SafeRelease(m_pCoolbar);
  206. SafeRelease(m_pBodyBar);
  207. SafeRelease(m_pFolderBar);
  208. SafeRelease(m_pStatus);
  209. SafeRelease(m_pOutBar);
  210. SafeRelease(m_pNavPane);
  211. SafeRelease(m_pAdBar);
  212. SafeMemFree(m_pAcctMenu);
  213. g_pBrowser = NULL;
  214. if (m_hIconPhone)
  215. SideAssert(DestroyIcon(m_hIconPhone));
  216. if (m_hIconError)
  217. SideAssert(DestroyIcon(m_hIconError));
  218. if (m_hIconAthena)
  219. SideAssert(DestroyIcon(m_hIconAthena));
  220. if (m_hIconOffline)
  221. SideAssert(DestroyIcon(m_hIconOffline));
  222. if (m_hIcon)
  223. SideAssert(DestroyIcon(m_hIcon));
  224. if (m_hIconSm)
  225. SideAssert(DestroyIcon(m_hIconSm));
  226. if (m_hMenuLanguage)
  227. {
  228. DeinitMultiLanguage();
  229. if(IsMenu(m_hMenuLanguage))
  230. DestroyMenu(m_hMenuLanguage);
  231. }
  232. DOUT("CBrowser calling CoDecrementInit()");
  233. CoDecrementInit("CBrowser::CBrowser", NULL);
  234. if (m_hMenu && IsMenu(m_hMenu))
  235. DestroyMenu(m_hMenu);
  236. }
  237. HRESULT CBrowser::HrInit(UINT nCmdShow, FOLDERID idFolder, HWND hWndParent)
  238. {
  239. DWORD cb, type, dw;
  240. WNDCLASSEX wc;
  241. WINDOWPLACEMENT wp;
  242. DWORD dwExStyle = 0;
  243. // Only load the layout from the registry only if we're standalone
  244. LoadLayoutSettings();
  245. m_idSelected = idFolder;
  246. if (!s_hAccelBrowser)
  247. s_hAccelBrowser = LoadAccelerators(g_hLocRes, MAKEINTRESOURCE(IDA_BROWSER_ACCEL));
  248. wc.cbSize = sizeof(WNDCLASSEX);
  249. if (!GetClassInfoEx(g_hInst, c_szBrowserWndClass, &wc))
  250. {
  251. wc.style = 0;
  252. wc.lpfnWndProc = CBrowser::BrowserWndProc;
  253. wc.cbClsExtra = 0;
  254. wc.cbWndExtra = 0;
  255. wc.hInstance = g_hInst;
  256. wc.hIcon = NULL; // Handled in WM_CREATE
  257. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  258. wc.hbrBackground = NULL;
  259. wc.lpszMenuName = NULL; // Handled in WM_CREATE
  260. wc.lpszClassName = c_szBrowserWndClass;
  261. wc.hIconSm = NULL; // Handled in WM_CREATE
  262. if (RegisterClassEx(&wc) == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  263. return E_FAIL;
  264. }
  265. if(IS_BIDI_LOCALIZED_SYSTEM())
  266. {
  267. dwExStyle |= RTL_MIRRORED_WINDOW;
  268. }
  269. m_hwnd = CreateWindowEx(dwExStyle, c_szBrowserWndClass, NULL, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  270. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  271. hWndParent, NULL, g_hInst, (LPVOID) this);
  272. if (GetOption(OPT_BROWSERPOS, (LPVOID)&wp, sizeof(wp)))
  273. {
  274. // If the user has SHOWNORMAL as the default setting in the shortcut, then
  275. // we'll respect the setting that we saved earlier. Otherwise, we have to
  276. // go with what's in the shortcut.
  277. if (nCmdShow != SW_SHOWNORMAL)
  278. wp.showCmd = nCmdShow;
  279. // Also, don't allow the user to come up minimized. That's kinda wierd.
  280. else if (wp.showCmd == SW_SHOWMINIMIZED)
  281. wp.showCmd = SW_SHOWNORMAL;
  282. SetWindowPlacement(m_hwnd, &wp);
  283. }
  284. else
  285. {
  286. CenterDialog(m_hwnd);
  287. ShowWindow(m_hwnd, nCmdShow);
  288. }
  289. // Register with identity manager
  290. SideAssert(SUCCEEDED(MU_RegisterIdentityNotifier((IUnknown *)(IAthenaBrowser *)this, &m_dwIdentCookie)));
  291. SetForegroundWindow(m_hwnd);
  292. if (!m_hwnd)
  293. return E_FAIL;
  294. cb = sizeof(DWORD);
  295. if (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE, c_szRegFlat, c_szRegValNoModifyAccts, &type, &dw, &cb) &&
  296. dw != 0)
  297. m_fNoModifyAccts = TRUE;
  298. return NOERROR;
  299. }
  300. /////////////////////////////////////////////////////////////////////////
  301. //
  302. // OLE Interfaces
  303. //
  304. ////////////////////////////////////////////////////////////////////////
  305. //
  306. // IUnknown
  307. //
  308. ////////////////////////////////////////////////////////////////////////
  309. HRESULT STDMETHODCALLTYPE CBrowser::QueryInterface(REFIID riid, void **ppvObj)
  310. {
  311. if (IsEqualIID(riid, IID_IUnknown))
  312. *ppvObj = (void*) (IUnknown *)(IAthenaBrowser *) this;
  313. else if (IsEqualIID(riid, IID_IAthenaBrowser))
  314. *ppvObj = (void*) (IAthenaBrowser *) this;
  315. else if (IsEqualIID(riid, IID_IDockingWindowSite))
  316. *ppvObj = (void*) (IDockingWindowSite *) this;
  317. else if (IsEqualIID(riid, IID_IInputObjectSite))
  318. *ppvObj = (void*) (IInputObjectSite *) this;
  319. else if (IsEqualIID(riid, IID_IOleCommandTarget))
  320. *ppvObj = (void*) (IOleCommandTarget *) this;
  321. else if (IsEqualIID(riid, IID_IIdentityChangeNotify))
  322. *ppvObj = (void*) (IIdentityChangeNotify *) this;
  323. else
  324. {
  325. *ppvObj = NULL;
  326. return E_NOINTERFACE;
  327. }
  328. AddRef();
  329. return NOERROR;
  330. }
  331. ULONG STDMETHODCALLTYPE CBrowser::AddRef()
  332. {
  333. DOUT(TEXT("CBrowser::AddRef() - m_cRef = %d"), m_cRef + 1);
  334. return ++m_cRef;
  335. }
  336. ULONG STDMETHODCALLTYPE CBrowser::Release()
  337. {
  338. DOUT(TEXT("CBrowser::Release() - m_cRef = %d"), m_cRef - 1);
  339. if (--m_cRef == 0)
  340. {
  341. delete this;
  342. return 0;
  343. }
  344. return m_cRef;
  345. }
  346. ////////////////////////////////////////////////////////////////////////
  347. //
  348. // IStoreCallback
  349. //
  350. ////////////////////////////////////////////////////////////////////////
  351. STDMETHODIMP CBrowser::GetParentWindow(DWORD dwReserved, HWND *phwndParent)
  352. {
  353. *phwndParent = GetLastActivePopup(m_hwnd);
  354. return(S_OK);
  355. }
  356. ////////////////////////////////////////////////////////////////////////
  357. //
  358. // IOleWindow
  359. //
  360. ////////////////////////////////////////////////////////////////////////
  361. HRESULT STDMETHODCALLTYPE CBrowser::GetWindow(HWND * lphwnd)
  362. {
  363. *lphwnd = m_hwnd;
  364. return (m_hwnd ? S_OK : E_FAIL);
  365. }
  366. HRESULT STDMETHODCALLTYPE CBrowser::ContextSensitiveHelp(BOOL fEnterMode)
  367. {
  368. return E_NOTIMPL;
  369. }
  370. ////////////////////////////////////////////////////////////////////////
  371. //
  372. // IAthenaBrowser
  373. //
  374. ////////////////////////////////////////////////////////////////////////
  375. BOOL IsOwner(HWND hwndOwner, HWND hwnd)
  376. {
  377. // Loop through until we find the topmost window
  378. HWND hwndTemp = hwnd;
  379. if (GetParent(hwndTemp))
  380. {
  381. while (GetParent(hwndTemp))
  382. hwndTemp = GetParent(hwndTemp);
  383. if (hwndOwner == hwndTemp)
  384. return (TRUE);
  385. }
  386. return (FALSE);
  387. }
  388. HRESULT CBrowser::TranslateAccelerator(LPMSG lpmsg)
  389. {
  390. HWND hwndFocus;
  391. BOOL fInnerValid, fViewFocus;
  392. int i;
  393. if (!(m_hwnd && IsWindow(m_hwnd)))
  394. return S_FALSE;
  395. if (FWABTranslateAccelerator(lpmsg))
  396. return S_TRUE;
  397. hwndFocus = GetFocus();
  398. //check if it is a menu message
  399. if (!GetTlsGlobalActiveNote())
  400. {
  401. if (m_pCoolbar->IsMenuMessage(lpmsg) == S_OK)
  402. return S_OK;
  403. }
  404. // handle the mousewheel messages for this thread
  405. if ((g_msgMSWheel && (lpmsg->message == g_msgMSWheel)) || (lpmsg->message == WM_MOUSEWHEEL))
  406. {
  407. POINT pt;
  408. HWND hwndT;
  409. pt.x = GET_X_LPARAM(lpmsg->lParam);
  410. pt.y = GET_Y_LPARAM(lpmsg->lParam);
  411. hwndT = WindowFromPoint(pt);
  412. if (hwndT != m_hwnd && IsChild(m_hwnd, hwndT))
  413. SendMessage(hwndT, lpmsg->message, lpmsg->wParam, lpmsg->lParam);
  414. else if (hwndFocus != m_hwnd && IsChild(m_hwnd, hwndFocus))
  415. SendMessage(hwndFocus, lpmsg->message, lpmsg->wParam, lpmsg->wParam);
  416. else
  417. return S_FALSE;
  418. return S_OK;
  419. }
  420. HWND hwndDropDown = HwndGlobalDropDown();
  421. BOOL fRetCode;
  422. if (hwndDropDown)
  423. {
  424. if (lpmsg->message == WM_LBUTTONDOWN ||
  425. lpmsg->message == WM_NCLBUTTONDOWN ||
  426. lpmsg->message == WM_RBUTTONDOWN ||
  427. lpmsg->message == WM_NCRBUTTONDOWN)
  428. {
  429. fRetCode = (BOOL)::SendMessage(hwndDropDown, WMR_CLICKOUTSIDE,
  430. CLK_OUT_MOUSE, (LPARAM)lpmsg->hwnd);
  431. if (fRetCode)
  432. return (S_OK);
  433. }
  434. if (lpmsg->message == WM_KEYDOWN &&
  435. // One of the possible hot keys
  436. (lpmsg->wParam==VK_ESCAPE || lpmsg->wParam==VK_TAB))
  437. {
  438. fRetCode = (BOOL)::SendMessage(hwndDropDown, WMR_CLICKOUTSIDE,
  439. CLK_OUT_KEYBD, (LPARAM)lpmsg->wParam);
  440. if (fRetCode)
  441. return S_OK;
  442. }
  443. }
  444. if (!(hwndFocus && (IsChild(m_hwnd, hwndFocus) || m_hwnd == hwndFocus || IsOwner(m_hwnd, hwndFocus))))
  445. return S_FALSE;
  446. fInnerValid = m_pView && m_hwndInner && IsWindow(m_hwndInner);
  447. fViewFocus = fInnerValid && hwndFocus && (IsChild(m_hwndInner, hwndFocus) || m_hwndInner == hwndFocus);
  448. if (fViewFocus)
  449. {
  450. if (m_pView->TranslateAccelerator(lpmsg) == S_OK)
  451. return S_OK;
  452. }
  453. for (i=0; i<ITB_MAX; i++)
  454. {
  455. if (m_rgTBar[i].ptbar && UnkHasFocusIO(m_rgTBar[i].ptbar) == S_OK)
  456. {
  457. if (UnkTranslateAcceleratorIO(m_rgTBar[i].ptbar, lpmsg) == S_OK)
  458. return S_OK;
  459. break;
  460. }
  461. }
  462. // Handle tabbing between windows
  463. if (lpmsg->hwnd &&
  464. IsChild(m_hwnd, lpmsg->hwnd))
  465. {
  466. if (lpmsg->message == WM_KEYDOWN)
  467. {
  468. if (lpmsg->wParam == VK_TAB && (FALSE == !!(0x8000 & GetKeyState(VK_CONTROL))))
  469. {
  470. SHORT state = GetKeyState(VK_SHIFT);
  471. HWND hwndNext = GetNextDlgTabItem(m_hwnd, GetFocus(), !!(state & 0x8000));
  472. SetFocus(hwndNext);
  473. return (S_OK);
  474. }
  475. }
  476. }
  477. if (lpmsg->hwnd &&
  478. IsChild(m_hwnd, lpmsg->hwnd) && s_hAccelBrowser && ::TranslateAccelerator(m_hwnd, s_hAccelBrowser, lpmsg))
  479. return S_OK;
  480. // if the view doesn't have focus, it still gets a chance at the accelerator, after the browser
  481. if (fInnerValid && !fViewFocus)
  482. if (m_pView->TranslateAccelerator(lpmsg) == S_OK)
  483. return S_OK;
  484. return S_FALSE;
  485. }
  486. //
  487. // Add the specified toolbar (as punkSrc) to this toolbar site
  488. //
  489. // Returns: S_OK, if successfully done.
  490. // E_FAIL, if failed (exceeded maximum).
  491. // E_NOINTERFACE, the toolbar does not support an approriate interface.
  492. //
  493. HRESULT CBrowser::AddToolbar(IUnknown* punk, DWORD dwIndex, BOOL fShow, BOOL fActivate)
  494. {
  495. HRESULT hres = E_FAIL;
  496. Assert(ITB_NONE == FindTBar(punk));
  497. Assert(dwIndex < ITB_MAX);
  498. Assert(m_rgTBar[dwIndex].ptbar == NULL);
  499. if (punk->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&m_rgTBar[dwIndex].pOleCmdTarget) != S_OK)
  500. {
  501. m_rgTBar[dwIndex].pOleCmdTarget = NULL;
  502. }
  503. hres = punk->QueryInterface(IID_IDockingWindow, (LPVOID*)&m_rgTBar[dwIndex].ptbar);
  504. if (SUCCEEDED(hres))
  505. {
  506. m_rgTBar[dwIndex].fShow = fShow;
  507. UnkSetSite(m_rgTBar[dwIndex].ptbar, (IAthenaBrowser *)this);
  508. if (fActivate)
  509. m_rgTBar[dwIndex].ptbar->ShowDW(fShow);
  510. }
  511. return hres;
  512. }
  513. HRESULT CBrowser::ShowToolbar(IUnknown* punkSrc, BOOL fShow)
  514. {
  515. UINT itb = FindTBar(punkSrc);
  516. if (itb == ITB_NONE)
  517. {
  518. Assert(0);
  519. return E_INVALIDARG;
  520. }
  521. if (m_rgTBar[itb].ptbar)
  522. {
  523. m_rgTBar[itb].fShow = fShow;
  524. m_rgTBar[itb].ptbar->ShowDW(fShow);
  525. }
  526. return S_OK;
  527. }
  528. HRESULT CBrowser::RemoveToolbar(IUnknown* punkSrc)
  529. {
  530. UINT itb = FindTBar(punkSrc);
  531. if (itb == ITB_NONE)
  532. {
  533. Assert(0);
  534. return E_INVALIDARG;
  535. }
  536. ReleaseToolbarItem(itb, TRUE);
  537. // Clear the rect and resize the inner ones (including the view).
  538. SetRect(&m_rgTBar[itb].rcBorderTool, 0, 0, 0, 0);
  539. ResizeNextBorder(itb+1);
  540. return S_OK;
  541. }
  542. HRESULT CBrowser::HasFocus(UINT itb)
  543. {
  544. HRESULT hres = S_FALSE;
  545. if (ITB_OEVIEW == itb)
  546. hres = (ITB_OEVIEW == m_itbLastFocus) ? S_OK : S_FALSE;
  547. else if (m_rgTBar[itb].fShow && m_rgTBar[itb].ptbar)
  548. hres = UnkHasFocusIO(m_rgTBar[itb].ptbar);
  549. return hres;
  550. }
  551. HRESULT CBrowser::OnViewWindowActive(IViewWindow *pAV)
  552. {
  553. _OnFocusChange(ITB_OEVIEW);
  554. return NOERROR;
  555. }
  556. HRESULT CBrowser::BrowseObject(FOLDERID idFolder, DWORD dwFlags)
  557. {
  558. if (!m_pTreeView)
  559. return E_FAIL;
  560. return m_pTreeView->SetSelection(idFolder, TVSS_INSERTIFNOTFOUND);
  561. }
  562. HRESULT CBrowser::GetStatusBar(CStatusBar * * ppStatusBar)
  563. {
  564. if (m_pStatus)
  565. {
  566. *ppStatusBar = m_pStatus;
  567. m_pStatus->AddRef();
  568. return S_OK;
  569. }
  570. *ppStatusBar = NULL;
  571. return E_FAIL;
  572. }
  573. HRESULT CBrowser::GetCoolbar(CBands * * ppCoolbar)
  574. {
  575. if (m_pCoolbar)
  576. {
  577. *ppCoolbar = m_pCoolbar;
  578. m_pCoolbar->AddRef();
  579. return S_OK;
  580. }
  581. *ppCoolbar = NULL;
  582. return E_FAIL;
  583. }
  584. HRESULT CBrowser::GetTreeView(CTreeView * * ppTreeView)
  585. {
  586. if (m_pTreeView)
  587. {
  588. *ppTreeView = m_pTreeView;
  589. m_pTreeView->AddRef();
  590. return S_OK;
  591. }
  592. *ppTreeView = NULL;
  593. return E_FAIL;
  594. }
  595. HRESULT CBrowser::GetFolderBar(CFolderBar * * ppFolderBar)
  596. {
  597. if (m_pFolderBar)
  598. {
  599. *ppFolderBar = m_pFolderBar;
  600. m_pFolderBar->AddRef();
  601. return S_OK;
  602. }
  603. *ppFolderBar = NULL;
  604. return E_FAIL;
  605. }
  606. HRESULT CBrowser::GetLanguageMenu(HMENU *phMenu, UINT uiCodepage)
  607. {
  608. if(!m_hMenuLanguage)
  609. InitMultiLanguage();
  610. else if (IsMenu(m_hMenuLanguage))
  611. DestroyMenu(m_hMenuLanguage);
  612. UINT cp;
  613. if(uiCodepage)
  614. cp = uiCodepage;
  615. else if(m_pView)
  616. {
  617. IMessageWindow *pWindow;
  618. if (SUCCEEDED(m_pView->QueryInterface(IID_IMessageWindow, (LPVOID *) &pWindow)))
  619. {
  620. pWindow->GetCurCharSet(&cp);
  621. pWindow->Release();
  622. }
  623. else
  624. cp = GetACP();
  625. }
  626. else
  627. cp = GetACP();
  628. m_hMenuLanguage = CreateMimeLanguageMenu(TRUE,TRUE, cp);
  629. if (!m_hMenuLanguage)
  630. return E_FAIL;
  631. *phMenu = m_hMenuLanguage;
  632. return S_OK;
  633. }
  634. HRESULT CBrowser::InitPopupMenu(HMENU hMenu)
  635. {
  636. if (!hMenu)
  637. return E_INVALIDARG;
  638. MenuUtil_EnablePopupMenu(hMenu, this);
  639. return S_OK;
  640. }
  641. HRESULT CBrowser::UpdateToolbar()
  642. {
  643. if (m_pCoolbar)
  644. return (m_pCoolbar->Update());
  645. return (E_FAIL);
  646. }
  647. HRESULT CBrowser::GetFolderType(FOLDERTYPE *pftType)
  648. {
  649. if (pftType)
  650. {
  651. *pftType = m_ftSel;
  652. return (S_OK);
  653. }
  654. return (E_INVALIDARG);
  655. }
  656. HRESULT CBrowser::GetCurrentFolder(FOLDERID *pidFolder)
  657. {
  658. if (pidFolder)
  659. {
  660. *pidFolder = m_idSelected;
  661. return (S_OK);
  662. }
  663. return (E_INVALIDARG);
  664. }
  665. HRESULT CBrowser::GetCurrentView(IViewWindow **ppView)
  666. {
  667. if (ppView)
  668. {
  669. *ppView = m_pView;
  670. (*ppView)->AddRef();
  671. return (S_OK);
  672. }
  673. return (E_INVALIDARG);
  674. }
  675. ////////////////////////////////////////////////////////////////////////
  676. //
  677. // IDockingWindowSite
  678. //
  679. ////////////////////////////////////////////////////////////////////////
  680. //
  681. // This is an implementation of IDockingWindowSite::GetBorderDW.
  682. //
  683. // This function returns a bounding rectangle for the specified toolbar
  684. // (by punkSrc). It gets the effective client area, then subtract border
  685. // area taken by "outer" toolbars.
  686. //
  687. HRESULT CBrowser::GetBorderDW(IUnknown* punkSrc, LPRECT lprectBorder)
  688. {
  689. UINT itb = FindTBar(punkSrc);
  690. if (itb == ITB_NONE)
  691. {
  692. Assert(0);
  693. return E_INVALIDARG;
  694. }
  695. GetClientArea(lprectBorder);
  696. //
  697. // Subtract border area taken by "outer toolbars"
  698. //
  699. for (UINT i=0; i<itb; i++)
  700. {
  701. lprectBorder->left += m_rgTBar[i].rcBorderTool.left;
  702. lprectBorder->top += m_rgTBar[i].rcBorderTool.top;
  703. lprectBorder->right -= m_rgTBar[i].rcBorderTool.right;
  704. lprectBorder->bottom -= m_rgTBar[i].rcBorderTool.bottom;
  705. }
  706. DOUTL(4, "CBrowser::GetBorderDW called returning=%x,%x,%x,%x",
  707. lprectBorder->left, lprectBorder->top, lprectBorder->right, lprectBorder->bottom);
  708. return S_OK;
  709. }
  710. HRESULT CBrowser::RequestBorderSpaceDW(IUnknown* punkSrc, LPCBORDERWIDTHS pborderwidths)
  711. {
  712. UINT itb = FindTBar(punkSrc);
  713. if (itb == ITB_NONE)
  714. {
  715. Assert(0);
  716. return E_INVALIDARG;
  717. }
  718. DOUTL(4, "CBrowser::ReqestBorderSpaceST pborderwidths=%x,%x,%x,%x",
  719. pborderwidths->left, pborderwidths->top, pborderwidths->right, pborderwidths->bottom);
  720. return S_OK;
  721. }
  722. HRESULT CBrowser::SetBorderSpaceDW(IUnknown* punkSrc, LPCBORDERWIDTHS pborderwidths)
  723. {
  724. UINT itb = FindTBar(punkSrc);
  725. if (itb == ITB_NONE)
  726. {
  727. Assert(0);
  728. return E_INVALIDARG;
  729. }
  730. DOUTL(4, "CBrowser::SetBorderSpaceDW pborderwidths=%x,%x,%x,%x",
  731. pborderwidths->left, pborderwidths->top, pborderwidths->right, pborderwidths->bottom);
  732. m_rgTBar[itb].rcBorderTool = *pborderwidths;
  733. ResizeNextBorder(itb+1);
  734. return S_OK;
  735. }
  736. ////////////////////////////////////////////////////////////////////////
  737. //
  738. // IInputObjectSite
  739. //
  740. ////////////////////////////////////////////////////////////////////////
  741. HRESULT CBrowser::OnFocusChangeIS(IUnknown* punkSrc, BOOL fSetFocus)
  742. {
  743. UINT itb = FindTBar(punkSrc);
  744. if (itb == ITB_NONE)
  745. {
  746. //Assert(0);
  747. return E_INVALIDARG;
  748. }
  749. //
  750. // Note that we keep track of which toolbar got the focus last.
  751. // We can't reliably monitor the kill focus event because OLE's
  752. // window procedure hook (for merged menu dispatching code) changes
  753. // focus around.
  754. //
  755. if (fSetFocus)
  756. {
  757. _OnFocusChange(itb);
  758. }
  759. UpdateToolbar();
  760. return S_OK;
  761. }
  762. ////////////////////////////////////////////////////////////////////////
  763. //
  764. // Support functions for IAthenaBrowser and IDockingWindowSite
  765. //
  766. ////////////////////////////////////////////////////////////////////////
  767. //
  768. // This function is called, when either tree control or the drives
  769. // get the focus.
  770. //
  771. void CBrowser::_OnFocusChange(UINT itb)
  772. {
  773. //
  774. // If the view is loosing the focus (within the explorer),
  775. // we should let it know. We should update _itbLastFocus before
  776. // calling UIActivate, because it will call our InsertMenu back.
  777. //
  778. if (m_itbLastFocus == itb)
  779. return;
  780. UINT itbPrevFocus = m_itbLastFocus;
  781. m_itbLastFocus = itb;
  782. if (itbPrevFocus == ITB_OEVIEW)
  783. {
  784. if (m_pView)
  785. m_pView->UIActivate(SVUIA_ACTIVATE_NOFOCUS);
  786. }
  787. else if (itbPrevFocus != ITB_NONE)
  788. {
  789. UnkUIActivateIO(m_rgTBar[itbPrevFocus].ptbar, FALSE, NULL);
  790. }
  791. UpdateToolbar();
  792. }
  793. UINT CBrowser::FindTBar(IUnknown* punkSrc)
  794. {
  795. int i;
  796. Assert(punkSrc);
  797. // Quick check without QI
  798. for (i=0; i<ITB_MAX ;i++ )
  799. {
  800. if (punkSrc == m_rgTBar[i].ptbar)
  801. return i;
  802. }
  803. // If failed, do the real COM object identity check.
  804. for (i=0; i<ITB_MAX ;i++ )
  805. {
  806. if (m_rgTBar[i].ptbar)
  807. {
  808. if (_IsSameObject(m_rgTBar[i].ptbar, punkSrc)==S_OK)
  809. {
  810. return i;
  811. }
  812. }
  813. }
  814. return ITB_NONE;
  815. }
  816. void CBrowser::ReleaseToolbarItem(int itb, BOOL fClose)
  817. {
  818. IDockingWindow *ptbTmp;
  819. // grab it and NULL it out to eliminate race condition.
  820. // (actually, there's still a v. small window btwn the 2 statements).
  821. //
  822. // e.g. if you close a WebBar and then quickly shutdown windows,
  823. // the close destroys the window etc. but then the shutdown code
  824. // does _SaveToolbars which tries to do ->Save on that destroyed guy.
  825. ptbTmp = m_rgTBar[itb].ptbar;
  826. m_rgTBar[itb].ptbar = NULL;
  827. if (fClose)
  828. ptbTmp->CloseDW(0);
  829. UnkSetSite(ptbTmp, NULL);
  830. ptbTmp->Release();
  831. SafeRelease(m_rgTBar[itb].pOleCmdTarget);
  832. m_rgTBar[itb].pOleCmdTarget = NULL;
  833. }
  834. void CBrowser::ResizeNextBorder(UINT itb)
  835. {
  836. // Find the next toolbar (even non-visible one)
  837. RECT rc;
  838. IDockingWindow* ptbarNext = NULL;
  839. for (int i=itb; i<ITB_MAX; i++)
  840. {
  841. if (m_rgTBar[i].ptbar)
  842. {
  843. ptbarNext = m_rgTBar[i].ptbar;
  844. break;
  845. }
  846. }
  847. if (ptbarNext)
  848. {
  849. GetBorderDW(ptbarNext, &rc);
  850. ptbarNext->ResizeBorderDW(&rc, (IUnknown*)(IAthenaBrowser*)this, TRUE);
  851. }
  852. else
  853. {
  854. // resize the inner shell view
  855. GetViewRect(&rc);
  856. if (m_hwndInner)
  857. {
  858. SetWindowPos(m_hwndInner,
  859. NULL,
  860. rc.left,
  861. rc.top,
  862. rc.right - rc.left,
  863. rc.bottom - rc.top,
  864. SWP_NOZORDER | SWP_NOACTIVATE);
  865. }
  866. else
  867. {
  868. InvalidateRect(m_hwnd, &rc, FALSE);
  869. }
  870. }
  871. }
  872. void CBrowser::GetClientArea(LPRECT prc)
  873. {
  874. static const int s_rgCtlIds[] = { 1, 0, 1, IDC_STATUS_BAR, 0, 0};
  875. Assert(m_hwnd);
  876. GetEffectiveClientRect(m_hwnd, prc, (LPINT)s_rgCtlIds);
  877. }
  878. HRESULT CBrowser::GetViewRect(LPRECT prc)
  879. {
  880. Assert(m_hwnd);
  881. GetClientArea(prc);
  882. //
  883. // Extract the border taken by all "frame" toolbars
  884. //
  885. for (int i=0; i<ITB_MAX; i++)
  886. {
  887. prc->left += m_rgTBar[i].rcBorderTool.left;
  888. prc->top += m_rgTBar[i].rcBorderTool.top;
  889. prc->right -= m_rgTBar[i].rcBorderTool.right;
  890. prc->bottom -= m_rgTBar[i].rcBorderTool.bottom;
  891. }
  892. return (S_OK);
  893. }
  894. HRESULT CBrowser::GetLayout(PLAYOUT playout)
  895. {
  896. Assert(playout);
  897. if (playout->cbSize != sizeof(LAYOUT))
  898. return(E_FAIL);
  899. Assert(m_rLayout.cbSize == sizeof(LAYOUT));
  900. CopyMemory(playout, &m_rLayout, sizeof(LAYOUT));
  901. return (S_OK);
  902. }
  903. HRESULT CBrowser::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[],
  904. OLECMDTEXT *pCmdText)
  905. {
  906. ULONG cServer;
  907. HRESULT hr = S_OK;
  908. // ATTENZIONE!
  909. // the view gets it first because it might want to handle a command that the treeview normally
  910. // handles. this is really only necessary for acct views where folders are displayed in the right
  911. // pane, and folder-related commands should work on the selected folder and not the current
  912. // treeview selection
  913. // View always get's it
  914. if (m_pViewCT)
  915. {
  916. m_pViewCT->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
  917. }
  918. // TreeView always get's it
  919. if (m_pTreeView)
  920. {
  921. m_pTreeView->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
  922. }
  923. // Contact's get's it
  924. if (m_pNavPane)
  925. {
  926. m_pNavPane->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
  927. }
  928. MenuUtil_NewMessageIDsQueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText, (m_ftSel != FOLDER_NEWS));
  929. // Loop through the list looking for commands the view didn't handle
  930. for (ULONG i = 0; i < cCmds; i++)
  931. {
  932. if (prgCmds[i].cmdf == 0)
  933. {
  934. // Handle the Send and Receive popup menu
  935. if (prgCmds[i].cmdID >= ID_ACCOUNT_FIRST && prgCmds[i].cmdID<= ID_ACCOUNT_LAST)
  936. {
  937. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  938. continue;
  939. }
  940. // Envelope stuff
  941. if (prgCmds[i].cmdID >= ID_ENVELOPE_HOST_FIRST && prgCmds[i].cmdID <= ID_ENVELOPE_HOST_LAST)
  942. {
  943. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  944. continue;
  945. }
  946. if (prgCmds[i].cmdID >= ID_NEW_ACCT_FIRST && prgCmds[i].cmdID <= ID_NEW_ACCT_LAST)
  947. {
  948. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  949. continue;
  950. }
  951. // Regular commands
  952. switch (prgCmds[i].cmdID)
  953. {
  954. case ID_WORK_OFFLINE:
  955. {
  956. // Always enabled and supported
  957. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  958. if (g_pConMan->IsGlobalOffline())
  959. prgCmds[i].cmdf |= OLECMDF_LATCHED;
  960. break;
  961. }
  962. case ID_SEND_RECEIVE:
  963. if (g_dwAthenaMode & MODE_NEWSONLY)
  964. {
  965. //We want to leave it enabled;
  966. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  967. break;
  968. }
  969. //Fall through. In News Only mode we want to do Send All even for Send & Receive All
  970. case ID_POPUP_ENVELOPE_HOST:
  971. case ID_RECEIVE_ALL:
  972. {
  973. // At least one SMTP server is configured
  974. if (SUCCEEDED(g_pAcctMan->GetAccountCount(ACCT_MAIL, &cServer)))
  975. {
  976. if (cServer)
  977. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  978. else
  979. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  980. }
  981. break;
  982. }
  983. case ID_SEND_ALL:
  984. {
  985. DWORD cMail = 0, cNews = 0;
  986. // At least one SMTP server is configured
  987. if (SUCCEEDED(g_pAcctMan->GetAccountCount(ACCT_MAIL, &cMail)) &&
  988. SUCCEEDED(g_pAcctMan->GetAccountCount(ACCT_NEWS, &cNews)))
  989. {
  990. if (cMail || cNews)
  991. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  992. else
  993. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  994. }
  995. break;
  996. }
  997. case ID_IMAP_FOLDERS:
  998. {
  999. // At least one news server is configured
  1000. if (SUCCEEDED(g_pAcctMan->GetAccountCount(ACCT_MAIL, &cServer)))
  1001. {
  1002. if (cServer)
  1003. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1004. else
  1005. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1006. }
  1007. break;
  1008. }
  1009. case ID_FOLDER_LIST:
  1010. {
  1011. // Always enabled
  1012. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1013. // Is it checked?
  1014. if (m_rLayout.fFolderList)
  1015. prgCmds[i].cmdf |= OLECMDF_LATCHED;
  1016. break;
  1017. }
  1018. case ID_CONTACTS_LIST:
  1019. {
  1020. // enabled only when not in outnews mode
  1021. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1022. if ((g_dwAthenaMode & MODE_OUTLOOKNEWS) != MODE_OUTLOOKNEWS)
  1023. {
  1024. prgCmds[i].cmdf |= OLECMDF_ENABLED;
  1025. }
  1026. // Is it checked?
  1027. if (m_rLayout.fContacts)
  1028. prgCmds[i].cmdf |= OLECMDF_LATCHED;
  1029. break;
  1030. }
  1031. case ID_EXIT_LOGOFF:
  1032. case ID_LOGOFF_IDENTITY:
  1033. {
  1034. if (MU_CountUsers() > 1)
  1035. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1036. else
  1037. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1038. break;
  1039. }
  1040. case ID_DELETE_ACCEL:
  1041. case ID_DELETE_NO_TRASH_ACCEL:
  1042. {
  1043. IOleCommandTarget *pTarget = NULL;
  1044. OLECMD cmd = { 0 };
  1045. // Check to see if it's the treeview
  1046. if (S_OK == m_pTreeView->HasFocusIO())
  1047. {
  1048. pTarget = m_pTreeView;
  1049. }
  1050. // Check to see if it's anything else on the Info Column
  1051. else if (m_pNavPane->IsContactsFocus())
  1052. {
  1053. pTarget = m_pNavPane;
  1054. cmd.cmdID = ID_DELETE_CONTACT;
  1055. }
  1056. // Otherwise, it must be the view
  1057. else
  1058. {
  1059. pTarget = m_pViewCT;
  1060. if (prgCmds[i].cmdID == ID_DELETE_NO_TRASH_ACCEL)
  1061. cmd.cmdID = ID_DELETE_NO_TRASH;
  1062. else
  1063. cmd.cmdID = ID_DELETE;
  1064. }
  1065. // Hit the target with the right command
  1066. if (pTarget)
  1067. {
  1068. pTarget->QueryStatus(NULL, 1, &cmd, NULL);
  1069. prgCmds[i].cmdf = cmd.cmdf;
  1070. }
  1071. else
  1072. {
  1073. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1074. }
  1075. break;
  1076. }
  1077. case ID_UP_ONE_LEVEL:
  1078. if (m_idSelected != FOLDERID_ROOT)
  1079. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1080. break;
  1081. case ID_SHOW_TOOLBAR:
  1082. case ID_SHOW_FILTERBAR:
  1083. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1084. break;
  1085. case ID_SWITCH_IDENTITY:
  1086. case ID_IDENTITIES:
  1087. case ID_MANAGE_IDENTITIES:
  1088. case ID_NEW_IDENTITY:
  1089. if (((g_dwAthenaMode & MODE_OUTLOOKNEWS) == MODE_OUTLOOKNEWS) && (MU_CountUsers() <= 1))
  1090. {
  1091. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1092. }
  1093. else
  1094. {
  1095. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1096. }
  1097. break;
  1098. case ID_MESSAGE_RULES_MAIL:
  1099. case ID_POPUP_NEW_ACCT:
  1100. if (g_dwAthenaMode & MODE_OUTLOOKNEWS)
  1101. {
  1102. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1103. }
  1104. else
  1105. {
  1106. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1107. }
  1108. break;
  1109. case ID_MESSAGE_RULES_JUNK:
  1110. if (g_dwAthenaMode & MODE_OUTLOOKNEWS)
  1111. {
  1112. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1113. }
  1114. else if (g_dwAthenaMode & MODE_JUNKMAIL)
  1115. {
  1116. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1117. }
  1118. break;
  1119. // always enabled
  1120. // File Menu
  1121. case ID_POPUP_NEW:
  1122. case ID_POPUP_FOLDER:
  1123. case ID_POPUP_IMPORT:
  1124. case ID_POPUP_EXPORT:
  1125. case ID_POPUP_USERS:
  1126. case ID_IMPORT_ADDRESS_BOOK:
  1127. case ID_IMPORT_WAB:
  1128. case ID_IMPORT_MESSAGES:
  1129. case ID_IMPORT_MAIL_ACCOUNTS:
  1130. case ID_IMPORT_NEWS_ACCOUNTS:
  1131. case ID_IMPORT_RULES:
  1132. case ID_EXPORT_ADDRESS_BOOK:
  1133. case ID_EXPORT_MESSAGES:
  1134. case ID_EXPORT_RULES:
  1135. case ID_EXIT:
  1136. // Edit Menu
  1137. case ID_POPUP_FIND:
  1138. case ID_FIND_MESSAGE:
  1139. case ID_FIND_PEOPLE:
  1140. // View Menu
  1141. case ID_POPUP_TOOLBAR:
  1142. case ID_POPUP_NEXT:
  1143. case ID_LAYOUT:
  1144. case ID_CUSTOMIZE:
  1145. // Go Menu
  1146. case ID_GO_INBOX:
  1147. case ID_GO_NEWS:
  1148. case ID_GO_FOLDER:
  1149. case ID_GO_NETMEETING:
  1150. case ID_GO_OUTBOX:
  1151. case ID_GO_SENT_ITEMS:
  1152. case ID_GO_DRAFTS:
  1153. // Message Menu
  1154. // Tools
  1155. case ID_POPUP_SEND_AND_RECEIVE:
  1156. case ID_SYNCHRONIZE:
  1157. case ID_ADDRESS_BOOK:
  1158. case ID_POPUP_RULES:
  1159. //case ID_MESSAGE_RULES_MAIL:
  1160. case ID_MESSAGE_RULES_NEWS:
  1161. //case ID_MESSAGE_RULES_JUNK:
  1162. case ID_MESSAGE_RULES_SENDERS:
  1163. case ID_OPTIONS:
  1164. case ID_ACCOUNTS:
  1165. // Help
  1166. case ID_HELP_CONTENTS:
  1167. case ID_README:
  1168. case ID_POPUP_MSWEB:
  1169. case ID_MSWEB_FREE_STUFF:
  1170. case ID_MSWEB_PRODUCT_NEWS:
  1171. case ID_MSWEB_FAQ:
  1172. case ID_MSWEB_SUPPORT:
  1173. case ID_MSWEB_FEEDBACK:
  1174. case ID_MSWEB_BEST:
  1175. case ID_MSWEB_SEARCH:
  1176. case ID_MSWEB_HOME:
  1177. case ID_MSWEB_HOTMAIL:
  1178. case ID_ABOUT:
  1179. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1180. break;
  1181. }
  1182. }
  1183. }
  1184. return S_OK;
  1185. }
  1186. HRESULT CBrowser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
  1187. VARIANTARG *pvaIn, VARIANTARG *pvaOut)
  1188. {
  1189. AssertSz(FALSE, "NYI");
  1190. return (E_NOTIMPL);
  1191. }
  1192. ////////////////////////////////////////////////////////////////////////
  1193. //
  1194. // ITreeViewNotify
  1195. //
  1196. ////////////////////////////////////////////////////////////////////////
  1197. void CBrowser::OnSelChange(FOLDERID idFolder)
  1198. {
  1199. HRESULT hr = S_OK;
  1200. IViewWindow *pNewView = NULL;
  1201. BOOL fViewFocus = FALSE;
  1202. // don't refresh if the pidls match
  1203. if (m_pView)
  1204. {
  1205. if (idFolder == m_idSelected)
  1206. return;
  1207. }
  1208. // Get Focus
  1209. HWND hwndFocus = GetFocus();
  1210. fViewFocus = (IsWindow(m_hwndInner) && IsChild(m_hwndInner, hwndFocus));
  1211. // hold on to the current pidl
  1212. m_idSelected = idFolder;
  1213. SetFolderType(idFolder);
  1214. hr = CreateFolderViewObject(m_idSelected, m_hwnd, IID_IViewWindow, (LPVOID *)&pNewView);
  1215. if (SUCCEEDED(hr))
  1216. {
  1217. IViewWindow *pOldView;
  1218. if (m_pView)
  1219. hr = m_pView->SaveViewState();
  1220. if (SUCCEEDED(hr))
  1221. {
  1222. RECT rc;
  1223. HWND hwnd;
  1224. // Release the old command target
  1225. if (m_pViewCT)
  1226. {
  1227. m_pViewCT->Release();
  1228. m_pViewCT = NULL;
  1229. }
  1230. pOldView = m_pView;
  1231. m_pView = pNewView;
  1232. GetViewRect(&rc);
  1233. hr = pNewView->CreateViewWindow(pOldView, (IAthenaBrowser*)this, &rc, &hwnd);
  1234. if (SUCCEEDED(hr))
  1235. {
  1236. if (pOldView)
  1237. {
  1238. pOldView->UIActivate(SVUIA_DEACTIVATE);
  1239. pOldView->DestroyViewWindow();
  1240. pOldView->Release();
  1241. }
  1242. m_pView->AddRef();
  1243. // Get the command target interface for the new view. If it fails,
  1244. // we can proceed, we just can't send commands.
  1245. if (FAILED(m_pView->QueryInterface(IID_IOleCommandTarget, (LPVOID *) &m_pViewCT)))
  1246. {
  1247. // Make sure that m_pViewCT is NULL
  1248. m_pViewCT = NULL;
  1249. }
  1250. m_hwndInner = hwnd;
  1251. m_pView->UIActivate(SVUIA_ACTIVATE_FOCUS);
  1252. if (m_itbLastFocus == ITB_NONE || m_itbLastFocus == ITB_OEVIEW || fViewFocus)
  1253. {
  1254. SetFocus(m_hwndInner);
  1255. m_itbLastFocus = ITB_OEVIEW;
  1256. }
  1257. UpdateToolbar();
  1258. if (m_pCoolbar)
  1259. m_pCoolbar->UpdateViewState();
  1260. }
  1261. else
  1262. {
  1263. // Bug #20855 - If we failed to browse, try to navigate to the root
  1264. // instead. If we failed to browse to the root, then
  1265. // we should just leave the view empty.
  1266. m_pView = pOldView;
  1267. AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsErrFailedNavigate),
  1268. 0, MB_OK | MB_ICONSTOP);
  1269. BrowseObject(FOLDERID_ROOT, NULL);
  1270. }
  1271. /*
  1272. if (m_ftSel != FOLDER_HTTPMAIL)
  1273. {
  1274. if (m_pAdBar)
  1275. ShowToolbar((IDockingWindow*)m_pAdBar, FALSE);
  1276. if (m_pBodyBar)
  1277. ShowToolbar((IUnknown *) (IDockingWindow *) m_pBodyBar, m_rLayout.fInfoPane);
  1278. }
  1279. else
  1280. {
  1281. if (m_pBodyBar && m_rLayout.fInfoPane)
  1282. ShowToolbar((IUnknown *) (IDockingWindow *)m_pBodyBar, FALSE);
  1283. if (m_pAdBar && m_pAdBar->fValidUrl())
  1284. {
  1285. ShowToolbar((IDockingWindow*)m_pAdBar, TRUE);
  1286. }
  1287. }
  1288. */
  1289. }
  1290. SafeRelease(pNewView);
  1291. }
  1292. }
  1293. void CBrowser::OnRename(FOLDERID idFolder)
  1294. {
  1295. m_idSelected = idFolder;
  1296. SetFolderType(idFolder);
  1297. }
  1298. void CBrowser::OnDoubleClick(FOLDERID idFolder)
  1299. {
  1300. return;
  1301. }
  1302. HRESULT CBrowser::OnConnectionNotify(CONNNOTIFY nCode, LPVOID pvData,
  1303. CConnectionManager *pConMan)
  1304. {
  1305. PostMessage(m_hwnd, CM_UPDATETOOLBAR, 0, 0L);
  1306. if (CONNNOTIFY_WORKOFFLINE == nCode)
  1307. {
  1308. if (NULL != pvData)
  1309. {
  1310. if (m_pStatus)
  1311. m_pStatus->SetConnectedStatus(CONN_STATUS_WORKOFFLINE);
  1312. }
  1313. else
  1314. {
  1315. if (m_pStatus)
  1316. m_pStatus->SetConnectedStatus(CONN_STATUS_CONNECTED);
  1317. }
  1318. }
  1319. else
  1320. if ((CONNNOTIFY_USER_CANCELLED == nCode) || (CONNNOTIFY_CONNECTED == nCode))
  1321. {
  1322. PostMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(ID_RESYNCHRONIZE, 0), 0);
  1323. }
  1324. return (S_OK);
  1325. }
  1326. ////////////////////////////////////////////////////////////////////////
  1327. //
  1328. // Message Handling
  1329. //
  1330. ////////////////////////////////////////////////////////////////////////
  1331. LRESULT CALLBACK CBrowser::BrowserWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1332. {
  1333. LRESULT lRet;
  1334. CBrowser *pThis;
  1335. LRESULT lres;
  1336. MSG Menumsg;
  1337. if (msg == WM_NCCREATE)
  1338. {
  1339. pThis = (CBrowser*)((LPCREATESTRUCT)lParam)->lpCreateParams;
  1340. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pThis);
  1341. }
  1342. else
  1343. {
  1344. pThis = (CBrowser*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  1345. if (msg == WM_NCDESTROY)
  1346. {
  1347. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)0);
  1348. pThis->Release();
  1349. // If this shutdown is due to an identity switch...
  1350. if (s_fQuickShutdown)
  1351. {
  1352. if (NULL != g_pInstance)
  1353. {
  1354. // ... break out of the message loop in COutlookExpress::Start
  1355. g_pInstance->SetSwitchingUsers(TRUE);
  1356. }
  1357. s_fQuickShutdown = FALSE;
  1358. }
  1359. return 0;
  1360. }
  1361. }
  1362. Menumsg.hwnd = hwnd;
  1363. Menumsg.message = msg;
  1364. Menumsg.wParam = wParam;
  1365. Menumsg.lParam = lParam;
  1366. if (pThis && (pThis->TranslateMenuMessage(&Menumsg, &lres) == S_OK))
  1367. return lres;
  1368. wParam = Menumsg.wParam;
  1369. lParam = Menumsg.lParam;
  1370. if (pThis)
  1371. return pThis->WndProc(hwnd, msg, wParam, lParam);
  1372. else
  1373. return DefWindowProc(hwnd, msg, wParam, lParam);
  1374. }
  1375. LRESULT CBrowser::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1376. {
  1377. int i;
  1378. HWND hwndActive;
  1379. switch (msg)
  1380. {
  1381. HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
  1382. HANDLE_MSG(hwnd, WM_SIZE, OnSize);
  1383. HANDLE_MSG(hwnd, WM_INITMENUPOPUP, OnInitMenuPopup);
  1384. HANDLE_MSG(hwnd, WM_COMMAND, OnCommand);
  1385. case WM_ENABLE:
  1386. if (!m_fInternal)
  1387. {
  1388. Assert (wParam || (m_hlDisabled.cHwnd == NULL && m_hlDisabled.rgHwnd == NULL));
  1389. EnableThreadWindows(&m_hlDisabled, (NULL != wParam), ETW_OE_WINDOWS_ONLY, hwnd);
  1390. g_hwndActiveModal = wParam ? NULL : hwnd;
  1391. }
  1392. break;
  1393. case WM_OE_ENABLETHREADWINDOW:
  1394. m_fInternal = 1;
  1395. EnableWindow(hwnd, (BOOL)wParam);
  1396. m_fInternal = 0;
  1397. break;
  1398. case WM_OE_ACTIVATETHREADWINDOW:
  1399. hwndActive = GetLastActivePopup(hwnd);
  1400. if (hwndActive && IsWindowEnabled(hwndActive) && IsWindowVisible(hwndActive))
  1401. ActivatePopupWindow(hwndActive);
  1402. break;
  1403. case WM_OESETFOCUS:
  1404. if (IsWindow((HWND) wParam) && IsWindowVisible((HWND) wParam))
  1405. SetFocus((HWND) wParam);
  1406. break;
  1407. case CBM_POSTCREATE:
  1408. DOUTL(2, "CBM_POSTCREATE: GetTickCount() = %ld", GetTickCount());
  1409. UpdateWindow(m_hwnd);
  1410. UpdateStatusBar();
  1411. m_fPainted = TRUE;
  1412. if (m_pTreeView)
  1413. {
  1414. m_pTreeView->Refresh();
  1415. if (!g_pConMan->IsGlobalOffline())
  1416. g_pConMan->DoOfflineTransactions();
  1417. // Set the focus to the view
  1418. m_itbLastFocus = ITB_OEVIEW;
  1419. m_pTreeView->SetSelection(m_idSelected, TVSS_INSERTIFNOTFOUND);
  1420. }
  1421. if (g_pConMan)
  1422. g_pConMan->OnActivate(TRUE);
  1423. ProcessIncompleteAccts(m_hwnd);
  1424. Assert(g_pSpooler);
  1425. if (g_pSpooler)
  1426. g_pSpooler->Advise(m_hwnd, TRUE);
  1427. // Tell the spooler we're done init'ing
  1428. if (g_pSpooler)
  1429. {
  1430. //safe fix for Bug#8149
  1431. g_pSpooler->OnStartupFinished();
  1432. }
  1433. if (g_pSpooler)
  1434. {
  1435. if (!!DwGetOption(OPT_POLLFORMSGS_ATSTARTUP))
  1436. {
  1437. DWORD dwFlags;
  1438. dwFlags = (!(g_dwAthenaMode & MODE_NEWSONLY)) ? DELIVER_NO_NEWSPOLL : 0;
  1439. g_pSpooler->StartDelivery(m_hwnd, NULL, FOLDERID_INVALID,
  1440. dwFlags | DELIVER_SEND | DELIVER_MAIL_RECV | DELIVER_POLL |
  1441. DELIVER_DIAL_ALWAYS | DELIVER_BACKGROUND |
  1442. DELIVER_OFFLINE_FLAGS | DELIVER_SERVER_TYPE_ALL);
  1443. }
  1444. }
  1445. return 0;
  1446. case CM_UPDATETOOLBAR:
  1447. UpdateToolbar();
  1448. return 0;
  1449. case WM_UPDATELAYOUT:
  1450. {
  1451. if (m_itbLastFocus == ITB_TREE)
  1452. CycleFocus(FALSE);
  1453. // Update our view to reflect these new options
  1454. if (m_pFolderBar)
  1455. m_pFolderBar->Update(FALSE, TRUE);
  1456. if (m_rgTBar[ITB_FOLDERBAR].fShow != m_rLayout.fFolderBar)
  1457. {
  1458. m_rgTBar[ITB_FOLDERBAR].fShow = !m_rgTBar[ITB_FOLDERBAR].fShow;
  1459. m_rgTBar[ITB_FOLDERBAR].ptbar->ShowDW(m_rgTBar[ITB_FOLDERBAR].fShow);
  1460. }
  1461. }
  1462. return 0;
  1463. case WM_PAINT:
  1464. DOUTL(2, "WM_PAINT: GetTickCount() = %ld", GetTickCount());
  1465. // if we don't have a shell view, paint a "clientedge window" instead
  1466. if (!m_pView)
  1467. {
  1468. HDC hdc;
  1469. PAINTSTRUCT ps;
  1470. RECT rc;
  1471. HBRUSH hBrush;
  1472. GetViewRect(&rc);
  1473. hdc = BeginPaint(hwnd, &ps);
  1474. DrawEdge(hdc, &rc, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
  1475. hBrush = SelectBrush(hdc, GetSysColorBrush(COLOR_WINDOW));
  1476. PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
  1477. SelectBrush(hdc, hBrush);
  1478. EndPaint(hwnd, &ps);
  1479. return 0;
  1480. }
  1481. break;
  1482. case WM_DISPLAYCHANGE:
  1483. {
  1484. WINDOWPLACEMENT wp;
  1485. wp.length = sizeof(wp);
  1486. GetWindowPlacement(hwnd, &wp);
  1487. SetWindowPlacement(hwnd, &wp);
  1488. }
  1489. if (m_hwndInner)
  1490. return SendMessage(m_hwndInner, msg, wParam, lParam);
  1491. return 0;
  1492. case WM_FONTCHANGE:
  1493. DeinitMultiLanguage();
  1494. // fail thru
  1495. case WM_SYSCOLORCHANGE:
  1496. case WM_WININICHANGE:
  1497. case WM_QUERYNEWPALETTE:
  1498. case WM_PALETTECHANGED:
  1499. // tell the toolbars Minus one coz we inform the InfoColumn seperately
  1500. for (i=0; i<ITB_MAX - 1; i++)
  1501. {
  1502. HWND hwndToolbar;
  1503. if (m_rgTBar[i].ptbar && SUCCEEDED(m_rgTBar[i].ptbar->GetWindow(&hwndToolbar)))
  1504. SendMessage(hwndToolbar, msg, wParam, lParam);
  1505. }
  1506. // Someone changed the default mail client.
  1507. #if 0
  1508. // The mapistub gets quite upset if you unload it while it has an active mapi
  1509. // call running
  1510. if (g_hlibMAPI && lParam && !lstrcmpi((LPSTR) lParam, "Software\\Clients\\Mail"))
  1511. {
  1512. FreeLibrary(g_hlibMAPI);
  1513. g_hlibMAPI = 0;
  1514. }
  1515. #endif
  1516. if (m_hwndInner)
  1517. return SendMessage(m_hwndInner, msg, wParam, lParam);
  1518. return 0;
  1519. case WM_MENUSELECT:
  1520. if (LOWORD(wParam) >= ID_STATIONERY_RECENT_0 && LOWORD(wParam) <= ID_STATIONERY_RECENT_9)
  1521. {
  1522. m_pStatus->ShowSimpleText(MAKEINTRESOURCE(idsRSListGeneralHelp));
  1523. return 0;
  1524. }
  1525. if (m_hwndInner)
  1526. return SendMessage(m_hwndInner, msg, wParam, lParam);
  1527. return 0;
  1528. case WM_NOTIFY:
  1529. if (IDC_STATUS_BAR == wParam && lParam)
  1530. {
  1531. m_pStatus->OnNotify((NMHDR *) lParam);
  1532. }
  1533. if (m_hwndInner)
  1534. return SendMessage(m_hwndInner, msg, wParam, lParam);
  1535. return 0;
  1536. case WM_DRAWITEM:
  1537. case WM_MEASUREITEM:
  1538. case WM_EXITMENULOOP:
  1539. case WM_ENTERMENULOOP:
  1540. case WM_ENTERSIZEMOVE:
  1541. case WM_EXITSIZEMOVE:
  1542. case WM_TIMECHANGE:
  1543. if (m_hwndInner)
  1544. return SendMessage(m_hwndInner, msg, wParam, lParam);
  1545. return 0;
  1546. case WM_SETFOCUS:
  1547. break;
  1548. case WM_INITMENU:
  1549. CancelGlobalDropDown();
  1550. break;
  1551. case WM_ACTIVATEAPP:
  1552. if (wParam && g_hwndActiveModal && g_hwndActiveModal != hwnd &&
  1553. !IsWindowEnabled(hwnd))
  1554. {
  1555. // $MODAL
  1556. // if we are getting activated, and are disabled then
  1557. // bring our 'active' window to the top
  1558. Assert (IsWindow(g_hwndActiveModal));
  1559. PostMessage(g_hwndActiveModal, WM_OE_ACTIVATETHREADWINDOW, 0, 0);
  1560. }
  1561. FrameActivatePopups(NULL != wParam);
  1562. break;
  1563. case WM_SYSCOMMAND:
  1564. // if we're minimizing, get the control with focus, as when we get the
  1565. // next WM_ACTIVATE we will already be minimized
  1566. if (wParam == SC_MINIMIZE)
  1567. m_hwndLastFocus = GetFocus();
  1568. break;
  1569. case WM_ACTIVATE:
  1570. if (LOWORD(wParam) == WA_INACTIVE)
  1571. {
  1572. if (!HIWORD(wParam))
  1573. {
  1574. // save the control with the focus don't do this is we're
  1575. // minimized, otherwise GetFocus()==m_hwnd
  1576. m_hwndLastFocus = GetFocus();
  1577. }
  1578. if (g_pConMan)
  1579. g_pConMan->OnActivate(FALSE);
  1580. FrameActivatePopups(FALSE);
  1581. }
  1582. else
  1583. {
  1584. HWND hwndFocus;
  1585. if (m_hwndLastFocus && IsWindow(m_hwndLastFocus) && IsChild(hwnd, m_hwndLastFocus))
  1586. SetFocus(m_hwndLastFocus);
  1587. else if (m_rgTBar[ITB_TREE].fShow && SUCCEEDED(m_rgTBar[ITB_TREE].ptbar->GetWindow(&hwndFocus)))
  1588. SetFocus(hwndFocus);
  1589. else if (m_hwndInner)
  1590. SetFocus(m_hwndInner);
  1591. if (g_pConMan && m_fPainted)
  1592. g_pConMan->OnActivate(TRUE);
  1593. FrameActivatePopups(FALSE);
  1594. }
  1595. if (m_pView)
  1596. {
  1597. // If the inner window is a message view, we need to hit it with
  1598. // a OnFrameWindowAcivate() so the preview pane get's updated
  1599. // correctly.
  1600. IMessageWindow *pWindow;
  1601. if (SUCCEEDED(m_pView->QueryInterface(IID_IMessageWindow, (LPVOID *) &pWindow)))
  1602. {
  1603. pWindow->OnFrameWindowActivate(LOWORD(wParam) != WA_INACTIVE);
  1604. pWindow->Release();
  1605. }
  1606. }
  1607. return 0;
  1608. case WM_ENDSESSION:
  1609. if (wParam)
  1610. {
  1611. DOUTL(2, "CBrowser::WM_ENDSESSION");
  1612. // g_fCheckOutboxOnShutdown = FALSE;
  1613. SendMessage(hwnd, WM_CLOSE, 0, 0L);
  1614. }
  1615. return 0;
  1616. case PUI_OFFICE_COMMAND:
  1617. if(wParam == PLUGUI_CMD_QUERY)
  1618. {
  1619. PLUGUI_QUERY pq;
  1620. pq.uQueryVal = 0; // initialize
  1621. pq.PlugUIInfo.uMajorVersion = OFFICE_VERSION_9; // Value filled in by Apps
  1622. pq.PlugUIInfo.uOleServer = FALSE; // Value filled in by Apps
  1623. return (pq.uQueryVal); // The state of the App
  1624. }
  1625. if(wParam != PLUGUI_CMD_SHUTDOWN)
  1626. return(0);
  1627. // for PLUGUI_CMD_SHUTDOWN fall to close application
  1628. CloseFinderTreads();
  1629. CloseThreadWindows(hwnd, GetCurrentThreadId());
  1630. case WM_CLOSE:
  1631. {
  1632. WINDOWPLACEMENT wp;
  1633. // WriteUnreadCount();
  1634. AcctUtil_FreeSendReceieveMenu(m_hMenu, m_cAcctMenu);
  1635. FreeNewAcctMenu(m_hMenu);
  1636. // Close any active RAS connections we brought up
  1637. if (g_pConMan)
  1638. {
  1639. // Release our notification for connection changes
  1640. g_pConMan->Unadvise(this);
  1641. }
  1642. if (g_pSpooler)
  1643. g_pSpooler->Advise(m_hwnd, FALSE);
  1644. if (m_pView)
  1645. {
  1646. FOLDERSETTINGS fs;
  1647. if (m_pViewCT)
  1648. {
  1649. m_pViewCT->Release();
  1650. m_pViewCT = NULL;
  1651. }
  1652. m_pView->SaveViewState();
  1653. m_pView->UIActivate(SVUIA_DEACTIVATE);
  1654. m_hwndInner = NULL;
  1655. m_pView->DestroyViewWindow();
  1656. m_pView->Release();
  1657. m_pView = NULL;
  1658. }
  1659. if (DwGetOption(OPT_PURGEWASTE))
  1660. EmptySpecialFolder(hwnd, FOLDER_DELETED);
  1661. // clean up the toolbars
  1662. for (i=0; i<ITB_MAX; i++)
  1663. {
  1664. if (m_rgTBar[i].ptbar)
  1665. ReleaseToolbarItem(i, TRUE);
  1666. }
  1667. // save browser settings
  1668. wp.length = sizeof(wp);
  1669. GetWindowPlacement(hwnd, &wp);
  1670. SetOption(OPT_BROWSERPOS, (LPVOID)&wp, sizeof(wp), NULL, 0);
  1671. if (m_idClearStatusTimer)
  1672. KillTimer(m_hwnd, m_idClearStatusTimer);
  1673. SaveLayoutSettings();
  1674. //Let the DocObj know that the browser is dying
  1675. if (m_pDocObj)
  1676. {
  1677. m_pDocObj->BrowserExiting();
  1678. }
  1679. // Unregister with Identity manager
  1680. if (m_dwIdentCookie != 0)
  1681. {
  1682. MU_UnregisterIdentityNotifier(m_dwIdentCookie);
  1683. m_dwIdentCookie = 0;
  1684. }
  1685. DestroyWindow(hwnd);
  1686. }
  1687. return 0;
  1688. case WM_NEW_MAIL:
  1689. Assert(0 == wParam);
  1690. Assert(0 == lParam);
  1691. // Add the tray icon
  1692. if (g_pInstance)
  1693. g_pInstance->UpdateTrayIcon(TRAYICONACTION_ADD);
  1694. // Play a sound
  1695. if (DwGetOption(OPT_NEWMAILSOUND) != 0)
  1696. {
  1697. if (!sndPlaySound((LPTSTR) s_szMailSndKey, SND_ASYNC | SND_NODEFAULT))
  1698. MessageBeep(MB_OK);
  1699. }
  1700. return 0;
  1701. case MVM_NOTIFYICONEVENT:
  1702. if (lParam == WM_LBUTTONDBLCLK)
  1703. {
  1704. if (IsIconic(m_hwnd))
  1705. ShowWindow(m_hwnd, SW_RESTORE);
  1706. SetForegroundWindow(m_hwnd);
  1707. }
  1708. return 0;
  1709. case MVM_SPOOLERDELIVERY:
  1710. SpoolerDeliver(wParam, lParam);
  1711. return 0;
  1712. case WM_TIMER:
  1713. if (wParam == TIMER_CLEAR_STATUS)
  1714. {
  1715. KillTimer(m_hwnd, m_idClearStatusTimer);
  1716. m_idClearStatusTimer = 0;
  1717. if (m_pStatus)
  1718. m_pStatus->SetSpoolerStatus(DELIVERY_NOTIFY_COMPLETE, 0);
  1719. }
  1720. return 0;
  1721. case WM_DESTROY:
  1722. {
  1723. #if 0
  1724. // We need to free our menu resource
  1725. HMENU hMenu = GetMenu(m_hwnd);
  1726. //SetMenu(m_hwnd, NULL);
  1727. DestroyMenu(hMenu);
  1728. #endif
  1729. RemoveProp(hwnd, c_szOETopLevel);
  1730. break;
  1731. }
  1732. }
  1733. return DefWindowProc(hwnd, msg, wParam, lParam);
  1734. }
  1735. //
  1736. // FUNCTION: CBrowser::OnCreate
  1737. //
  1738. // PURPOSE: Creates the child windows necessary for the view and
  1739. // initializes the data in those child windows.
  1740. //
  1741. // PARAMETERS:
  1742. // hwnd - Handle of the view being created.
  1743. // lpCreateStruct - Pointer to the creation params passed to
  1744. // CreateWindow().
  1745. //
  1746. // RETURN VALUE:
  1747. // Returns TRUE if the initialization is successful.
  1748. //
  1749. BOOL CBrowser::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
  1750. {
  1751. // Spooler comes first
  1752. g_fCheckOutboxOnShutdown = TRUE;
  1753. m_hwnd = hwnd;
  1754. // Set the title bar icon to the mailnews icon
  1755. UINT idRes = (g_dwAthenaMode & MODE_NEWSONLY) ? idiNewsGroup : idiMailNews;
  1756. m_hIcon = (HICON) LoadImage(g_hLocRes, MAKEINTRESOURCE(idRes), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
  1757. SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)m_hIcon);
  1758. m_hIconSm = (HICON) LoadImage(g_hLocRes, MAKEINTRESOURCE(idRes), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
  1759. SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)m_hIconSm);
  1760. SetProp(hwnd, c_szOETopLevel, (HANDLE)TRUE);
  1761. m_pStatus = new CStatusBar();
  1762. if (!m_pStatus)
  1763. goto error;
  1764. m_pStatus->Initialize(m_hwnd, 0);
  1765. m_pStatus->ShowStatus(m_rLayout.fStatusBar);
  1766. // Init the menu bar
  1767. m_hMenu = LoadMenu(g_hLocRes, MAKEINTRESOURCE(IDR_BROWSER_MENU));
  1768. MenuUtil_ReplaceHelpMenu(m_hMenu);
  1769. MenuUtil_ReplaceNewMsgMenus(m_hMenu);
  1770. MenuUtil_ReplaceMessengerMenus(m_hMenu);
  1771. // Register for connection changes
  1772. if (g_pConMan)
  1773. g_pConMan->Advise((IConnectionNotify *) this);
  1774. // Create all our toolbar windows
  1775. if (!_InitToolbars())
  1776. goto error;
  1777. // Initialize the folder bar
  1778. SetFolderType(NULL);
  1779. m_pFolderBar->Update(FALSE, TRUE);
  1780. // Post this so we can do post creation init
  1781. PostMessage(m_hwnd, CBM_POSTCREATE, 0, 0L);
  1782. return TRUE;
  1783. error:
  1784. return FALSE;
  1785. }
  1786. //
  1787. // FUNCTION: CBrowser::OnSize
  1788. //
  1789. // PURPOSE: Notification that the view window has been resized. In
  1790. // response we update the positions of our child windows and
  1791. // controls.
  1792. //
  1793. // PARAMETERS:
  1794. // hwnd - Handle of the view window being resized.
  1795. // state - Type of resizing requested.
  1796. // cxClient - New width of the client area.
  1797. // cyClient - New height of the client area.
  1798. //
  1799. void CBrowser::OnSize(HWND hwnd, UINT state, int cxClient, int cyClient)
  1800. {
  1801. if (state != SIZE_MINIMIZED)
  1802. {
  1803. if (m_pStatus)
  1804. m_pStatus->OnSize(cxClient, cyClient);
  1805. ResizeNextBorder(0);
  1806. }
  1807. }
  1808. HRESULT CBrowser::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  1809. {
  1810. ACCTTYPE type;
  1811. RULEID ridTag;
  1812. Assert(m_pTreeView != NULL);
  1813. if (S_OK == m_pTreeView->ForceSelectionChange())
  1814. {
  1815. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(id, codeNotify), (LPARAM)hwndCtl);
  1816. return(S_OK);
  1817. }
  1818. // Check to see if the command is even enabled
  1819. OLECMD cmd;
  1820. cmd.cmdID = id;
  1821. cmd.cmdf = 0;
  1822. HRESULT hr = QueryStatus(&CMDSETID_OutlookExpress, 1, &cmd, NULL);
  1823. if (FAILED(hr) || (0 == (cmd.cmdf & OLECMDF_ENABLED)))
  1824. return (OLECMDERR_E_DISABLED);
  1825. // Give the view first chance at any command so that it can override
  1826. // browser behavior.
  1827. VARIANTARG va;
  1828. va.vt = VT_I8;
  1829. va.ullVal = (ULONGLONG)hwndCtl;
  1830. // ATTENZIONE!
  1831. // the view gets it first because it might want to handle a command that the treeview normally
  1832. // handles. this is really only necessary for acct views where folders are displayed in the right
  1833. // pane, and folder-related commands should work on the selected folder and not the current
  1834. // treeview selection
  1835. // We should always allow the views to see the command list.
  1836. if (m_pViewCT && SUCCEEDED(hr = m_pViewCT->Exec(&CMDSETID_OutlookExpress, id, OLECMDEXECOPT_DODEFAULT, &va, NULL)))
  1837. return (S_OK);
  1838. // Infocolumn always get's a chance
  1839. if (m_pTreeView && SUCCEEDED(hr = m_pTreeView->Exec(NULL, id, OLECMDEXECOPT_DODEFAULT, NULL, NULL)))
  1840. return (S_OK);
  1841. // Infocolumn always get's a chance
  1842. if (m_pNavPane && SUCCEEDED(hr = m_pNavPane->Exec(NULL, id, OLECMDEXECOPT_DODEFAULT, NULL, NULL)))
  1843. return (S_OK);
  1844. // $REVIEW - Why should we route commands to a toolbar?
  1845. if (m_pCoolbar && (m_pCoolbar->OnCommand(hwnd, id, hwndCtl, codeNotify) == S_OK))
  1846. return S_OK;
  1847. if (Envelope_WMCommand(hwnd, id, (WORD) codeNotify)== S_OK)
  1848. return S_OK;
  1849. // Handle the extra help menu commands
  1850. if (id > ID_MSWEB_BASE && id < ID_MSWEB_LAST)
  1851. {
  1852. OnHelpGoto(m_hwnd, id);
  1853. return S_OK;
  1854. }
  1855. // Handle the Receive From... popup menu
  1856. if (id >= ID_ACCOUNT_FIRST && id <= ID_ACCOUNT_LAST)
  1857. {
  1858. Assert(g_pSpooler);
  1859. CmdSendReceieveAccount(id, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
  1860. return (S_OK);
  1861. }
  1862. if (id >= ID_NEW_ACCT_FIRST && id <= ID_NEW_ACCT_LAST)
  1863. {
  1864. HandleNewAcctMenu(m_hwnd, m_hMenu, id);
  1865. return(S_OK);
  1866. }
  1867. // Handle all "create new note" IDs
  1868. if (MenuUtil_HandleNewMessageIDs(id, m_hwnd, m_idSelected, m_ftSel != FOLDER_NEWS, FALSE, NULL))
  1869. return S_OK;
  1870. switch (id)
  1871. {
  1872. // File Menu
  1873. case ID_EXPORT_ADDRESS_BOOK:
  1874. case ID_IMPORT_ADDRESS_BOOK:
  1875. MailUtil_OnImportExportAddressBook(m_hwnd, id == ID_IMPORT_ADDRESS_BOOK);
  1876. break;
  1877. case ID_IMPORT_WAB:
  1878. ImportWAB(m_hwnd);
  1879. break;
  1880. case ID_IMPORT_MESSAGES:
  1881. DoImport(m_hwnd);
  1882. break;
  1883. case ID_IMPORT_MAIL_ACCOUNTS:
  1884. case ID_IMPORT_NEWS_ACCOUNTS:
  1885. DoAcctImport(m_hwnd, id == ID_IMPORT_MAIL_ACCOUNTS);
  1886. break;
  1887. case ID_EXPORT_MESSAGES:
  1888. DoExport(m_hwnd);
  1889. break;
  1890. case ID_IMPORT_RULES:
  1891. RuleUtil_HrImportRules(m_hwnd);
  1892. break;
  1893. case ID_EXPORT_RULES:
  1894. RuleUtil_HrExportRules(m_hwnd);
  1895. break;
  1896. case ID_NEW_IDENTITY:
  1897. MU_NewIdentity(m_hwnd);
  1898. break;
  1899. case ID_SWITCH_IDENTITY:
  1900. MU_Login(m_hwnd, TRUE, NULL);
  1901. break;
  1902. case ID_EXIT_LOGOFF:
  1903. case ID_LOGOFF_IDENTITY:
  1904. MU_Logoff(m_hwnd);
  1905. break;
  1906. case ID_MANAGE_IDENTITIES:
  1907. MU_ManageIdentities(m_hwnd);
  1908. break;
  1909. case ID_EXIT:
  1910. PostMessage(m_hwnd, WM_CLOSE, 0, 0L);
  1911. break;
  1912. case ID_WORK_OFFLINE:
  1913. if (g_pConMan)
  1914. {
  1915. g_pConMan->SetGlobalOffline(!g_pConMan->IsGlobalOffline(), hwnd);
  1916. UpdateToolbar();
  1917. }
  1918. break;
  1919. // Edit Menu
  1920. case ID_FIND_MESSAGE:
  1921. DoFindMsg(m_idSelected, FOLDER_LOCAL);
  1922. break;
  1923. case ID_FIND_PEOPLE:
  1924. {
  1925. TCHAR szWABExePath[MAX_PATH];
  1926. if(S_OK == HrLoadPathWABEXE(szWABExePath, sizeof(szWABExePath)))
  1927. ShellExecute(NULL, "open", szWABExePath, "/find", "", SW_SHOWNORMAL);
  1928. break;
  1929. }
  1930. // View Menu
  1931. case ID_LAYOUT:
  1932. {
  1933. LayoutProp_Create(m_hwnd, this, &m_rLayout);
  1934. break;
  1935. }
  1936. case ID_SHOW_TOOLBAR:
  1937. {
  1938. SetViewLayout(DISPID_MSGVIEW_TOOLBAR, LAYOUT_POS_NA, !m_rLayout.fToolbar, 0, 0);
  1939. break;
  1940. }
  1941. case ID_SHOW_FILTERBAR:
  1942. {
  1943. SetViewLayout(DISPID_MSGVIEW_FILTERBAR, LAYOUT_POS_NA, !m_rLayout.fFilterBar, 0, 0);
  1944. break;
  1945. }
  1946. // Go Menu
  1947. case ID_UP_ONE_LEVEL:
  1948. Assert(m_ftSel != FOLDER_ROOTNODE);
  1949. m_pTreeView->SelectParent();
  1950. break;
  1951. case ID_GO_FOLDER:
  1952. {
  1953. FOLDERID idFolder;
  1954. if (SUCCEEDED(SelectFolderDialog(m_hwnd, SFD_SELECTFOLDER, FOLDERID_ROOT, NOFLAGS, MAKEINTRESOURCE(idsGoToFolderTitle), MAKEINTRESOURCE(idsGoToFolderText), &idFolder)))
  1955. BrowseObject(idFolder, 0);
  1956. break;
  1957. }
  1958. case ID_GO_INBOX:
  1959. // special case this for newsonly mode
  1960. if (g_dwAthenaMode & MODE_NEWSONLY)
  1961. {
  1962. ShellUtil_RunClientRegCommand(m_hwnd, s_szMailClient);
  1963. }
  1964. else
  1965. // fall through
  1966. case ID_GO_OUTBOX:
  1967. case ID_GO_SENT_ITEMS:
  1968. case ID_GO_DRAFTS:
  1969. {
  1970. FOLDERID idStore;
  1971. FOLDERINFO Folder;
  1972. SPECIALFOLDER sf;
  1973. if (id == ID_GO_OUTBOX)
  1974. sf = FOLDER_OUTBOX;
  1975. else if (id == ID_GO_INBOX)
  1976. sf = FOLDER_INBOX;
  1977. else if (id == ID_GO_SENT_ITEMS)
  1978. sf = FOLDER_SENT;
  1979. else
  1980. sf = FOLDER_DRAFT;
  1981. if (FAILED(GetDefaultServerId(ACCT_MAIL, &idStore)))
  1982. idStore = FOLDERID_LOCAL_STORE;
  1983. if (SUCCEEDED(g_pStore->GetSpecialFolderInfo(idStore, sf, &Folder)))
  1984. {
  1985. BrowseObject(Folder.idFolder, SBSP_DEFBROWSER | SBSP_DEFMODE | SBSP_ABSOLUTE);
  1986. g_pStore->FreeRecord(&Folder);
  1987. }
  1988. else
  1989. {
  1990. // We might not have this special folder for this account. Try local.
  1991. if (SUCCEEDED(g_pStore->GetSpecialFolderInfo(FOLDERID_LOCAL_STORE, sf, &Folder)))
  1992. {
  1993. BrowseObject(Folder.idFolder, SBSP_DEFBROWSER | SBSP_DEFMODE | SBSP_ABSOLUTE);
  1994. g_pStore->FreeRecord(&Folder);
  1995. }
  1996. }
  1997. break;
  1998. }
  1999. case ID_GO_NEWS:
  2000. {
  2001. if (g_dwAthenaMode & MODE_MAILONLY)
  2002. {
  2003. ShellUtil_RunClientRegCommand(m_hwnd, s_szNewsClient);
  2004. }
  2005. else
  2006. {
  2007. FOLDERID idServer;
  2008. ProcessICW(m_hwnd, FOLDER_NEWS, TRUE);
  2009. if (SUCCEEDED(GetDefaultServerId(ACCT_NEWS, &idServer)))
  2010. {
  2011. BrowseObject(idServer, 0);
  2012. }
  2013. }
  2014. break;
  2015. }
  2016. case ID_GO_NETMEETING:
  2017. ShellUtil_RunClientRegCommand(m_hwnd, s_szCallClient);
  2018. break;
  2019. // Tools Menu
  2020. case ID_SEND_RECEIVE:
  2021. Assert(g_pSpooler);
  2022. if (!(g_dwAthenaMode & MODE_NEWSONLY))
  2023. {
  2024. if (g_pSpooler)
  2025. {
  2026. DWORD dwFlags = 0;
  2027. dwFlags = (!(g_dwAthenaMode & MODE_NEWSONLY)) ? DELIVER_NO_NEWSPOLL : 0;
  2028. g_pSpooler->StartDelivery(m_hwnd, NULL, FOLDERID_INVALID,
  2029. dwFlags | DELIVER_SEND | DELIVER_MAIL_RECV |
  2030. DELIVER_POLL | DELIVER_OFFLINE_FLAGS | DELIVER_SERVER_TYPE_ALL);
  2031. }
  2032. // $REVIEW - Can someone explain why it's here??? - steveser
  2033. // Tell currently selected folder to refresh itself
  2034. // if (NULL != m_pViewCT)
  2035. // m_pViewCT->Exec(NULL, ID_REFRESH, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
  2036. break;
  2037. }
  2038. //Fall through. In News only mode we want to do Send All even for Send & Receive All
  2039. case ID_SEND_ALL:
  2040. Assert(g_pSpooler);
  2041. if (g_pSpooler)
  2042. g_pSpooler->StartDelivery(m_hwnd, NULL, FOLDERID_INVALID,
  2043. DELIVER_SEND | DELIVER_NOSKIP | DELIVER_NEWS_TYPE | DELIVER_SMTP_TYPE | DELIVER_HTTP_TYPE);
  2044. break;
  2045. case ID_RECEIVE_ALL:
  2046. Assert(g_pSpooler);
  2047. if (g_pSpooler)
  2048. g_pSpooler->StartDelivery(m_hwnd, NULL, FOLDERID_INVALID,
  2049. DELIVER_MAIL_RECV | DELIVER_POLL | DELIVER_OFFLINE_FLAGS | DELIVER_IMAP_TYPE |
  2050. DELIVER_HTTP_TYPE);
  2051. break;
  2052. case ID_SYNCHRONIZE:
  2053. {
  2054. Assert(g_pSpooler);
  2055. if (g_pSpooler)
  2056. g_pSpooler->StartDelivery(m_hwnd, NULL, FOLDERID_INVALID, DELIVER_OFFLINE_SYNC | DELIVER_UPDATE_ALL);
  2057. /*
  2058. Bug# 60668
  2059. // Tell currently selected folder to refresh itself
  2060. if (NULL != m_pViewCT)
  2061. m_pViewCT->Exec(NULL, ID_REFRESH, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
  2062. */
  2063. break;
  2064. }
  2065. case ID_ADDRESS_BOOK:
  2066. {
  2067. CWab *pWab = NULL;
  2068. if (SUCCEEDED(HrCreateWabObject(&pWab)))
  2069. {
  2070. pWab->HrBrowse(m_hwnd);
  2071. pWab->Release();
  2072. }
  2073. else
  2074. {
  2075. AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsGeneralWabError),
  2076. NULL, MB_OK | MB_ICONEXCLAMATION);
  2077. }
  2078. break;
  2079. }
  2080. case ID_MESSAGE_RULES_MAIL:
  2081. case ID_MESSAGE_RULES_NEWS:
  2082. case ID_MESSAGE_RULES_JUNK:
  2083. case ID_MESSAGE_RULES_SENDERS:
  2084. {
  2085. DWORD dwFlags = 0;
  2086. switch (id)
  2087. {
  2088. case ID_MESSAGE_RULES_MAIL:
  2089. dwFlags = MRDF_MAIL;
  2090. break;
  2091. case ID_MESSAGE_RULES_NEWS:
  2092. dwFlags = MRDF_NEWS;
  2093. break;
  2094. case ID_MESSAGE_RULES_JUNK:
  2095. dwFlags = MRDF_JUNK;
  2096. break;
  2097. case ID_MESSAGE_RULES_SENDERS:
  2098. dwFlags = MRDF_SENDERS;
  2099. break;
  2100. default:
  2101. Assert(FALSE);
  2102. dwFlags = MRDF_MAIL;
  2103. break;
  2104. }
  2105. DoMessageRulesDialog(m_hwnd, dwFlags);
  2106. break;
  2107. }
  2108. case ID_OPTIONS:
  2109. ShowOptions(hwnd, ATHENA_OPTIONS, 0, this);
  2110. break;
  2111. case ID_ACCOUNTS:
  2112. {
  2113. if (m_ftSel == FOLDER_NEWS)
  2114. type = ACCT_NEWS;
  2115. else if (m_ftSel == FOLDER_IMAP || m_ftSel == FOLDER_LOCAL)
  2116. type = ACCT_MAIL;
  2117. else
  2118. type = ACCT_LAST;
  2119. DoAccountListDialog(m_hwnd, type);
  2120. break;
  2121. }
  2122. // HELP MENU COMMANDS
  2123. case ID_HELP_CONTENTS:
  2124. OEHtmlHelp(m_hwnd, c_szMailHelpFileHTML, HH_DISPLAY_TOPIC, (DWORD_PTR) (LPCSTR) c_szCtxHelpDefault);
  2125. break;
  2126. case ID_README:
  2127. DoReadme(m_hwnd);
  2128. break;
  2129. case ID_ABOUT:
  2130. DoAboutAthena(m_hwnd, m_ftSel == FOLDER_NEWS ? idiNews : idiMail);
  2131. break;
  2132. // Toolbar Buttons & Accelerators
  2133. case ID_FOLDER_LIST:
  2134. if (m_itbLastFocus == ITB_NAVPANE)
  2135. CycleFocus(FALSE);
  2136. SetViewLayout(DISPID_MSGVIEW_FOLDERLIST, LAYOUT_POS_NA, !m_rLayout.fFolderList, 0, 0);
  2137. if (m_pFolderBar)
  2138. m_pFolderBar->Update(FALSE, TRUE);
  2139. break;
  2140. case ID_CONTACTS_LIST:
  2141. if (m_itbLastFocus == ITB_NAVPANE)
  2142. CycleFocus(FALSE);
  2143. SetViewLayout(DISPID_MSGVIEW_CONTACTS, LAYOUT_POS_NA, !m_rLayout.fContacts, 0, 0);
  2144. break;
  2145. // $REVIEW - Do we still need this?
  2146. /*
  2147. case idmAccelNextCtl:
  2148. case idmAccelPrevCtl:
  2149. CycleFocus(id == idmAccelPrevCtl);
  2150. break;
  2151. */
  2152. case ID_DELETE_ACCEL:
  2153. case ID_DELETE_NO_TRASH_ACCEL:
  2154. return (CmdDeleteAccel(id, OLECMDEXECOPT_DODEFAULT, NULL, NULL));
  2155. //Msglist handles this command. But if our view is frontpage or account view, this is not handled by them.
  2156. //So we break here so we don't show NYI.
  2157. case ID_RESYNCHRONIZE:
  2158. break;
  2159. default:
  2160. #ifdef DEBUG
  2161. if (!hwndCtl || codeNotify == BN_CLICKED)
  2162. nyi(MAKEINTRESOURCE(idsNYIGeneral));
  2163. #endif
  2164. return E_NOTIMPL;
  2165. }
  2166. return S_OK;
  2167. }
  2168. #define MF_CHECKFLAGS(b) (MF_BYCOMMAND|(b ? MF_CHECKED : MF_UNCHECKED))
  2169. void CBrowser::OnInitMenuPopup(HWND hwnd, HMENU hmenuPopup, UINT uPos, BOOL fSystemMenu)
  2170. {
  2171. char sz[CCHMAX_STRINGRES], szT[CCHMAX_STRINGRES];
  2172. MENUITEMINFO mii;
  2173. UINT uIDPopup;
  2174. HMENU hMenuLang;
  2175. FOLDERINFO info;
  2176. HRESULT hr;
  2177. mii.cbSize = sizeof(MENUITEMINFO);
  2178. mii.fMask = MIIM_ID | MIIM_SUBMENU;
  2179. // make sure we recognize the popup as one of ours
  2180. if (m_hMenu == NULL || !GetMenuItemInfo(m_hMenu, uPos, TRUE, &mii) || mii.hSubMenu != hmenuPopup)
  2181. {
  2182. HMENU hMenuDrop = NULL;
  2183. int cItems = 0;
  2184. if (GetMenuItemInfo(m_hMenu, ID_POPUP_LANGUAGE_DEFERRED, FALSE, &mii) && mii.hSubMenu == hmenuPopup)
  2185. {
  2186. // MessageView will take care of creating language menu
  2187. // let's just fix menu ID
  2188. mii.fMask = MIIM_ID;
  2189. mii.wID = ID_POPUP_LANGUAGE;
  2190. SetMenuItemInfo(m_hMenu, ID_POPUP_LANGUAGE_DEFERRED, FALSE, &mii);
  2191. }
  2192. // Get the drop down menu
  2193. hMenuDrop = GetSubMenu(m_hMenu, uPos);
  2194. if (NULL == hMenuDrop)
  2195. {
  2196. goto exit;
  2197. }
  2198. // Get the number of items in the drop down menu
  2199. cItems = GetMenuItemCount(hMenuDrop);
  2200. if (-1 == cItems)
  2201. {
  2202. goto exit;
  2203. }
  2204. // Initialize the menu info
  2205. mii.cbSize = sizeof(MENUITEMINFO);
  2206. mii.fMask = MIIM_ID | MIIM_SUBMENU;
  2207. // Spin throught the submenus finding the correct menu id
  2208. for (cItems--; cItems >= 0; cItems--)
  2209. {
  2210. if (FALSE == GetMenuItemInfo(hMenuDrop, cItems, TRUE, &mii))
  2211. {
  2212. continue;
  2213. }
  2214. if (hmenuPopup == mii.hSubMenu)
  2215. {
  2216. break;
  2217. }
  2218. }
  2219. // Did we find anything?
  2220. if (cItems < 0)
  2221. {
  2222. goto exit;
  2223. }
  2224. }
  2225. uIDPopup = mii.wID;
  2226. switch (uIDPopup)
  2227. {
  2228. case ID_POPUP_FILE:
  2229. hr = g_pStore->GetFolderInfo(m_idSelected, &info);
  2230. if (SUCCEEDED(hr))
  2231. {
  2232. if (info.tyFolder == FOLDER_IMAP)
  2233. {
  2234. AthLoadString(idsShowFolderCmd, sz, ARRAYSIZE(sz));
  2235. ModifyMenu(hmenuPopup, ID_SUBSCRIBE, MF_BYCOMMAND | MF_STRING, ID_SUBSCRIBE, sz);
  2236. AthLoadString(idsHideFolderCmd, sz, ARRAYSIZE(sz));
  2237. ModifyMenu(hmenuPopup, ID_UNSUBSCRIBE, MF_BYCOMMAND | MF_STRING, ID_UNSUBSCRIBE, sz);
  2238. }
  2239. else
  2240. {
  2241. AthLoadString(idsSubscribeFolderCmd, sz, ARRAYSIZE(sz));
  2242. ModifyMenu(hmenuPopup, ID_SUBSCRIBE, MF_BYCOMMAND | MF_STRING, ID_SUBSCRIBE, sz);
  2243. AthLoadString(idsUnsubscribeFolderCmd, sz, ARRAYSIZE(sz));
  2244. ModifyMenu(hmenuPopup, ID_UNSUBSCRIBE, MF_BYCOMMAND | MF_STRING, ID_UNSUBSCRIBE, sz);
  2245. }
  2246. g_pStore->FreeRecord(&info);
  2247. }
  2248. MU_UpdateIdentityMenus(hmenuPopup);
  2249. if (m_fNoModifyAccts)
  2250. {
  2251. DeleteMenu(hmenuPopup, ID_IMPORT_MAIL_ACCOUNTS, MF_BYCOMMAND);
  2252. DeleteMenu(hmenuPopup, ID_IMPORT_NEWS_ACCOUNTS, MF_BYCOMMAND);
  2253. }
  2254. break;
  2255. case ID_POPUP_TOOLS:
  2256. {
  2257. DWORD dwHeaders;
  2258. // See if things were changed
  2259. if (m_fRebuildAccountMenu)
  2260. {
  2261. AcctUtil_FreeSendReceieveMenu(hmenuPopup, m_cAcctMenu);
  2262. }
  2263. // Get the submenu for Send & Receieve
  2264. if (m_fRebuildAccountMenu && GetMenuItemInfo(m_hMenu, ID_POPUP_SEND_AND_RECEIVE, FALSE, &mii))
  2265. {
  2266. AcctUtil_CreateSendReceieveMenu(mii.hSubMenu, &m_cAcctMenu);
  2267. m_fRebuildAccountMenu = FALSE;
  2268. }
  2269. if (!m_fInitNewAcctMenu)
  2270. {
  2271. InitNewAcctMenu(hmenuPopup);
  2272. m_fInitNewAcctMenu = TRUE;
  2273. }
  2274. // Figure out if the user has the "Download 300 headers" turned on
  2275. dwHeaders = DwGetOption(OPT_DOWNLOADCHUNKS);
  2276. if (OPTION_OFF != dwHeaders)
  2277. {
  2278. // Load a new menu string from the resources
  2279. AthLoadString(idsGetHeaderFmt, sz, ARRAYSIZE(sz));
  2280. // Format it
  2281. wnsprintf(szT, ARRAYSIZE(szT), sz, dwHeaders);
  2282. // Splat it on the menu
  2283. ModifyMenu(hmenuPopup, ID_GET_HEADERS, MF_BYCOMMAND | MF_STRING, ID_GET_HEADERS, szT);
  2284. }
  2285. else
  2286. {
  2287. // Load a new menu string from the resources
  2288. AthLoadString(idsGetNewHeaders, sz, ARRAYSIZE(sz));
  2289. // Splat it on the menu
  2290. ModifyMenu(hmenuPopup, ID_GET_HEADERS, MF_BYCOMMAND | MF_STRING, ID_GET_HEADERS, sz);
  2291. }
  2292. if (m_fNoModifyAccts)
  2293. {
  2294. DeleteMenu(hmenuPopup, ID_ACCOUNTS, MF_BYCOMMAND);
  2295. DeleteMenu(hmenuPopup, ID_POPUP_NEW_ACCT, MF_BYCOMMAND);
  2296. }
  2297. //Change Sync Folder to Sync Account or Sync NewsGroup depending on the folder selected
  2298. MENUITEMINFO mii = {0};
  2299. FOLDERINFO FolderInfo = {0};
  2300. int id;
  2301. TCHAR szMenuName[CCHMAX_STRINGRES] = {0};
  2302. if (g_pStore && SUCCEEDED(g_pStore->GetFolderInfo(m_idSelected, &FolderInfo)))
  2303. {
  2304. if (ISFLAGSET(FolderInfo.dwFlags, FOLDER_SERVER))
  2305. {
  2306. id = idsSynchronizeNowBtnTT;
  2307. }
  2308. else if(FolderInfo.tyFolder == FOLDER_NEWS)
  2309. {
  2310. id = idsDownloadNewsgroupTT;
  2311. }
  2312. else
  2313. id = idsSyncFolder;
  2314. LoadString(g_hLocRes, id, szMenuName, ARRAYSIZE(szMenuName));
  2315. mii.cbSize = sizeof(MENUITEMINFO);
  2316. mii.fMask = MIIM_TYPE;
  2317. mii.fType = MFT_STRING;
  2318. mii.dwTypeData = szMenuName;
  2319. SetMenuItemInfo(hmenuPopup, ID_SYNC_THIS_NOW, FALSE, &mii);
  2320. g_pStore->FreeRecord(&FolderInfo);
  2321. }
  2322. if (0 == (g_dwAthenaMode & MODE_JUNKMAIL))
  2323. DeleteMenu(hmenuPopup, ID_MESSAGE_RULES_JUNK, MF_BYCOMMAND);
  2324. break;
  2325. }
  2326. case ID_POPUP_MESSAGE:
  2327. {
  2328. AddStationeryMenu(hmenuPopup, ID_POPUP_NEW_MSG, ID_STATIONERY_RECENT_0, ID_STATIONERY_MORE);
  2329. if (!m_fEnvMenuInited && DwGetOption(OPT_SHOW_ENVELOPES))
  2330. {
  2331. Envelope_AddHostMenu(hmenuPopup, 2);
  2332. m_fEnvMenuInited=TRUE;
  2333. }
  2334. break;
  2335. }
  2336. }
  2337. // let the view handle it last so that it can override any browser init if necessary
  2338. if (m_pView)
  2339. {
  2340. m_pView->OnPopupMenu(m_hMenu, hmenuPopup, uIDPopup);
  2341. if(uIDPopup == ID_POPUP_LANGUAGE) // It was destroyed
  2342. hmenuPopup = m_hMenuLanguage;
  2343. }
  2344. // now enable/disable the items
  2345. MenuUtil_EnablePopupMenu(hmenuPopup, this);
  2346. exit:
  2347. return;
  2348. }
  2349. inline void CBrowser::_AppendIdentityName(LPCTSTR pszIdentityName, LPSTR pszName, DWORD cchName)
  2350. {
  2351. /*
  2352. if (((g_dwAthenaMode & MODE_OUTLOOKNEWS) != MODE_OUTLOOKNEWS) && pszIdentityName && *pszIdentityName)
  2353. {
  2354. */
  2355. if (pszIdentityName && *pszIdentityName)
  2356. {
  2357. StrCatBuff(pszName, c_szSpaceDashSpace, cchName);
  2358. StrCatBuff(pszName, pszIdentityName, cchName);
  2359. }
  2360. /*
  2361. }
  2362. */
  2363. }
  2364. void CBrowser::SetFolderType(FOLDERID idFolder)
  2365. {
  2366. int iIcon;
  2367. LPSTR pszName=NULL;
  2368. LPCSTR pszIdentityName=NULL;
  2369. HICON hIconOld, hIcon;
  2370. FOLDERTYPE ftNew;
  2371. int cch;
  2372. DWORD type, cb, dwLen;
  2373. FOLDERINFO Folder;
  2374. FOLDERINFO SvrFolderInfo = {0};
  2375. IImnAccount *pAccount = NULL;
  2376. DWORD dwShow = 0;
  2377. CHAR szAccountId[CCHMAX_ACCOUNT_NAME];
  2378. HRESULT hr = S_OK;
  2379. BOOL fHideHotMail = FALSE;
  2380. if (*m_szName == 0)
  2381. {
  2382. // TODO: it seems like the window title should a global setting not per user
  2383. cb = sizeof(m_szName);
  2384. if (ERROR_SUCCESS != AthUserGetValue(NULL, c_szWindowTitle, &type, (LPBYTE)m_szName, &cb) ||
  2385. FIsEmpty(m_szName))
  2386. {
  2387. if ((g_dwAthenaMode & MODE_OUTLOOKNEWS) == MODE_OUTLOOKNEWS)
  2388. {
  2389. LoadString(g_hLocRes, idsMSOutlookNewsReader, m_szName, ARRAYSIZE(m_szName));
  2390. }
  2391. else
  2392. {
  2393. LoadString(g_hLocRes, idsAthena, m_szName, ARRAYSIZE(m_szName));
  2394. }
  2395. }
  2396. Assert(*m_szName != 0);
  2397. }
  2398. pszIdentityName = MU_GetCurrentIdentityName();
  2399. if (FOLDERID_ROOT != idFolder && SUCCEEDED(g_pStore->GetFolderInfo(idFolder, &Folder)))
  2400. {
  2401. iIcon = GetFolderIcon(&Folder);
  2402. ftNew = Folder.tyFolder;
  2403. dwLen = lstrlen(Folder.pszName) + lstrlen(m_szName) + lstrlen(c_szSpaceDashSpace) + 1;
  2404. if (*pszIdentityName)
  2405. dwLen += (lstrlen(pszIdentityName) + lstrlen(c_szSpaceDashSpace));
  2406. //Its better to allocate a few extra bytes now than having to reallocate later depending on the outnews switch.
  2407. //This memory gets freed before exiting the function
  2408. if (MemAlloc((LPVOID *)&pszName, dwLen))
  2409. {
  2410. StrCpyN(pszName, Folder.pszName, dwLen);
  2411. StrCatBuff(pszName, c_szSpaceDashSpace, dwLen);
  2412. StrCatBuff(pszName, m_szName, dwLen);
  2413. _AppendIdentityName(pszIdentityName, pszName, dwLen);
  2414. }
  2415. g_pStore->FreeRecord(&Folder);
  2416. }
  2417. else
  2418. {
  2419. iIcon = iMailNews;
  2420. ftNew = FOLDER_ROOTNODE;
  2421. if (*pszIdentityName)
  2422. {
  2423. dwLen = lstrlen(m_szName) + 1;
  2424. if (*pszIdentityName)
  2425. dwLen += lstrlen(pszIdentityName) + lstrlen(c_szSpaceDashSpace);
  2426. if (MemAlloc((LPVOID *)&pszName, dwLen))
  2427. {
  2428. StrCpyN(pszName, m_szName, dwLen);
  2429. _AppendIdentityName(pszIdentityName, pszName, dwLen);
  2430. }
  2431. }
  2432. else
  2433. pszName = PszDupA(m_szName);
  2434. }
  2435. SetWindowText(m_hwnd, pszName?pszName:m_szName);
  2436. // Update the folder bar
  2437. if (m_pFolderBar)
  2438. m_pFolderBar->SetCurrentFolder(idFolder);
  2439. // Update of Adv Bar
  2440. if (m_pAdBar) // Say that for Hotmail we have Ad bar always
  2441. {
  2442. if (FOLDER_HTTPMAIL == ftNew)
  2443. {
  2444. //At startup too if the cached state is to show the URL, then just show the toolbar with whatever it is loaded with
  2445. // Get the server for this folder
  2446. IF_FAILEXIT(hr = GetFolderServer(idFolder, &SvrFolderInfo));
  2447. // Get the account ID for the server
  2448. *szAccountId = 0;
  2449. IF_FAILEXIT(hr = GetFolderAccountId(&SvrFolderInfo, szAccountId, ARRAYSIZE(szAccountId)));
  2450. // Get the account interface
  2451. IF_FAILEXIT(hr = g_pAcctMan->FindAccount(AP_ACCOUNT_ID, szAccountId, &pAccount));
  2452. IF_FAILEXIT(hr = pAccount->GetPropDw(AP_HTTPMAIL_DOMAIN_MSN, &dwShow));
  2453. if(dwShow)
  2454. {
  2455. if(!HideHotmail())
  2456. {
  2457. IF_FAILEXIT(hr = pAccount->GetPropDw(AP_HTTPMAIL_SHOW_ADBAR, &dwShow));
  2458. ShowToolbar((IDockingWindow*)m_pAdBar, !!dwShow);
  2459. }
  2460. else
  2461. fHideHotMail = TRUE;
  2462. }
  2463. }
  2464. else
  2465. ShowToolbar((IDockingWindow*)m_pAdBar, FALSE);
  2466. }
  2467. // update the coolbar and menus if we're changing folder type
  2468. if (m_ftSel != ftNew)
  2469. {
  2470. m_ftSel = ftNew;
  2471. _ResetMenu(ftNew, fHideHotMail);
  2472. m_pCoolbar->SetFolderType(ftNew);
  2473. }
  2474. if (m_pBodyBar)
  2475. ShowToolbar((IDockingWindow*)m_pBodyBar,
  2476. m_rLayout.fInfoPaneEnabled && m_rLayout.fInfoPane && (m_ftSel != FOLDER_HTTPMAIL));
  2477. exit:
  2478. SafeMemFree(pszName);
  2479. g_pStore->FreeRecord(&SvrFolderInfo);
  2480. ReleaseObj(pAccount);
  2481. }
  2482. void CBrowser::_ResetMenu(FOLDERTYPE ftNew, BOOL fHideHotMail)
  2483. {
  2484. HMENU hMenu, hMenuT;
  2485. MENUITEMINFO mii;
  2486. BOOL fNews;
  2487. DWORD cServers;
  2488. IImnEnumAccounts *pEnum;
  2489. if (m_hMenuLanguage)
  2490. {
  2491. DeinitMultiLanguage();
  2492. if (IsMenu(m_hMenuLanguage))
  2493. DestroyMenu(m_hMenuLanguage);
  2494. m_hMenuLanguage = NULL;
  2495. }
  2496. // load the new menu for the view
  2497. SideAssert(hMenu = LoadMenu(g_hLocRes, MAKEINTRESOURCE(IDR_BROWSER_MENU)));
  2498. MenuUtil_ReplaceNewMsgMenus(hMenu);
  2499. MenuUtil_ReplaceHelpMenu(hMenu);
  2500. MenuUtil_ReplaceMessengerMenus(hMenu);
  2501. mii.cbSize = sizeof(MENUITEMINFO);
  2502. mii.fMask = MIIM_SUBMENU;
  2503. if ((g_dwHideMessenger == BL_HIDE) || (g_dwHideMessenger == BL_DISABLE))
  2504. {
  2505. // get the file popup
  2506. SideAssert(GetMenuItemInfo(hMenu, ID_POPUP_FILE, FALSE, &mii));
  2507. DeleteMenu(mii.hSubMenu, ID_SEND_INSTANT_MESSAGE, MF_BYCOMMAND);
  2508. }
  2509. if ((ftNew != FOLDER_NEWS) && (ftNew != FOLDER_IMAP))
  2510. {
  2511. // get the edit popup
  2512. SideAssert(GetMenuItemInfo(hMenu, ID_POPUP_EDIT, FALSE, &mii));
  2513. if (ftNew != FOLDER_NEWS)
  2514. DeleteMenu(mii.hSubMenu, ID_CATCH_UP, MF_BYCOMMAND);
  2515. if (ftNew != FOLDER_IMAP)
  2516. {
  2517. DeleteMenu(mii.hSubMenu, ID_UNDELETE, MF_BYCOMMAND);
  2518. DeleteMenu(mii.hSubMenu, ID_PURGE_DELETED, MF_BYCOMMAND);
  2519. }
  2520. }
  2521. if (ftNew != FOLDER_NEWS)
  2522. {
  2523. g_pAcctMan->GetAccountCount(ACCT_NEWS, &cServers);
  2524. fNews = (cServers > 0);
  2525. // get the message popup
  2526. SideAssert(GetMenuItemInfo(hMenu, ID_POPUP_MESSAGE, FALSE, &mii));
  2527. DeleteMenu(mii.hSubMenu, ID_UNSCRAMBLE, MF_BYCOMMAND);
  2528. DeleteMenu(mii.hSubMenu, ID_CANCEL_MESSAGE, MF_BYCOMMAND);
  2529. if (!fNews)
  2530. DeleteMenu(mii.hSubMenu, ID_REPLY_GROUP, MF_BYCOMMAND);
  2531. }
  2532. else
  2533. {
  2534. fNews = TRUE;
  2535. }
  2536. // get the tools popup
  2537. SideAssert(GetMenuItemInfo(hMenu, ID_POPUP_TOOLS, FALSE, &mii));
  2538. if (ftNew != FOLDER_NEWS)
  2539. {
  2540. DeleteMenu(mii.hSubMenu, ID_GET_HEADERS, MF_BYCOMMAND);
  2541. if (!fNews)
  2542. DeleteMenu(mii.hSubMenu, ID_NEWSGROUPS, MF_BYCOMMAND);
  2543. }
  2544. if ((ftNew == FOLDER_LOCAL) || fHideHotMail)
  2545. {
  2546. DeleteMenu(mii.hSubMenu, ID_POPUP_RETRIEVE, MF_BYCOMMAND);
  2547. DeleteMenu(mii.hSubMenu, ID_SYNC_THIS_NOW, MF_BYCOMMAND);
  2548. }
  2549. if (ftNew != FOLDER_IMAP)
  2550. {
  2551. cServers = 0;
  2552. if (S_OK == g_pAcctMan->Enumerate(SRV_IMAP, &pEnum))
  2553. {
  2554. pEnum->GetCount(&cServers);
  2555. pEnum->Release();
  2556. }
  2557. if (cServers == 0)
  2558. {
  2559. DeleteMenu(mii.hSubMenu, ID_IMAP_FOLDERS, MF_BYCOMMAND);
  2560. if (!fNews)
  2561. DeleteMenu(mii.hSubMenu, SEP_SUBSCRIBE, MF_BYCOMMAND);
  2562. }
  2563. }
  2564. if ((g_dwHideMessenger == BL_HIDE) || (g_dwHideMessenger == BL_DISABLE))
  2565. {
  2566. DeleteMenu(mii.hSubMenu, SEP_MESSENGER, MF_BYCOMMAND);
  2567. DeleteMenu(mii.hSubMenu, ID_POPUP_MESSENGER, MF_BYCOMMAND);
  2568. DeleteMenu(mii.hSubMenu, ID_POPUP_MESSENGER_STATUS, MF_BYCOMMAND);
  2569. }
  2570. m_pCoolbar->ResetMenu(hMenu);
  2571. if (m_hMenu != NULL)
  2572. {
  2573. if (IsMenu(m_hMenu))
  2574. {
  2575. AcctUtil_FreeSendReceieveMenu(m_hMenu, m_cAcctMenu);
  2576. m_cAcctMenu = 0;
  2577. m_fRebuildAccountMenu = TRUE;
  2578. FreeNewAcctMenu(m_hMenu);
  2579. m_fInitNewAcctMenu = FALSE;
  2580. DestroyMenu(m_hMenu);
  2581. }
  2582. }
  2583. m_hMenu = hMenu;
  2584. }
  2585. void CBrowser::SpoolerDeliver(WPARAM wParam, LPARAM lParam)
  2586. {
  2587. HWND hwndCoolbar = 0;
  2588. char szRes[256], sz[256];
  2589. LPSTR pszRes = 0;
  2590. static BOOL s_fWarnings=FALSE;
  2591. static ULONG s_cMsgs=0;
  2592. if (wParam != DELIVERY_NOTIFY_ALLDONE)
  2593. m_pStatus->SetSpoolerStatus((DELIVERYNOTIFYTYPE) wParam, 0);
  2594. switch (wParam)
  2595. {
  2596. case DELIVERY_NOTIFY_STARTING:
  2597. s_cMsgs = 0;
  2598. s_fWarnings = FALSE;
  2599. break;
  2600. case DELIVERY_NOTIFY_CONNECTING:
  2601. if (m_pCoolbar)
  2602. m_pCoolbar->Invoke(idDownloadBegin, 0);
  2603. if (m_idClearStatusTimer)
  2604. {
  2605. KillTimer(m_hwnd, m_idClearStatusTimer);
  2606. m_idClearStatusTimer = 0;
  2607. }
  2608. if (m_pCoolbar)
  2609. m_pCoolbar->GetWindow(&hwndCoolbar);
  2610. break;
  2611. case DELIVERY_NOTIFY_RESULT:
  2612. if (EVENT_FAILED == lParam || EVENT_WARNINGS == lParam)
  2613. s_fWarnings = TRUE;
  2614. break;
  2615. case DELIVERY_NOTIFY_COMPLETE:
  2616. s_cMsgs += (ULONG) lParam;
  2617. break;
  2618. case DELIVERY_NOTIFY_ALLDONE:
  2619. // Stop coolbar animation
  2620. if (m_pCoolbar)
  2621. m_pCoolbar->Invoke(idDownloadEnd, 0);
  2622. if (s_cMsgs && IsWindow(m_hwnd))
  2623. {
  2624. PostMessage(m_hwnd, WM_NEW_MAIL, 0, 0);
  2625. }
  2626. // Show the Warnings Icon
  2627. if (s_fWarnings)
  2628. {
  2629. m_pStatus->SetSpoolerStatus((DELIVERYNOTIFYTYPE) wParam, -1);
  2630. }
  2631. else
  2632. {
  2633. m_pStatus->SetSpoolerStatus((DELIVERYNOTIFYTYPE) wParam, s_cMsgs);
  2634. // Clear the Timer
  2635. m_idClearStatusTimer = SetTimer(m_hwnd, TIMER_CLEAR_STATUS, TIME_TO_CLEAR_NEWMSGSTATUS, NULL);
  2636. }
  2637. break;
  2638. }
  2639. }
  2640. HRESULT CBrowser::CycleFocus(BOOL fReverse)
  2641. {
  2642. DWORD dwFlags;
  2643. BOOL bLast;
  2644. HWND hwndFocus = GetFocus();
  2645. HWND hwndNext;
  2646. if (IsWindowVisible(hwndFocus))
  2647. {
  2648. hwndNext = GetNextDlgTabItem(m_hwnd, hwndFocus, fReverse);
  2649. }
  2650. else
  2651. {
  2652. hwndNext = GetNextDlgTabItem(m_hwnd, NULL, fReverse);
  2653. }
  2654. SetFocus(hwndNext);
  2655. if (hwndNext == m_hwndInner || IsChild(m_hwndInner, hwndNext))
  2656. m_itbLastFocus = ITB_OEVIEW;
  2657. else
  2658. m_itbLastFocus = ITB_NAVPANE;
  2659. return (S_OK);
  2660. }
  2661. void CBrowser::FrameActivatePopups(BOOL fActivate)
  2662. {
  2663. HWND hwndDropDown = HwndGlobalDropDown();
  2664. if (!fActivate && hwndDropDown)
  2665. SendMessage(hwndDropDown, WMR_CLICKOUTSIDE, CLK_OUT_DEACTIVATE, 0);
  2666. }
  2667. void CBrowser::UpdateStatusBar(void)
  2668. {
  2669. if (g_pConMan && m_pStatus)
  2670. {
  2671. if (g_pConMan->IsGlobalOffline())
  2672. {
  2673. m_pStatus->SetConnectedStatus(CONN_STATUS_WORKOFFLINE);
  2674. }
  2675. else
  2676. {
  2677. m_pStatus->SetConnectedStatus(CONN_STATUS_CONNECTED);
  2678. }
  2679. }
  2680. }
  2681. /////////////////////////////////////////////////////////////////////////////
  2682. // Support for drop-down treeview. Trust me, this is necessary no matter
  2683. // how gross it is.
  2684. // currently active global drop down (if any)
  2685. static HWND s_hwndDropDown = NULL;
  2686. void RegisterGlobalDropDown(HWND hwndCtrl)
  2687. {
  2688. Assert(s_hwndDropDown == 0);
  2689. s_hwndDropDown = hwndCtrl;
  2690. }
  2691. void UnregisterGlobalDropDown(HWND hwndCtrl)
  2692. {
  2693. if (s_hwndDropDown == hwndCtrl)
  2694. s_hwndDropDown = 0;
  2695. }
  2696. void CancelGlobalDropDown()
  2697. {
  2698. if (s_hwndDropDown)
  2699. SendMessage(s_hwndDropDown, WMR_CLICKOUTSIDE, 0, 0);
  2700. }
  2701. HWND HwndGlobalDropDown()
  2702. {
  2703. return s_hwndDropDown;
  2704. }
  2705. BOOL ModifyLocalFolderMenu(HMENU hMenu)
  2706. {
  2707. MENUITEMINFO mii;
  2708. TCHAR szRes[CCHMAX_STRINGRES];
  2709. if (g_dwAthenaMode & MODE_NEWSONLY)
  2710. {
  2711. // File menu
  2712. DeleteMenu(hMenu, ID_IMPORT_MESSAGES, MF_BYCOMMAND);
  2713. DeleteMenu(hMenu, ID_IMPORT_MAIL_ACCOUNTS, MF_BYCOMMAND);
  2714. DeleteMenu(hMenu, ID_EXPORT_MESSAGES, MF_BYCOMMAND);
  2715. // Tools
  2716. ZeroMemory(&mii, sizeof(MENUITEMINFO));
  2717. mii.cbSize = sizeof(MENUITEMINFO);
  2718. mii.fMask = MIIM_SUBMENU;
  2719. if (GetMenuItemInfo(hMenu, ID_POPUP_TOOLS, FALSE, &mii))
  2720. {
  2721. // Remove Send & Receive and Message Rules
  2722. DeleteMenu(mii.hSubMenu, ID_SEND_RECEIVE, MF_BYCOMMAND);
  2723. }
  2724. }
  2725. return (TRUE);
  2726. }
  2727. BOOL ModifyRootFolderMenu(HMENU hMenu)
  2728. {
  2729. if (g_dwAthenaMode & MODE_NEWSONLY)
  2730. {
  2731. // File menu
  2732. DeleteMenu(hMenu, ID_IMPORT_MESSAGES, MF_BYCOMMAND);
  2733. DeleteMenu(hMenu, ID_IMPORT_MAIL_ACCOUNTS, MF_BYCOMMAND);
  2734. DeleteMenu(hMenu, ID_EXPORT_MESSAGES, MF_BYCOMMAND);
  2735. // Tools
  2736. DeleteMenu(hMenu, ID_SEND_RECEIVE, MF_BYCOMMAND);
  2737. }
  2738. return (TRUE);
  2739. }
  2740. HRESULT CBrowser::GetViewLayout(DWORD opt, LAYOUTPOS *pPos, BOOL *pfVisible, DWORD *pdwFlags, DWORD *pdwSize)
  2741. {
  2742. HRESULT hr = E_FAIL;
  2743. switch (opt)
  2744. {
  2745. case DISPID_MSGVIEW_TOOLBAR:
  2746. {
  2747. if (pfVisible)
  2748. *pfVisible = m_rgTBar[ITB_COOLBAR].fShow;
  2749. if (pdwFlags)
  2750. *pdwFlags = 0;
  2751. hr = S_OK;
  2752. break;
  2753. }
  2754. case DISPID_MSGVIEW_STATUSBAR:
  2755. {
  2756. if (pfVisible)
  2757. *pfVisible = m_rLayout.fStatusBar;
  2758. if (pPos)
  2759. *pPos = LAYOUT_POS_NA;
  2760. if (pdwFlags)
  2761. *pdwFlags = 0;
  2762. hr = S_OK;
  2763. break;
  2764. }
  2765. case DISPID_MSGVIEW_FOLDERBAR:
  2766. {
  2767. if (pfVisible)
  2768. *pfVisible = m_rgTBar[ITB_COOLBAR].fShow;
  2769. if (pPos)
  2770. *pPos = LAYOUT_POS_NA;
  2771. if (pdwFlags)
  2772. *pdwFlags = 0;
  2773. hr = S_OK;
  2774. break;
  2775. }
  2776. case DISPID_MSGVIEW_FOLDERLIST:
  2777. {
  2778. if (pfVisible)
  2779. *pfVisible = m_rLayout.fFolderList;
  2780. if (pPos)
  2781. *pPos = LAYOUT_POS_NA;
  2782. if (pdwFlags)
  2783. *pdwFlags = 0;
  2784. hr = S_OK;
  2785. break;
  2786. }
  2787. case DISPID_MSGVIEW_TIPOFTHEDAY:
  2788. {
  2789. if (pfVisible)
  2790. *pfVisible = m_rLayout.fTipOfTheDay;
  2791. if (pPos)
  2792. *pPos = LAYOUT_POS_NA;
  2793. if (pdwFlags)
  2794. *pdwFlags = 0;
  2795. hr = S_OK;
  2796. break;
  2797. }
  2798. case DISPID_MSGVIEW_INFOPANE:
  2799. {
  2800. if (pfVisible)
  2801. *pfVisible = m_rLayout.fInfoPane;
  2802. if (pPos)
  2803. *pPos = LAYOUT_POS_NA;
  2804. if (pdwFlags)
  2805. *pdwFlags = 0;
  2806. hr = S_OK;
  2807. break;
  2808. }
  2809. case DISPID_MSGVIEW_OUTLOOK_BAR:
  2810. {
  2811. if (pfVisible)
  2812. *pfVisible = m_rLayout.fOutlookBar;
  2813. if (pPos)
  2814. *pPos = LAYOUT_POS_NA;
  2815. if (pdwFlags)
  2816. *pdwFlags = 0;
  2817. hr = S_OK;
  2818. break;
  2819. }
  2820. case DISPID_MSGVIEW_CONTACTS:
  2821. {
  2822. if (pfVisible)
  2823. *pfVisible = m_rLayout.fContacts;
  2824. if (pPos)
  2825. *pPos = LAYOUT_POS_NA;
  2826. if (pdwFlags)
  2827. *pdwFlags = 0;
  2828. hr = S_OK;
  2829. break;
  2830. }
  2831. case DISPID_MSGVIEW_PREVIEWPANE_NEWS:
  2832. {
  2833. if (pfVisible)
  2834. *pfVisible = m_rLayout.fNewsPreviewPane;
  2835. if (pPos)
  2836. *pPos = m_rLayout.fNewsSplitVertically ? LAYOUT_POS_LEFT : LAYOUT_POS_BOTTOM ;
  2837. if (pdwFlags)
  2838. *pdwFlags = m_rLayout.fNewsPreviewPaneHeader;
  2839. if (pdwSize)
  2840. {
  2841. if (0 == m_rLayout.bNewsSplitHorzPct)
  2842. m_rLayout.bNewsSplitHorzPct = 50;
  2843. if (0 == m_rLayout.bNewsSplitVertPct)
  2844. m_rLayout.bNewsSplitVertPct = 50;
  2845. *pdwSize = MAKELONG((WORD) m_rLayout.bNewsSplitHorzPct, (WORD) m_rLayout.bNewsSplitVertPct);
  2846. }
  2847. hr = S_OK;
  2848. break;
  2849. }
  2850. case DISPID_MSGVIEW_PREVIEWPANE_MAIL:
  2851. {
  2852. if (pfVisible)
  2853. *pfVisible = m_rLayout.fMailPreviewPane;
  2854. if (pPos)
  2855. *pPos = m_rLayout.fMailSplitVertically ? LAYOUT_POS_LEFT : LAYOUT_POS_BOTTOM ;
  2856. if (pdwFlags)
  2857. *pdwFlags = m_rLayout.fMailPreviewPaneHeader;
  2858. if (pdwSize)
  2859. {
  2860. if (0 == m_rLayout.bMailSplitHorzPct)
  2861. m_rLayout.bMailSplitHorzPct = 50;
  2862. if (0 == m_rLayout.bMailSplitVertPct)
  2863. m_rLayout.bMailSplitVertPct = 50;
  2864. *pdwSize = MAKELONG((WORD) m_rLayout.bMailSplitHorzPct, (WORD) m_rLayout.bMailSplitVertPct);
  2865. }
  2866. hr = S_OK;
  2867. break;
  2868. }
  2869. default:
  2870. AssertSz(0, "CBrowser::GetViewLayout() - Called with an unrecognized layout option.");
  2871. }
  2872. return (hr);
  2873. }
  2874. HRESULT CBrowser::SetViewLayout(DWORD opt, LAYOUTPOS pos, BOOL fVisible, DWORD dwFlags, DWORD dwSize)
  2875. {
  2876. HRESULT hr = E_FAIL;
  2877. switch (opt)
  2878. {
  2879. case DISPID_MSGVIEW_TOOLBAR:
  2880. {
  2881. m_rLayout.fToolbar = !!fVisible;
  2882. // This can be called before the windows are created. If so, we
  2883. // store the setting and will use it later.
  2884. if (m_pCoolbar)
  2885. {
  2886. m_pCoolbar->HideToolbar(!m_rLayout.fToolbar);
  2887. }
  2888. hr = S_OK;
  2889. break;
  2890. }
  2891. case DISPID_MSGVIEW_FILTERBAR:
  2892. {
  2893. m_rLayout.fFilterBar = !!fVisible;
  2894. if (m_pCoolbar)
  2895. m_pCoolbar->HideToolbar(!m_rLayout.fFilterBar, CBTYPE_RULESTOOLBAR);
  2896. hr = S_OK;
  2897. break;
  2898. }
  2899. case DISPID_MSGVIEW_STATUSBAR:
  2900. {
  2901. m_rLayout.fStatusBar = !!fVisible;
  2902. if (m_pStatus)
  2903. {
  2904. m_pStatus->ShowStatus(m_rLayout.fStatusBar);
  2905. ResizeNextBorder(0);
  2906. }
  2907. hr = S_OK;
  2908. break;
  2909. }
  2910. case DISPID_MSGVIEW_FOLDERBAR:
  2911. {
  2912. m_rLayout.fFolderBar = fVisible;
  2913. if (m_pFolderBar)
  2914. ShowToolbar((IUnknown *) (IDockingWindow *) m_pFolderBar, fVisible);
  2915. hr = S_OK;
  2916. break;
  2917. }
  2918. case DISPID_MSGVIEW_FOLDERLIST:
  2919. {
  2920. m_rLayout.fFolderList = fVisible;
  2921. if (m_pNavPane)
  2922. {
  2923. m_pNavPane->ShowFolderList(fVisible);
  2924. m_pFolderBar->Update(FALSE, TRUE);
  2925. }
  2926. UpdateToolbar();
  2927. hr = S_OK;
  2928. break;
  2929. }
  2930. case DISPID_MSGVIEW_TIPOFTHEDAY:
  2931. {
  2932. m_rLayout.fTipOfTheDay = fVisible;
  2933. if (m_hwndInner)
  2934. SendMessage(m_hwndInner, WM_UPDATELAYOUT, 0, 0);
  2935. hr = S_OK;
  2936. break;
  2937. }
  2938. case DISPID_MSGVIEW_INFOPANE:
  2939. {
  2940. m_rLayout.fInfoPane = fVisible;
  2941. if (m_pBodyBar)
  2942. ShowToolbar((IUnknown *) (IDockingWindow *) m_pBodyBar, fVisible);
  2943. hr = S_OK;
  2944. break;
  2945. }
  2946. case DISPID_MSGVIEW_OUTLOOK_BAR:
  2947. {
  2948. m_rLayout.fOutlookBar = fVisible;
  2949. if (m_pOutBar)
  2950. ShowToolbar((IUnknown *) (IDockingWindow *) m_pOutBar, fVisible);
  2951. hr = S_OK;
  2952. break;
  2953. }
  2954. case DISPID_MSGVIEW_CONTACTS:
  2955. {
  2956. m_rLayout.fContacts = fVisible;
  2957. if (m_pNavPane)
  2958. {
  2959. m_pNavPane->ShowContacts(fVisible);
  2960. }
  2961. UpdateToolbar();
  2962. hr = S_OK;
  2963. break;
  2964. }
  2965. case DISPID_MSGVIEW_PREVIEWPANE_NEWS:
  2966. {
  2967. BOOL fForceUpdate = (m_rLayout.fMailPreviewPane != (unsigned) !!fVisible);
  2968. m_rLayout.fNewsPreviewPane = !!fVisible;
  2969. m_rLayout.fNewsPreviewPaneHeader = !!dwFlags;
  2970. if (pos != LAYOUT_POS_NA)
  2971. m_rLayout.fNewsSplitVertically = (LAYOUT_POS_LEFT == pos);
  2972. if (LOWORD(dwSize))
  2973. {
  2974. m_rLayout.bNewsSplitHorzPct = (BYTE) LOWORD(dwSize);
  2975. }
  2976. if (HIWORD(dwSize))
  2977. {
  2978. m_rLayout.bNewsSplitVertPct = (BYTE) HIWORD(dwSize);
  2979. }
  2980. if (m_pView)
  2981. {
  2982. IMessageWindow *pWindow;
  2983. if (SUCCEEDED(m_pView->QueryInterface(IID_IMessageWindow, (LPVOID *) &pWindow)))
  2984. {
  2985. pWindow->UpdateLayout(fVisible, (BOOL) dwFlags, m_rLayout.fNewsSplitVertically, fForceUpdate);
  2986. pWindow->Release();
  2987. }
  2988. }
  2989. UpdateToolbar();
  2990. hr = S_OK;
  2991. break;
  2992. }
  2993. case DISPID_MSGVIEW_PREVIEWPANE_MAIL:
  2994. {
  2995. BOOL fForceUpdate = (m_rLayout.fMailPreviewPane != (unsigned) !!fVisible);
  2996. m_rLayout.fMailPreviewPane = !!fVisible;
  2997. m_rLayout.fMailPreviewPaneHeader = !!dwFlags;
  2998. if (pos != LAYOUT_POS_NA)
  2999. m_rLayout.fMailSplitVertically = (LAYOUT_POS_LEFT == pos);
  3000. if (LOWORD(dwSize))
  3001. {
  3002. m_rLayout.bMailSplitHorzPct = (BYTE) LOWORD(dwSize);
  3003. }
  3004. if (HIWORD(dwSize))
  3005. {
  3006. m_rLayout.bMailSplitVertPct = (BYTE) HIWORD(dwSize);
  3007. }
  3008. if (m_pView)
  3009. {
  3010. IMessageWindow *pWindow;
  3011. if (SUCCEEDED(m_pView->QueryInterface(IID_IMessageWindow, (LPVOID *) &pWindow)))
  3012. {
  3013. pWindow->UpdateLayout(fVisible, (BOOL) dwFlags, m_rLayout.fMailSplitVertically, fForceUpdate);
  3014. pWindow->Release();
  3015. }
  3016. }
  3017. UpdateToolbar();
  3018. hr = S_OK;
  3019. break;
  3020. }
  3021. default:
  3022. AssertSz(0, "CBrowser::SetViewLayout() - Called with an unrecognized layout option.");
  3023. }
  3024. return (hr);
  3025. }
  3026. //
  3027. // FUNCTION: CBrowser::LoadLayoutSettings()
  3028. //
  3029. // PURPOSE: Loads all of the layout settings from the registry and
  3030. // caches them in the rLayout member.
  3031. //
  3032. // RETURN VALUE:
  3033. // Returns S_OK all the time
  3034. //
  3035. HRESULT CBrowser::LoadLayoutSettings(void)
  3036. {
  3037. TraceCall("CBrowser::LoadLayoutSettings");
  3038. m_rLayout.cbSize = sizeof(LAYOUT);
  3039. // Things that can be turned on or off
  3040. m_rLayout.fStatusBar = DwGetOption(OPT_SHOWSTATUSBAR);
  3041. m_rLayout.fFolderBar = !DwGetOption(OPT_HIDEFOLDERBAR);
  3042. m_rLayout.fFolderList = DwGetOption(OPT_SHOWTREE);
  3043. m_rLayout.fTipOfTheDay = DwGetOption(OPT_TIPOFTHEDAY);
  3044. m_rLayout.fInfoPaneEnabled = FALSE;
  3045. m_rLayout.fInfoPane = DwGetOption(OPT_SHOWBODYBAR);
  3046. m_rLayout.fOutlookBar = DwGetOption(OPT_SHOWOUTLOOKBAR);
  3047. m_rLayout.fContacts = DwGetOption(OPT_SHOWCONTACTS);
  3048. m_rLayout.fMailPreviewPane = DwGetOption(OPT_MAILHYBRIDVIEW);
  3049. m_rLayout.fMailPreviewPaneHeader = DwGetOption(OPT_MAILSHOWHEADERINFO);
  3050. m_rLayout.fMailSplitVertically = DwGetOption(OPT_MAILSPLITDIR);
  3051. m_rLayout.fNewsPreviewPane = DwGetOption(OPT_NEWSHYBRIDVIEW);
  3052. m_rLayout.fNewsPreviewPaneHeader = DwGetOption(OPT_NEWSSHOWHEADERINFO);
  3053. m_rLayout.fNewsSplitVertically = DwGetOption(OPT_NEWSSPLITDIR);
  3054. // Coolbar Side
  3055. //m_rLayout.csToolbarSide = COOLBAR_TOP;
  3056. // Preview Pane widths
  3057. m_rLayout.bMailSplitHorzPct = (BYTE) DwGetOption(OPT_MAILCYSPLIT);
  3058. m_rLayout.bMailSplitVertPct = (BYTE) DwGetOption(OPT_MAILCXSPLIT);
  3059. m_rLayout.bNewsSplitHorzPct = (BYTE) DwGetOption(OPT_NEWSCYSPLIT);
  3060. m_rLayout.bNewsSplitVertPct = (BYTE) DwGetOption(OPT_NEWSCXSPLIT);
  3061. return (S_OK);
  3062. }
  3063. //
  3064. // FUNCTION: CBrowser::SaveLayoutSettings()
  3065. //
  3066. // PURPOSE: Saves all of the layout configuration back to the registry.
  3067. //
  3068. // RETURN VALUE:
  3069. // Returns S_OK all the time
  3070. //
  3071. HRESULT CBrowser::SaveLayoutSettings(void)
  3072. {
  3073. TraceCall("CBrowser::SaveLayoutSettings");
  3074. // Things that can be turned on or off
  3075. SetDwOption(OPT_SHOWSTATUSBAR, m_rLayout.fStatusBar, 0, 0);
  3076. SetDwOption(OPT_HIDEFOLDERBAR, !m_rLayout.fFolderBar, 0, 0);
  3077. SetDwOption(OPT_SHOWTREE, m_rLayout.fFolderList, 0, 0);
  3078. SetDwOption(OPT_TIPOFTHEDAY, m_rLayout.fTipOfTheDay, 0, 0);
  3079. SetDwOption(OPT_SHOWBODYBAR, m_rLayout.fInfoPane, 0, 0);
  3080. SetDwOption(OPT_SHOWOUTLOOKBAR, m_rLayout.fOutlookBar, 0, 0);
  3081. SetDwOption(OPT_SHOWCONTACTS, m_rLayout.fContacts, 0, 0);
  3082. SetDwOption(OPT_MAILHYBRIDVIEW, m_rLayout.fMailPreviewPane, 0, 0);
  3083. SetDwOption(OPT_MAILSHOWHEADERINFO, m_rLayout.fMailPreviewPaneHeader, 0, 0);
  3084. SetDwOption(OPT_MAILSPLITDIR, m_rLayout.fMailSplitVertically, 0, 0);
  3085. SetDwOption(OPT_NEWSHYBRIDVIEW, m_rLayout.fNewsPreviewPane, 0, 0);
  3086. SetDwOption(OPT_NEWSSHOWHEADERINFO, m_rLayout.fNewsPreviewPaneHeader, 0, 0);
  3087. SetDwOption(OPT_NEWSSPLITDIR, m_rLayout.fNewsSplitVertically, 0, 0);
  3088. // Preview Pane widths
  3089. SetDwOption(OPT_MAILCYSPLIT, (DWORD) m_rLayout.bMailSplitHorzPct, 0, 0);
  3090. SetDwOption(OPT_MAILCXSPLIT, (DWORD) m_rLayout.bMailSplitVertPct, 0, 0);
  3091. SetDwOption(OPT_NEWSCYSPLIT, (DWORD) m_rLayout.bNewsSplitHorzPct, 0, 0);
  3092. SetDwOption(OPT_NEWSCXSPLIT, (DWORD) m_rLayout.bNewsSplitVertPct, 0, 0);
  3093. return (S_OK);
  3094. }
  3095. HRESULT CBrowser::CmdSendReceieveAccount(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
  3096. {
  3097. MENUITEMINFO mii;
  3098. mii.cbSize = sizeof(MENUITEMINFO);
  3099. mii.fMask = MIIM_DATA;
  3100. mii.dwItemData = 0;
  3101. if (GetMenuItemInfo(m_hMenu, nCmdID, FALSE, &mii))
  3102. {
  3103. if (mii.dwItemData)
  3104. {
  3105. g_pSpooler->StartDelivery(m_hwnd, (LPTSTR) mii.dwItemData, FOLDERID_INVALID,
  3106. DELIVER_MAIL_SEND | DELIVER_MAIL_RECV | DELIVER_NOSKIP |
  3107. DELIVER_POLL | DELIVER_OFFLINE_FLAGS);
  3108. }
  3109. else
  3110. {
  3111. g_pSpooler->StartDelivery(m_hwnd, NULL, FOLDERID_INVALID,
  3112. DELIVER_MAIL_SEND | DELIVER_MAIL_RECV | DELIVER_POLL |
  3113. DELIVER_OFFLINE_FLAGS);
  3114. }
  3115. }
  3116. return (S_OK);
  3117. }
  3118. HRESULT CBrowser::CmdDeleteAccel(DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
  3119. {
  3120. BOOL fNoTrash;
  3121. IOleCommandTarget *pTarget = NULL;
  3122. // Figure out where the focus is
  3123. HWND hwndFocus = GetFocus();
  3124. Assert(nCmdID == ID_DELETE_ACCEL || nCmdID == ID_DELETE_NO_TRASH_ACCEL);
  3125. fNoTrash = (nCmdID == ID_DELETE_NO_TRASH_ACCEL);
  3126. // Check to see if it's the treeview
  3127. if (S_OK == m_pTreeView->HasFocusIO())
  3128. {
  3129. pTarget = m_pTreeView;
  3130. nCmdID = fNoTrash ? ID_DELETE_NO_TRASH : ID_DELETE_FOLDER;
  3131. }
  3132. // Check to see if it's anything else on the Info Column
  3133. else if (m_pNavPane->IsContactsFocus())
  3134. {
  3135. pTarget = m_pNavPane;
  3136. nCmdID = ID_DELETE_CONTACT;
  3137. }
  3138. // Otherwise, it must be the view
  3139. else
  3140. {
  3141. pTarget = m_pViewCT;
  3142. nCmdID = fNoTrash ? ID_DELETE_NO_TRASH : ID_DELETE;
  3143. }
  3144. // Hit the target with the right command
  3145. if (pTarget)
  3146. return (pTarget->Exec(NULL, nCmdID, nCmdExecOpt, pvaIn, pvaOut));
  3147. else
  3148. return (OLECMDERR_E_NOTSUPPORTED);
  3149. }
  3150. HRESULT CBrowser::TranslateMenuMessage(MSG *lpmsg, LRESULT *lres)
  3151. {
  3152. if (m_pCoolbar)
  3153. return m_pCoolbar->TranslateMenuMessage(lpmsg, lres);
  3154. else
  3155. return S_FALSE;
  3156. }
  3157. BOOL CBrowser::_InitToolbars(void)
  3158. {
  3159. DWORD dwTreeFlags = 0;
  3160. if (!(m_pTreeView = new CTreeView(this)))
  3161. goto error;
  3162. if (g_dwAthenaMode & MODE_OUTLOOKNEWS)
  3163. dwTreeFlags |= TREEVIEW_NOIMAP | TREEVIEW_NOHTTP;
  3164. if (FAILED(m_pTreeView->HrInit(dwTreeFlags, this)))
  3165. goto error;
  3166. if (!(m_pCoolbar = new CBands()))
  3167. goto error;
  3168. if (FAILED(m_pCoolbar->HrInit(NULL, m_hMenu, PARENT_TYPE_BROWSER)))
  3169. goto error;
  3170. if (FAILED(AddToolbar((IDockingWindow*)m_pCoolbar, ITB_COOLBAR, TRUE, TRUE)))
  3171. goto error;
  3172. //m_pCoolbar->HideToolbar(!m_rLayout.fToolbar);
  3173. m_rLayout.fToolbar = m_pCoolbar->IsBandVisible(CBTYPE_TOOLS);
  3174. m_rLayout.fFilterBar = m_pCoolbar->IsBandVisible(CBTYPE_RULESTOOLBAR);
  3175. if (FAILED(m_pCoolbar->SetFolderType(m_ftSel)))
  3176. goto error;
  3177. if (!(m_pOutBar = new COutBar()))
  3178. goto error;
  3179. if (FAILED(m_pOutBar->HrInit(NULL, this)))
  3180. goto error;
  3181. if (FAILED(AddToolbar((IDockingWindow *) m_pOutBar, ITB_OUTBAR, m_rLayout.fOutlookBar, TRUE)))
  3182. goto error;
  3183. #ifdef HOTMAILADV
  3184. if (!(m_pAdBar = new CAdBar()))
  3185. goto error;
  3186. if (FAILED(AddToolbar((IDockingWindow*)m_pAdBar, ITB_ADBAR, TRUE, FALSE)))
  3187. goto error;
  3188. #endif // HOTMAILADV
  3189. if (!(m_pBodyBar = new CBodyBar()))
  3190. goto error;
  3191. BOOL fBodyBarEnabled;
  3192. if (FAILED(m_pBodyBar->HrInit(&fBodyBarEnabled)))
  3193. goto error;
  3194. m_rLayout.fInfoPaneEnabled = !!fBodyBarEnabled;
  3195. if (FAILED(AddToolbar((IDockingWindow*)m_pBodyBar, ITB_BODYBAR,
  3196. m_rLayout.fInfoPaneEnabled && m_rLayout.fInfoPane, FALSE)))
  3197. goto error;
  3198. if (!(m_pFolderBar = new CFolderBar()))
  3199. goto error;
  3200. if (FAILED(m_pFolderBar->HrInit(this)))
  3201. goto error;
  3202. if (FAILED(AddToolbar((IDockingWindow*)m_pFolderBar, ITB_FOLDERBAR, m_rLayout.fFolderBar, TRUE)))
  3203. goto error;
  3204. if (!(m_pNavPane = new CNavPane()))
  3205. goto error;
  3206. if (FAILED(m_pNavPane->Initialize(m_pTreeView)))
  3207. goto error;
  3208. if (FAILED(AddToolbar((IDockingWindow*) m_pNavPane, ITB_NAVPANE, m_rLayout.fFolderList || m_rLayout.fContacts, TRUE)))
  3209. goto error;
  3210. return (TRUE);
  3211. error:
  3212. SafeRelease(m_pStatus);
  3213. SafeRelease(m_pTreeView);
  3214. SafeRelease(m_pCoolbar);
  3215. SafeRelease(m_pFolderBar);
  3216. return (FALSE);
  3217. }
  3218. HRESULT CBrowser::QuerySwitchIdentities()
  3219. {
  3220. TraceCall("CBrowser::QuerySwitchIdentities");
  3221. if (!IsWindowEnabled(m_hwnd))
  3222. {
  3223. Assert(IsWindowVisible(m_hwnd));
  3224. return E_PROCESS_CANCELLED_SWITCH;
  3225. }
  3226. if (g_pConMan->IsConnected())
  3227. {
  3228. SetForegroundWindow(m_hwnd);
  3229. if (IDNO == AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsSwitchUser),MAKEINTRESOURCEW(idsMaintainConnection),
  3230. NULL, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON1 | MB_SYSTEMMODAL))
  3231. g_pConMan->Disconnect(m_hwnd, TRUE, FALSE, FALSE );
  3232. }
  3233. m_fSwitchIsLogout = MU_CheckForIdentityLogout();
  3234. return S_OK;
  3235. }
  3236. HRESULT CBrowser::SwitchIdentities()
  3237. {
  3238. TraceCall("CBrowser::SwitchIdentities");
  3239. if (!m_fSwitchIsLogout)
  3240. {
  3241. // Let ::BrowserWndProc know that this close is due to an id switch
  3242. s_fQuickShutdown = TRUE;
  3243. }
  3244. else
  3245. {
  3246. s_fQuickShutdown = FALSE;
  3247. g_pInstance->SetSwitchingUsers(FALSE);
  3248. }
  3249. // We can't SendMessage here as we'd cause ole to throw RPC_E_CANTCALLOUT_ININPUTSYNCCALL
  3250. PostMessage(m_hwnd, WM_CLOSE, 0, 0);
  3251. return S_OK;
  3252. }
  3253. HRESULT CBrowser::IdentityInformationChanged(DWORD dwType)
  3254. {
  3255. TraceCall("CBrowser::IdentityInformationChanged");
  3256. // Refresh for adds, delete, or current identity changed
  3257. // since adding could require that the name show up,
  3258. // deleteing could require that it go away and changed
  3259. // should be reflected immediately.
  3260. if (dwType != IIC_IDENTITY_CHANGED)
  3261. {
  3262. MU_IdentityChanged();
  3263. OnRename(m_idSelected);
  3264. }
  3265. return S_OK;
  3266. }
  3267. HRESULT CBrowser::ShowAdBar(BSTR bstr)
  3268. {
  3269. HRESULT hr = S_OK;
  3270. #ifdef HOTMAILADV
  3271. LPSTR pszAdInfo = NULL;
  3272. BOOL fShowAdPane = FALSE;
  3273. LPSTR pszActualUrl = NULL;
  3274. DWORD ActualCount = 0;
  3275. CHAR szAdPaneValue[MAX_PATH];
  3276. DWORD cchRetCount = 0;
  3277. CHAR szAdOther[MAX_PATH];
  3278. CHAR szEncodedString[MAX_PATH];
  3279. CHAR szAdSvr[MAX_PATH];
  3280. FOLDERINFO FolderInfo = {0};
  3281. CHAR szAccountId[CCHMAX_ACCOUNT_NAME];
  3282. IImnAccount *pAccount = NULL;
  3283. CHAR szCachedAdUrl[INTERNET_MAX_URL_LENGTH];
  3284. IF_FAILEXIT(hr = HrBSTRToLPSZ(CP_ACP, bstr, &pszAdInfo));
  3285. //Search for AdPane token
  3286. IF_FAILEXIT(hr = HrProcessAdTokens(pszAdInfo, c_szAdPane, szAdPaneValue, ARRAYSIZE(szAdPaneValue), &cchRetCount));
  3287. fShowAdPane = (lstrcmp(szAdPaneValue, c_szAdPaneOn) == 0);
  3288. // Get the server for this folder
  3289. IF_FAILEXIT(hr = GetFolderServer(m_idSelected, &FolderInfo));
  3290. // Get the account ID for the server
  3291. IF_FAILEXIT(hr = GetFolderAccountId(&FolderInfo, szAccountId));
  3292. // Get the account interface
  3293. IF_FAILEXIT(hr = g_pAcctMan->FindAccount(AP_ACCOUNT_ID, szAccountId, &pAccount));
  3294. IF_FAILEXIT(hr = pAccount->SetPropDw(AP_HTTPMAIL_SHOW_ADBAR, fShowAdPane));
  3295. if (fShowAdPane)
  3296. {
  3297. //Plus one for null in version string
  3298. ActualCount += CCH_REDIRECT_ADURL + strlen(c_szUrlSubPVER) + 1;
  3299. //Search for AdSvr token
  3300. IF_FAILEXIT(hr = HrProcessAdTokens(pszAdInfo, c_szAdSvr, szAdSvr, ARRAYSIZE(szAdSvr), &cchRetCount));
  3301. ActualCount += cchRetCount;
  3302. ActualCount += CCH_ADSVR_TOKEN_FORMAT;
  3303. //Search for the token other
  3304. IF_FAILEXIT(hr = HrProcessAdTokens(pszAdInfo, c_szAdOther, szAdOther, ARRAYSIZE(szAdOther), &cchRetCount));
  3305. //Encode the other string
  3306. IF_FAILEXIT(hr = HrEscapeOtherAdToken(szAdOther, szEncodedString, ARRAYSIZE(szEncodedString), &cchRetCount));
  3307. ActualCount += cchRetCount;
  3308. //one for null
  3309. ActualCount += CCH_OTHER_FORMAT + 1;
  3310. IF_FAILEXIT(hr = HrAlloc((LPVOID*)&pszActualUrl, ActualCount));
  3311. *pszActualUrl = 0;
  3312. wnsprintf(pszActualUrl, ActualCount, c_szAdRedirectFormat, c_szRedirectAdUrl, c_szUrlSubPVER,
  3313. c_szAdSvrFormat, szAdSvr, c_szAdOtherFormat, szEncodedString);
  3314. IF_FAILEXIT(hr = m_pAdBar->SetUrl(pszActualUrl));
  3315. IF_FAILEXIT(hr = pAccount->SetPropSz(AP_HTTPMAIL_ADURL, pszActualUrl));
  3316. }
  3317. ShowToolbar((IDockingWindow*)m_pAdBar, fShowAdPane);
  3318. //We need to do this to persist the property into registry.
  3319. IF_FAILEXIT(hr = pAccount->WriteChanges());
  3320. exit:
  3321. if (FAILED(hr) && fShowAdPane)
  3322. {
  3323. BOOL fSucceeded = FALSE;
  3324. //We are supposed to show adpane, but something went wrong in the info we got.
  3325. //We just display the cached URL.
  3326. *szCachedAdUrl = 0;
  3327. if (pAccount)
  3328. {
  3329. if (SUCCEEDED(pAccount->GetPropSz(AP_HTTPMAIL_ADURL, szCachedAdUrl, ARRAYSIZE(szCachedAdUrl))))
  3330. {
  3331. fSucceeded = SUCCEEDED(m_pAdBar->SetUrl(szCachedAdUrl));
  3332. }
  3333. }
  3334. if (!fSucceeded)
  3335. {
  3336. //If we can't get the cached ad or if the cached is empty, we turn off the adpane
  3337. ShowToolbar((IDockingWindow*)m_pAdBar, FALSE);
  3338. }
  3339. }
  3340. g_pStore->FreeRecord(&FolderInfo);
  3341. ReleaseObj(pAccount);
  3342. MemFree(pszActualUrl);
  3343. MemFree(pszAdInfo);
  3344. #endif // HOTMAILADV
  3345. return hr;
  3346. }
  3347. void CBrowser::WriteUnreadCount(void)
  3348. {
  3349. IImnEnumAccounts *pEnum = NULL;
  3350. IImnAccount *pAcct = NULL;
  3351. DWORD cServers = 0;
  3352. IMessageFolder *pFolder = NULL;
  3353. DWORD nCount = 0 ;
  3354. FOLDERID idServer;
  3355. TCHAR szUserEmail[CCHMAX_EMAIL_ADDRESS];
  3356. WCHAR wsz[CCHMAX_EMAIL_ADDRESS];
  3357. HRESULT hr = S_OK;
  3358. // can't proceed if there's no accnt manager
  3359. if (g_pAcctMan == NULL)
  3360. return;
  3361. // 1. Enumerate POP3 accounts:
  3362. if (S_OK == g_pAcctMan->Enumerate(SRV_POP3, &pEnum))
  3363. {
  3364. // Get count of servers
  3365. pEnum->GetCount(&cServers);
  3366. if(cServers == 1)
  3367. {
  3368. // a). All POP3 account in local store
  3369. if(SUCCEEDED(pEnum->GetNext(&pAcct)) && g_pStore)
  3370. {
  3371. IF_FAILEXIT(hr = g_pStore->OpenSpecialFolder(FOLDERID_LOCAL_STORE, NULL, FOLDER_INBOX, &pFolder));
  3372. nCount = _GetNumberOfUnreadMsg(pFolder);
  3373. IF_FAILEXIT(hr = pAcct->GetPropSz(AP_SMTP_EMAIL_ADDRESS, szUserEmail, ARRAYSIZE(szUserEmail)));
  3374. if(MultiByteToWideChar(CP_ACP, 0, szUserEmail, -1, wsz, ARRAYSIZE(wsz)) != 0)
  3375. // write # unread messages to registry
  3376. hr = SHSetUnreadMailCountW(wsz, nCount, L"msimn");
  3377. SafeRelease(pFolder);
  3378. }
  3379. }
  3380. }
  3381. // 1. Enumerate IMAP accounts:
  3382. IF_FAILEXIT(hr = _CheckAndWriteUnreadNumber(SRV_IMAP));
  3383. IF_FAILEXIT(hr = _CheckAndWriteUnreadNumber(SRV_HTTPMAIL));
  3384. exit:
  3385. SafeRelease(pAcct);
  3386. SafeRelease(pEnum);
  3387. return;
  3388. }
  3389. DWORD CBrowser::_GetNumberOfUnreadMsg(IMessageFolder *pFolder)
  3390. {
  3391. DWORD nCount = 0;
  3392. HROWSET hRowset=NULL;
  3393. MESSAGEINFO Message={0};
  3394. HRESULT hr = S_OK;
  3395. // Create Rowset
  3396. IF_FAILEXIT(hr = pFolder->CreateRowset(IINDEX_PRIMARY, NOFLAGS, &hRowset));
  3397. // Iterate throug the messages
  3398. while (S_OK == pFolder->QueryRowset(hRowset, 1, (LPVOID *)&Message, NULL))
  3399. {
  3400. // Not Read
  3401. if (FALSE == ISFLAGSET(Message.dwFlags, ARF_READ))
  3402. nCount++;
  3403. // Free
  3404. pFolder->FreeRecord(&Message);
  3405. }
  3406. exit:
  3407. // Clenaup
  3408. pFolder->CloseRowset(&hRowset);
  3409. return(nCount);
  3410. }
  3411. HRESULT CBrowser::_CheckAndWriteUnreadNumber(DWORD dwSrvTypes)
  3412. {
  3413. IImnEnumAccounts *pEnum = NULL;
  3414. IImnAccount *pAcct = NULL;
  3415. DWORD cServers = 0;
  3416. IMessageFolder *pFolder = NULL;
  3417. DWORD nCount = 0 ;
  3418. FOLDERID idServer;
  3419. TCHAR szAccountId[CCHMAX_ACCOUNT_NAME];
  3420. TCHAR szUserEmail[CCHMAX_EMAIL_ADDRESS];
  3421. WCHAR wsz[CCHMAX_EMAIL_ADDRESS];
  3422. HRESULT hr = S_OK;
  3423. if(g_pStore == NULL)
  3424. return(hr);
  3425. if (S_OK == g_pAcctMan->Enumerate(dwSrvTypes, &pEnum))
  3426. {
  3427. while(SUCCEEDED(pEnum->GetNext(&pAcct)))
  3428. {
  3429. // Get the Account ID for pAccount
  3430. IF_FAILEXIT(hr = pAcct->GetPropSz(AP_ACCOUNT_ID, szAccountId, ARRAYSIZE(szAccountId)));
  3431. // Find the Server Id
  3432. IF_FAILEXIT(hr = g_pStore->FindServerId(szAccountId, &idServer));
  3433. // Open Store
  3434. IF_FAILEXIT(hr = g_pStore->OpenSpecialFolder(idServer, NULL, FOLDER_INBOX, &pFolder));
  3435. nCount = _GetNumberOfUnreadMsg(pFolder);
  3436. // write # unread messages to registry
  3437. IF_FAILEXIT(hr = pAcct->GetPropSz(AP_SMTP_EMAIL_ADDRESS, szUserEmail, ARRAYSIZE(szUserEmail)));
  3438. if(MultiByteToWideChar(CP_ACP, 0, szUserEmail, -1, wsz, ARRAYSIZE(wsz)) != 0)
  3439. hr = SHSetUnreadMailCountW(wsz, nCount, L"msimn");
  3440. SafeRelease(pFolder);
  3441. SafeRelease(pAcct);
  3442. }
  3443. }
  3444. exit:
  3445. SafeRelease(pFolder);
  3446. SafeRelease(pAcct);
  3447. SafeRelease(pEnum);
  3448. return(hr);
  3449. }