win32 sdk树形控件的项拖拽实现
来源:互联网 发布:知乎手机端发文章 编辑:程序博客网 时间:2024/05/16 09:05
理论:
树型视图是一种特别的窗口,我们可以使用它一目了然地表示某种层次关系。譬如象在资源管理器中左边窗口中的就是树型视图。您可以调用CreateWindowEx来创建树型视图,传递一个类名“"SysTreeView32"”,或者您也可以把它放到一个对话框中去。不要忘了在您的代码中加入InitCommonControls函数。树型视图有几种特有的风格。下面是几种经常使用的。
TVS_HASLINES == 在层次中用线条来连接各个项目名称。
TVS_LINESATROOT ==
当有事件发生时,树型视图发送一个WM_NOTIFY消息个父窗口,并在消息中附带传递一些附加信息。
wParam ==控件的ID。因为该值不是唯一的,故我们不用它。我们使用NMHDR结构体中的hwndFrom或IDFrom成员变量。
lParam ==
typedef struct tagNMHDR
{
}NMHDR;
idFrom是发送WM_NOTIFY消息的控件的ID。
code是控件发送给父窗口的数据。
树型视图发送给父窗口的通知消息以TVN_打头。 树型视图接收到的消息以TVM_打头,譬如:TVM_CREATEDRAGIMAGE。树型视图发送TVN_XXX消息时在code变量中放入NMHDR型变量。父窗口发送TVM_消息来控制树型视图。
在树型视图中加入项目
在创建完树型视图后可以通过发送TVM_INSERTITEM消息往其中加入项目了。TVM_INSERTITEM
wParam = 0;
lParam = 指向结构体TV_INSERTSTRUCT的指针;
您应当知道一些关于树型视图中的项目之间关系的一些术语。一个项目可能是一个父亲、儿子或两者都是。父项目下含有子项目,而该父项目又有可能是其它项目的子项目。一个没有父项目的项目叫根项目。在树型视图中可能有多个根项目。现在我们来看看TV_INSERTSTRUCT结构体:
typedef struct tagTVINSERTSTRUCT {HTREEITEM hParent;HTREEITEM hInsertAfter;#if (_WIN32_IE >= 0x0400)union{TVITEMEX itemex;TVITEM item;} DUMMYUNIONNAME;#elseTVITEM item;#endif} TVINSERTSTRUCT, *LPTVINSERTSTRUCT;
hInsertAfter
- TVI_FIRST ==> 插在列表的头部。
- TVI_LAST ==> 插在列表的尾部。
- TVI_SORT ==> 按字母顺序插入。
union{TVITEMEX itemex;TVITEM item;} DUMMYUNIONNAME;
typedef struct tagTVITEM {
} TVITEM, *LPTVITEM;
该结构体根据消息类型,用来发送或接收关于一个树型视图的项目的有关信息。譬如:对于消息TVM_INSERTITEM,它用来指定插入树型视图控件的项目的属性。而对于消息TVM_GETITEM,该结构体用来填充关于选定项目的信息。
imask
hItem
pszText
cchTextMax仅在查询项目的名称时使用。由于在pszText中指定了指针,WINDOWS还要知道该缓冲去的大小。所以您必须给出该值。
iImage
为了在树型视图中插入一个项目,您必须至少设定hParent, hInsertAfter,另外您还要设定imask和pszText值。
把图形加到图形视图中
如果您想要在项目的名称左边显示图标的话,您必须创建一个图形列表,并且把它和树形视图相关联起来。您可以调用ImageList_Create来创建一个图形列表。HIMAGELIST ImageList_Create(int cx, int cy, UINT flags, int cInitial, int cGrow);
如果创建成功的话,该函数返回一个空的图象列表的句柄。
cx
cy
flags
cInitial
cGrow
图象列表不是窗口。仅仅是保存在那给其它的窗口使用的一种资源。在图象列表产生后,您可以调用ImageList_Add来向其中加入图象。
int ImageList_Add(HBITMAP
);
如果该函数调用失败的话,返回-1。
himl
hbmImage
hbmMask
当图象列表准备就绪后,您可以发送消息TVM_SETIMAGELIST给树型视图来让图象列表和树型视图联系起来。
wParam =
- TVSIL_NORMAL
包含被选中和没有被选中两种状态的图象。 - TVSIL_STATE
包含了用户自定义的状态的图象。
检索树型视图的信息
您可以通过发送消息TVM_GETITEM来检索图形视图的信息。TVM_GETITEM
wParam = 0
lParam =指向结构体TV_ITEM的指针。该结构体将用来得到相关的信息。
在发送该消息前必须设置成员变量imask的值,以便WINDOWS能告诉相关的信息。当然,最重要的是,您必须传递您想得到信息的项目的句柄。这就引起了一个问题,您如何得到项目的句柄?要保存所有项目的句柄吗?
答案是很简单的:没有必要。您可以发送消息TVM_GETNEXTITEM到树型视图以检索您想要得到其属性的项目的句柄。譬如:您可以查询第一个子项目的句柄、根目录的句柄、选中的项目的句柄等等。
wParam =
lParam =
- TVGN_CARET
选中的项目 - TVGN_CHILD
hitem参数指定项目的第一个子项目 - TVGN_DROPHILITE
拖-拉操作的目的项目 - TVGN_FIRSTVISIBLE
第一个可见项目 - TVGN_NEXT
下一个同级项目 - TVGN_NEXTVISIBLE
下一个可见项目,指定的项目必须可见。发送消息TVM_GETITEMRECT 来决定项目是否可见 - TVGN_PARENT
指定项目的父项目 - TVGN_PREVIOUS
前一个同级项目 - TVGN_PREVIOUSVISIBLE
前一个可见项目,指定的项目必须可见。发送消息TVM_GETITEMRECT 来决定项目是否可见 - TVGN_ROOT
根项目
在树型视图中进行拖-拉操作
也就是因为这一部分我才决定写这课教程。当我按照InPrise公司的WIN32帮助来运行例子时,发现它的帮助中缺少真正重要的信息。我只有通过自己做实验,最后总算弄明白来个中来由。希望您不要和我一样再去走这些弯路,下面我把我所知的在树型视图中进行拖-拉操作的步骤描述如下:- 当用户要拖动一个项目时,树型视图控件会给它的父窗口发送TVN_BEGINDRAG通知消息。您可以在此处创建表示项目处在拖动操作中的图象,这可以通过发送TVM_CREATEDRAGIMAGE消息给树型视图,让其为目前使用的图象产生一副缺省的图象来实现。树型视图控件将创建一个图象列表,其中仅包含一副在拖动中显示的图象,图象列表创建后,您可以得到它的句柄。
- 在拖拉的图象生成后,您可以通过调用ImageList_BeginDrag来指定拖动图象的热点位置。
- BOOL ImageList_BeginDrag(