树型视图控件详解
2007-05-01 09:31:13 来源:WEB开发网hbmMask == 掩码位图的句柄。如果没有使用掩码位图,可以忽略该值。 通常我们加入两种图象到图象列表中。一种时被选中时显示的图象,另一种时没被选中时显示的。
当图象列表准备就绪后,您可以发送消息TVM_SETIMAGELIST给树型视图来让图象列表和树型视图联系起来。
TVM_SETIMAGELIST
wParam = 图象列表的状态,一共有两种:
TVSIL_NORMAL 包含被选中和没有被选中两种状态的图象。
TVSIL_STATE 包含了用户自定义的状态的图象。
lParam = 图象列表的句柄。
检索树型视图的信息
您可以通过发送消息TVM_GETITEM来检索图形视图的信息。
TVM_GETITEM
wParam = 0
lParam =指向结构体TV_ITEM的指针。该结构体将用来得到相关的信息。
在发送该消息前必须设置成员变量imask的值,以便WINDOWS能告诉相关的信息。当然,最重要的是,您必须传递您想得到信息的项目的句柄。这就引起了一个问题,您如何得到项目的句柄?要保存所有项目的句柄吗?
答案是很简单的:没有必要。您可以发送消息TVM_GETNEXTITEM到树型视图以检索您想要得到其属性的项目的句柄。譬如:您可以查询第一个子项目的句柄、根目录的句柄、选中的项目的句柄等等。
TVM_GETNEXTITEM
wParam = 标志
lParam = 树型视图的句柄(仅仅当wParam的值是某些标志位时才是必须的)。
wParam中的值非常重要, 我解释如下:
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 根项目
由此您可以通过发送该消息来得到项目的句柄,然后在发送消息TVM_GETITEM时在结构体变量TV_ITEM的成员变量hItem中放入该项目的句柄就可以得到关于该项目的有关信息了。
在树型视图中进行拖-拉操作
也就是因为这一部分我才决定写这课教程。当我按照InPrise公司的WIN32帮助来运行例子时,发现它的帮助中缺少真正重要的信息。我只有通过自己做实验,最后总算弄明白来个中来由。希望您不要和我一样再去走这些弯路,下面我把我所知的在树型视图中进行拖-拉操作的步骤描述如下:
当用户要拖动一个项目时,树型视图控件会给它的父窗口发送TVN_BEGINDRAG通知消息。您可以在此处创建表示项目处在拖动操作中的图象,这可以通过发送TVM_CREATEDRAGIMAGE消息给树型视图,让其为目前使用的图象产生一副缺省的图象来实现。树型视图控件将创建一个图象列表,其中仅包含一副在拖动中显示的图象,图象列表创建后,您可以得到它的句柄。
在拖拉的图象生成后,您可以通过调用ImageList_BeginDrag来指定拖动图象的热点位置。
ImageList_BeginDrag PROTO himlTrack:DWORD, \
iTrack:DWORD , \
dxHotspot:DWORD, \
dyHotspot:DWORD
himlTrack 是包含了拖拉时显示的图象的图象列表的句柄
iTrack 是选中的图象在图象列表中的索引号。
dxHotspot 因为在拖动中该图象被用来取代光标,所以我们必须指定图象中的哪一点是光标的左上角的位置。dxHotspot是水平相对位置。
dyHotspot 是垂直相对位置。
iTrack等于0。如果您要想光标的热点在拖拉中显示的图象的左上角,把dxHotspot和dyHotspot都设成0。
当拖拉的图象要显示时,我们调用ImageList_DragEnter 在树型视图中显示该图象。
ImageList_DragEnter PROTO hwndLock:DWORD, x:DWORD, y:DWORD
hwndLock 是进行拖拉中的窗口的句柄,拖拉的动作限制在该窗口中。
x 和 y是在拖拉时显示图象的初始位置的坐标值。这些值是相对于窗口的左上角而不是客户区的左上角。
既然可以显示拖动中的图象了,我们就要处理拖动操作了。在这里有一个小问题。我们监视拖动是通过监视鼠标光标的移动来实现的,譬如在移动时我们通过捕获WM_MOUSEMOVE消息来得到移动中的坐标位置,通过捕获WM_LBUTTONUP消息来获知用户的放下操作。但这时如果鼠标光标移过子窗口时父窗口就无法再得到鼠标光标的移动以及鼠标的按键消息了。解决办法是调用SetCapture函数了锁定鼠标事件,这样无论鼠标移到那里和有什么动作,我们的窗口都可以知道了。
在处理WM_MOUSEMOVE消息时,您可以调用ImageList_DragMove来更新图象移动的轨迹。 该函数可以移动拖放操作中的图象位置。另外,如果您想让移动中的图象经过某些项目时高量度显示,可以调用TVM_HITTEST 来确定是否经过某个项目的上面。如果是的话,您可以发送TVM_SELECTITEM消息并设置 TVGN_DROPHILITE标志位使得那个项目高亮度显示。注意:在发送消息TVM_SELECTITEM前,您必须先隐藏图象列表,否则会留下非常难看的轨迹。要隐藏拖动中的图象可以调用ImageList_DragShowNolock,在显示完高亮度的图象后再调用该函数以让拖动中的图象再正常显示。
当用户释放主键后,您必须做几件事。 如果您在高亮度显示的时候释放鼠标主键(表示您想把该项目加到此处),您必须使该项目变成正常地显示,这可以通过发送消息TVM_SELECTITEM消息并设置标志位TVGN_DROPHILITE来实现,只是这时lParam必须为0。如果您不让高亮度显示的项目恢复正常,那就会发生一个奇怪的现象:当您再选择另外的项目时,那个项目的图象会包含在一个正方形中,当时高亮度显示的项目依旧是上一个项目。接下来必须调用ImageList_EndDrag和ImageList_DragLeave。还有调用ReleaseCapture来释放捕获的鼠标。如果您创建了一个图象列表,那还要调用calling ImageList来将它销毁,在拖放操作结束后您可以进行另外其它的操作。
例子代码:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
include \masm32\include\gdi32.inc
更多精彩
赞助商链接