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

为了实现将自己窗口中的文件,或者文件夹从自己本身的客户端窗口拖动到其他的客户端窗口,或者系统窗口中实现系统的拖动效果;需要对系统接口 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:
};

 效果图:

 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论 4

打赏作者

llC2018

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值