小弟初学VC,最近在用bcg做一个程序,bcg里有一个workspacebar的树形菜单,我想实现对树的拖拽,拖拽到view栏中,并能够在视图栏中显示一个图标,请各位帮忙!!

解决方案 »

  1.   

    WIN32拖拽扩展COleDropTarget,重写以下虚方法:
    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);
      

  2.   

    OleDropTargetEx.h// OleDropTargetEx.h: interface for the COleDropTargetEx class.#if !defined(AFX_OLEDROPTARGETEX_H__I_LOVE_MY_MOTHERLAND)
    #define AFX_OLEDROPTARGETEX_H__I_LOVE_MY_MOTHERLAND#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // OleDropTargetEx.h header file
    //Drag & Drop User define Messages/////////////////////////////////////////////////////////////////////////////
    //Drop info class
    //ΪÍ϶¯ÏûÏ¢ÏìÓ¦º¯ÊýÌṩÍ϶¯ÐÅÏ¢
    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 );
    };/////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////
    //COleDropTargetEx class 
    class COleDropTargetEx : public COleDropTarget
    {
    public:
    COleDropTargetEx();
    virtual ~COleDropTargetEx();protected:
    //´¦ÀíOnDropExÏûÏ¢ÊDZØÐëµÄ£¬·ñÔò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);
    };#endif // !defined(AFX_OLEDROPTARGETEX_H__I_LOVE_MY_MOTHERLAND)OleDropTargetEx.cpp// OleDropTargetEx.cpp: implementation of the COleDropTargetEx class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "LAD EDIT.h"
    //#include "OleDropTargetEx.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////
    //COleDropInfo Construction/Destruction
    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;
    }//////////////////////////////////////////////////////////////////////
    //COleDropTargetEx Construction/Destruction
    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;
    }
      

  3.   

    如何使用:
    数据源注册:
    COleDropTargetEx m_OleDropTarget;
       if(!m_OleDropTarget.Register(this))
       {
          MessageBox("Register error!", "Error" , MB_OK);
       }目标注册:
    与数据来源者注册一样
    COleDropTargetEx m_OleDropTarget;
       if(!m_OleDropTarget.Register(this))
       {
          MessageBox("Register error!", "Error" , MB_OK);
       }
    注册是很重要的一步,只有两头都要注册才会有效
      

  4.   

    昨天连续发了3次,就不能发了,今天继续最后一步,模拟拖拽:
    模拟拖拽动作数据源中响应鼠标消息, OnLButtonDown
    [code=C/C++]
    void CXX::OnLButtonDown(UINT nFlags, CPoint point) 
    {
       // TODO: Add your message handler code here and/or call default
       SetFocus();
       
       HTREEITEM hItem = HitTest(point, NULL);
       if(NULL != hItem)
       {
          SelectItem(hItem);
          XX*pBlockLib = (XX*)GetItemData(hItem);
          if(NULL != pBlockLib)
          {
             HGLOBAL hData = GlobalAlloc(GHND|GMEM_SHARE, sizeof(XX));
             char *pS = (char *)GlobalLock(hData);
             memcpy(pS, (LPCTSTR)pBlockLib, sizeof(XX));
             GlobalUnlock(hData);
             
             COleDataSource source;
             UINT uBlockFormat = m_uBlockFormat;
             source.CacheGlobalData(uBlockFormat, hData);
             source.DoDragDrop(DROPEFFECT_COPY);
             GlobalFree(hData);
          }
       }
    }
    上边m_uBlockFormat要事先注册   UINT m_uBlockFormat = RegisterClipboardFormat("myblock");
       if(0 == m_uBlockFormat)
       {//register failed
          if(MessageBox(NULL, "Register the block format error!", "Error\n \
             close the instance(Y/N)", MB_YESNO) == IDYES)
          {
             return FALSE;
          }
       }
    鼠标拖到目标上:
    重写
    virtual BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
    virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
    DROPEFFECT CxxView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
    {
    // TODO: Add your specialized code here and/or call the base class

    //return CScrollView::OnDragOver(pDataObject, dwKeyState, point);   UINT uBlockFormat = m_uBlockFormat;
       if(pDataObject->IsDataAvailable(uBlockFormat))
    return DROPEFFECT_COPY;
    else
    return DROPEFFECT_NONE;
    }BOOL CxxView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) 
    {
       // TODO: Add your specialized code here and/or call the base class
       CPoint scrpt = GetScrollPosition();
       CPoint pt(point.x+scrpt.x, point.y+scrpt.y);   UINT uBlockFormat = m_uBlockFormat;
       if(pDataObject->IsDataAvailable(uBlockFormat))
       {
          HGLOBAL hMem = pDataObject->GetGlobalData(uBlockFormat);
          XX*pBlockLib = (XX*)GlobalLock((HGLOBAL)hMem);
          //自己处理的函数(pBlockLib, pt);
          GlobalUnlock(hMem);//unlock source
          Invalidate();
       }
       
    return CScrollView::OnDrop(pDataObject, dropEffect, point);
    }[/code]
      

  5.   

    楼主使用时,请去掉#include "LAD EDIT.h"