刚刚完成了树控件中树节点的拖曳功能,将一些东西记录下来。
先得说一下,这次实现这个功能,基本上没有通过google,完全是通过看MSDN学到的。
时间上来看,反而比google后实现出来要快不少,因为google出来的代码是别人消化完的,都是一些纯代码,而一些心得性的文章反而比msdn写得还复杂。。。
这次查找资料的顺序是:
MSDN -> CTreeCtrl -> Using CtreeCtrl -> Tree Control Drag-and-Drop Operations
然后就找到了想要的东西,而且那篇文章很短,很实用:)
过程中还顺便学了下Notify消息的一些相关知识,相当不错。(原来WM_COMMAND也是一种NOTIFY消息,而且是最简单的消息,因为它能带的参数太少了。。。)
言归正传,拖曳是控件的一个通用的功能,要实现拖曳首先需要在父窗口或控件窗口中对 TVN_BEGINDRAG 消息进行处理。
然后在消息处理函数中添加上拖曳的启动代码:
COleDataSource* pOleSourceObj = new COleDataSource;DROPEFFECT dropeffect = pOleSourceObj->DoDragDrop();delete pOleSourceObj;
在调用DoDragDrop函数后,就会进入拖曳过程中,这时需要一个处理对象来处理拖曳的消息,这里我们在窗口中添加一个成员对象 COleDropTarget,并在窗口的Create函数中进行注册:
m_dragTarget.register(this);
这时所有的拖曳消息就都会由m_dragTarget对象进行处理。
我们可以对 COleDropTarget 进行派生,来处理各个拖曳操作。
COleDropTarget 主要以下几个虚函数:
- virtual DROPEFFECT OnDragEnter(CWnd * pWnd, COleDataObject * pDataObject, DWORD dwKeyState, CPoint point );
在拖曳刚开始的时候调用,主要用于定制拖曳支持哪些功能,支持的有:
#define DROPEFFECT_NONE ( 0 ) // 啥也不支持
#define DROPEFFECT_COPY ( 1 ) // 拷贝
#define DROPEFFECT_MOVE ( 2 ) // 移动
#define DROPEFFECT_LINK ( 4 ) // 链接
#define DROPEFFECT_SCROLL ( 0x80000000 ) // 滚动
- virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point );
当在窗口中拖曳时,就会调用这个函数。就是鼠标划过窗口的意思。
这个函数可用于拖曳过程中鼠标的样式,还有鼠标到窗口边缘时窗口的滚动操作等。
- virtual void OnDragLeave(CWnd * pWnd );
当拖曳到窗口外面的时候,会调用此函数。
- virtual BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point );
松开鼠标左键,完成拖曳操作时会调用此函数。