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.

1394 lines
41 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
  3. //
  4. // MODULE: menuutil.cpp
  5. //
  6. // PURPOSE: Reusable menu & menu command handling code
  7. //
  8. #include "pch.hxx"
  9. #include "resource.h"
  10. #include "menuutil.h"
  11. #include "imnact.h"
  12. #include "strconst.h"
  13. #include "fldrprop.h"
  14. #include "mailutil.h"
  15. #include "mimeutil.h"
  16. #include "inetcfg.h"
  17. #include "newfldr.h"
  18. #include "browser.h"
  19. #include "instance.h"
  20. #include "statbar.h"
  21. #include "storutil.h"
  22. #include "subscr.h"
  23. #include "demand.h"
  24. #include "menures.h"
  25. #include "statnery.h"
  26. #include "store.h"
  27. #include <storecb.h>
  28. #include <range.h>
  29. #include <newsdlgs.h>
  30. #include "acctutil.h"
  31. static const UINT c_rgidNewsNoShow[] =
  32. { ID_NEW_FOLDER, ID_RENAME, ID_DELETE_FOLDER, SEP_MAILFOLDER };
  33. static const UINT c_rgidSubNoShow[] =
  34. { ID_SUBSCRIBE, ID_UNSUBSCRIBE, SEP_SUBSCRIBE };
  35. static const UINT c_rgidSyncNoShow[] =
  36. { ID_POPUP_SYNCHRONIZE, SEP_SYNCHRONIZE };
  37. static const UINT c_rgidCatchUpNoShow[] =
  38. { ID_CATCH_UP, SEP_CATCH_UP };
  39. void DeleteMenuItems(HMENU hMenu, const UINT *rgid, UINT cid)
  40. {
  41. Assert(rgid != NULL);
  42. Assert(cid != 0);
  43. for ( ; cid > 0; cid--, rgid++)
  44. DeleteMenu(hMenu, *rgid, MF_BYCOMMAND);
  45. }
  46. //
  47. // FUNCTION: MenuUtil_GetContextMenu()
  48. //
  49. // PURPOSE: Returns a handle to the context menu that is appropriate for
  50. // the folder type passed in pidl. The correct menu items will
  51. // be enabled, disabled, bolded, etc.
  52. //
  53. // PARAMETERS:
  54. // <in> pidl - PIDL that points to the folder that the caller needs a
  55. // context menu for.
  56. // <out> phMenu - Returns the handle to a popup menu.
  57. //
  58. // RETURN VALUE:
  59. // S_OK - phMenu contains a valid hMenu for the folder
  60. // E_UNEXPECTED - Either there was a problem loading the menu or the
  61. // folder type was unrecognized.
  62. // E_FAIL - The folder type doesn't support a menu.
  63. //
  64. HRESULT MenuUtil_GetContextMenu(FOLDERID idFolder, IOleCommandTarget *pTarget, HMENU *phMenu)
  65. {
  66. HRESULT hr;
  67. TCHAR sz[CCHMAX_STRINGRES];
  68. FOLDERINFO Folder;
  69. HMENU hMenu;
  70. int idMenu;
  71. // Get folder INfo
  72. hr = g_pStore->GetFolderInfo(idFolder, &Folder);
  73. if (FAILED(hr))
  74. return hr;
  75. // Root ?
  76. if (FOLDERID_ROOT == idFolder || ISFLAGSET(Folder.dwFlags, FOLDER_SERVER))
  77. idMenu = IDR_SERVER_POPUP;
  78. else
  79. idMenu = IDR_FOLDER_POPUP;
  80. if (0 == (hMenu = LoadPopupMenu(idMenu)))
  81. {
  82. g_pStore->FreeRecord(&Folder);
  83. return (E_OUTOFMEMORY);
  84. }
  85. // Bold the default menu items
  86. MENUITEMINFO mii;
  87. if (!(MF_GRAYED & GetMenuState(hMenu, ID_OPEN_FOLDER, MF_BYCOMMAND)))
  88. {
  89. mii.cbSize = sizeof(MENUITEMINFO);
  90. mii.fMask = MIIM_STATE;
  91. mii.fState = MFS_DEFAULT;
  92. SetMenuItemInfo(hMenu, ID_OPEN_FOLDER, FALSE, &mii);
  93. }
  94. if (idMenu == IDR_SERVER_POPUP)
  95. {
  96. if (Folder.tyFolder != FOLDER_IMAP)
  97. DeleteMenu(hMenu, ID_IMAP_FOLDERS, MF_BYCOMMAND);
  98. if (Folder.tyFolder != FOLDER_NEWS)
  99. DeleteMenu(hMenu, ID_NEWSGROUPS, MF_BYCOMMAND);
  100. }
  101. else
  102. {
  103. if (Folder.tyFolder == FOLDER_IMAP)
  104. {
  105. AthLoadString(idsShowFolderCmd, sz, ARRAYSIZE(sz));
  106. ModifyMenu(hMenu, ID_SUBSCRIBE, MF_BYCOMMAND | MF_STRING, ID_SUBSCRIBE, sz);
  107. AthLoadString(idsHideFolderCmd, sz, ARRAYSIZE(sz));
  108. ModifyMenu(hMenu, ID_UNSUBSCRIBE, MF_BYCOMMAND | MF_STRING, ID_UNSUBSCRIBE, sz);
  109. }
  110. if (FOLDER_DELETED != Folder.tySpecial)
  111. DeleteMenu(hMenu, ID_EMPTY_WASTEBASKET, MF_BYCOMMAND);
  112. if (FOLDER_JUNK != Folder.tySpecial)
  113. DeleteMenu(hMenu, ID_EMPTY_JUNKMAIL, MF_BYCOMMAND);
  114. if (Folder.tyFolder == FOLDER_NEWS)
  115. DeleteMenuItems(hMenu, c_rgidNewsNoShow, ARRAYSIZE(c_rgidNewsNoShow));
  116. if (Folder.tyFolder != FOLDER_NEWS &&
  117. Folder.tyFolder != FOLDER_IMAP)
  118. DeleteMenuItems(hMenu, c_rgidSubNoShow, ARRAYSIZE(c_rgidSubNoShow));
  119. if (Folder.tyFolder == FOLDER_LOCAL)
  120. DeleteMenuItems(hMenu, c_rgidSyncNoShow, ARRAYSIZE(c_rgidSyncNoShow));
  121. if (Folder.tyFolder != FOLDER_NEWS)
  122. DeleteMenuItems(hMenu, c_rgidCatchUpNoShow, ARRAYSIZE(c_rgidCatchUpNoShow));
  123. }
  124. // Enable / disable
  125. MenuUtil_EnablePopupMenu(hMenu, pTarget);
  126. // Return
  127. *phMenu = hMenu;
  128. g_pStore->FreeRecord(&Folder);
  129. return (S_OK);
  130. }
  131. void MenuUtil_OnSubscribeGroups(HWND hwnd, FOLDERID *pidFolder, DWORD cFolder, BOOL fSubscribe)
  132. {
  133. CStoreCB *pCB;
  134. HRESULT hr;
  135. DWORD iFolder;
  136. char szRes[CCHMAX_STRINGRES], szBuf[CCHMAX_STRINGRES];
  137. FOLDERINFO info;
  138. Assert(hwnd != NULL);
  139. Assert(pidFolder != NULL);
  140. Assert(cFolder > 0);
  141. ZeroMemory(&info, sizeof(FOLDERINFO));
  142. pCB = NULL;
  143. for (iFolder = 0; iFolder < cFolder; iFolder++, pidFolder++)
  144. {
  145. hr = g_pStore->GetFolderInfo(*pidFolder, &info);
  146. if (FAILED(hr))
  147. break;
  148. if (iFolder == 0)
  149. {
  150. if (!fSubscribe)
  151. {
  152. if (cFolder == 1)
  153. {
  154. AthLoadString(info.tyFolder == FOLDER_NEWS ? idsWantToUnSubscribe : idsWantToHideFolder, szRes, ARRAYSIZE(szRes));
  155. wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, info.pszName);
  156. }
  157. else
  158. {
  159. AthLoadString(info.tyFolder == FOLDER_NEWS ? idsWantToUnSubscribeN : idsWantToHideFolderN, szBuf, ARRAYSIZE(szBuf));
  160. }
  161. if (IDOK != DoDontShowMeAgainDlg(hwnd,
  162. info.tyFolder == FOLDER_NEWS ? c_szRegUnsubscribe : c_szRegHide,
  163. MAKEINTRESOURCE(idsAthena), szBuf, MB_OKCANCEL))
  164. {
  165. break;
  166. }
  167. }
  168. if (info.tyFolder == FOLDER_IMAP)
  169. {
  170. pCB = new CStoreCB;
  171. if (pCB == NULL)
  172. break;
  173. hr = pCB->Initialize(hwnd,
  174. fSubscribe ? MAKEINTRESOURCE(idsShowingFolders) : MAKEINTRESOURCE(idsHidingFolders),
  175. FALSE);
  176. if (FAILED(hr))
  177. break;
  178. }
  179. }
  180. if (info.tySpecial == FOLDER_NOTSPECIAL &&
  181. ISFLAGSET(info.dwFlags, FOLDER_SUBSCRIBED) ^ fSubscribe)
  182. {
  183. if (pCB != NULL)
  184. pCB->Reset();
  185. hr = g_pStore->SubscribeToFolder(*pidFolder, fSubscribe, (IStoreCallback *)pCB);
  186. if (hr == E_PENDING)
  187. {
  188. Assert(info.tyFolder == FOLDER_IMAP);
  189. Assert(pCB != NULL);
  190. hr = pCB->Block();
  191. }
  192. if (FAILED(hr))
  193. break;
  194. }
  195. g_pStore->FreeRecord(&info);
  196. }
  197. g_pStore->FreeRecord(&info);
  198. if (pCB != NULL)
  199. {
  200. pCB->Close();
  201. pCB->Release();
  202. }
  203. }
  204. void MenuUtil_DeleteFolders(HWND hwnd, FOLDERID *pidFolder, DWORD cFolder, BOOL fNoTrash)
  205. {
  206. CStoreCB *pCB;
  207. HRESULT hr;
  208. DWORD iFolder, dwFlags;
  209. FOLDERID idDeleted, idServer;
  210. char szRes[CCHMAX_STRINGRES], szBuf[CCHMAX_STRINGRES], szFolder[CCHMAX_FOLDER_NAME];
  211. FOLDERID *pidFolderT;
  212. FOLDERINFO info;
  213. BOOL fPermDelete, fCallback;
  214. Assert(hwnd != NULL);
  215. Assert(pidFolder != NULL);
  216. Assert(cFolder > 0);
  217. pCB = NULL;
  218. fCallback = FALSE;
  219. *szFolder = 0;
  220. if (fNoTrash)
  221. {
  222. dwFlags = DELETE_FOLDER_RECURSIVE | DELETE_FOLDER_NOTRASHCAN;
  223. fPermDelete = TRUE;
  224. }
  225. else
  226. {
  227. dwFlags = DELETE_FOLDER_RECURSIVE;
  228. fPermDelete = FALSE;
  229. for (iFolder = 0, pidFolderT = pidFolder; iFolder < cFolder; iFolder++, pidFolderT++)
  230. {
  231. hr = g_pStore->GetFolderInfo(*pidFolderT, &info);
  232. if (FAILED(hr))
  233. return;
  234. // Skip deletion of any special folders
  235. if (info.tySpecial == FOLDER_NOTSPECIAL)
  236. {
  237. if (iFolder == 0 && cFolder == 1)
  238. StrCpyN(szFolder, info.pszName, ARRAYSIZE(szFolder));
  239. if (info.tyFolder == FOLDER_IMAP ||
  240. info.tyFolder == FOLDER_HTTPMAIL)
  241. {
  242. fPermDelete = TRUE;
  243. fCallback = TRUE;
  244. }
  245. else if (S_OK == IsParentDeletedItems(*pidFolderT, &idDeleted, &idServer))
  246. {
  247. fPermDelete = TRUE;
  248. }
  249. }
  250. g_pStore->FreeRecord(&info);
  251. if (fPermDelete)
  252. break;
  253. }
  254. }
  255. if (fPermDelete)
  256. {
  257. if (cFolder == 1 && *szFolder != 0)
  258. {
  259. AthLoadString(idsWarnDeleteFolder, szRes, ARRAYSIZE(szRes));
  260. wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, szFolder);
  261. }
  262. else
  263. {
  264. AthLoadString(idsWarnDeleteFolderN, szBuf, ARRAYSIZE(szBuf));
  265. }
  266. }
  267. else
  268. {
  269. if (cFolder == 1 && *szFolder != 0)
  270. {
  271. AthLoadString(idsPromptDeleteFolder, szRes, ARRAYSIZE(szRes));
  272. wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, szFolder);
  273. }
  274. else
  275. {
  276. AthLoadString(idsPromptDeleteFolderN, szBuf, ARRAYSIZE(szBuf));
  277. }
  278. }
  279. if (IDYES != AthMessageBox(hwnd, MAKEINTRESOURCE(idsAthena), szBuf, 0, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2))
  280. return;
  281. if (fCallback)
  282. {
  283. pCB = new CStoreCB;
  284. if (pCB == NULL)
  285. return;
  286. hr = pCB->Initialize(hwnd, MAKEINTRESOURCE(idsDeletingFolder), FALSE);
  287. if (FAILED(hr))
  288. {
  289. pCB->Release();
  290. return;
  291. }
  292. }
  293. for (iFolder = 0, pidFolderT = pidFolder; iFolder < cFolder; iFolder++, pidFolderT++)
  294. {
  295. hr = g_pStore->GetFolderInfo(*pidFolderT, &info);
  296. if (FAILED(hr))
  297. break;
  298. // Skip deletion of any special folders
  299. if (info.tySpecial == FOLDER_NOTSPECIAL)
  300. {
  301. if (pCB != NULL)
  302. pCB->Reset();
  303. hr = g_pStore->DeleteFolder(*pidFolderT, dwFlags, (IStoreCallback *)pCB);
  304. if (hr == E_PENDING)
  305. {
  306. Assert(info.tyFolder == FOLDER_IMAP || info.tyFolder == FOLDER_HTTPMAIL);
  307. Assert(pCB != NULL);
  308. hr = pCB->Block();
  309. }
  310. }
  311. g_pStore->FreeRecord(&info);
  312. if (FAILED(hr))
  313. break;
  314. }
  315. if (pCB != NULL)
  316. {
  317. pCB->Close();
  318. pCB->Release();
  319. }
  320. }
  321. void MenuUtil_SyncThisNow(HWND hwnd, FOLDERID idFolder)
  322. {
  323. UPDATENEWSGROUPINFO uni;
  324. HRESULT hr;
  325. DWORD dwFlags;
  326. FOLDERINFO info;
  327. char szAcctId[CCHMAX_ACCOUNT_NAME];
  328. BOOL fNews, fMarked;
  329. if (g_pSpooler)
  330. {
  331. hr = g_pStore->GetFolderInfo(idFolder, &info);
  332. if (SUCCEEDED(hr))
  333. {
  334. Assert(info.tyFolder == FOLDER_NEWS || info.tyFolder == FOLDER_IMAP || info.tyFolder == FOLDER_HTTPMAIL);
  335. if((info.tyFolder == FOLDER_NEWS) ||
  336. (!g_pConMan->IsAccountDisabled((LPSTR)info.pszAccountId)))
  337. {
  338. fNews = (info.tyFolder == FOLDER_NEWS);
  339. dwFlags = fNews ? DELIVER_NEWS_TYPE : DELIVER_IMAP_TYPE;
  340. //Tells the spooler that this is a sync operation and not Send&Receive
  341. dwFlags |= DELIVER_OFFLINE_SYNC | DELIVER_WATCH | DELIVER_NOSKIP;
  342. if (!!(info.dwFlags & FOLDER_SERVER))
  343. {
  344. // TODO: review these flags to make sure they are correct
  345. //dwFlags |= DELIVER_POLL | DELIVER_NEWS_SEND | DELIVER_NEWSIMAP_NOSKIP | DELIVER_NEWSIMAP_OFFLINE;
  346. dwFlags |= DELIVER_POLL | DELIVER_SEND | DELIVER_OFFLINE_FLAGS;
  347. g_pSpooler->StartDelivery(hwnd, info.pszAccountId, FOLDERID_INVALID, dwFlags);
  348. }
  349. else
  350. {
  351. hr = GetFolderAccountId(&info, szAcctId, ARRAYSIZE(szAcctId));
  352. if (SUCCEEDED(hr))
  353. {
  354. hr = HasMarkedMsgs(idFolder, &fMarked);
  355. if (SUCCEEDED(hr))
  356. {
  357. uni.fNews = fNews;
  358. uni.dwGroupFlags = info.dwFlags;
  359. uni.cMarked = fMarked;
  360. uni.idCmd = dwFlags;
  361. // Display the dialog to find what get thing to get
  362. DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddUpdateNewsgroup), hwnd, UpdateNewsgroup, (LPARAM)&uni);
  363. // Check to see if the user canceled
  364. if (uni.idCmd != -1)
  365. g_pSpooler->StartDelivery(hwnd, szAcctId, idFolder, uni.idCmd);
  366. }
  367. }
  368. }
  369. }
  370. g_pStore->FreeRecord(&info);
  371. }
  372. }
  373. }
  374. //
  375. // FUNCTION: MenuUtil_OnDelete()
  376. //
  377. // PURPOSE: Deletes the folder designated by the pidl.
  378. //
  379. // PARAMETERS:
  380. // <in> hwnd - Handle of the window to display UI over
  381. // <in> pidl - PIDL of the folder to browse to
  382. // <in> pStore - Pointer to the store to delete folders from
  383. //
  384. void MenuUtil_OnDelete(HWND hwnd, FOLDERID idFolder, BOOL fNoTrash)
  385. {
  386. TCHAR szRes[CCHMAX_STRINGRES], szBuf[CCHMAX_STRINGRES];
  387. FOLDERINFO Folder;
  388. IImnAccount *pAcct;
  389. // Get Folder Info
  390. if (FAILED(g_pStore->GetFolderInfo(idFolder, &Folder)))
  391. return;
  392. // Is a server
  393. if (ISFLAGSET(Folder.dwFlags, FOLDER_SERVER))
  394. {
  395. Assert(g_pAcctMan);
  396. if (SUCCEEDED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, Folder.pszAccountId, &pAcct)))
  397. {
  398. AthLoadString(idsWarnDeleteAccount, szRes, ARRAYSIZE(szRes));
  399. wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, Folder.pszName);
  400. if (IDYES == AthMessageBox(hwnd, MAKEINTRESOURCE(idsAthena), szBuf,
  401. 0, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2))
  402. {
  403. pAcct->Delete();
  404. }
  405. pAcct->Release();
  406. }
  407. }
  408. else
  409. {
  410. if (Folder.tyFolder == FOLDER_NEWS)
  411. {
  412. MenuUtil_OnSubscribeGroups(hwnd, &idFolder, 1, FALSE);
  413. }
  414. else
  415. {
  416. MenuUtil_DeleteFolders(hwnd, &idFolder, 1, fNoTrash);
  417. }
  418. }
  419. g_pStore->FreeRecord(&Folder);
  420. }
  421. //
  422. // FUNCTION: MenuUtil_OnProperties()
  423. //
  424. // PURPOSE: Displays properties for the folder designated by the pidl
  425. //
  426. // PARAMETERS:
  427. // <in> hwnd - Handle of the window to parent the properties
  428. // <in> pidl - PIDL of the folder to browse to
  429. //
  430. void MenuUtil_OnProperties(HWND hwnd, FOLDERID idFolder)
  431. {
  432. IImnAccount *pAcct;
  433. FOLDERINFO Folder;
  434. if (SUCCEEDED(g_pStore->GetFolderInfo(idFolder, &Folder)))
  435. {
  436. if (ISFLAGSET(Folder.dwFlags, FOLDER_SERVER))
  437. {
  438. if (SUCCEEDED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, Folder.pszAccountId, &pAcct)))
  439. {
  440. HRESULT hr;
  441. Assert(pAcct != NULL);
  442. DWORD dwFlags = ACCTDLG_SHOWIMAPSPECIAL | ACCTDLG_INTERNETCONNECTION | ACCTDLG_OE;
  443. if((DwGetOption(OPT_REVOKE_CHECK) != 0) && !g_pConMan->IsGlobalOffline())
  444. dwFlags |= ACCTDLG_REVOCATION;
  445. //We want to use the new dialog for the properties, hence the new flag internetconnection
  446. hr = pAcct->ShowProperties(hwnd, dwFlags);
  447. if (S_OK == hr)
  448. // User hit "OK" to exit, not "Cancel"
  449. CheckIMAPDirty(Folder.pszAccountId, hwnd, idFolder, NOFLAGS);
  450. pAcct->Release();
  451. }
  452. }
  453. else if (FOLDER_NEWS == Folder.tyFolder)
  454. {
  455. GroupProp_Create(hwnd, idFolder);
  456. }
  457. else
  458. {
  459. FolderProp_Create(hwnd, idFolder);
  460. }
  461. g_pStore->FreeRecord(&Folder);
  462. }
  463. }
  464. void MenuUtil_OnSetDefaultServer(FOLDERID idFolder)
  465. {
  466. TCHAR *sz;
  467. IImnAccount *pAcct = 0;
  468. FOLDERINFO Folder;
  469. if (FAILED(g_pStore->GetFolderInfo(idFolder, &Folder)))
  470. return;
  471. Assert(ISFLAGSET(Folder.dwFlags, FOLDER_SERVER));
  472. if (SUCCEEDED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, Folder.pszAccountId, &pAcct)))
  473. {
  474. pAcct->SetAsDefault();
  475. pAcct->Release();
  476. }
  477. g_pStore->FreeRecord(&Folder);
  478. }
  479. void MenuUtil_OnMarkNewsgroups(HWND hwnd, int id, FOLDERID idFolder)
  480. {
  481. FOLDERINFO Folder;
  482. if (FAILED(g_pStore->GetFolderInfo(idFolder, &Folder)))
  483. return;
  484. Folder.dwFlags &= ~(FOLDER_DOWNLOADHEADERS | FOLDER_DOWNLOADNEW | FOLDER_DOWNLOADALL);
  485. if (id == ID_MARK_RETRIEVE_FLD_NEW_HDRS)
  486. Folder.dwFlags |= FOLDER_DOWNLOADHEADERS;
  487. else if (id == ID_MARK_RETRIEVE_FLD_ALL_MSGS)
  488. Folder.dwFlags |= FOLDER_DOWNLOADALL;
  489. else if (id == ID_MARK_RETRIEVE_FLD_NEW_MSGS)
  490. Folder.dwFlags |= FOLDER_DOWNLOADNEW;
  491. g_pStore->UpdateRecord(&Folder);
  492. g_pStore->FreeRecord(&Folder);
  493. }
  494. // BUG #41686 Catchup Implementation
  495. void MenuUtil_OnCatchUp(FOLDERID idFolder)
  496. {
  497. FOLDERINFO Folder;
  498. BOOL fFreeRange;
  499. CRangeList *pRange;
  500. IMessageFolder *pFolder;
  501. ADJUSTFLAGS flags;
  502. HCURSOR hcur;
  503. hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  504. if (SUCCEEDED(g_pStore->OpenFolder(idFolder, NULL, NOFLAGS, &pFolder)))
  505. {
  506. flags.dwAdd = ARF_READ;
  507. flags.dwRemove = ARF_DOWNLOAD;
  508. pFolder->SetMessageFlags(NULL, &flags, NULL, NULL);
  509. pFolder->Release();
  510. }
  511. if (SUCCEEDED(g_pStore->GetFolderInfo(idFolder, &Folder)))
  512. {
  513. fFreeRange = FALSE;
  514. if (Folder.dwServerHigh > 0)
  515. {
  516. Folder.dwClientHigh = Folder.dwServerHigh;
  517. pRange = new CRangeList;
  518. if (pRange != NULL)
  519. {
  520. if (Folder.Requested.cbSize > 0)
  521. pRange->Load(Folder.Requested.pBlobData, Folder.Requested.cbSize);
  522. pRange->AddRange(0, Folder.dwServerHigh);
  523. fFreeRange = pRange->Save(&Folder.Requested.pBlobData, &Folder.Requested.cbSize);
  524. pRange->Release();
  525. }
  526. }
  527. else
  528. {
  529. Folder.dwServerLow = 0;
  530. Folder.dwServerHigh = 0;
  531. Folder.dwServerCount = 0;
  532. }
  533. Folder.dwNotDownloaded = 0;
  534. g_pStore->UpdateRecord(&Folder);
  535. if (fFreeRange)
  536. MemFree(Folder.Requested.pBlobData);
  537. g_pStore->FreeRecord(&Folder);
  538. }
  539. SetCursor(hcur);
  540. }
  541. UINT GetMenuItemPos(HMENU hmenu, UINT cmd)
  542. {
  543. MENUITEMINFO mii;
  544. UINT cItem, ipos;
  545. cItem = GetMenuItemCount(hmenu);
  546. mii.cbSize = sizeof(MENUITEMINFO);
  547. mii.fMask = MIIM_ID;
  548. for (ipos = 0; ipos < cItem; ipos++)
  549. {
  550. SideAssert(GetMenuItemInfo(hmenu, ipos, TRUE, &mii));
  551. if (mii.wID == cmd)
  552. break;
  553. }
  554. Assert(ipos != cItem);
  555. return(ipos);
  556. }
  557. BOOL MergeMenus(HMENU hmenuSrc, HMENU hmenuDst, int iPos, UINT uFlags)
  558. {
  559. MENUITEMINFO mii;
  560. UINT uState, i, cMerge;
  561. int cItem;
  562. BOOL fSepPre, fSepPost, fPopup, fCommand;
  563. BYTE rgch[CCHMAX_STRINGRES];
  564. HMENU hmenuPopup;
  565. cMerge = GetMenuItemCount(hmenuSrc);
  566. if (cMerge == 0)
  567. return(TRUE);
  568. cItem = GetMenuItemCount(hmenuDst);
  569. if (iPos == MMPOS_REPLACE)
  570. {
  571. // destroy all menus
  572. while (RemoveMenu(hmenuDst, 0, MF_BYPOSITION));
  573. cItem = 0;
  574. iPos = 0;
  575. }
  576. if (iPos == MMPOS_APPEND)
  577. iPos = cItem;
  578. fCommand = ((uFlags & MMF_BYCOMMAND) != 0);
  579. if (fCommand)
  580. iPos = GetMenuItemPos(hmenuDst, (UINT)iPos);
  581. if (iPos > cItem)
  582. iPos = cItem;
  583. fSepPre = FALSE;
  584. fSepPost = FALSE;
  585. if (uFlags & MMF_SEPARATOR)
  586. {
  587. if (iPos == 0)
  588. {
  589. // prepending, so stick in a separator after all the items
  590. // ASSUMES: never a separator as the last item in a menu
  591. if (cItem > 0)
  592. fSepPost = TRUE;
  593. }
  594. else if (iPos == cItem)
  595. {
  596. // appending, so stick in a separator before all the items
  597. // ASSUMES: never a separator as the first item in a menu
  598. fSepPre = TRUE;
  599. }
  600. else
  601. {
  602. // merging stuff into the middle of the menu, so need to check before and after
  603. uState = GetMenuState(hmenuDst, iPos - 1, MF_BYPOSITION);
  604. if (!(uState & MF_SEPARATOR))
  605. fSepPre = TRUE;
  606. uState = GetMenuState(hmenuDst, iPos, MF_BYPOSITION);
  607. if (!(uState & MF_SEPARATOR))
  608. fSepPost = TRUE;
  609. }
  610. }
  611. if (fSepPre)
  612. {
  613. InsertMenu(hmenuDst, (UINT)iPos, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
  614. iPos++;
  615. }
  616. ZeroMemory(&mii, sizeof(mii));
  617. mii.cbSize = sizeof(MENUITEMINFO);
  618. mii.fMask = MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
  619. for (i = 0; i < cMerge; i++)
  620. {
  621. mii.dwTypeData = (LPSTR)rgch;
  622. mii.cch = sizeof(rgch);
  623. mii.fType = 0;
  624. GetMenuItemInfo(hmenuSrc, i, TRUE, &mii);
  625. fPopup = (mii.hSubMenu != NULL);
  626. if (!fPopup && (mii.fType & MFT_SEPARATOR))
  627. {
  628. InsertMenuItem(hmenuDst, (UINT)iPos, TRUE, &mii);
  629. }
  630. else
  631. {
  632. if (fPopup)
  633. {
  634. // its a popup submenu item
  635. hmenuPopup = CreateMenu();
  636. MergeMenus(mii.hSubMenu, hmenuPopup, 0, 0);
  637. mii.hSubMenu = hmenuPopup;
  638. }
  639. InsertMenuItem(hmenuDst, (UINT)iPos, TRUE, &mii);
  640. }
  641. iPos++;
  642. }
  643. if (fSepPost)
  644. {
  645. InsertMenu(hmenuDst, (UINT)iPos, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
  646. iPos++;
  647. }
  648. return(TRUE);
  649. }
  650. //
  651. // REVIEW: We need this function because current version of USER.EXE does
  652. // not support pop-up only menu.
  653. //
  654. HMENU LoadPopupMenu(UINT id)
  655. {
  656. HMENU hmenuParent = LoadMenu(g_hLocRes, MAKEINTRESOURCE(id));
  657. if (hmenuParent) {
  658. HMENU hpopup = GetSubMenu(hmenuParent, 0);
  659. RemoveMenu(hmenuParent, 0, MF_BYPOSITION);
  660. DestroyMenu(hmenuParent);
  661. return hpopup;
  662. }
  663. return NULL;
  664. }
  665. // walks a menu recursively, calling pfn for each item that isn't a separator
  666. void WalkMenu(HMENU hMenu, WALKMENUFN pfn, LPVOID lpv)
  667. {
  668. MENUITEMINFO mii;
  669. int i, cItems;
  670. ZeroMemory(&mii, sizeof(mii));
  671. mii.cbSize = sizeof(mii);
  672. mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_SUBMENU;
  673. cItems = GetMenuItemCount(hMenu);
  674. for (i=0; i<cItems; i++)
  675. {
  676. mii.dwTypeData = 0;
  677. mii.cch = 0;
  678. if (GetMenuItemInfo(hMenu, i, TRUE, &mii))
  679. {
  680. if (!(mii.fType & MFT_SEPARATOR))
  681. (*pfn)(hMenu, mii.wID, lpv);
  682. if (mii.hSubMenu)
  683. WalkMenu(mii.hSubMenu, pfn, lpv);
  684. }
  685. }
  686. }
  687. void MenuUtil_BuildMenuIDList(HMENU hMenu, OLECMD **prgCmds, ULONG *pcStart, ULONG *pcCmds)
  688. {
  689. ULONG cItems = 0;
  690. MENUITEMINFO mii;
  691. ZeroMemory(&mii, sizeof(mii));
  692. if(!IsMenu(hMenu))
  693. return;
  694. // Start by getting the count of items on this menu
  695. cItems = GetMenuItemCount(hMenu);
  696. if (!cItems)
  697. return;
  698. // Realloc the array to be cItems elements bigger
  699. if (!MemRealloc((LPVOID *) prgCmds, sizeof(OLECMD) * (cItems + (*pcCmds))))
  700. return;
  701. *pcCmds += cItems;
  702. // Walk this menu and add our items to it
  703. mii.cbSize = sizeof(MENUITEMINFO);
  704. mii.fMask = MIIM_ID | MIIM_SUBMENU;
  705. for (ULONG i = 0; i < cItems; i++)
  706. {
  707. if (GetMenuItemInfo(hMenu, i, TRUE, &mii))
  708. {
  709. // Make sure this isn't a separator
  710. if (mii.wID != -1 && mii.wID != 0)
  711. {
  712. // Add the ID to our array
  713. (*prgCmds)[*pcStart].cmdID = mii.wID;
  714. (*prgCmds)[*pcStart].cmdf = 0;
  715. (*pcStart)++;
  716. // See if we need to recurse
  717. if (mii.hSubMenu)
  718. {
  719. MenuUtil_BuildMenuIDList(mii.hSubMenu, prgCmds, pcStart, pcCmds);
  720. }
  721. }
  722. }
  723. }
  724. return;
  725. }
  726. //
  727. // FUNCTION: MenuUtil_EnablePopupMenu()
  728. //
  729. // PURPOSE: Walks the given menu and takes care of enabling and
  730. // disabling each item via the provided commnand target.
  731. //
  732. // PARAMETERS:
  733. // [in] hPopup
  734. // [in] *pTarget
  735. //
  736. HRESULT MenuUtil_EnablePopupMenu(HMENU hPopup, IOleCommandTarget *pTarget)
  737. {
  738. HRESULT hr = S_OK;
  739. int i;
  740. int cItems;
  741. OLECMD *rgCmds = NULL;
  742. ULONG cStart = 0;
  743. ULONG cCmds = 0;
  744. MENUITEMINFO mii = {0};
  745. Assert(hPopup && pTarget);
  746. // Build the array of menu ids
  747. MenuUtil_BuildMenuIDList(hPopup, &rgCmds, &cCmds, &cStart);
  748. // Ask our parent for the state of the commands
  749. if (SUCCEEDED(hr = pTarget->QueryStatus(&CMDSETID_OutlookExpress, cCmds, rgCmds, NULL)))
  750. {
  751. mii.cbSize = sizeof(MENUITEMINFO);
  752. // Now loop through the menu and apply the state
  753. for (i = 0; i < (int) cCmds; i++)
  754. {
  755. // The default thing we're going to update is the state
  756. mii.fMask = MIIM_STATE;
  757. // Enabled or Disabled
  758. if (rgCmds[i].cmdf & OLECMDF_ENABLED)
  759. mii.fState = MFS_ENABLED;
  760. else
  761. mii.fState = MFS_GRAYED;
  762. // Checked?
  763. if (rgCmds[i].cmdf & OLECMDF_LATCHED)
  764. mii.fState |= MFS_CHECKED;
  765. // Set the item state
  766. BOOL f;
  767. f = SetMenuItemInfo(hPopup, rgCmds[i].cmdID, FALSE, &mii);
  768. // Radio Check?
  769. if ((rgCmds[i].cmdf & OLECMDF_NINCHED) && rgCmds[i].cmdID != (-1))
  770. {
  771. CheckMenuRadioItem(hPopup, rgCmds[i].cmdID, rgCmds[i].cmdID, rgCmds[i].cmdID, MF_BYCOMMAND);
  772. // mii.fMask |= MIIM_TYPE;
  773. // mii.fType = MFT_RADIOCHECK;
  774. // mii.fState |= MFS_CHECKED;
  775. }
  776. // Assert(f);
  777. }
  778. }
  779. SafeMemFree(rgCmds);
  780. return (hr);
  781. }
  782. void HandleMenuSelect(CStatusBar *pStatus, WPARAM wParam, LPARAM lParam)
  783. {
  784. UINT fuFlags, uItem;
  785. HMENU hmenu = GET_WM_MENUSELECT_HMENU(wParam, lParam);
  786. if (!pStatus)
  787. return;
  788. uItem = (UINT) LOWORD(wParam);
  789. fuFlags = (UINT) HIWORD(wParam);
  790. if (fuFlags & MF_POPUP)
  791. {
  792. MENUITEMINFO mii = { sizeof(MENUITEMINFO), MIIM_ID, 0 };
  793. if (hmenu && IsMenu(hmenu))
  794. {
  795. // Windows 98 seems to pass the command ID for popup items instead
  796. // of the documented position. So, if uItem is less than 40000 then
  797. // we can assume this is a menu position otherwise we assume it's
  798. // a command ID.
  799. if (GetMenuItemInfo(hmenu, uItem, (uItem < ID_FIRST), &mii))
  800. {
  801. // change the parameters to simulate a normal menu item
  802. uItem = mii.wID;
  803. fuFlags = 0;
  804. }
  805. }
  806. }
  807. if (0 == (fuFlags & (MF_SYSMENU | MF_POPUP)))
  808. {
  809. TCHAR szMenu[256], szRes[CCHMAX_STRINGRES], szTemp[CCHMAX_STRINGRES + 256];
  810. if (uItem >= ID_SORT_MENU_FIRST && uItem <= ID_SORT_MENU_LAST)
  811. {
  812. MENUITEMINFO mii = {0};
  813. *szMenu = '\0';
  814. *szRes = '\0';
  815. *szTemp = '\0';
  816. // must be a sort menu command! pull the menu name from the menu
  817. mii.cbSize = sizeof(MENUITEMINFO);
  818. mii.fMask = MIIM_TYPE;
  819. mii.dwTypeData = (LPSTR)szMenu;
  820. mii.cch = ARRAYSIZE(szMenu);
  821. if (GetMenuItemInfo((HMENU)lParam, uItem, FALSE, &mii))
  822. {
  823. AthLoadString(idsSortMenuHelpControl, szRes, sizeof(szRes));
  824. wnsprintf(szTemp, ARRAYSIZE(szTemp), szRes, szMenu);
  825. pStatus->ShowSimpleText(szTemp);
  826. }
  827. }
  828. else if (uItem >= ID_FIRST && uItem <= ID_LAST)
  829. {
  830. uItem = uItem - ID_FIRST;
  831. pStatus->ShowSimpleText(MAKEINTRESOURCE(uItem));
  832. }
  833. else if ((uItem >= ID_VIEW_FILTER_FIRST) && (uItem <= ID_VIEW_FILTER_LAST))
  834. {
  835. if ((uItem >= ID_VIEW_CURRENT) && (uItem <= ID_VIEW_RECENT_4))
  836. {
  837. MENUITEMINFO mii = {0};
  838. *szMenu = '\0';
  839. *szRes = '\0';
  840. *szTemp = '\0';
  841. // must be a sort menu command! pull the menu name from the menu
  842. mii.cbSize = sizeof(MENUITEMINFO);
  843. mii.fMask = MIIM_TYPE;
  844. mii.dwTypeData = (LPSTR)szMenu;
  845. mii.cch = ARRAYSIZE(szMenu);
  846. if (GetMenuItemInfo((HMENU)lParam, uItem, FALSE, &mii))
  847. {
  848. AthLoadString(idsViewMenuHelpControl, szRes, sizeof(szRes));
  849. wnsprintf(szTemp, ARRAYSIZE(szTemp), szRes, szMenu);
  850. pStatus->ShowSimpleText(szTemp);
  851. }
  852. }
  853. else
  854. {
  855. uItem = uItem - ID_FIRST;
  856. pStatus->ShowSimpleText(MAKEINTRESOURCE(uItem));
  857. }
  858. }
  859. else if ((uItem >= ID_MESSENGER_FIRST) && (uItem<= ID_MESSENGER_LAST))
  860. {
  861. TCHAR szBuf[CCHMAX_STRINGRES] = "";
  862. AthLoadString(uItem - ID_FIRST, szBuf, ARRAYSIZE(szBuf));
  863. MenuUtil_BuildMessengerString(szBuf, ARRAYSIZE(szBuf));
  864. pStatus->ShowSimpleText(szBuf);
  865. }
  866. else
  867. {
  868. if (uItem >= ID_ACCOUNT_FIRST && uItem <= ID_ACCOUNT_LAST)
  869. pStatus->ShowSimpleText(MAKEINTRESOURCE(idsSRAccountMenuHelp));
  870. else
  871. pStatus->ShowSimpleText(0);
  872. }
  873. }
  874. else if (fuFlags == 0xffff && ((HMENU)lParam) == NULL)
  875. {
  876. pStatus->HideSimpleText();
  877. }
  878. }
  879. //
  880. // FUNCTION: MenuUtil_SetPopupDefault()
  881. //
  882. // PURPOSE: Bolds the default item in a context menu
  883. //
  884. // PARAMETERS:
  885. //
  886. // RETURN VALUE:
  887. //
  888. void MenuUtil_SetPopupDefault(HMENU hPopup, UINT idDefault)
  889. {
  890. MENUITEMINFO mii;
  891. mii.cbSize = sizeof(MENUITEMINFO);
  892. mii.fMask = MIIM_STATE;
  893. if (GetMenuItemInfo(hPopup, idDefault, FALSE, &mii))
  894. {
  895. mii.fState |= MFS_DEFAULT;
  896. SetMenuItemInfo(hPopup, idDefault, FALSE , &mii);
  897. }
  898. }
  899. //
  900. // FUNCTION: MenuUtil_ReplaceHelpMenu
  901. //
  902. // PURPOSE: Populates the ID_POPUP_HELP menu
  903. //
  904. void MenuUtil_ReplaceHelpMenu(HMENU hMenu)
  905. {
  906. MENUITEMINFO mii;
  907. if (mii.hSubMenu = LoadPopupMenu(IDR_HELP_POPUP))
  908. {
  909. mii.cbSize = sizeof(MENUITEMINFO);
  910. mii.fMask = MIIM_SUBMENU;
  911. SetMenuItemInfo(hMenu, ID_POPUP_HELP, FALSE, &mii);
  912. }
  913. }
  914. //
  915. // FUNCTION: MenuUtil_ReplaceNewMsgMenu
  916. //
  917. // PURPOSE: Populates the ID_POPUP_HELP menu
  918. //
  919. void MenuUtil_ReplaceNewMsgMenus(HMENU hMenu)
  920. {
  921. MENUITEMINFO mii;
  922. if (mii.hSubMenu = LoadPopupMenu(IDR_NEW_MSG_POPUP))
  923. {
  924. mii.cbSize = sizeof(MENUITEMINFO);
  925. mii.fMask = MIIM_SUBMENU;
  926. SetMenuItemInfo(hMenu, ID_POPUP_NEW_MSG, FALSE, &mii);
  927. }
  928. }
  929. //
  930. // FUNCTION: MenuUtil_ReplaceMessengerMenus
  931. //
  932. // PURPOSE: Customizes the Messenger menus with IEAK Messenger names...
  933. //
  934. void MenuUtil_ReplaceMessengerMenus(HMENU hMenu)
  935. {
  936. ULONG ulMenuItem;
  937. MENUITEMINFO mii;
  938. TCHAR szName[CCHMAX_STRINGRES];
  939. for(ulMenuItem=ID_MESSENGER_FIRST;ulMenuItem<ID_MESSENGER_LAST;ulMenuItem++)
  940. {
  941. ZeroMemory(&mii, sizeof(MENUITEMINFO));
  942. mii.cbSize = sizeof(MENUITEMINFO);
  943. mii.fMask = MIIM_TYPE;
  944. mii.dwTypeData = szName;
  945. mii.cch = CCHMAX_STRINGRES;
  946. if(GetMenuItemInfo(hMenu, ulMenuItem, FALSE, &mii))
  947. {
  948. if(MenuUtil_BuildMessengerString(szName, ARRAYSIZE(szName)))
  949. {
  950. mii.cbSize = sizeof(MENUITEMINFO);
  951. mii.fMask = MIIM_TYPE;
  952. mii.fType = MFT_STRING;
  953. mii.dwTypeData = szName;
  954. SetMenuItemInfo(hMenu, ulMenuItem, FALSE, &mii);
  955. }
  956. }
  957. }
  958. }
  959. BOOL MenuUtil_BuildMessengerString(LPTSTR szMesStr, DWORD cchMesStr)
  960. {
  961. static TCHAR s_szCustName[51] = ""; //We know the name is less than 50 chars
  962. TCHAR szNewMesStr[CCHMAX_STRINGRES];
  963. HKEY hkey = NULL;
  964. DWORD cb;
  965. BOOL fReplaced=FALSE;
  966. Assert(szMesStr);
  967. if(s_szCustName[0] == 0)
  968. {
  969. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\MessengerService", 0, KEY_READ, &hkey))
  970. {
  971. cb = sizeof(s_szCustName);
  972. RegQueryValueEx(hkey, "", NULL, NULL, (LPBYTE)s_szCustName, &cb);
  973. RegCloseKey(hkey);
  974. }
  975. if(s_szCustName[0] == 0)
  976. AthLoadString(idsServiceName, s_szCustName, ARRAYSIZE(s_szCustName));
  977. }
  978. fReplaced = (NULL != StrStr(szMesStr, "%s"));
  979. //HACK! For strings needing multiple replacement...
  980. if (fReplaced)
  981. {
  982. wnsprintf(szNewMesStr, ARRAYSIZE(szNewMesStr), szMesStr, s_szCustName, s_szCustName, s_szCustName, s_szCustName);
  983. StrCpyN(szMesStr, szNewMesStr, cchMesStr);
  984. }
  985. return fReplaced;
  986. }
  987. void GetDefaultFolderID(BOOL fMail, FOLDERID *pFolderID)
  988. {
  989. IImnAccount *pAcct = NULL;
  990. CHAR szAccountId[CCHMAX_ACCOUNT_NAME];
  991. IEnumerateFolders *pEnumFolders = NULL;
  992. FOLDERINFO rFolder;
  993. BOOL fFound = FALSE;
  994. ACCTTYPE acctType = ACCT_NEWS;
  995. DWORD dwServerTypes = 0;
  996. *pFolderID = FOLDERID_INVALID;
  997. if (FAILED(g_pAcctMan->GetDefaultAccount(fMail?ACCT_MAIL:ACCT_NEWS, &pAcct)))
  998. goto Exit;
  999. if (FAILED(pAcct->GetAccountType(&acctType)))
  1000. goto Exit;
  1001. if ((ACCT_NEWS != acctType) && SUCCEEDED(pAcct->GetServerTypes(&dwServerTypes)) && (dwServerTypes & SRV_POP3))
  1002. {
  1003. *pFolderID = FOLDERID_LOCAL_STORE;
  1004. goto Exit;
  1005. }
  1006. *szAccountId = 0;
  1007. if (FAILED(pAcct->GetPropSz(AP_ACCOUNT_ID, szAccountId, ARRAYSIZE(szAccountId))))
  1008. goto Exit;
  1009. if (FAILED(g_pStore->EnumChildren(FOLDERID_ROOT, TRUE, &pEnumFolders)))
  1010. goto Exit;
  1011. AssertSz(pAcct, "How did we succeed and not get a pAcct?");
  1012. AssertSz(pEnumFolders, "How did we succeed and not get a pEnumFolders?");
  1013. while (!fFound && (S_OK == pEnumFolders->Next(1, &rFolder, NULL)))
  1014. {
  1015. fFound = (0 == lstrcmp(szAccountId, rFolder.pszAccountId));
  1016. if (fFound)
  1017. *pFolderID = rFolder.idFolder;
  1018. g_pStore->FreeRecord(&rFolder);
  1019. }
  1020. Exit:
  1021. ReleaseObj(pAcct);
  1022. ReleaseObj(pEnumFolders);
  1023. }
  1024. //
  1025. // FUNCTION: MenuUtil_HandleNewMessageIDs
  1026. //
  1027. // PURPOSE: Handles creation of notes from an ID
  1028. //
  1029. // RETURN VALUE: Returns TRUE if event was handled
  1030. //
  1031. BOOL MenuUtil_HandleNewMessageIDs(DWORD id, HWND hwnd, FOLDERID folderID, BOOL fMail, BOOL fModal, IUnknown *pUnkPump)
  1032. {
  1033. switch (id)
  1034. {
  1035. case ID_NEW_NEWS_MESSAGE:
  1036. case ID_NEW_MAIL_MESSAGE:
  1037. case ID_NEW_MSG_DEFAULT:
  1038. {
  1039. FOLDERINFO rInfo = {0};
  1040. if (id != ID_NEW_MSG_DEFAULT)
  1041. fMail = (id == ID_NEW_MAIL_MESSAGE);
  1042. if (SUCCEEDED(g_pStore->GetFolderInfo(folderID, &rInfo)))
  1043. {
  1044. BOOL fFolderIsMail = (rInfo.tyFolder != FOLDER_NEWS);
  1045. if (fFolderIsMail != fMail)
  1046. GetDefaultFolderID(fMail, &folderID);
  1047. g_pStore->FreeRecord(&rInfo);
  1048. }
  1049. if (DwGetOption(fMail ? OPT_MAIL_USESTATIONERY : OPT_NEWS_USESTATIONERY))
  1050. {
  1051. WCHAR wszFile[MAX_PATH];
  1052. if (SUCCEEDED(GetDefaultStationeryName(fMail, wszFile)) &&
  1053. SUCCEEDED(HrNewStationery(hwnd, 0, wszFile, fModal, fMail, folderID, FALSE, NSS_DEFAULT, pUnkPump, NULL)))
  1054. {
  1055. return TRUE;
  1056. }
  1057. // If HrNewStationery fails, go ahead and try opening a blank note without stationery.
  1058. }
  1059. FNewMessage(hwnd, fModal, !DwGetOption(fMail ? OPT_MAIL_SEND_HTML : OPT_NEWS_SEND_HTML), !fMail, folderID, pUnkPump);
  1060. return TRUE;
  1061. }
  1062. case ID_STATIONERY_RECENT_0:
  1063. case ID_STATIONERY_RECENT_1:
  1064. case ID_STATIONERY_RECENT_2:
  1065. case ID_STATIONERY_RECENT_3:
  1066. case ID_STATIONERY_RECENT_4:
  1067. case ID_STATIONERY_RECENT_5:
  1068. case ID_STATIONERY_RECENT_6:
  1069. case ID_STATIONERY_RECENT_7:
  1070. case ID_STATIONERY_RECENT_8:
  1071. case ID_STATIONERY_RECENT_9:
  1072. HrNewStationery(hwnd, id, NULL, fModal, fMail, folderID, TRUE, NSS_MRU, pUnkPump, NULL);
  1073. return TRUE;
  1074. case ID_STATIONERY_MORE:
  1075. HrMoreStationery(hwnd, fModal, fMail, folderID, pUnkPump);
  1076. return TRUE;
  1077. case ID_STATIONERY_NONE:
  1078. FNewMessage(hwnd, fModal, TRUE, !fMail, folderID, pUnkPump);
  1079. return TRUE;
  1080. case ID_WEB_PAGE:
  1081. HrSendWebPage(hwnd, fModal, fMail, folderID, pUnkPump);
  1082. return TRUE;
  1083. }
  1084. return FALSE;
  1085. }
  1086. HRESULT MenuUtil_NewMessageIDsQueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText, BOOL fMail)
  1087. {
  1088. DWORD cMailServer = 0;
  1089. DWORD cNewsServer = 0;
  1090. DWORD cDefServer = 0;
  1091. DWORD dwDefFlags;
  1092. // For right now, NULL is acceptable.
  1093. if (pguidCmdGroup && !IsEqualGUID(CMDSETID_OutlookExpress, *pguidCmdGroup))
  1094. return S_OK;
  1095. g_pAcctMan->GetAccountCount(ACCT_NEWS, &cMailServer);
  1096. g_pAcctMan->GetAccountCount(ACCT_MAIL, &cNewsServer);
  1097. cDefServer = fMail ? cMailServer : cNewsServer;
  1098. // If there is at least one server and we are not mail in news only mode
  1099. if (!fMail || (0 == (g_dwAthenaMode & MODE_NEWSONLY)))
  1100. dwDefFlags = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1101. else
  1102. dwDefFlags = OLECMDF_SUPPORTED;
  1103. for (UINT i = 0; i < cCmds; i++)
  1104. {
  1105. if (prgCmds[i].cmdf == 0)
  1106. {
  1107. switch (prgCmds[i].cmdID)
  1108. {
  1109. case ID_POPUP_NEW_MSG:
  1110. case ID_NEW_MSG_DEFAULT:
  1111. case ID_STATIONERY_RECENT_0:
  1112. case ID_STATIONERY_RECENT_1:
  1113. case ID_STATIONERY_RECENT_2:
  1114. case ID_STATIONERY_RECENT_3:
  1115. case ID_STATIONERY_RECENT_4:
  1116. case ID_STATIONERY_RECENT_5:
  1117. case ID_STATIONERY_RECENT_6:
  1118. case ID_STATIONERY_RECENT_7:
  1119. case ID_STATIONERY_RECENT_8:
  1120. case ID_STATIONERY_RECENT_9:
  1121. case ID_STATIONERY_MORE:
  1122. case ID_STATIONERY_NONE:
  1123. prgCmds[i].cmdf = dwDefFlags;
  1124. break;
  1125. case ID_WEB_PAGE:
  1126. // If is enabled, then better make sure that we are on line.
  1127. if ((dwDefFlags & OLECMDF_ENABLED) && g_pConMan->IsGlobalOffline())
  1128. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1129. else
  1130. prgCmds[i].cmdf = dwDefFlags;
  1131. break;
  1132. case ID_NEW_MAIL_MESSAGE:
  1133. if (!(g_dwAthenaMode & MODE_NEWSONLY))
  1134. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1135. else
  1136. prgCmds[i].cmdf = OLECMDF_SUPPORTED;
  1137. break;
  1138. case ID_NEW_NEWS_MESSAGE:
  1139. prgCmds[i].cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
  1140. break;
  1141. }
  1142. }
  1143. }
  1144. return S_OK;
  1145. }
  1146. HRESULT MenuUtil_EnableMenu(HMENU hMenu, IOleCommandTarget *pTarget)
  1147. {
  1148. int Count;
  1149. HMENU hMenuSub;
  1150. HRESULT hr = S_OK;
  1151. Count = GetMenuItemCount(hMenu);
  1152. if (Count != -1)
  1153. {
  1154. while (--Count >= 0)
  1155. {
  1156. hMenuSub = GetSubMenu(hMenu, Count);
  1157. hr = MenuUtil_EnablePopupMenu(hMenuSub, pTarget);
  1158. }
  1159. }
  1160. else
  1161. hr = E_FAIL;
  1162. return hr;
  1163. }