MFC 拖放
- 添加一个继承自COleDropTarget的类
- 添加继承自CObject的拖动信息类
- 在要实现的控件类里面申明和注册COleDropTarget
- 在应用程序初始化里面加入AfxOleInit
添加继承自COleDropTarget的类
class COleDropTargetEx : public COleDropTarget
{
public:
COleDropTargetEx();
virtual ~COleDropTargetEx();
protected:
//处理OnDropEx消息是必须的,否则OnDrop函数不会被执行
//当然也可以在OnDropEx函数中处理数据
virtual DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point);
virtual DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, DROPEFFECT dropEffectList, CPoint point);
virtual void OnDragLeave(CWnd* pWnd);
};
{
public:
COleDropTargetEx();
virtual ~COleDropTargetEx();
protected:
//处理OnDropEx消息是必须的,否则OnDrop函数不会被执行
//当然也可以在OnDropEx函数中处理数据
virtual DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point);
virtual DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, DROPEFFECT dropEffectList, CPoint point);
virtual void OnDragLeave(CWnd* pWnd);
};
.cpp文件
COleDropTargetEx::COleDropTargetEx()
{
}
COleDropTargetEx::~COleDropTargetEx()
{
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
DROPEFFECT COleDropTargetEx::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDragEnter(pWnd,pDataObject, dwKeyState, point);
COleDropInfo DropInfo( pDataObject, dwKeyState, 0, 0, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DRAGENTER, (WPARAM)&DropInfo, 0 );
}
DROPEFFECT COleDropTargetEx::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDragOver(pWnd,pDataObject, dwKeyState, point);
COleDropInfo DropInfo( pDataObject, dwKeyState, 0, 0, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DRAGOVER, (WPARAM)&DropInfo, 0 );
}
BOOL COleDropTargetEx::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDrop(pWnd, pDataObject,dropEffect,point);
COleDropInfo DropInfo( pDataObject, 0, dropEffect, 0, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DROP, (WPARAM)&DropInfo, 0 );
}
DROPEFFECT COleDropTargetEx::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, DROPEFFECT dropEffectList, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDropEx( pWnd, pDataObject, dropEffect, dropEffectList, point) ;
COleDropInfo DropInfo( pDataObject, 0, dropEffect, dropEffectList, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DROPEX, (WPARAM)&DropInfo, 0 );
}
void COleDropTargetEx::OnDragLeave(CWnd* pWnd)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
{
COleDropTarget::OnDragLeave( pWnd );
return;
}
::SendMessage( pWnd->GetSafeHwnd(), DROPM_DRAGLEAVE, 0, 0 );
return;
}
{
}
COleDropTargetEx::~COleDropTargetEx()
{
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
DROPEFFECT COleDropTargetEx::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDragEnter(pWnd,pDataObject, dwKeyState, point);
COleDropInfo DropInfo( pDataObject, dwKeyState, 0, 0, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DRAGENTER, (WPARAM)&DropInfo, 0 );
}
DROPEFFECT COleDropTargetEx::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDragOver(pWnd,pDataObject, dwKeyState, point);
COleDropInfo DropInfo( pDataObject, dwKeyState, 0, 0, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DRAGOVER, (WPARAM)&DropInfo, 0 );
}
BOOL COleDropTargetEx::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDrop(pWnd, pDataObject,dropEffect,point);
COleDropInfo DropInfo( pDataObject, 0, dropEffect, 0, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DROP, (WPARAM)&DropInfo, 0 );
}
DROPEFFECT COleDropTargetEx::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, DROPEFFECT dropEffectList, CPoint point)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
return COleDropTarget::OnDropEx( pWnd, pDataObject, dropEffect, dropEffectList, point) ;
COleDropInfo DropInfo( pDataObject, 0, dropEffect, dropEffectList, point );
return ::SendMessage( pWnd->GetSafeHwnd(), DROPM_DROPEX, (WPARAM)&DropInfo, 0 );
}
void COleDropTargetEx::OnDragLeave(CWnd* pWnd)
{
ASSERT_VALID(this);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))//if CView,Call base class
{
COleDropTarget::OnDragLeave( pWnd );
return;
}
::SendMessage( pWnd->GetSafeHwnd(), DROPM_DRAGLEAVE, 0, 0 );
return;
}
添加继承自CObject的拖动信息类
class COleDropInfo : public CObject
{
public:
COleDropInfo();
COleDropInfo(COleDataObject* pDataObject,DWORD dwKeyState,
DROPEFFECT dropEffect,DROPEFFECT dropEffectList,CPoint point );
virtual ~COleDropInfo();
public:
//COleDropTargetEx member functions params
COleDataObject* m_pDataObject;
DWORD m_dwKeyState;
DROPEFFECT m_dropEffect;
DROPEFFECT m_dropEffectList;
CPoint m_point;
DECLARE_DYNAMIC( COleDropInfo );
};
{
public:
COleDropInfo();
COleDropInfo(COleDataObject* pDataObject,DWORD dwKeyState,
DROPEFFECT dropEffect,DROPEFFECT dropEffectList,CPoint point );
virtual ~COleDropInfo();
public:
//COleDropTargetEx member functions params
COleDataObject* m_pDataObject;
DWORD m_dwKeyState;
DROPEFFECT m_dropEffect;
DROPEFFECT m_dropEffectList;
CPoint m_point;
DECLARE_DYNAMIC( COleDropInfo );
};
.cpp文件
IMPLEMENT_DYNAMIC( COleDropInfo, CObject );
COleDropInfo::COleDropInfo()
{
m_pDataObject = NULL;
m_dwKeyState = 0;
m_dropEffect = (DROPEFFECT)-1;
m_dropEffectList = DROPEFFECT_NONE;
}
COleDropInfo::COleDropInfo(COleDataObject* pDataObject,DWORD dwKeyState,
DROPEFFECT dropEffect,DROPEFFECT dropEffectList,CPoint point )
{
m_pDataObject = pDataObject;
m_dwKeyState = dwKeyState;
m_dropEffect = dropEffect;
m_dropEffectList = dropEffectList;
m_point = point;
}
COleDropInfo::~COleDropInfo()
{
m_pDataObject = NULL;
}
COleDropInfo::COleDropInfo()
{
m_pDataObject = NULL;
m_dwKeyState = 0;
m_dropEffect = (DROPEFFECT)-1;
m_dropEffectList = DROPEFFECT_NONE;
}
COleDropInfo::COleDropInfo(COleDataObject* pDataObject,DWORD dwKeyState,
DROPEFFECT dropEffect,DROPEFFECT dropEffectList,CPoint point )
{
m_pDataObject = pDataObject;
m_dwKeyState = dwKeyState;
m_dropEffect = dropEffect;
m_dropEffectList = dropEffectList;
m_point = point;
}
COleDropInfo::~COleDropInfo()
{
m_pDataObject = NULL;
}
在要实现拖放功能的控件类里面注册COleDropTarget
class CDropEdit : public CEdit
{
public:
CDropEdit();
public:
BOOL m_bDraging;
virtual BOOL Register();
virtual ~CDropEdit();
protected:
COleDropTargetEx m_dropEx;
//处理OnDropEx消息是必须的,否则OnDrop函数不会被执行
//当然也可以在OnDropEx函数中处理数据
virtual BOOL OnDrop(WPARAM pDropInfoClass, LPARAM lParm);
virtual DROPEFFECT OnDropEx(WPARAM pDropInfoClass, LPARAM lParm);
virtual DROPEFFECT OnDragOver(WPARAM pDropInfoClass,LPARAM lParm);
virtual void OnDragLeave(CWnd* pWnd );
DECLARE_MESSAGE_MAP()
};
{
public:
CDropEdit();
public:
BOOL m_bDraging;
virtual BOOL Register();
virtual ~CDropEdit();
protected:
COleDropTargetEx m_dropEx;
//处理OnDropEx消息是必须的,否则OnDrop函数不会被执行
//当然也可以在OnDropEx函数中处理数据
virtual BOOL OnDrop(WPARAM pDropInfoClass, LPARAM lParm);
virtual DROPEFFECT OnDropEx(WPARAM pDropInfoClass, LPARAM lParm);
virtual DROPEFFECT OnDragOver(WPARAM pDropInfoClass,LPARAM lParm);
virtual void OnDragLeave(CWnd* pWnd );
DECLARE_MESSAGE_MAP()
};
.cpp文件
BEGIN_MESSAGE_MAP(CDropEdit, CEdit)
//{{AFX_MSG_MAP(CDropEdit)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE(DROPM_DRAGOVER,OnDragOver)
ON_MESSAGE(DROPM_DROPEX,OnDropEx)
ON_MESSAGE(DROPM_DROP,OnDrop)
ON_MESSAGE(DROPM_DRAGLEAVE,OnDragLeave)
END_MESSAGE_MAP()
CDropEdit::CDropEdit()
{
m_bDraging = FALSE;
}
CDropEdit::~CDropEdit()
{
}
BOOL CDropEdit::Register()
{
return m_dropEx.Register( this );
}
void CDropEdit::OnDragLeave(CWnd* pWnd )
{
}
DROPEFFECT CDropEdit::OnDragOver(WPARAM pDropInfoClass, LPARAM lParm)
{
this->SetFocus();
COleDropInfo* pInfo = (COleDropInfo* )pDropInfoClass;
ASSERT(pInfo->IsKindOf(RUNTIME_CLASS(COleDropInfo)));
if( pInfo->m_pDataObject->IsDataAvailable( CF_TEXT ) )
return DROPEFFECT_COPY;
else
return DROPEFFECT_NONE;
}
DROPEFFECT CDropEdit::OnDropEx(WPARAM pDropInfoClass, LPARAM lParm)
{
return (DROPEFFECT)-1;
}
BOOL CDropEdit::OnDrop(WPARAM pDropInfoClass, LPARAM lParm)
{
COleDropInfo* pInfo = (COleDropInfo* )pDropInfoClass;
ASSERT(pInfo->IsKindOf(RUNTIME_CLASS(COleDropInfo)));
if( pInfo->m_pDataObject->IsDataAvailable( CF_TEXT ) )
{
HGLOBAL hMem = pInfo->m_pDataObject->GetGlobalData( CF_TEXT );
char* lp = (char *)GlobalLock((HGLOBAL) hMem);//lock source
if (lp != NULL)
{
//Set Windows title with Drop text
SetWindowText( lp );
}
GlobalUnlock( hMem );//unlock source
return TRUE;
}
else
return FALSE;
}
void CDropEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
CEdit::OnLButtonDown(nFlags, point);
//确信要拖动,而不是随便点击
//按下左键250ms则认为要拖动
Sleep(250);
MSG msg;
::PeekMessage(&msg,GetSafeHwnd(),WM_LBUTTONUP,WM_LBUTTONUP,PM_NOREMOVE);
//随意点击而已,返回
if( msg.message==WM_LBUTTONUP )return;
CString sContens;
GetWindowText( sContens );
HGLOBAL hData = GlobalAlloc(GHND|GMEM_SHARE, sContens.GetLength()+1 );
char *pS = (char *)GlobalLock( hData );
memcpy( pS, (LPCTSTR)sContens, sContens.GetLength()+1 );
GlobalUnlock( hData );
m_bDraging = TRUE; //开始拖动
COleDataSource source;
source.CacheGlobalData( CF_TEXT, hData );
source.DoDragDrop( DROPEFFECT_COPY );
GlobalFree( hData );
m_bDraging = FALSE; //完成拖动
}
//{{AFX_MSG_MAP(CDropEdit)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE(DROPM_DRAGOVER,OnDragOver)
ON_MESSAGE(DROPM_DROPEX,OnDropEx)
ON_MESSAGE(DROPM_DROP,OnDrop)
ON_MESSAGE(DROPM_DRAGLEAVE,OnDragLeave)
END_MESSAGE_MAP()
CDropEdit::CDropEdit()
{
m_bDraging = FALSE;
}
CDropEdit::~CDropEdit()
{
}
BOOL CDropEdit::Register()
{
return m_dropEx.Register( this );
}
void CDropEdit::OnDragLeave(CWnd* pWnd )
{
}
DROPEFFECT CDropEdit::OnDragOver(WPARAM pDropInfoClass, LPARAM lParm)
{
this->SetFocus();
COleDropInfo* pInfo = (COleDropInfo* )pDropInfoClass;
ASSERT(pInfo->IsKindOf(RUNTIME_CLASS(COleDropInfo)));
if( pInfo->m_pDataObject->IsDataAvailable( CF_TEXT ) )
return DROPEFFECT_COPY;
else
return DROPEFFECT_NONE;
}
DROPEFFECT CDropEdit::OnDropEx(WPARAM pDropInfoClass, LPARAM lParm)
{
return (DROPEFFECT)-1;
}
BOOL CDropEdit::OnDrop(WPARAM pDropInfoClass, LPARAM lParm)
{
COleDropInfo* pInfo = (COleDropInfo* )pDropInfoClass;
ASSERT(pInfo->IsKindOf(RUNTIME_CLASS(COleDropInfo)));
if( pInfo->m_pDataObject->IsDataAvailable( CF_TEXT ) )
{
HGLOBAL hMem = pInfo->m_pDataObject->GetGlobalData( CF_TEXT );
char* lp = (char *)GlobalLock((HGLOBAL) hMem);//lock source
if (lp != NULL)
{
//Set Windows title with Drop text
SetWindowText( lp );
}
GlobalUnlock( hMem );//unlock source
return TRUE;
}
else
return FALSE;
}
void CDropEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
CEdit::OnLButtonDown(nFlags, point);
//确信要拖动,而不是随便点击
//按下左键250ms则认为要拖动
Sleep(250);
MSG msg;
::PeekMessage(&msg,GetSafeHwnd(),WM_LBUTTONUP,WM_LBUTTONUP,PM_NOREMOVE);
//随意点击而已,返回
if( msg.message==WM_LBUTTONUP )return;
CString sContens;
GetWindowText( sContens );
HGLOBAL hData = GlobalAlloc(GHND|GMEM_SHARE, sContens.GetLength()+1 );
char *pS = (char *)GlobalLock( hData );
memcpy( pS, (LPCTSTR)sContens, sContens.GetLength()+1 );
GlobalUnlock( hData );
m_bDraging = TRUE; //开始拖动
COleDataSource source;
source.CacheGlobalData( CF_TEXT, hData );
source.DoDragDrop( DROPEFFECT_COPY );
GlobalFree( hData );
m_bDraging = FALSE; //完成拖动
}
在应用程序初始化函数里面添加OLE初始化
BOOL CDropExDemoApp::InitInstance()
{
if( !AfxOleInit() )//初始化OLE
TRACE("Ole init faile");
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CDropExDemoDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{}
else if (nResponse == IDCANCEL)
{}
return FALSE;
}
{
if( !AfxOleInit() )//初始化OLE
TRACE("Ole init faile");
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CDropExDemoDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{}
else if (nResponse == IDCANCEL)
{}
return FALSE;
}
相关参考:
MSDN(vc6)地址:Visual C++ Documentation->Using Visual C++->Visual C++ Programmer's Guide->Adding Program Functionality->Details->OLE Topics->Drag and Drop(OLE)
MSDN地址:http://msdn.microsoft.com/en-us/library/aa294159(VS.60).aspx
控件接收文件拖放
posted on 2008-08-07 12:42 Xproer-松鼠 阅读(1380) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)