C++ IDropSource,IDataObject,IDropTarget 文件从自己窗口拖到其他窗口操作

it2024-03-29  12

为了实现将自己窗口中的文件,或者文件夹从自己本身的客户端窗口拖动到其他的客户端窗口,或者系统窗口中实现系统的拖动效果;需要对系统接口 IDropSource,IDataObject,IDropTarget 重写

代码如下:

IDropSource,IDataObject,IDropTarget 重写头文件

// IDataObjectImpl.h: interface for the CIDataObjectImpl class. /************************************************************************** THIS CODE AND INFORMATION IS PROVIDED 'AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. Author: Leon Finker 1/2001 **************************************************************************/ #ifndef __DRAGDROPIMPL_H__ #define __DRAGDROPIMPL_H__ #include <shlobj.h> #include <vector> namespace DropSpace { typedef std::vector<FORMATETC> FormatEtcArray; typedef std::vector<FORMATETC*> PFormatEtcArray; typedef std::vector<STGMEDIUM*> PStgMediumArray; /// class CEnumFormatEtc : public IEnumFORMATETC { private: ULONG m_cRefCount; FormatEtcArray m_pFmtEtc; size_t m_iCur; public: CEnumFormatEtc(const FormatEtcArray& ArrFE); CEnumFormatEtc(const PFormatEtcArray& ArrFE); //IUnknown members STDMETHOD(QueryInterface)(REFIID, void FAR* FAR*); STDMETHOD_(ULONG, AddRef)(void); STDMETHOD_(ULONG, Release)(void); //IEnumFORMATETC members STDMETHOD(Next)(ULONG, LPFORMATETC, ULONG FAR *); STDMETHOD(Skip)(ULONG); STDMETHOD(Reset)(void); STDMETHOD(Clone)(IEnumFORMATETC FAR * FAR*); }; /// class CIDropSource : public IDropSource { long m_cRefCount; public: bool m_bDropped; CIDropSource():m_cRefCount(0),m_bDropped(false) {} //IUnknown virtual HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef( void); virtual ULONG STDMETHODCALLTYPE Release( void); //IDropSource virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag( /* [in] */ BOOL fEscapePressed, /* [in] */ DWORD grfKeyState); virtual HRESULT STDMETHODCALLTYPE GiveFeedback( /* [in] */ DWORD dwEffect); }; /// class CIDataObject : public IDataObject//,public IAsyncOperation { CIDropSource* m_pDropSource; long m_cRefCount; PFormatEtcArray m_ArrFormatEtc; PStgMediumArray m_StgMedium; public: CIDataObject(CIDropSource* pDropSource); ~CIDataObject(); void CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc); //IUnknown virtual HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef( void); virtual ULONG STDMETHODCALLTYPE Release( void); //IDataObject virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetData( /* [unique][in] */ FORMATETC __RPC_FAR *pformatetcIn, /* [out] */ STGMEDIUM __RPC_FAR *pmedium); virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDataHere( /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc, /* [out][in] */ STGMEDIUM __RPC_FAR *pmedium); virtual HRESULT STDMETHODCALLTYPE QueryGetData( /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc); virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc( /* [unique][in] */ FORMATETC __RPC_FAR *pformatectIn, /* [out] */ FORMATETC __RPC_FAR *pformatetcOut); virtual /* [local] */ HRESULT STDMETHODCALLTYPE SetData( /* [unique][in] */ FORMATETC __RPC_FAR *pformatetc, /* [unique][in] */ STGMEDIUM __RPC_FAR *pmedium, /* [in] */ BOOL fRelease); virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc( /* [in] */ DWORD dwDirection, /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenumFormatEtc); virtual HRESULT STDMETHODCALLTYPE DAdvise( /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ DWORD advf, /* [unique][in] */ IAdviseSink __RPC_FAR *pAdvSink, /* [out] */ DWORD __RPC_FAR *pdwConnection); virtual HRESULT STDMETHODCALLTYPE DUnadvise( /* [in] */ DWORD dwConnection); virtual HRESULT STDMETHODCALLTYPE EnumDAdvise( /* [out] */ IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise); //IAsyncOperation //virtual HRESULT STDMETHODCALLTYPE SetAsyncMode( // /* [in] */ BOOL fDoOpAsync) //{ // return E_NOTIMPL; //} // //virtual HRESULT STDMETHODCALLTYPE GetAsyncMode( // /* [out] */ BOOL __RPC_FAR *pfIsOpAsync) //{ // return E_NOTIMPL; //} // //virtual HRESULT STDMETHODCALLTYPE StartOperation( // /* [optional][unique][in] */ IBindCtx __RPC_FAR *pbcReserved) //{ // return E_NOTIMPL; //} // //virtual HRESULT STDMETHODCALLTYPE InOperation( // /* [out] */ BOOL __RPC_FAR *pfInAsyncOp) //{ // return E_NOTIMPL; //} // //virtual HRESULT STDMETHODCALLTYPE EndOperation( // /* [in] */ HRESULT hResult, // /* [unique][in] */ IBindCtx __RPC_FAR *pbcReserved, // /* [in] */ DWORD dwEffects) //{ // return E_NOTIMPL; //} }; /// class CIDropTarget : public IDropTarget { DWORD m_cRefCount; bool m_bAllowDrop; struct IDropTargetHelper *m_pDropTargetHelper; FormatEtcArray m_formatetc; FORMATETC* m_pSupportedFrmt; protected: HWND m_hTargetWnd; public: CIDropTarget(HWND m_hTargetWnd = NULL); virtual ~CIDropTarget(); void AddSuportedFormat(FORMATETC& ftetc) { m_formatetc.push_back(ftetc); } void SetTargetWnd(HWND hWnd) { m_hTargetWnd = hWnd; } //return values: true - release the medium. false - don't release the medium virtual bool OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium,DWORD *pdwEffect) = 0; virtual HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef( void) { return ++m_cRefCount; } virtual ULONG STDMETHODCALLTYPE Release( void); bool QueryDrop(DWORD grfKeyState, LPDWORD pdwEffect); virtual HRESULT STDMETHODCALLTYPE DragEnter( /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt, /* [out][in] */ DWORD __RPC_FAR *pdwEffect); virtual HRESULT STDMETHODCALLTYPE DragOver( /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt, /* [out][in] */ DWORD __RPC_FAR *pdwEffect); virtual HRESULT STDMETHODCALLTYPE DragLeave( void); virtual HRESULT STDMETHODCALLTYPE Drop( /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, /* [in] */ DWORD grfKeyState, /* [in] */ POINTL pt, /* [out][in] */ DWORD __RPC_FAR *pdwEffect); }; class CDragSourceHelper { IDragSourceHelper* pDragSourceHelper; public: CDragSourceHelper() { if(FAILED(CoCreateInstance(CLSID_DragDropHelper, NULL, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, (void**)&pDragSourceHelper))) pDragSourceHelper = NULL; } virtual ~CDragSourceHelper() { if( pDragSourceHelper!= NULL ) { pDragSourceHelper->Release(); pDragSourceHelper=NULL; } } // IDragSourceHelper HRESULT InitializeFromBitmap(HBITMAP hBitmap, POINT& pt, // cursor position in client coords of the window RECT& rc, // selected item's bounding rect IDataObject* pDataObject, COLORREF crColorKey=GetSysColor(COLOR_WINDOW)// color of the window used for transparent effect. ) { if(pDragSourceHelper == NULL) return E_FAIL; SHDRAGIMAGE di; BITMAP bm; GetObject(hBitmap, sizeof(bm), &bm); di.sizeDragImage.cx = bm.bmWidth; di.sizeDragImage.cy = bm.bmHeight; di.hbmpDragImage = hBitmap; di.crColorKey = crColorKey; di.ptOffset.x = pt.x - rc.left; di.ptOffset.y = pt.y - rc.top; return pDragSourceHelper->InitializeFromBitmap(&di, pDataObject); } HRESULT InitializeFromWindow(HWND hwnd, POINT& pt,IDataObject* pDataObject) { if(pDragSourceHelper == NULL) return E_FAIL; return pDragSourceHelper->InitializeFromWindow(hwnd, &pt, pDataObject); } }; } #endif //__DRAGDROPIMPL_H__

