#include "StdAfx.h"
#pragma once
#include "oleidl.h"
class IDropTargetImpl :
public IDropTarget
{
public:
IDropTargetImpl(void)
{
m_def=0;
}
~IDropTargetImpl(void)
{
}
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject)
{
if(!ppvObject)return E_POINTER;
if (riid==IID_IUnknown||riid==IID_IDropTarget)
{
*ppvObject=static_cast<IDropTarget*>(this);
}
else
return (*ppvObject=0),E_NOINTERFACE;
((IUnknown*)*ppvObject)->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef( void)
{
return ++m_def;
}
ULONG STDMETHODCALLTYPE Release( void)
{
ULONG Temp=--m_def;
if (m_def==0)
{
delete this;
}
return Temp;
}
HRESULT STDMETHODCALLTYPE DragEnter(
/* [unique][in] */ IDataObject *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD *pdwEffect)
{
/*FORMATETC cFmt = {(CLIPFORMAT) CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stgMedium;
HRESULT hr = pDataObj->GetData(&cFmt, &stgMedium);
if (S_OK != hr)
{
return E_FAIL;
}*/
return S_OK;
}
HRESULT STDMETHODCALLTYPE DragOver(
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD *pdwEffect)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE DragLeave( void)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE Drop(
/* [unique][in] */ IDataObject *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD *pdwEffect)
{
FORMATETC cFmt = {(CLIPFORMAT) CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
GetDragData(pDataObj,cFmt);
return S_OK;
}
BOOL ProcessDrop(HDROP hDrop)
{
UINT iFiles,ich =0;
TCHAR Buffer[MAX_PATH] = {0};
memset(&iFiles,0xff,sizeof(iFiles));
CString strFilePath;
int Count = ::DragQueryFile(hDrop,iFiles,Buffer,0); //Get the Drag _Files Number.
if(Count)
{
for (int i=0;i<Count;i++)
{
if(::DragQueryFile(hDrop,i,Buffer,sizeof(Buffer)))
{
strFilePath = Buffer;//获取了路径做相应处理
memset(Buffer,0,sizeof(Buffer) );
}
}
}
::DragFinish(hDrop);
return true;
}
BOOL GetDragData(IDataObject *pDataObject,FORMATETC cFmt)
{
HRESULT ret=S_OK;
STGMEDIUM stgMedium;
ret = pDataObject->GetData(&cFmt, &stgMedium);//GetData(CF_TEXT, &stgMedium);
if (FAILED(ret))
{
return FALSE;
}
if (stgMedium.pUnkForRelease != NULL)
{
return FALSE;
}
switch (stgMedium.tymed)
{
case TYMED_HGLOBAL:
{
ProcessDrop((HDROP)stgMedium.hGlobal);
return true;
break;
}
default:
{
::ReleaseStgMedium(&stgMedium);
}
break;
}
return false;
}
protected:
ULONG m_def;
};
/////////////////////////////////////////////////////////////////////////////////////////////////
class IHandlerImpl :
public IDocHostUIHandler
{
public:
IHandlerImpl(void)
{
m_def=0;
}
~IHandlerImpl(void)
{
}
virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(
/* [in] */ DWORD dwID,
/* [in] */ POINT *ppt,
/* [in] */ IUnknown *pcmdtReserved,
/* [in] */ IDispatch *pdispReserved)
{
// ATLTRACE("%d,%d ",ppt->x,ppt->y);
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE GetHostInfo(
/* [out][in] */ DOCHOSTUIINFO *pInfo)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE ShowUI(
/* [in] */ DWORD dwID,
/* [in] */ IOleInPlaceActiveObject *pActiveObject,
/* [in] */ IOleCommandTarget *pCommandTarget,
/* [in] */ IOleInPlaceFrame *pFrame,
/* [in] */ IOleInPlaceUIWindow *pDoc)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE HideUI( void)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE UpdateUI( void)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE EnableModeless(
/* [in] */ BOOL fEnable)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(
/* [in] */ BOOL fActivate)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(
/* [in] */ BOOL fActivate)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE ResizeBorder(
/* [in] */ LPCRECT prcBorder,
/* [in] */ IOleInPlaceUIWindow *pUIWindow,
/* [in] */ BOOL fRameWindow)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(
/* [in] */ LPMSG lpMsg,
/* [in] */ const GUID *pguidCmdGroup,
/* [in] */ DWORD nCmdID)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath(
/* [out] */ LPOLESTR *pchKey,
/* [in] */ DWORD dw)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetDropTarget(
/* [in] */ IDropTarget *pDropTarget,
/* [out] */ IDropTarget **ppDropTarget)
{
IDropTarget *pDrag = new IDropTargetImpl;
*ppDropTarget = pDrag;
((IUnknown*)*ppDropTarget)->AddRef();
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetExternal(
/* [out] */ IDispatch **ppDispatch)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE TranslateUrl(
/* [in] */ DWORD dwTranslate,
/* [in] */ OLECHAR *pchURLIn,
/* [out] */ OLECHAR **ppchURLOut)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE FilterDataObject(
/* [in] */ IDataObject *pDO,
/* [out] */ IDataObject **ppDORet)
{
return S_FALSE;
}
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject)
{
return S_OK;
}
ULONG STDMETHODCALLTYPE AddRef( void)
{
return ++m_def;
}
ULONG STDMETHODCALLTYPE Release( void)
{
ULONG Temp=--m_def;
if (m_def==0)
{
delete this;
}
return Temp;
}
protected:
ULONG m_def;
};
真正处理拖放的是IDropTarget,使用方法:替换默认的文件拖放,代码为
CComPtr<IHTMLDocument2> spDoc;
m_HtmlEditCtrl.GetDHtmlDocument(&spDoc);
CComPtr<ICustomDoc> spCustomDoc;
spDoc->QueryInterface(IID_ICustomDoc, (void **)&spCustomDoc);
CComPtr<IDocHostUIHandler> spDocHostUIHandler;
spCustomDoc->QueryInterface(IID_IDocHostUIHandler, (void **)&spDocHostUIHandler);
IDocHostUIHandler* myDocHandler = new IHandlerImpl;
HRESULT r = spCustomDoc->SetUIHandler(myDocHandler);