松鼠的博客

导航

统计

MFC 拖放

  1. 添加一个继承自COleDropTarget的类
  2. 添加继承自CObject的拖动信息类
  3. 在要实现的控件类里面申明和注册COleDropTarget
  4. 在应用程序初始化里面加入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);
};
复制代码

 

.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, 
00, 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, 
00, 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, 00 );

    
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 );
};
复制代码

 

.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;
}
复制代码

 

在要实现拖放功能的控件类里面注册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()
};
复制代码

 

.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;    //完成拖动
}
复制代码

 

在应用程序初始化函数里面添加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;
}
复制代码

 

相关参考:
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   Xproer-松鼠  阅读(1380)  评论(0编辑  收藏  举报

编辑推荐:
· 基于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)
点击右上角即可分享
微信分享提示