在实际使用过程中,当treeview控件允许拖动drag时,由于treeview控件在expand后,高度都会比较高,以至于数据在控件内,无法完全显示,而在drag过程中,经常需要执行大幅度的拖动,这样一来就会导致拖动过程经常受阻。
虽然在拖动时,可以通过滚动鼠标滚轮的方式来手动为treeview控件滚动数据,但是这样的操作比较麻烦,经常会在滚动滚轮时,不经意的松开鼠标左键,导致drag过程被终止。
为了解决treeview控件的这一不足,本人对treeview控件进行改写,实现treeview控件在drag过程中,当鼠标移动到treeview上方时,可以自动向上滚动数据;当鼠标移动到treeview下方时,可以自动向下滚动数据。
将以下内容复制,并保存到本地文件 uo_autoscroll_tv.sru 中,然后导入pbl中,之后就可以通过 nsert userobject 方式插入该控件了。
本控件已经集成了drag功能,您在使用时,只需要更改它的dragicon(拖动时显示的图标)属性。
另外插入后的控件,只需要在ue_dragdrop事件及ue_dragdrop_o两个事件中进行编程即可。其中ue_dragdrop事件用于treeview控件内部的拖动;ue_dragdrop_o事件用于从其他控件到该treeview控件的拖动。
$PBExportHeader$uo_autoscroll_tv.sru
forward
global type uo_autoscroll_tv from treeview
end type
type itiming from timing within uo_autoscroll_tv
end type
end forward
global type uo_autoscroll_tv from treeview
integer width = 549
integer height = 452
string dragicon = "DataPipeline!"
integer textsize = -9
integer weight = 400
fontcharset fontcharset = gb2312charset!
fontpitch fontpitch = variable!
string facename = "宋体"
long textcolor = 33554432
borderstyle borderstyle = stylelowered!
boolean linesatroot = true
long picturemaskcolor = 536870912
long statepicturemaskcolor = 536870912
event ue_dragdrop ( long al_from, long al_to )
event ue_dragdrop_o ( dragobject source, long al_to )
event ue_lbuttondown pbm_lbuttondown
event ue_lbuttonup pbm_lbuttonup
itiming itiming
end type
global uo_autoscroll_tv uo_autoscroll_tv
type prototypes
function ulong SetCapture(ulong hwnd) library "user32.dll"
function boolean ReleaseCapture() library "user32.dll"
end prototypes
type variables
protected:
long il_drag_handle //开始拖动的节点的句柄
long il_dragwithin_handle //当前拖动到的节点
constant long SB_LINEUP = 0
constant long SB_LINELEFT = 0
constant long SB_LINEDOWN = 1
constant long SB_LINERIGHT = 1
constant long SB_PAGEUP = 2
constant long SB_PAGELEFT = 2
constant long SB_PAGEDOWN = 3
constant long SB_PAGERIGHT = 3
constant long SB_TOP = 6
constant long SB_LEFT = 6
constant long SB_BOTTOM = 7
constant long SB_RIGHT = 7
constant long WM_HSCROLL= 276
constant long WM_VSCROLL = 277
end variables
forward prototypes
public subroutine of_bolditem (long al_h, boolean ab)
protected subroutine of_timing ()
end prototypes
event ue_dragdrop(long al_from, long al_to);//响应内部拖动
end event
event ue_dragdrop_o(dragobject source, long al_to);//响应外部拖动
end event
event ue_lbuttondown;SetCapture(handle(this))
this.drag(begin!)
il_drag_handle = this.getitematpointer()
end event
event ue_lbuttonup;ReleaseCapture()
itiming.stop()
end event
public subroutine of_bolditem (long al_h, boolean ab);//选择/不选 节点al_h
treeviewitem ltvi
if this.getitem(al_h, ltvi) <> 1 then return
ltvi.bold = ab
this.setitem(al_h, ltvi)
end subroutine
protected subroutine of_timing ();if this.pointerY() <= 0 then
//连续send两次,是为了加快滚动速度
SEND(handle(this), WM_VSCROLL, SB_LINEUP, 0)
SEND(handle(this), WM_VSCROLL, SB_LINEUP, 0)
elseif this.pointerY() >= this.width - 10 then
SEND(handle(this), WM_VSCROLL, SB_LINEDOWN, 0)
SEND(handle(this), WM_VSCROLL, SB_LINEDOWN, 0)
end if
end subroutine
on uo_autoscroll_tv.create
this.itiming=create itiming
end on
on uo_autoscroll_tv.destroy
destroy(this.itiming)
end on
event dragenter;itiming.stop()
end event
event dragwithin;of_bolditem(il_dragwithin_handle, false)
of_bolditem(handle, true)
il_dragwithin_handle = handle
end event
event dragdrop;of_bolditem(il_dragwithin_handle, false)
if source = this then
event ue_dragdrop(il_drag_handle, handle)
else
event ue_dragdrop_o(source, handle)
end if
end event
event dragleave;itiming.start(0.1)
end event
type itiming from timing within uo_autoscroll_tv descriptor "pb_nvo" = "true"
end type
on itiming.create
call super::create
TriggerEvent( this, "constructor" )
end on
on itiming.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
event timer;parent.of_timing()
end event