windows-nt/Source/XPSP1/NT/shell/inc/shmenu.cpp
2020-09-26 16:20:57 +08:00

219 lines
4.3 KiB
C++

/*++
shmenu.cpp
this is for IShellMenu and related stuff. eventually all
of the fsmenu.c functionality should be in here
--*/
class CFMDropTarget : public IDropTarget
{
public:
CFMDropTarget();
~CFMDropTarget();
HRESULT Init (
HWND hwnd,
IShellFolder *psf,
LPITEMIDLIST pidl,
DWORD dwFlags);
// IUnknown methods
virtual STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppvObj);
virtual STDMETHODIMP_(ULONG) AddRef(void);
virtual STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP DragEnter(
IDataObject *pdata,
DWORD grfKeyState,
POINTL pt,
DWORD *pdwEffect)
{return _pdrop->DragEnter(pdata, grfKeyState, pt, pdwEffect);}
STDMETHODIMP DragOver(
DWORD grfKeyState,
POINTL pt,
DWORD *pdwEffect)
{return _pdrop->DragOver(grfKeyState, pt, pdwEffect);}
STDMETHODIMP DragLeave( void)
{return _pdrop->DragLeave();}
STDMETHODIMP Drop(
IDataObject *pDataObj,
DWORD grfKeyState,
POINTL pt,
DWORD *pdwEffect)
{return _pdrop->Drop(pDataObj, grfKeyState, pt, pdwEffect);}
private:
ULONG _cRef;
IShellFolder *_psf; // the psf to use...
LPITEMIDLIST _pidl;
DWORD _dwFlags;
IDropTarget *_pdrop; // the actual droptarget
}
CFMDropTarget :: CFMDropTarget ()
{
_cRef = 1;
DllAddRef();
}
CFMDropTarget :: ~CFMDropTarget ()
{
SAFERELEASE(_psf);
if(pidl)
ILFree(pidl);
SAFERELEASE(_pdrop);
DllRelease();
}
HRESULT
CFMDropTarget :: QueryInterface(REFIID riid, PVOID *ppvObj)
{
HRESULT hr = E_NOINTERFACE;
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropTarget))
{
AddRef();
*ppvObj = (LPVOID) SAFECAST(this, IDropTarget*);
hr = S_OK;
}
return hr;
}
ULONG
CFMDropTarget :: AddRef(void)
{
_cRef++;
return _cRef;
}
ULONG
CFMDropTarget :: Release(void)
{
ASSERT (_cRef > 0);
cRef--;
if (!cRef)
{
//time to go bye bye
delete this;
return 0;
}
return cRef;
}
// FEATURE: ZEKEL we are just using the psf here...we need to support more
HRESULT Init (
HWND hwnd,
IShellFolder *psf,
LPITEMIDLIST pidl,
DWORD dwFlags)
{
HRESULT hr = E_INVALIDARG;
if(psf)
hr = psf->QueryInterface(IID_IShellFolder, (LPVOID *) &_psf);
_pidl = ILClone(pidl);
_dwFlags = dwFlags;
if(SUCCEEDED(hr) && _psf && _pidl)
{
hr = _psf->CreateViewObject(hwnd, IID_IDropTarget, (LPVOID*) &_pdrop);
}
return hr;
}
//FEATURE: ZEKEL right now this doesnt support ordering, and assumes that you
//want to drop right onto the current menu. this is just a start.
//pidl and dwFlags are just dummy params
HRESULT
CFMDropTarget_CreateAndInit(
HWND hwnd,
IShellFolder *psf,
LPITEMIDLIST pidl,
DWORD dwFlags,
LPVOID *ppvObj)
{
HRESULT hr = E_OUTOFMEMORY;
CFMDropTarget *pdt;
ASSERT(ppvObj)
if(ppvObj)
*ppvObj = NULL;
else
return E_INVALIDARG;
pdt = new CFMDropTargetNULL;
if (pdt)
{
hr = pdt->Init(hwnd, psf, pidl, dwFlags);
if (SUCCEEDED(hr))
*ppvObj= SAFECAST(pdt, IDropTarget * );
else
pdt->Release();
}
return hr;
}
if (psf)
{
hr = psf->QueryInterface(IID_IShellFolder, (LPVOID *) &psfMine);
if(SUCCEEDED(hr) && psfMine)
{
}
#if 0 // ZEKEL
{
if(pmgoi->dwFlags & (MNGO_TOPGAP | MNGO_BOTTOMGAP))
{
//then we need to use the current psf as the droptarget
// and the pidl is just a marker
}
else
{
// we need to use the pidl's psf as the droptarget if possible
DWORD dwAttr = SFGAO_DROPTARGET;
hr = psf->lpVtbl->GetAttributesOf(1, (LPCITEMIDLIST*)&pfmi->pidl, &dwAttr);
if (SUCCEEDED(hres) && (dwAttr & SFGAO_DROPTARGET))
{
hr = psf->lpVtbl->GetUIObjectOf(hwnd, 1, (LPCITEMIDLIST*)&pfmi->pidl,
IID_IDropTarget, NULL, (LPVOID*)&_pdropgtCur);
}
}
#endif