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.

665 lines
21 KiB

  1. #include "shellprv.h"
  2. #include <regstr.h>
  3. #include <shellp.h>
  4. #include "ole2dup.h"
  5. #include "ids.h"
  6. #include "defview.h"
  7. #include "lvutil.h"
  8. #include "idlcomm.h"
  9. #include "filetbl.h"
  10. #include "undo.h"
  11. #include "cnctnpt.h"
  12. #include "mshtml.h"
  13. #include <sfview.h>
  14. #include "defviewp.h"
  15. #include "shellp.h"
  16. #define LISTVIEW_PROP TEXT("CombView_listview_subclass")
  17. #define ISMOUSEDOWN(msg) ((msg) == WM_LBUTTONDOWN || (msg) == WM_RBUTTONDOWN || (msg) == WM_MBUTTONDOWN)
  18. #define HWNDLISTVIEW (g_pdsvlvp->pdsv->_hwndListview)
  19. #define COMBVIEW_SUBCLASS_ID 42
  20. typedef struct
  21. {
  22. CDefView *pdsv;
  23. BOOL fInPaint;
  24. HHOOK hHookMouse;
  25. HHOOK hHookGetMsg;
  26. } DVLVPROP;
  27. //
  28. // We need this global (g_pdsvlvp) for the mouse hook we need to implement the combined
  29. // view. Since we only have one combined view at this point it is sufficient to have
  30. // a single global, but if we end up with more than one combined view then
  31. // there needs to be some additional code added so the hook(s) can figure out
  32. // which combined view(s) it is associated with.
  33. //
  34. DVLVPROP * g_pdsvlvp = NULL;
  35. const LPCTSTR c_rgElements[] = {
  36. TEXT("A"),
  37. TEXT("ANCHOR"), // ???
  38. TEXT("PLUGINS"), // ???
  39. TEXT("APPLET"),
  40. TEXT("EMBED"),
  41. TEXT("FORM"),
  42. TEXT("IFRAME"),
  43. TEXT("BUTTON"),
  44. TEXT("INPUT"),
  45. TEXT("OBJECT")
  46. };
  47. BOOL CombView_EnableAnimations(BOOL fEnable);
  48. // Returns the first sibling window of the passed in window
  49. HWND GetSpecialSibling(HWND hwnd)
  50. {
  51. HWND hwndT = GetWindow(hwnd, GW_HWNDFIRST);
  52. while (hwnd == hwndT)
  53. hwndT = GetWindow(hwndT, GW_HWNDNEXT);
  54. return hwndT;
  55. }
  56. LRESULT CALLBACK CombView_LV_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  57. LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
  58. {
  59. DVLVPROP *pdsvlvp = (DVLVPROP *)dwRefData;
  60. // 2000-07-11 vtan: First check g_pdsvlvp for NULL. If this is NULL then the dwRefData
  61. // has already been released in EnableCombinedView. There is only one DVLVPROP stored
  62. // in the entire process in g_pdsvlvp. This seems like a problem. lamadio should fix
  63. // this properly in the future.
  64. if ((g_pdsvlvp != NULL) &&
  65. pdsvlvp &&
  66. pdsvlvp->pdsv->_fCombinedView &&
  67. !pdsvlvp->fInPaint &&
  68. uMsg == WM_PAINT)
  69. {
  70. // This code works well for general painting, like minimizing a window or
  71. // or surfacing the desktop. However, it doesn't help the drag full windows
  72. // scenario very much.
  73. HRGN hrgn, hrgn2;
  74. RECT rc;
  75. HWND hwndT = GetSpecialSibling(hwnd);
  76. // Turn on animations!
  77. CombView_EnableAnimations(TRUE);
  78. if (hwndT && (hrgn = CreateRectRgn(0, 0, 0, 0)))
  79. {
  80. if (hrgn2 = CreateRectRgn(0, 0, 0, 0))
  81. {
  82. pdsvlvp->fInPaint = TRUE;
  83. if (!GetClassLongPtr(hwndT, GCLP_HBRBACKGROUND))
  84. SetClassLongPtr(hwndT, GCLP_HBRBACKGROUND, (LPARAM)GetStockObject(HOLLOW_BRUSH));
  85. if (GetUpdateRect(hwndT, &rc, FALSE))
  86. {
  87. RECT rcLV = rc;
  88. MapWindowPoints(hwndT, hwnd, (LPPOINT)&rcLV, 2);
  89. SetRectRgn(hrgn2, rcLV.left, rcLV.top, rcLV.right, rcLV.bottom);
  90. GetWindowRgn(hwnd, hrgn);
  91. CombineRgn(hrgn2, hrgn, hrgn2, RGN_DIFF);
  92. SetWindowRgn(hwnd, hrgn2, FALSE);
  93. InvalidateRect(hwndT, &rc, FALSE);
  94. UpdateWindow(hwndT);
  95. SetWindowRgn(hwnd, hrgn, FALSE);
  96. InvalidateRect(hwnd, &rcLV, FALSE);
  97. }
  98. else
  99. {
  100. DeleteObject(hrgn);
  101. DeleteObject(hrgn2);
  102. }
  103. pdsvlvp->fInPaint = FALSE;
  104. }
  105. else
  106. {
  107. DeleteObject(hrgn);
  108. }
  109. }
  110. }
  111. return DefSubclassProc(hwnd, uMsg, wParam, lParam);
  112. }
  113. // We need to set capture while we are stealing the mouse so that the
  114. // window manager won't send WM_SETCURSOR messages to the wrong window.
  115. // This function will also, as a side effect, send the WM_SETCURSOR to the
  116. // listview so that it will set the hand cursor when it needs to.
  117. void StealMouse(DVLVPROP * pdvlvp, BOOL fSteal, UINT msg)
  118. {
  119. HWND hwndCapture = GetCapture();
  120. if (fSteal && (hwndCapture == NULL || hwndCapture == HWNDLISTVIEW))
  121. {
  122. // We need to set capture so that the window manager will not
  123. // try to send the w_setcursor message to the wrong window, and we
  124. // send it here ourself to the listview.
  125. SetCapture(HWNDLISTVIEW);
  126. SendMessage(HWNDLISTVIEW, WM_SETCURSOR, (WPARAM)HWNDLISTVIEW,
  127. MAKELPARAM(HTCLIENT, LOWORD(msg)));
  128. }
  129. else
  130. {
  131. // If the listview still has capture release it now
  132. if (HWNDLISTVIEW == hwndCapture)
  133. ReleaseCapture();
  134. }
  135. }
  136. LRESULT CALLBACK CombView_GetMsgHook(int nCode, WPARAM wParam, LPARAM lParam)
  137. {
  138. #define LPMSG ((LPMSG)lParam)
  139. HHOOK hHookNext = NULL;
  140. if (g_pdsvlvp)
  141. {
  142. if (LPMSG->message >= WM_MOUSEFIRST && LPMSG->message <= WM_MOUSELAST)
  143. {
  144. POINT pt;
  145. pt.x = GET_X_LPARAM(LPMSG->lParam);
  146. pt.y = GET_Y_LPARAM(LPMSG->lParam);
  147. MapWindowPoints(LPMSG->hwnd, HWNDLISTVIEW, &pt, 1);
  148. int iHit = g_pdsvlvp->pdsv->_HitTest(&pt);
  149. // Unhook our hook when all of the mouse buttons are up and we're not over
  150. // an item in the listview
  151. if (GetKeyState(VK_LBUTTON) >= 0 &&
  152. GetKeyState(VK_RBUTTON) >= 0 &&
  153. GetKeyState(VK_MBUTTON) >= 0 &&
  154. iHit == -1)
  155. {
  156. UnhookWindowsHookEx(g_pdsvlvp->hHookGetMsg);
  157. g_pdsvlvp->hHookGetMsg = NULL;
  158. }
  159. else
  160. {
  161. hHookNext = g_pdsvlvp->hHookGetMsg;
  162. }
  163. if (IsChildOrSelf(GetSpecialSibling(HWNDLISTVIEW), LPMSG->hwnd) == S_OK)
  164. {
  165. // If we have grabbed the mouse, give it to the listview
  166. LPMSG->hwnd = HWNDLISTVIEW;
  167. LPMSG->lParam = MAKELPARAM(LOWORD(pt.x), LOWORD(pt.y));
  168. }
  169. }
  170. else
  171. {
  172. hHookNext = g_pdsvlvp->hHookGetMsg;
  173. }
  174. // If we've just unhooked, or the hover is coming through to the listview and
  175. // no mouse button is down then clear our ownership of the mouse
  176. #define MK_BUTTON (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)
  177. if (!hHookNext ||
  178. // We need to special case the WM_MOUSEHOVER here so that the listview
  179. // is able to implement hover select. If we have capture set when the
  180. // hover select message goes through then it will ignore the message, so
  181. // clear the capture now.
  182. (LPMSG->message == WM_MOUSEHOVER && LPMSG->hwnd == HWNDLISTVIEW && !(LPMSG->wParam & MK_BUTTON)))
  183. StealMouse(g_pdsvlvp, FALSE, 0);
  184. }
  185. if (hHookNext)
  186. CallNextHookEx(hHookNext, nCode, wParam, lParam);
  187. return 0;
  188. #undef LPMSG
  189. }
  190. BOOL DoesElementNeedMouse (LPTSTR psz)
  191. {
  192. for (int i = 0; i < ARRAYSIZE(c_rgElements); i++)
  193. {
  194. if (lstrcmpi(c_rgElements[i], psz) == 0)
  195. return TRUE;
  196. }
  197. return FALSE;
  198. }
  199. BOOL ShouldStealMouseClick(POINT * ppt, DVLVPROP * pdsvlvp)
  200. {
  201. IHTMLDocument2 *pihtmldoc2;
  202. IHTMLElement *pielem;
  203. HRESULT hr = E_FAIL;
  204. if (SUCCEEDED(pdsvlvp->pdsv->GetItemObject(SVGIO_BACKGROUND, IID_IHTMLDocument2, (void **)&pihtmldoc2)))
  205. {
  206. // Work around for Trident issue -
  207. // elementFromPoint is returning success here even though pielem is
  208. // still NULL.
  209. if (SUCCEEDED(pihtmldoc2->elementFromPoint(ppt->x, ppt->y, &pielem)) && pielem)
  210. {
  211. IHTMLElement *pielemT;
  212. do {
  213. BSTR bstr = NULL;
  214. TCHAR sz[MAX_PATH];
  215. pielem->get_tagName(&bstr);
  216. SHUnicodeToTChar(bstr, sz, ARRAYSIZE(sz));
  217. SysFreeString(bstr);
  218. if (DoesElementNeedMouse(sz))
  219. {
  220. hr = E_FAIL;
  221. }
  222. else
  223. {
  224. if (SUCCEEDED(hr = pielem->get_parentElement(&pielemT)))
  225. {
  226. pielem->Release();
  227. pielem = pielemT;
  228. }
  229. else
  230. {
  231. hr = S_OK;
  232. pielem->Release();
  233. pielem = NULL;
  234. }
  235. }
  236. } while (SUCCEEDED(hr) && pielem);
  237. if (pielem)
  238. pielem->Release();
  239. }
  240. pihtmldoc2->Release();
  241. }
  242. return SUCCEEDED(hr);
  243. }
  244. LRESULT CALLBACK CombView_MouseHook(int nCode, WPARAM wParam, LPARAM lParam)
  245. {
  246. #define PMHS ((MOUSEHOOKSTRUCT *)lParam)
  247. if ((nCode == HC_ACTION) && g_pdsvlvp && (PMHS->hwnd != HWNDLISTVIEW) && IsWindowVisible(HWNDLISTVIEW))
  248. {
  249. // If it isn't over the listview and the button is going down or we're
  250. // moving over an area that would hit a listview icon then
  251. // we need to start hooking mouse events. Install the GetMessage hook
  252. // so that we can do what we need to do.
  253. HWND hwndParent = GetSpecialSibling(HWNDLISTVIEW);
  254. POINT ptLV = PMHS->pt;
  255. HWND hwndHittest = WindowFromPoint(PMHS->pt);
  256. ScreenToClient(HWNDLISTVIEW, &ptLV);
  257. int iHit = g_pdsvlvp->pdsv->_HitTest(&ptLV);
  258. ScreenToClient(hwndParent, &(PMHS->pt));
  259. BOOL fStealMouse = (ISMOUSEDOWN(wParam) && ShouldStealMouseClick(&(PMHS->pt), g_pdsvlvp)) ||
  260. (!GetCapture() && (iHit != -1) && (!hwndHittest || (hwndHittest == HWNDLISTVIEW)));
  261. if (!g_pdsvlvp->hHookGetMsg)
  262. {
  263. if (hwndHittest && (IsChildOrSelf(hwndParent, hwndHittest) == S_OK))
  264. {
  265. if (fStealMouse)
  266. {
  267. // Note: We have to steal the mouse at this point and use the
  268. // GetMessage hook to redirect the mouse messages to our listview
  269. // window. If we do something different like swallow the message here
  270. // and then PostMessage faked up events to the listview then all
  271. // of the hover select functionality will break because the system
  272. // won't detect the mouse as being over the listview.
  273. StealMouse(g_pdsvlvp, TRUE, (UINT) wParam);
  274. g_pdsvlvp->hHookGetMsg = SetWindowsHookEx(WH_GETMESSAGE, CombView_GetMsgHook,
  275. NULL, GetCurrentThreadId());
  276. }
  277. }
  278. }
  279. else
  280. {
  281. if (fStealMouse)
  282. StealMouse(g_pdsvlvp, TRUE, (UINT) wParam);
  283. else
  284. SendMessage(HWNDLISTVIEW, WM_SETCURSOR, (WPARAM)HWNDLISTVIEW, MAKELPARAM(HTCLIENT, LOWORD((UINT) wParam)));
  285. }
  286. }
  287. if (g_pdsvlvp)
  288. return CallNextHookEx(g_pdsvlvp->hHookMouse, nCode, wParam, lParam);
  289. else
  290. return 0;
  291. #undef PMHS
  292. }
  293. /*
  294. * This is the main entry point where a defview can be turned into a combined
  295. * view. The effect of a combined view is to layer an extended view under
  296. * the listview icons (via a regional listview) of a normal defview.
  297. *
  298. * Warnings:
  299. * 1) This is currently only used by the "Active Desktop", it is optimized
  300. * to only support one instance. Multiple combined views are not currently supported.
  301. * 2) Disabling the combined view doesn't completely unhook itself from the defview
  302. */
  303. void EnableCombinedView(CDefView *pdsv, BOOL fEnable)
  304. {
  305. DVLVPROP * pdsvlvp = g_pdsvlvp;
  306. if (pdsvlvp)
  307. {
  308. if (!fEnable)
  309. {
  310. // Unhook ourselves
  311. UnhookWindowsHookEx(pdsvlvp->hHookMouse);
  312. if (pdsvlvp->hHookGetMsg)
  313. {
  314. UnhookWindowsHookEx(pdsvlvp->hHookGetMsg);
  315. StealMouse(pdsvlvp, FALSE, 0);
  316. }
  317. g_pdsvlvp = NULL;
  318. RemoveWindowSubclass(pdsv->_hwndListview, CombView_LV_SubclassProc, COMBVIEW_SUBCLASS_ID);
  319. LocalFree((HLOCAL)pdsvlvp);
  320. }
  321. }
  322. else
  323. {
  324. if (fEnable)
  325. {
  326. pdsvlvp = (DVLVPROP *)LocalAlloc(LPTR, sizeof(DVLVPROP));
  327. if (pdsvlvp)
  328. {
  329. // We are only expecting one combined view
  330. ASSERT(g_pdsvlvp == NULL);
  331. // Get ourself hooked in
  332. pdsvlvp->pdsv = pdsv;
  333. SetWindowSubclass(pdsv->_hwndListview, CombView_LV_SubclassProc, COMBVIEW_SUBCLASS_ID, (DWORD_PTR)pdsvlvp);
  334. pdsvlvp->hHookMouse = SetWindowsHookEx(WH_MOUSE, CombView_MouseHook, NULL, GetCurrentThreadId());
  335. g_pdsvlvp = pdsvlvp;
  336. }
  337. }
  338. }
  339. }
  340. /*
  341. * This function is used to optimize the combined view ("Active Desktop") by turning
  342. * off any animated html elements or embeddings when it is completely obscured.
  343. *
  344. * Note that we always honor enabling animations if they aren't already enabled.
  345. * To make the client code easier though we only disable animations if we know
  346. * the desktop is obscured.
  347. *
  348. * Returns: The state of animation after the call
  349. */
  350. BOOL CombView_EnableAnimations(BOOL fEnable)
  351. {
  352. static BOOL fEnabled = TRUE;
  353. if ((fEnable != fEnabled) && g_pdsvlvp)
  354. {
  355. IOleCommandTarget* pct;
  356. BOOL fChangeAnimationState = fEnable;
  357. if (!fEnable)
  358. {
  359. HDC hdc;
  360. RECT rc;
  361. HWND hwnd;
  362. if ((hwnd = GetSpecialSibling(HWNDLISTVIEW)) && (hdc = GetDC(hwnd)))
  363. {
  364. fChangeAnimationState = (GetClipBox(hdc, &rc) == NULLREGION);
  365. ReleaseDC(hwnd, hdc);
  366. }
  367. }
  368. if (fChangeAnimationState &&
  369. SUCCEEDED(g_pdsvlvp->pdsv->_psb->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pct))))
  370. {
  371. VARIANT var = { 0 };
  372. TraceMsg(DM_TRACE, "Active Desktop: Animation state is changing:%d", fEnable);
  373. var.vt = VT_I4;
  374. var.lVal = fEnable;
  375. pct->Exec(NULL, OLECMDID_ENABLE_INTERACTION, OLECMDEXECOPT_DONTPROMPTUSER, &var, NULL);
  376. pct->Release();
  377. fEnabled = fEnable;
  378. }
  379. }
  380. return fEnabled;
  381. }
  382. // IDocHostUIHandler
  383. // This is implemented by the combined view so that we can support various
  384. // Win95 desktop functionality in a compatible way in the extended view.
  385. // Some examples include picking off context menu invocations, configuring the
  386. // host to display the way we want it too, and modifying drag/drop behavior.
  387. HRESULT CSFVSite::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved)
  388. {
  389. CSFVFrame* pFrame = IToClass(CSFVFrame, _cSite, this);
  390. CDefView* pView = IToClass(CDefView, _cFrame, pFrame);
  391. // For Web View's w/o DVOC, it might be nice to let Trident's menu through...
  392. if ((dwID == CONTEXT_MENU_DEFAULT || dwID == CONTEXT_MENU_IMAGE) && pView->_hwndListview)
  393. {
  394. // we used to unselect everything first, but that's bogus because it breaks the app key trying
  395. // to get a context menu on the currently selected items
  396. // BOGUS - Trident blows up if we send the message here and the user
  397. // turns off webview. Post it for now.
  398. PostMessage(pView->_hwndListview, WM_CONTEXTMENU,
  399. (WPARAM)pView->_hwndListview, MAKELPARAM((short)LOWORD(ppt->x), (short)LOWORD(ppt->y)));
  400. return S_OK;
  401. }
  402. else
  403. {
  404. return S_FALSE;
  405. }
  406. }
  407. // IDocHostUIHandler
  408. HRESULT CSFVSite::GetHostInfo(DOCHOSTUIINFO *pInfo)
  409. {
  410. CSFVFrame* pFrame = IToClass(CSFVFrame, _cSite, this);
  411. CDefView* pView = IToClass(CDefView, _cFrame, pFrame);
  412. pInfo->cbSize = sizeof(*pInfo);
  413. if (pView->_fCombinedView)
  414. {
  415. pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU | // We don't want Trident's help
  416. DOCHOSTUIFLAG_NO3DBORDER | // Desktop should be borderless
  417. DOCHOSTUIFLAG_SCROLL_NO; // | // Desktop should never scroll
  418. // DOCHOSTUIFLAG_DIALOG; // Prevent selection in Trident
  419. }
  420. else
  421. {
  422. pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU |
  423. DOCHOSTUIFLAG_DIALOG |
  424. DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE;
  425. }
  426. if (SHIsLowMemoryMachine(ILMM_IE4))
  427. pInfo->dwFlags = pInfo->dwFlags | DOCHOSTUIFLAG_DISABLE_OFFSCREEN;
  428. pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; // default
  429. return S_OK;
  430. }
  431. HRESULT CSFVSite::ShowUI(DWORD dwID, IOleInPlaceActiveObject *pActiveObject,
  432. IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
  433. {
  434. // Host did not display its own UI. Trident will proceed to display its own.
  435. return S_OK;
  436. }
  437. HRESULT CSFVSite::HideUI(void)
  438. {
  439. // This one is paired with ShowUI
  440. return S_FALSE;
  441. }
  442. HRESULT CSFVSite::UpdateUI(void)
  443. {
  444. // LATER: Isn't this equivalent to OLECMDID_UPDATECOMMANDS?
  445. return S_FALSE;
  446. }
  447. HRESULT CSFVSite::EnableModeless(BOOL fEnable)
  448. {
  449. // Called from the Trident when the equivalent member of its
  450. // IOleInPlaceActiveObject is called by the frame. We don't care
  451. // those cases.
  452. return S_OK;
  453. }
  454. HRESULT CSFVSite::OnDocWindowActivate(BOOL fActivate)
  455. {
  456. // Called from the Trident when the equivalent member of its
  457. // IOleInPlaceActiveObject is called by the frame. We don't care
  458. // those cases.
  459. return S_OK;
  460. }
  461. HRESULT CSFVSite::OnFrameWindowActivate(BOOL fActivate)
  462. {
  463. // Called from the Trident when the equivalent member of its
  464. // IOleInPlaceActiveObject is called by the frame. We don't care
  465. // those cases.
  466. return S_OK;
  467. }
  468. HRESULT CSFVSite::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
  469. {
  470. // Called from the Trident when the equivalent member of its
  471. // IOleInPlaceActiveObject is called by the frame. We don't care
  472. // those cases.
  473. return S_OK;
  474. }
  475. HRESULT CSFVSite::TranslateAccelerator(LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID)
  476. {
  477. // Called from the Trident when the equivalent member of its
  478. // IOleInPlaceActiveObject is called by the frame.
  479. // Trap F5 alone and handle the refresh ourselves!
  480. // Note:This code-path will be hit for desktop only if the active desktop
  481. // is turned on.
  482. //
  483. // And probably if focus is on Trident. It's probably good to
  484. // pick this off for Web View too.
  485. //
  486. if ((lpMsg->message == WM_KEYDOWN) && (lpMsg->wParam == VK_F5))
  487. {
  488. CSFVFrame* pFrame = IToClass(CSFVFrame, _cSite, this);
  489. CDefView* pView = IToClass(CDefView, _cFrame, pFrame);
  490. pView->Refresh();
  491. return S_OK;
  492. }
  493. return S_FALSE; // The message was not translated
  494. }
  495. HRESULT CSFVSite::GetOptionKeyPath(BSTR *pbstrKey, DWORD dw)
  496. {
  497. // Trident will default to its own user options.
  498. *pbstrKey = NULL;
  499. return S_FALSE;
  500. }
  501. HRESULT CSFVSite::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
  502. {
  503. HRESULT hr;
  504. CSFVFrame* pFrame = IToClass(CSFVFrame, _cSite, this);
  505. CDefView* pView = IToClass(CDefView, _cFrame, pFrame);
  506. if (!pView->_IsDesktop())
  507. {
  508. hr = S_FALSE; // Let trident delegate in webview folders
  509. }
  510. else
  511. {
  512. if (_dt._pdtFrame == NULL)
  513. {
  514. pView->_psb->QueryInterface(IID_PPV_ARG(IDropTarget, &_dt._pdtFrame));
  515. }
  516. if (_dt._pdtFrame)
  517. {
  518. *ppDropTarget = &_dt;
  519. AddRef();
  520. hr = S_OK;
  521. }
  522. else
  523. {
  524. ASSERT(0);
  525. hr = E_UNEXPECTED;
  526. }
  527. }
  528. return hr;
  529. }
  530. HRESULT CSFVSite::GetExternal(IDispatch **ppDisp)
  531. {
  532. HRESULT hr;
  533. if (ppDisp)
  534. {
  535. *ppDisp = NULL;
  536. hr = S_OK;
  537. }
  538. else
  539. {
  540. hr = E_INVALIDARG;
  541. }
  542. return hr;
  543. }
  544. HRESULT CSFVSite::TranslateUrl(DWORD dwTranslate, OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
  545. {
  546. HRESULT hr;
  547. if (ppchURLOut)
  548. {
  549. *ppchURLOut = NULL;
  550. hr = S_OK;
  551. }
  552. else
  553. {
  554. hr = E_INVALIDARG;
  555. }
  556. return hr;
  557. }
  558. HRESULT CSFVSite::FilterDataObject(IDataObject *pdtobj, IDataObject **ppdtobjRet)
  559. {
  560. HRESULT hr;
  561. if (ppdtobjRet)
  562. {
  563. *ppdtobjRet = NULL;
  564. hr = S_OK;
  565. }
  566. else
  567. {
  568. hr = E_INVALIDARG;
  569. }
  570. return hr;
  571. }