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.

697 lines
20 KiB

  1. #include "priv.h"
  2. #include "browmenu.h"
  3. #include "resource.h"
  4. #include "uemapp.h"
  5. #include "mluisupp.h"
  6. #include <varutil.h>
  7. #include "legacy.h"
  8. #define UEM_NEWITEMCOUNT 2
  9. // Exported by shdocvw
  10. STDAPI GetLinkInfo(IShellFolder* psf, LPCITEMIDLIST pidlItem, BOOL* pfAvailable, BOOL* pfSticky);
  11. #define REG_STR_MAIN TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\Main")
  12. BOOL AreIntelliMenusEnbaled()
  13. {
  14. // This is only garenteed to work on version 5 shell because the session
  15. // incrementer is located in the tray
  16. if (GetUIVersion() >= 5)
  17. {
  18. DWORD dwRest = SHRestricted(REST_INTELLIMENUS);
  19. if (dwRest != RESTOPT_INTELLIMENUS_USER)
  20. return (dwRest == RESTOPT_INTELLIMENUS_ENABLED);
  21. return SHRegGetBoolUSValue(REG_STR_MAIN, TEXT("FavIntelliMenus"),
  22. FALSE, FALSE); // Don't ignore HKCU, Disable Menus by default
  23. }
  24. else
  25. return FALSE;
  26. }
  27. CFavoritesCallback::CFavoritesCallback() : _cRef(1)
  28. {
  29. _fOffline = BOOLIFY(SHIsGlobalOffline());
  30. }
  31. CFavoritesCallback::~CFavoritesCallback()
  32. {
  33. ASSERT(_punkSite == NULL);
  34. ASSERT(_psmFavCache == NULL);
  35. }
  36. /*----------------------------------------------------------
  37. Purpose: IUnknown::QueryInterface method
  38. */
  39. STDMETHODIMP CFavoritesCallback::QueryInterface (REFIID riid, LPVOID * ppvObj)
  40. {
  41. static const QITAB qit[] =
  42. {
  43. QITABENT(CFavoritesCallback, IShellMenuCallback),
  44. QITABENT(CFavoritesCallback, IObjectWithSite),
  45. { 0 },
  46. };
  47. return QISearch(this, qit, riid, ppvObj);
  48. }
  49. /*----------------------------------------------------------
  50. Purpose: IUnknown::AddRef method
  51. */
  52. STDMETHODIMP_(ULONG) CFavoritesCallback::AddRef ()
  53. {
  54. return ++_cRef;
  55. }
  56. /*----------------------------------------------------------
  57. Purpose: IUnknown::Release method
  58. */
  59. STDMETHODIMP_(ULONG) CFavoritesCallback::Release()
  60. {
  61. ASSERT(_cRef > 0);
  62. _cRef--;
  63. if( _cRef > 0)
  64. return _cRef;
  65. delete this;
  66. return 0;
  67. }
  68. /*----------------------------------------------------------
  69. Purpose: IObjectWithSite::SetSite method
  70. */
  71. STDMETHODIMP CFavoritesCallback::SetSite(IUnknown* punk)
  72. {
  73. ATOMICRELEASE(_punkSite);
  74. _punkSite = punk;
  75. if (_punkSite)
  76. {
  77. _punkSite->AddRef();
  78. }
  79. else if (_psmFavCache)
  80. {
  81. // Since the top level menu is being destroyed, they are removing
  82. // our site. We should cleanup.
  83. DWORD dwFlags;
  84. UINT uId;
  85. UINT uIdA;
  86. _psmFavCache->GetMenuInfo(NULL, &uId, &uIdA, &dwFlags);
  87. // Tell menuband we're no longer caching it. We need to do this so ClowseDW
  88. // cleans up the menus.
  89. dwFlags &= ~SMINIT_CACHED;
  90. _psmFavCache->Initialize(NULL, uId, uIdA, dwFlags);
  91. IDeskBand* pdesk;
  92. if (SUCCEEDED(_psmFavCache->QueryInterface(IID_IDeskBand, (LPVOID*)&pdesk)))
  93. {
  94. pdesk->CloseDW(0);
  95. pdesk->Release();
  96. }
  97. ATOMICRELEASE(_psmFavCache);
  98. }
  99. return NOERROR;
  100. }
  101. /*----------------------------------------------------------
  102. Purpose: IShellMenuCallback::CallbackSM method
  103. */
  104. STDMETHODIMP CFavoritesCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  105. {
  106. HRESULT hres = S_FALSE;
  107. switch (uMsg)
  108. {
  109. case SMC_INITMENU:
  110. hres = _Init(psmd->hmenu, psmd->uIdParent, psmd->punk);
  111. break;
  112. case SMC_EXITMENU:
  113. hres = _Exit();
  114. break;
  115. case SMC_CREATE:
  116. if (psmd->uIdParent == FCIDM_MENU_FAVORITES)
  117. _fExpandoMenus = AreIntelliMenusEnbaled();
  118. break;
  119. case SMC_DEMOTE:
  120. hres = _Demote(psmd);
  121. break;
  122. case SMC_PROMOTE:
  123. hres = _Promote(psmd);
  124. break;
  125. case SMC_NEWITEM:
  126. hres = _HandleNew(psmd);
  127. break;
  128. case SMC_SFEXEC:
  129. hres = SHNavigateToFavorite(psmd->psf, psmd->pidlItem, _punkSite, SBSP_DEFBROWSER | SBSP_DEFMODE);
  130. break;
  131. case SMC_GETINFO:
  132. hres = _GetHmenuInfo(psmd->hmenu, psmd->uId, (SMINFO*)lParam);
  133. break;
  134. case SMC_SFSELECTITEM:
  135. hres = _SelectItem(psmd->pidlFolder, psmd->pidlItem);
  136. break;
  137. case SMC_GETOBJECT:
  138. hres = _GetObject(psmd, (GUID)*((GUID*)wParam), (void**)lParam);
  139. break;
  140. case SMC_DEFAULTICON:
  141. hres = _GetDefaultIcon((LPTSTR)wParam, (int*)lParam);
  142. break;
  143. case SMC_GETSFINFO:
  144. hres = _GetSFInfo(psmd, (SMINFO*)lParam);
  145. break;
  146. case SMC_SHCHANGENOTIFY:
  147. {
  148. PSMCSHCHANGENOTIFYSTRUCT pshf = (PSMCSHCHANGENOTIFYSTRUCT)lParam;
  149. hres = _ProcessChangeNotify(psmd, pshf->lEvent, pshf->pidl1, pshf->pidl2);
  150. }
  151. break;
  152. case SMC_REFRESH:
  153. _fExpandoMenus = AreIntelliMenusEnbaled();
  154. break;
  155. case SMC_CHEVRONGETTIP:
  156. hres = _GetTip((LPTSTR)wParam, (LPTSTR)lParam);
  157. break;
  158. case SMC_CHEVRONEXPAND:
  159. {
  160. if (_fShowingTip)
  161. {
  162. LPTSTR pszExpanded = TEXT("NO");
  163. SHRegSetUSValue(REG_STR_MAIN, TEXT("FavChevron"),
  164. REG_SZ, pszExpanded, lstrlen(pszExpanded) * sizeof(TCHAR), SHREGSET_FORCE_HKCU);
  165. }
  166. _fShowingTip = FALSE;
  167. hres = S_OK;
  168. }
  169. break;
  170. case SMC_DISPLAYCHEVRONTIP:
  171. // Should we show the tip?
  172. _fShowingTip = SHRegGetBoolUSValue(REG_STR_MAIN, TEXT("FavChevron"), FALSE, TRUE); // Default to YES.
  173. if (_fShowingTip)
  174. {
  175. hres = S_OK;
  176. }
  177. break;
  178. case SMC_SFDDRESTRICTED:
  179. hres = _AllowDrop((IDataObject*)wParam, (HWND)lParam) ? S_FALSE : S_OK;
  180. break;
  181. }
  182. return hres;
  183. }
  184. HRESULT CFavoritesCallback::_Init(HMENU hMenu, UINT uIdParent, IUnknown* punk)
  185. {
  186. #ifdef DEBUG
  187. if (GetAsyncKeyState(VK_SHIFT) < 0)
  188. {
  189. UEMFireEvent(&UEMIID_BROWSER, UEME_CTLSESSION, UEMF_XEVENT, TRUE, -1);
  190. }
  191. #endif
  192. HRESULT hres = S_FALSE;
  193. if (SUCCEEDED(IUnknown_QueryServiceExec(_punkSite, SID_STopLevelBrowser, &CGID_MenuBand, MBANDCID_ENTERMENU, 0, NULL, NULL)))
  194. hres = S_OK;
  195. // Only do this for the favorites dropdown. This was causing
  196. // the chevron menu to be invalidated before it was created. This caused some
  197. // resize problems because the metrics were unavailable.
  198. if (uIdParent == FCIDM_MENU_FAVORITES)
  199. {
  200. // If we switched between online and offline, we need to re-init the menu
  201. BOOL fOffline = BOOLIFY(SHIsGlobalOffline());
  202. if (fOffline ^ _fOffline || _fRefresh)
  203. {
  204. _fOffline = fOffline;
  205. IShellMenu* psm;
  206. if (SUCCEEDED(punk->QueryInterface(IID_IShellMenu, (void**)&psm)))
  207. {
  208. psm->InvalidateItem(NULL, SMINV_REFRESH);
  209. psm->Release();
  210. }
  211. _fRefresh = FALSE;
  212. }
  213. }
  214. return hres;
  215. }
  216. HRESULT CFavoritesCallback::_Exit()
  217. {
  218. HRESULT hr = IUnknown_QueryServiceExec(_punkSite, SID_STopLevelBrowser, &CGID_MenuBand, MBANDCID_EXITMENU, 0, NULL, NULL);
  219. return SUCCEEDED(hr) ? S_OK : S_FALSE;
  220. }
  221. HRESULT CFavoritesCallback::_GetHmenuInfo(HMENU hMenu, UINT uId, SMINFO* psminfo)
  222. {
  223. if (uId == FCIDM_MENU_FAVORITES)
  224. {
  225. if (psminfo->dwMask & SMIM_FLAGS)
  226. psminfo->dwFlags |= SMIF_DROPCASCADE;
  227. }
  228. else
  229. {
  230. if (psminfo->dwMask & SMIM_FLAGS)
  231. psminfo->dwFlags |= SMIF_TRACKPOPUP;
  232. }
  233. // No item has icons
  234. if (psminfo->dwMask & SMIM_ICON)
  235. psminfo->iIcon = -1;
  236. return S_OK;
  237. }
  238. HRESULT CFavoritesCallback::_GetSFInfo(SMDATA* psmd, SMINFO* psminfo)
  239. {
  240. BOOL fAvailable;
  241. //
  242. // If we are offline and the item is not available, we set the
  243. // SMIF_ALTSTATE so that the menu item is greyed
  244. //
  245. if (psminfo->dwMask & SMIM_FLAGS)
  246. {
  247. if (_fOffline &&
  248. SUCCEEDED(GetLinkInfo(psmd->psf, psmd->pidlItem, &fAvailable, NULL)) &&
  249. fAvailable == FALSE)
  250. {
  251. // Not available, so grey the item
  252. psminfo->dwFlags |= SMIF_ALTSTATE;
  253. }
  254. if (_fExpandoMenus)
  255. psminfo->dwFlags |= _GetDemote(psmd);
  256. }
  257. return S_OK;
  258. }
  259. HRESULT CFavoritesCallback::_SelectItem(LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidl)
  260. {
  261. HRESULT hres = S_FALSE;
  262. LPITEMIDLIST pidlFull = ILCombine(pidlFolder, pidl);
  263. if (pidlFull)
  264. {
  265. VARIANTARG vargIn;
  266. hres = InitVariantFromIDList(&vargIn, pidlFull);
  267. if (SUCCEEDED(hres))
  268. {
  269. hres = IUnknown_QueryServiceExec(_punkSite, SID_SMenuBandHandler,
  270. &CGID_MenuBandHandler, MBHANDCID_PIDLSELECT, 0, &vargIn, NULL);
  271. VariantClearLazy(&vargIn);
  272. }
  273. ILFree(pidlFull);
  274. }
  275. return hres;
  276. }
  277. void CFavoritesCallback::_RefreshItem(HMENU hmenu, int idCmd, IShellMenu* psm)
  278. {
  279. SMDATA smd;
  280. smd.dwMask = SMDM_HMENU;
  281. smd.hmenu = hmenu;
  282. smd.uId = idCmd;
  283. psm->InvalidateItem(&smd, SMINV_ID | SMINV_REFRESH);
  284. }
  285. HRESULT CFavoritesCallback::_GetObject(LPSMDATA psmd, REFIID riid, void** ppvOut)
  286. {
  287. HRESULT hres = S_FALSE;
  288. *ppvOut = NULL;
  289. if (IsEqualIID(IID_IShellMenu, riid))
  290. {
  291. if (psmd->uId == FCIDM_MENU_FAVORITES)
  292. {
  293. // Do we have a cached Favorites menu?
  294. if (_psmFavCache)
  295. {
  296. // Yes we do, return it
  297. _psmFavCache->AddRef();
  298. *ppvOut = (LPVOID)_psmFavCache;
  299. hres = S_OK;
  300. }
  301. else
  302. {
  303. // Nope; We need to create one...
  304. hres = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC,
  305. IID_IShellMenu, (void**)&_psmFavCache);
  306. if (SUCCEEDED(hres))
  307. {
  308. HMENU hmenu = NULL;
  309. HWND hwnd;
  310. _psmFavCache->Initialize(this, FCIDM_MENU_FAVORITES, ANCESTORDEFAULT,
  311. SMINIT_CACHED | SMINIT_VERTICAL);
  312. // We need to grab the Top HMENU portion of the Favorites menu from the current band
  313. IShellMenu* psm;
  314. if (SUCCEEDED(psmd->punk->QueryInterface(IID_IShellMenu, (LPVOID*)&psm)))
  315. {
  316. psm->GetMenu(&hmenu, &hwnd, NULL);
  317. hmenu = GetSubMenu(hmenu, GetMenuPosFromID(hmenu, FCIDM_MENU_FAVORITES));
  318. // Delete the placeholder item (there to keep the separator from getting
  319. // lost during shbrowse menu merging, which deletes trailing separators).
  320. int iPos = GetMenuPosFromID(hmenu, FCIDM_FAVPLACEHOLDER);
  321. if (iPos >= 0)
  322. DeleteMenu(hmenu, iPos, MF_BYPOSITION);
  323. psm->Release();
  324. }
  325. if (hmenu)
  326. {
  327. hres = _psmFavCache->SetMenu(hmenu, hwnd, SMSET_TOP | SMSET_DONTOWN);
  328. }
  329. LPITEMIDLIST pidlFav;
  330. if (SUCCEEDED(hres) &&
  331. SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidlFav)))
  332. {
  333. IShellFolder* psf;
  334. if (SUCCEEDED(IEBindToObject(pidlFav, &psf)))
  335. {
  336. HKEY hMenuKey;
  337. DWORD dwDisp;
  338. RegCreateKeyEx(HKEY_CURRENT_USER, STRREG_FAVORITES, NULL, NULL,
  339. REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
  340. NULL, &hMenuKey, &dwDisp);
  341. hres = _psmFavCache->SetShellFolder(psf, pidlFav, hMenuKey,
  342. SMSET_BOTTOM | SMSET_USEBKICONEXTRACTION | SMSET_HASEXPANDABLEFOLDERS);
  343. psf->Release();
  344. }
  345. ILFree(pidlFav);
  346. }
  347. if (SUCCEEDED(hres))
  348. {
  349. _psmFavCache->AddRef(); // We're caching this.
  350. *ppvOut = _psmFavCache;
  351. }
  352. }
  353. }
  354. }
  355. }
  356. else if (IsEqualIID(IID_IShellMenuCallback, riid))
  357. {
  358. IShellMenuCallback* psmcb = (IShellMenuCallback*) new CFavoritesCallback;
  359. if (psmcb)
  360. {
  361. *ppvOut = (LPVOID)psmcb;
  362. hres = S_OK;
  363. }
  364. }
  365. return hres;
  366. }
  367. // Short circuit the looking up of a default icon. We're going to assume that all of them
  368. // are URLs, even folders, for the sake of speed. It gives the user feedback directly, then
  369. // we asyncronously render the real icons.
  370. HRESULT CFavoritesCallback::_GetDefaultIcon(TCHAR* psz, int* piIndex)
  371. {
  372. HRESULT hr;
  373. DWORD cchSize = MAX_PATH;
  374. if (SUCCEEDED(hr = AssocQueryString(0, ASSOCSTR_DEFAULTICON, TEXT("InternetShortcut"), NULL, psz, &cchSize)))
  375. *piIndex = PathParseIconLocation(psz);
  376. return hr;
  377. }
  378. DWORD CFavoritesCallback::_GetDemote(SMDATA* psmd)
  379. {
  380. UEMINFO uei;
  381. DWORD dwFlags = 0;
  382. if (_fExpandoMenus)
  383. {
  384. uei.cbSize = SIZEOF(uei);
  385. uei.dwMask = UEIM_HIT;
  386. if (SUCCEEDED(UEMQueryEvent(&UEMIID_BROWSER, UEME_RUNPIDL, (WPARAM)psmd->psf, (LPARAM)psmd->pidlItem, &uei)))
  387. {
  388. if (uei.cHit == 0)
  389. {
  390. dwFlags |= SMIF_DEMOTED;
  391. }
  392. }
  393. }
  394. return dwFlags;
  395. }
  396. HRESULT CFavoritesCallback::_Demote(LPSMDATA psmd)
  397. {
  398. HRESULT hres = S_FALSE;
  399. if (_fExpandoMenus)
  400. {
  401. UEMINFO uei;
  402. uei.cbSize = SIZEOF(uei);
  403. uei.dwMask = UEIM_HIT;
  404. uei.cHit = 0;
  405. hres = UEMSetEvent(&UEMIID_BROWSER, UEME_RUNPIDL, (WPARAM)psmd->psf, (LPARAM)psmd->pidlItem, &uei);
  406. }
  407. return hres;
  408. }
  409. HRESULT CFavoritesCallback::_Promote(LPSMDATA psmd)
  410. {
  411. if (_fExpandoMenus)
  412. {
  413. UEMFireEvent(&UEMIID_BROWSER, UEME_RUNPIDL, UEMF_XEVENT, (WPARAM)psmd->psf, (LPARAM)psmd->pidlItem);
  414. }
  415. return S_OK;
  416. }
  417. HRESULT CFavoritesCallback::_HandleNew(LPSMDATA psmd)
  418. {
  419. HRESULT hres = S_FALSE;
  420. if (_fExpandoMenus)
  421. {
  422. UEMINFO uei;
  423. uei.cbSize = SIZEOF(uei);
  424. uei.dwMask = UEIM_HIT;
  425. uei.cHit = UEM_NEWITEMCOUNT;
  426. hres = UEMSetEvent(&UEMIID_BROWSER, UEME_RUNPIDL, (WPARAM)psmd->psf, (LPARAM)psmd->pidlItem, &uei);
  427. }
  428. return hres;
  429. }
  430. HRESULT CFavoritesCallback::_GetTip(LPTSTR pstrTitle, LPTSTR pstrTip)
  431. {
  432. MLLoadString(IDS_CHEVRONTIPTITLE, pstrTitle, MAX_PATH);
  433. MLLoadString(IDS_CHEVRONTIP, pstrTip, MAX_PATH);
  434. // Why would this fail?
  435. if (EVAL(pstrTitle[0] != TEXT('\0') && pstrTip[0] != TEXT('\0')))
  436. return S_OK;
  437. return S_FALSE;
  438. }
  439. // There is a duplicate of this helper in shell32\unicpp\startmnu.cpp
  440. // When modifying this, rev that one as well.
  441. void UEMRenamePidl(const GUID *pguidGrp1, IShellFolder* psf1, LPCITEMIDLIST pidl1,
  442. const GUID *pguidGrp2, IShellFolder* psf2, LPCITEMIDLIST pidl2)
  443. {
  444. UEMINFO uei;
  445. uei.cbSize = SIZEOF(uei);
  446. uei.dwMask = UEIM_HIT | UEIM_FILETIME;
  447. if (SUCCEEDED(UEMQueryEvent(pguidGrp1,
  448. UEME_RUNPIDL, (WPARAM)psf1,
  449. (LPARAM)pidl1, &uei)) &&
  450. uei.cHit > 0)
  451. {
  452. UEMSetEvent(pguidGrp2,
  453. UEME_RUNPIDL, (WPARAM)psf2, (LPARAM)pidl2, &uei);
  454. uei.cHit = 0;
  455. UEMSetEvent(pguidGrp1,
  456. UEME_RUNPIDL, (WPARAM)psf1, (LPARAM)pidl1, &uei);
  457. }
  458. }
  459. // There is a duplicate of this helper in shell32\unicpp\startmnu.cpp
  460. // When modifying this, rev that one as well.
  461. void UEMDeletePidl(const GUID *pguidGrp, IShellFolder* psf, LPCITEMIDLIST pidl)
  462. {
  463. UEMINFO uei;
  464. uei.cbSize = SIZEOF(uei);
  465. uei.dwMask = UEIM_HIT;
  466. uei.cHit = 0;
  467. UEMSetEvent(pguidGrp, UEME_RUNPIDL, (WPARAM)psf, (LPARAM)pidl, &uei);
  468. }
  469. HRESULT CFavoritesCallback::_ProcessChangeNotify(SMDATA* psmd, LONG lEvent,
  470. LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
  471. {
  472. switch (lEvent)
  473. {
  474. case SHCNE_RENAMEFOLDER:
  475. case SHCNE_RENAMEITEM:
  476. {
  477. LPITEMIDLIST pidlFavorites;
  478. if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidlFavorites)))
  479. {
  480. if (ILIsParent(pidlFavorites, pidl1, FALSE))
  481. {
  482. IShellFolder* psfFrom;
  483. LPCITEMIDLIST pidlFrom;
  484. if (SUCCEEDED(IEBindToParentFolder(pidl1, &psfFrom, &pidlFrom)))
  485. {
  486. if (ILIsParent(pidlFavorites, pidl2, FALSE))
  487. {
  488. IShellFolder* psfTo;
  489. LPCITEMIDLIST pidlTo;
  490. if (SUCCEEDED(IEBindToParentFolder(pidl2, &psfTo, &pidlTo)))
  491. {
  492. // Then we need to rename it
  493. UEMRenamePidl(&UEMIID_BROWSER, psfFrom, pidlFrom,
  494. &UEMIID_BROWSER, psfTo, pidlTo);
  495. psfTo->Release();
  496. }
  497. }
  498. else
  499. {
  500. // Otherwise, we delete it.
  501. UEMDeletePidl(&UEMIID_BROWSER, psfFrom, pidlFrom);
  502. }
  503. psfFrom->Release();
  504. }
  505. }
  506. ILFree(pidlFavorites);
  507. }
  508. }
  509. break;
  510. case SHCNE_DELETE:
  511. case SHCNE_RMDIR:
  512. {
  513. IShellFolder* psf;
  514. LPCITEMIDLIST pidl;
  515. if (SUCCEEDED(IEBindToParentFolder(pidl1, &psf, &pidl)))
  516. {
  517. UEMDeletePidl(&UEMIID_BROWSER, psf, pidl);
  518. psf->Release();
  519. }
  520. }
  521. break;
  522. case SHCNE_CREATE:
  523. case SHCNE_MKDIR:
  524. {
  525. IShellFolder* psf;
  526. LPCITEMIDLIST pidl;
  527. if (SUCCEEDED(IEBindToParentFolder(pidl1, &psf, &pidl)))
  528. {
  529. UEMINFO uei;
  530. uei.cbSize = SIZEOF(uei);
  531. uei.dwMask = UEIM_HIT;
  532. uei.cHit = UEM_NEWITEMCOUNT;
  533. UEMSetEvent(&UEMIID_BROWSER,
  534. UEME_RUNPIDL, (WPARAM)psf, (LPARAM)pidl, &uei);
  535. }
  536. }
  537. break;
  538. case SHCNE_EXTENDED_EVENT:
  539. {
  540. // We get this event when we are offline and the cache was changed.
  541. // We need to refresh the favorites menu when we next show it so the
  542. // correct items are greyed.
  543. SHChangeDWORDAsIDList UNALIGNED * pdwidl = (SHChangeDWORDAsIDList UNALIGNED *)pidl1;
  544. int iEvent = pdwidl->dwItem1;
  545. if (iEvent == SHCNEE_WININETCHANGED &&
  546. (pdwidl->dwItem2 & (CACHE_NOTIFY_ADD_URL |
  547. CACHE_NOTIFY_DELETE_URL |
  548. CACHE_NOTIFY_DELETE_ALL |
  549. CACHE_NOTIFY_URL_SET_STICKY |
  550. CACHE_NOTIFY_URL_UNSET_STICKY)))
  551. {
  552. _fRefresh = TRUE;
  553. }
  554. }
  555. break;
  556. }
  557. return S_FALSE;
  558. }
  559. //
  560. // _Disallow drop returns S_OK if the drop shold not be allowed. S_FALSE if
  561. // the drop should be allowed.
  562. //
  563. BOOL CFavoritesCallback::_AllowDrop(IDataObject* pIDataObject, HWND hwnd)
  564. {
  565. ASSERT(NULL == hwnd || IsWindow(hwnd));
  566. BOOL fRet = True; // Allow drop.
  567. if (hwnd && pIDataObject)
  568. {
  569. LPITEMIDLIST pidl;
  570. if (SUCCEEDED(SHPidlFromDataObject(pIDataObject, &pidl, NULL, 0)))
  571. {
  572. fRet = IEIsLinkSafe(hwnd, pidl, ILS_ADDTOFAV);
  573. ILFree(pidl);
  574. }
  575. }
  576. return fRet;
  577. }