一、窗口支持拖放的實現步驟
1. 初始化OLE, ::OleInitialize(NULL);
2. 實現接口 : IDropTarget
二、IDropTarget接口內容
1. DragEnter
在拖放進入窗口區域的時候觸發調用,可以在這裏獲取拖放數據,判斷數據是否是需要支持的拖放類型,根據返回值,系統顯示相應的拖放圖標。
2. DragOver
在拖放操作在窗口區域內移動的時候,觸發調用,可以在這裏根據鼠標的位置來判斷是否某區域支持該拖放。
3. DragLeave
在拖放操作離開窗口的時候觸發調用,可以在這裏做一些拖放操作的資源釋放的動作。
4. Drop
拖放操作在窗口區域釋放的時候觸發調用,完成一次拖放。在這裏獲取拖放數據,實現窗口定義的拖放功能。
三、舉例實現文件/文本/URL的拖放
1. DragEnter
STDMETHOD(DragEnter)(IDataObject * pDataObject,DWORD grfKeyState, POINTL pt,DWORD * pdwEffect)
{
*pdwEffect = DROPEFFECT_LINK|DROPEFFECT_COPY ;
return S_OK ;
}
{
*pdwEffect = DROPEFFECT_LINK|DROPEFFECT_COPY ;
return S_OK ;
}
2. DragOver
STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
*pdwEffect = DROPEFFECT_LINK|DROPEFFECT_COPY ;
return S_OK ;
}
{
*pdwEffect = DROPEFFECT_LINK|DROPEFFECT_COPY ;
return S_OK ;
}
3. DragLeave
STDMETHOD(DragLeave)(){ return S_OK ;}
4. Drop
STDMETHOD(Drop)(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD __RPC_FAR *pdwEffect)
{
FORMATETC cFmt = {(CLIPFORMAT) CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stgMedium;
if(SUCCEEDED(pDataObj->GetData(&cFmt, &stgMedium)))
{
char *pBuff = NULL;
pBuff=(LPSTR)GlobalLock(stgMedium.hGlobal);
GlobalUnlock(stgMedium.hGlobal);
USES_CONVERSION;
// 觸發文本/URL的Drop,內容(A2T(pBuff))
::ReleaseStgMedium(&stgMedium);
}
FORMATETC cFmt2 = {(CLIPFORMAT) CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
if(SUCCEEDED(pDataObj->GetData(&cFmt2, &stgMedium)))
{
{
FORMATETC cFmt = {(CLIPFORMAT) CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stgMedium;
if(SUCCEEDED(pDataObj->GetData(&cFmt, &stgMedium)))
{
char *pBuff = NULL;
pBuff=(LPSTR)GlobalLock(stgMedium.hGlobal);
GlobalUnlock(stgMedium.hGlobal);
USES_CONVERSION;
// 觸發文本/URL的Drop,內容(A2T(pBuff))
::ReleaseStgMedium(&stgMedium);
}
FORMATETC cFmt2 = {(CLIPFORMAT) CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
if(SUCCEEDED(pDataObj->GetData(&cFmt2, &stgMedium)))
{
// 觸發文件拖放,hDrop=(HDROP)stgMedium.hGlobal
if(m_pTarget) m_pTarget->OnDropFile((HDROP)stgMedium.hGlobal);
::ReleaseStgMedium(&stgMedium);
}
return S_OK ;
}
if(m_pTarget) m_pTarget->OnDropFile((HDROP)stgMedium.hGlobal);
::ReleaseStgMedium(&stgMedium);
}
return S_OK ;
}
5. 擴展
在獲取數據的時候,可以參考獲取文本/文件數據,獲取其它類型的數據,來實現支持其他數據的拖放功能。
四、使用附件
1. 附件中封裝了支持文件/文本/URL的拖放支持代碼 IDropTargetImpl.h
2. 使用步驟
1.) Include “IDropTargetImpl.h”
2.) 爲需要實現拖放的窗口添加繼承列表,如下:
class CDropWnd : public IDropTargetImpl<CDropWnd >
3.) 在窗口初始化過程中(OnInitDialog/OnCreate)調用RegisterDragDrop();
4.) 根據需要實現的拖放功能,選擇性的重載虛函數:
virtual void OnDropText(LPCTSTR ptszText);
virtual void OnDropFile(HDROP hDrop);