我在做一個拖拽的小例子,大概描述如下:
一個Form上有一個Label,這個label的Caption為一個本地檔案(檔案A)的全路徑,拖拽這個label到資源管理器的E盤松開,檔案A會被復制到E盤,我實作了IDataObject和IDropSource介面,不知道是不是實作的問題,拖拽時總顯示禁止drop的圖示。
完整代碼可以到此處下載:http://pan.baidu.com/s/1eQcUbPS
代碼如下:
MyDataObject.h
#include <stdio.h>
#include "IDragDemo.h"
class MyDataObject : public IDataObject
{
public:
//IUnknown implementation
ULONG __stdcall AddRef();
ULONG __stdcall Release();
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
//IDataObject members
STDMETHODIMP GetData (FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
STDMETHODIMP GetDataHere (FORMATETC *pformatetc, STGMEDIUM *pmedium);
STDMETHODIMP QueryGetData (FORMATETC *pformatetc);
STDMETHODIMP GetCanonicalFormatEtc (FORMATETC *pformatectIn, FORMATETC *pformatetcOut);
STDMETHODIMP SetData (FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
STDMETHODIMP EnumFormatEtc (DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
STDMETHODIMP DAdvise (FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
STDMETHODIMP DUnadvise (DWORD dwConnection);
STDMETHODIMP EnumDAdvise (IEnumSTATDATA **ppenumAdvise);
public:
MyDataObject(char* vFileName);
~MyDataObject();
private:
LONG refcount;
//自定義的接受格式
FORMATETC m_AcceptFormat;
STGMEDIUM m_StorageMedium;
HGLOBAL DupGlobalMem(HGLOBAL hMem);
};
MyDataObject.cpp
#include "MyDataObject.h"
#include "MyDropSource.h"
#include <Urlmon.h>
//Constructors
MyDataObject::MyDataObject(char* vFileName) : refcount(1)
{
//設定自定義接受的格式為
m_AcceptFormat.cfFormat = CF_HDROP;
m_AcceptFormat.dwAspect = DVASPECT_CONTENT;
m_AcceptFormat.tymed = TYMED_HGLOBAL;
//產生一個DROPFILES實體
DROPFILES tDropFiles;
tDropFiles.fNC = false;
tDropFiles.fWide = true;
tDropFiles.pFiles = sizeof(DROPFILES);
tDropFiles.pt.x = 0;
tDropFiles.pt.y = 0;
//產生自定義的存盤媒介
m_StorageMedium.tymed = TYMED_HGLOBAL;
m_StorageMedium.pUnkForRelease = NULL;
m_StorageMedium.hGlobal = &tDropFiles;
//設定檔案名格式
HGLOBAL hGblFiles;
LPSTR lpData;
hGblFiles = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(DROPFILES)+strlen(vFileName)+2);
//為hGblFiles分配記憶體并初始化
char tFileName[256];
lpData = (LPSTR)GlobalLock(hGblFiles);
memcpy(lpData,&tDropFiles,sizeof(DROPFILES));
strcpy(lpData+sizeof(DROPFILES), vFileName);
GlobalUnlock(hGblFiles);
//呼叫SetData
SetData(&m_AcceptFormat, &m_StorageMedium, true);
//呼叫DoDragDrop
MyDropSource tDropSource;
DWORD dwEffect;
DoDragDrop(this, &tDropSource, DROPEFFECT_COPY, &dwEffect);
fprintf(stdout, "Initiate a data object!\n");
}
//Destructors
MyDataObject::~MyDataObject()
{
fprintf(stdout, "Destruct a data object!\n");
}
//IUnkown implementation
ULONG __stdcall MyDataObject::AddRef()
{
return InterlockedIncrement(&refcount);
}
ULONG __stdcall MyDataObject::Release()
{
ULONG nRefCount = InterlockedDecrement(&refcount);
if (nRefCount == 0)
delete this;
return nRefCount;
}
STDMETHODIMP MyDataObject::QueryInterface(REFIID riid, void **ppvObject) {
if (!ppvObject) return E_POINTER;
if (riid == IID_IUnknown) {
*ppvObject = static_cast<IUnknown*>(this);
AddRef();
return S_OK;
} else if (riid == IID_IDropSource) {
*ppvObject = static_cast<IDataObject*>(this);
AddRef();
return S_OK;
} else {
*ppvObject = NULL;
return E_NOINTERFACE;
}
}
//Data Object implement
//呈現指定的 pformatetcIn 結構中描述的資料,并將它傳輸給 pmedium
STDMETHODIMP MyDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
if(pformatetcIn == NULL || pmedium == NULL) return E_INVALIDARG;
//清空medium
memset(pmedium, 0, sizeof(STGMEDIUM));
//比較型別是否被接受
// if(( m_AcceptFormat.tymed & pformatetcIn->tymed) &&
// (m_AcceptFormat.dwAspect == pformatetcIn->dwAspect) &&
// (m_AcceptFormat.cfFormat == pformatetcIn->cfFormat)){
//將合格的資料填充進pmedium
pmedium->hGlobal = DupGlobalMem(m_StorageMedium.hGlobal);
// HRESULT hr = CopyStgMedium(pmedium, &m_StorageMedium);
//
// if(S_OK != hr)
// return DV_E_FORMATETC;
//
// if(pmedium->tymed == TYMED_HGLOBAL){
// //this tell's the caller not to free the global memory
// QueryInterface(IID_IUnknown, (LPVOID*)&pmedium->pUnkForRelease);
// }
// return S_OK;
// }
return S_OK;
}
STDMETHODIMP MyDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
{
return E_NOTIMPL;
}
STDMETHODIMP MyDataObject::QueryGetData(FORMATETC *pformatetc)
{
//pformatetc is invalid
return DV_E_FORMATETC;
}
STDMETHODIMP MyDataObject::GetCanonicalFormatEtc(FORMATETC *pformatectIn, FORMATETC *pformatetcOut)
{
return DATA_S_SAMEFORMATETC;
}
STDMETHODIMP MyDataObject::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
//獲取檔案名,并塞入媒介
return S_OK;
}
STDMETHODIMP MyDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{
return E_NOTIMPL;
}
//Advises:OLE_E_ADVISENOTSUPPORTED
STDMETHODIMP MyDataObject::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP MyDataObject::DUnadvise(DWORD dwConnection)
{
return OLE_E_ADVISENOTSUPPORTED;
}
STDMETHODIMP MyDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
return OLE_E_ADVISENOTSUPPORTED;
}
HGLOBAL MyDataObject::DupGlobalMem(HGLOBAL hMem)
{
DWORD len = GlobalSize(hMem);
PVOID source = GlobalLock(hMem);
PVOID dest = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, len);
memcpy(dest, source, len);
GlobalUnlock(hMem);
return dest;
}
MyDropSource.h
#include <stdio.h>
#include "IDragDemo.h"
class MyDropSource : public IDropSource
{
public:
//IUnknown implementation
ULONG __stdcall AddRef();
ULONG __stdcall Release();
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
//IDropSource members
STDMETHODIMP QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
STDMETHODIMP GiveFeedback(DWORD dwEffect);
//Cons/Destructors
MyDropSource();
~MyDropSource();
private:
LONG refcount;
};
MyDropSource.cpp
#include "MyDropSource.h"
//Constructors
MyDropSource::MyDropSource() : refcount(1)
{
fprintf(stdout, "Initiate a drop source!\n");
}
//Destructors
MyDropSource::~MyDropSource()
{
fprintf(stdout, "Destruct a drop source!\n");
}
//IUnkown implementation
ULONG __stdcall MyDropSource::AddRef()
{
return InterlockedIncrement(&refcount);
}
ULONG __stdcall MyDropSource::Release()
{
ULONG nRefCount = InterlockedDecrement(&refcount);
if (nRefCount == 0)
delete this;
return nRefCount;
}
STDMETHODIMP MyDropSource::QueryInterface(REFIID riid, void **ppvObject) {
if (!ppvObject) return E_POINTER;
if (riid == IID_IUnknown) {
*ppvObject = static_cast<IUnknown*>(this);
AddRef();
return S_OK;
} else if (riid == IID_IDropSource) {
*ppvObject = static_cast<IDropSource*>(this);
AddRef();
return S_OK;
} else {
*ppvObject = NULL;
return E_NOINTERFACE;
}
}
//DropSource implement
STDMETHODIMP __stdcall MyDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
if (fEscapePressed)
return DRAGDROP_S_CANCEL;
if (!(grfKeyState & (MK_LBUTTON | MK_RBUTTON)))
return DRAGDROP_S_DROP;
return S_OK;
}
STDMETHODIMP MyDropSource::GiveFeedback(DWORD dwEffect)
{
return DRAGDROP_S_USEDEFAULTCURSORS;
}
完整代碼可以到此處下載:http://pan.baidu.com/s/1eQcUbPS
請大家看看是什么問題,先謝啦。
uj5u.com熱心網友回復:
都沒人了嗎
uj5u.com熱心網友回復:
現在沒心事寫代碼,感覺自已老了。。uj5u.com熱心網友回復:
如果是WINDOWS 7系統的話,我們的程式沒有拖拽的權限了,要先獲得相關權限轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/105711.html
