BEGIN_MESSAGE_MAP(CDlgScenegraph, CDialog)//添加消息响应函数
//{{AFX_MSG_MAP(CDlgScenegraph)
ON_WM_SIZE()
ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE1,  OnEndlabeleditTree)//此处实现鼠标单击时进行的一些操作
ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBegindrag)//想在此处实现树形控件的节点拖动功能
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()如上的消息响应函数,ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE1,  OnEndlabeleditTree)可以正常运行,但是ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBegindrag)这一句在鼠标拖动时没有执行,不知道是怎么回事。希望各位高手能给于一定的指导,谢谢!
因为鼠标左键单击执行显示对应零件的包围盒,所以节点拖动改为右键拖动,即TVN_BEGINRDRAG而不是TVN_BEGINDRAG

解决方案 »

  1.   

    ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBegindrag)
    -->
    ON_NOTIFY(TVN_BEGINRDRAG, IDC_TREE1, OnBegindrag)
      

  2.   

    ON_NOTIFY_REFLECT是消息发射,意思是此消息交给控件自己处理
    看你的消息是BEGIN_MESSAGE_MAP(CDlgScenegraph, CDialog)  应该是在父窗口,当然不能效应一种办法是ls所说,另一种办法是重载CTreeCtrl 将此写在重载的类里,即
    BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)
       ON_NOTIFY_REFLECT(TVN_BEGINRDRAG, OnBegindrag)
    END_MESSAGE_MAP()
      

  3.   

    void CDlgScenegraph::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
    {

    NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
    HTREEITEM hItem = pNMTreeView->itemNew.hItem; //获取开始拖动的节点
    if (hItem==m_treeScenegraph.GetRootItem()) //不允许拖动根节点
    {
    *pResult = 0;
    return ;
    }
    m_hBeginDrag = hItem; //记录开始拖动的项目
    m_pImageList = m_treeScenegraph.CreateDragImage(hItem); //创建拖动的图像列表 CPoint dragPT; //记录起始点
    dragPT.x = pNMTreeView->ptDrag.x;
    dragPT.y = pNMTreeView->ptDrag.y;
    if (m_pImageList != NULL)
    {
    m_pImageList->BeginDrag(0, CPoint(8, 8)); //开始拖动图像
    ClientToScreen(&dragPT); //转换客户坐标到屏幕坐标
    m_pImageList->DragEnter(this, dragPT); //锁定窗口更新,在拖动的过程中显示拖动的图像
    SetCapture(); //开始鼠标捕捉
    m_bDrag = TRUE;
    }
    *pResult = 0;

    }void CDlgScenegraph::OnMouseMove(UINT nFlags, CPoint point) 
    {
    if (m_bDrag) //处于拖动状态
    {
    HTREEITEM hItem;
    UINT nHitFlags;
    CRect clientRC;
    GetClientRect(&clientRC); //获取客户区域
    m_pImageList->DragMove(point); //设置拖动的图像位置
    //鼠标经过时高亮显示
    if( (hItem = m_treeScenegraph.HitTest(point, &nHitFlags)) != NULL )
    {
    CImageList::DragShowNolock(FALSE); //隐藏拖动的图像
    m_treeScenegraph.SelectDropTarget(hItem); //设置选中的项目
    CImageList::DragShowNolock(TRUE); //显示拖动的图像
    }
    }
    else

          CDlgScenegraph::OnMouseMove(nFlags, point);
    }void CDlgScenegraph::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    if (m_bDrag) //处于拖动状态
    {
    m_bDrag = FALSE;
    CImageList::DragLeave(this); //
    CImageList::EndDrag(); //结束图像拖动
    ReleaseCapture(); //释放鼠标捕捉
    delete m_pImageList; //释放图像列表
    m_pImageList = NULL;
    CRect winRC;
    GetWindowRect(&winRC); //获取窗口区域
    HTREEITEM hItem;
    if((hItem = m_treeScenegraph.HitTest(point, &nFlags)) != NULL)
    {
    //进行拖动处理
    //如果目标项目与开始拖动的项目相同或者目标项目仍是开始项目的父节点,不进行处理
    if (m_hBeginDrag != hItem && hItem != m_treeScenegraph.GetParentItem(m_hBeginDrag))
    {
    CopyNodes(hItem, m_hBeginDrag); //进行节点的复制
    m_treeScenegraph.DeleteItem(m_hBeginDrag); //删除源节点
    }
    Invalidate();
    m_treeScenegraph.SelectDropTarget(NULL);
    m_hBeginDrag = NULL;
    }
    }
    }//复制节点,将hSrcItem及其子项目复制到下hDesItem节点下
    void CDlgScenegraph::CopyNodes(HTREEITEM hDesItem, HTREEITEM hSrcItem)
    { if (hDesItem==NULL || hSrcItem==NULL) //验证参数
    {
    return;
    }
    TVITEM tvItem; //定义项目信息
    tvItem.mask = TVIF_TEXT|TVIF_IMAGE; //设置返回标记
    tvItem.hItem = hSrcItem;
    char chText[MAX_PATH] = {0};
    tvItem.pszText = chText;
    tvItem.cchTextMax = MAX_PATH;
    m_treeScenegraph.GetItem(&tvItem); //获取项目信息
    TVINSERTSTRUCT tvInsert; //定义插入操作的数据结构
    tvInsert.hParent = hDesItem;
    tvInsert.item = tvItem;
    HTREEITEM hInsert = m_treeScenegraph.InsertItem(&tvInsert); //插入项目
    HTREEITEM hChild = m_treeScenegraph.GetChildItem(hSrcItem); //获取子节点
    while (hChild != NULL) //遍历子节点
    {
    tvItem.mask = TVIF_TEXT|TVIF_IMAGE;
    tvItem.hItem = hChild;
    tvItem.pszText = chText;
    tvItem.cchTextMax = MAX_PATH;
    m_treeScenegraph.GetItem(&tvItem);
    tvInsert.hParent = hInsert;
    tvInsert.item = tvItem;
    CopyNodes(hInsert, hChild); //递归调用
    hChild = m_treeScenegraph.GetNextSiblingItem(hChild); //查找下一个兄弟节点
    }
    }谢谢,按照1#的做法可以运行拖动的程序了!但是还有一个问题想请教一下,
    这是我的代码 但是只能实现拖动到作为某个节点的子节点,但是我想实现拖动到作为某个节点的前或后节点。同时拖动时能像PRO/E里的一样用一道线来确定位置。