Source code of Windows XP (NT5)
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.

218 lines
4.3 KiB

  1. /*++
  2. shmenu.cpp
  3. this is for IShellMenu and related stuff. eventually all
  4. of the fsmenu.c functionality should be in here
  5. --*/
  6. class CFMDropTarget : public IDropTarget
  7. {
  8. public:
  9. CFMDropTarget();
  10. ~CFMDropTarget();
  11. HRESULT Init (
  12. HWND hwnd,
  13. IShellFolder *psf,
  14. LPITEMIDLIST pidl,
  15. DWORD dwFlags);
  16. // IUnknown methods
  17. virtual STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppvObj);
  18. virtual STDMETHODIMP_(ULONG) AddRef(void);
  19. virtual STDMETHODIMP_(ULONG) Release(void);
  20. STDMETHODIMP DragEnter(
  21. IDataObject *pdata,
  22. DWORD grfKeyState,
  23. POINTL pt,
  24. DWORD *pdwEffect)
  25. {return _pdrop->DragEnter(pdata, grfKeyState, pt, pdwEffect);}
  26. STDMETHODIMP DragOver(
  27. DWORD grfKeyState,
  28. POINTL pt,
  29. DWORD *pdwEffect)
  30. {return _pdrop->DragOver(grfKeyState, pt, pdwEffect);}
  31. STDMETHODIMP DragLeave( void)
  32. {return _pdrop->DragLeave();}
  33. STDMETHODIMP Drop(
  34. IDataObject *pDataObj,
  35. DWORD grfKeyState,
  36. POINTL pt,
  37. DWORD *pdwEffect)
  38. {return _pdrop->Drop(pDataObj, grfKeyState, pt, pdwEffect);}
  39. private:
  40. ULONG _cRef;
  41. IShellFolder *_psf; // the psf to use...
  42. LPITEMIDLIST _pidl;
  43. DWORD _dwFlags;
  44. IDropTarget *_pdrop; // the actual droptarget
  45. }
  46. CFMDropTarget :: CFMDropTarget ()
  47. {
  48. _cRef = 1;
  49. DllAddRef();
  50. }
  51. CFMDropTarget :: ~CFMDropTarget ()
  52. {
  53. SAFERELEASE(_psf);
  54. if(pidl)
  55. ILFree(pidl);
  56. SAFERELEASE(_pdrop);
  57. DllRelease();
  58. }
  59. HRESULT
  60. CFMDropTarget :: QueryInterface(REFIID riid, PVOID *ppvObj)
  61. {
  62. HRESULT hr = E_NOINTERFACE;
  63. *ppvObj = NULL;
  64. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropTarget))
  65. {
  66. AddRef();
  67. *ppvObj = (LPVOID) SAFECAST(this, IDropTarget*);
  68. hr = S_OK;
  69. }
  70. return hr;
  71. }
  72. ULONG
  73. CFMDropTarget :: AddRef(void)
  74. {
  75. _cRef++;
  76. return _cRef;
  77. }
  78. ULONG
  79. CFMDropTarget :: Release(void)
  80. {
  81. ASSERT (_cRef > 0);
  82. cRef--;
  83. if (!cRef)
  84. {
  85. //time to go bye bye
  86. delete this;
  87. return 0;
  88. }
  89. return cRef;
  90. }
  91. // FEATURE: ZEKEL we are just using the psf here...we need to support more
  92. HRESULT Init (
  93. HWND hwnd,
  94. IShellFolder *psf,
  95. LPITEMIDLIST pidl,
  96. DWORD dwFlags)
  97. {
  98. HRESULT hr = E_INVALIDARG;
  99. if(psf)
  100. hr = psf->QueryInterface(IID_IShellFolder, (LPVOID *) &_psf);
  101. _pidl = ILClone(pidl);
  102. _dwFlags = dwFlags;
  103. if(SUCCEEDED(hr) && _psf && _pidl)
  104. {
  105. hr = _psf->CreateViewObject(hwnd, IID_IDropTarget, (LPVOID*) &_pdrop);
  106. }
  107. return hr;
  108. }
  109. //FEATURE: ZEKEL right now this doesnt support ordering, and assumes that you
  110. //want to drop right onto the current menu. this is just a start.
  111. //pidl and dwFlags are just dummy params
  112. HRESULT
  113. CFMDropTarget_CreateAndInit(
  114. HWND hwnd,
  115. IShellFolder *psf,
  116. LPITEMIDLIST pidl,
  117. DWORD dwFlags,
  118. LPVOID *ppvObj)
  119. {
  120. HRESULT hr = E_OUTOFMEMORY;
  121. CFMDropTarget *pdt;
  122. ASSERT(ppvObj)
  123. if(ppvObj)
  124. *ppvObj = NULL;
  125. else
  126. return E_INVALIDARG;
  127. pdt = new CFMDropTargetNULL;
  128. if (pdt)
  129. {
  130. hr = pdt->Init(hwnd, psf, pidl, dwFlags);
  131. if (SUCCEEDED(hr))
  132. *ppvObj= SAFECAST(pdt, IDropTarget * );
  133. else
  134. pdt->Release();
  135. }
  136. return hr;
  137. }
  138. if (psf)
  139. {
  140. hr = psf->QueryInterface(IID_IShellFolder, (LPVOID *) &psfMine);
  141. if(SUCCEEDED(hr) && psfMine)
  142. {
  143. }
  144. #if 0 // ZEKEL
  145. {
  146. if(pmgoi->dwFlags & (MNGO_TOPGAP | MNGO_BOTTOMGAP))
  147. {
  148. //then we need to use the current psf as the droptarget
  149. // and the pidl is just a marker
  150. }
  151. else
  152. {
  153. // we need to use the pidl's psf as the droptarget if possible
  154. DWORD dwAttr = SFGAO_DROPTARGET;
  155. hr = psf->lpVtbl->GetAttributesOf(1, (LPCITEMIDLIST*)&pfmi->pidl, &dwAttr);
  156. if (SUCCEEDED(hres) && (dwAttr & SFGAO_DROPTARGET))
  157. {
  158. hr = psf->lpVtbl->GetUIObjectOf(hwnd, 1, (LPCITEMIDLIST*)&pfmi->pidl,
  159. IID_IDropTarget, NULL, (LPVOID*)&_pdropgtCur);
  160. }
  161. }
  162. #endif