在實際使用過程中,當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控件的拖動。
[cpp]
$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
摘自 yyoinge的專欄