拖出文件封装:

#pragma once /** * @brief * @brief * @brief */ #include <string> #include <list> #include <Ole2.h> #include "DragDropImpl.h" using namespace std; using namespace DropSpace; struct DragHelper_FileSizeItem { wstring strName; int nSize; }; class CDropHelper { public: CDropHelper(); ~CDropHelper(); /** * @brief 将文件列表拖动到其他程序窗口 * @param[in] POINT pt * @param[in] RECT rc * @param[in] HBITMAP hBitMap 拖动图标显示 * @param[in] std::list<wstring> listFile 拖动文件列表 * @return 无 */ void DragOutFile(POINT pt, RECT rc, HBITMAP hBitMap, std::list<wstring> listFile); /* * @brief 计算拖动文件名转换为DROPFILES的总长度 * @param[in] std::list<wstring> listFile 需要转换的文件列表 * @param[out] std::list<DragHelper_FileSizeItem> listFileSize 单个Item 文件名对应大小 * @return int 拖动文件名转换为DROPFILES的总长度 */ int CalFileListLen( std::list<wstring> listFile , std::list<DragHelper_FileSizeItem>& listFileSize); /* * @brief 将文件列表拷贝到 DROPFILES 文件列表区域内存 * @param[in] std::list<DragHelper_FileSizeItem> &listSize 文件列表 * @param[out] char* pData DROPFILES 文件列表区域内存首地址 * @return */ void CopyFileListIntoDropFiles(char* pData, std::list<DragHelper_FileSizeItem> &listSize); private: };

 效果图:

 

最新回复(0)