[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Jon Lewis

7/26/2011 1:00:00 PM

I'm using the V5 Treeview with a manifest pointing to Windows Common
Controls 6 using mostly Win API methods. The TV displays a 2 tier
Access recordset (about 5K parent noads each of which has between 0 and 5
children). I've got it loading reasonably fast and it has checkbox's which I
can check all (parent and child) using an API based routine (similar to the
expand code below) virtually
instantaneously. (c. 100 ticks). The problem is that a expand/collapse all
routine is taking
to long (c. 2000 ticks for expand 4000 ticks for collapse). It may be
because the TV scrolls when expanding all whereas it
doesn't when checking all. I've tried ensuring that the root node is
visible in the expand loop but this just slows things down further. Anyone
got any suggestions (other than load/expand nodes on demand) please?
I'd imagine that preventing the scrolling would do the trick but this seems
to be built into the TVM_EXPAND message.

Here's the expand code:

Public Function TreeView_ExpandAll(hwnd As Long) As Boolean
Dim hItem As Long
Redraw hwnd, False
hItem = TreeView_GetNextItem(hwnd, 0, TVGN_ROOT)
Call SendMessageLong(hwnd, TVM_EXPAND, TVE_EXPAND, hItem)
Do Until hItem <= 0
hItem = TreeView_GetNextItem(hwnd, hItem, TVGN_NEXT)
Call SendMessageLong(hwnd, TVM_EXPAND, TVE_EXPAND, hItem)
Loop
Redraw hwnd, True
End Function

Private Sub Redraw(Hwnd As Long, Enabled As Boolean)
If Enabled Then
SendMessageLong Hwnd, WM_SETREDRAW, True, &H0
Else
SendMessageLong Hwnd, WM_SETREDRAW, False, &H0
End If
End Sub

Private Function TreeView_GetNextItem(hwnd As Long, hItem As Long, flag As
Long) As Long
TreeView_GetNextItem = SendMessage(hwnd, TVM_GETNEXTITEM, ByVal flag,
ByVal hItem)
End Function



3 Answers

DaveO

7/26/2011 2:16:00 PM

0


"Jon Lewis" <jon.lewis@cutthespambtinternet.com> wrote in message
news:2eudnUEjB6HAJ7PTnZ2dnUVZ8vOdnZ2d@bt.com...
> I'm using the V5 Treeview with a manifest pointing to Windows Common
> Controls 6 using mostly Win API methods. The TV displays a 2 tier
> Access recordset (about 5K parent noads each of which has between 0 and 5
> children). I've got it loading reasonably fast and it has checkbox's which
> I
> can check all (parent and child) using an API based routine (similar to
> the expand code below) virtually
> instantaneously. (c. 100 ticks). The problem is that a expand/collapse all
> routine is taking
> to long (c. 2000 ticks for expand 4000 ticks for collapse). It may be
> because the TV scrolls when expanding all whereas it
> doesn't when checking all. I've tried ensuring that the root node is
> visible in the expand loop but this just slows things down further.
> Anyone
> got any suggestions (other than load/expand nodes on demand) please?
> I'd imagine that preventing the scrolling would do the trick but this
> seems
> to be built into the TVM_EXPAND message.
>
> Here's the expand code:
>
> Public Function TreeView_ExpandAll(hwnd As Long) As Boolean
> Dim hItem As Long
> Redraw hwnd, False
> hItem = TreeView_GetNextItem(hwnd, 0, TVGN_ROOT)
> Call SendMessageLong(hwnd, TVM_EXPAND, TVE_EXPAND, hItem)
> Do Until hItem <= 0
> hItem = TreeView_GetNextItem(hwnd, hItem, TVGN_NEXT)
> Call SendMessageLong(hwnd, TVM_EXPAND, TVE_EXPAND, hItem)
> Loop
> Redraw hwnd, True
> End Function
>
> Private Sub Redraw(Hwnd As Long, Enabled As Boolean)
> If Enabled Then
> SendMessageLong Hwnd, WM_SETREDRAW, True, &H0
> Else
> SendMessageLong Hwnd, WM_SETREDRAW, False, &H0
> End If
> End Sub
>
> Private Function TreeView_GetNextItem(hwnd As Long, hItem As Long, flag As
> Long) As Long
> TreeView_GetNextItem = SendMessage(hwnd, TVM_GETNEXTITEM, ByVal flag,
> ByVal hItem)
> End Function
>

Quick and easy test

Try adding: (and maybe lose your "ReDraw" stuff)
TreeView.Visible = False
Do stuff
TreeView.Visible = True

Make sure the routines that "Do Stuff" are free from DoEvents or the
TreeView will flicker or possibly actually go away for a bit.
It seems counter-intuitve but if you make the control invisible but prevent
redraws the control will actually stay (apparently) visible, but as the code
thinks the control is not visible it won't try to update it so things should
speed up a bit.

Also is there any reason to have the GetNextItem stuff in a seperate
function, just jumping to and returning from a function takes a small but
measurable time, not a problem for a few calls but if you have lots of nodes
it could add up.

Regards
DaveO.


Jon Lewis

7/27/2011 3:36:00 PM

0

Hi Dave and thanks for the response.

I've tried 'Doing stuff' with the TV invisible before and it's not
significantly different to using Windows messages to suspend repaints (as
the Redraw function does). However I thought you might be onto something as
the scroll bar would have a seperate Hwnd to the TW. So I tried and yes this
does prevent the TV from being scrolled during execution BUT it also
prevents the nodes from being expanded - even after a Redraw True after
making the TV visible again.

I can only assume that TVM_EXPAND sends a Ensure Visible message to the Node
before it sets the Expanded state. If that fails (which presumably it does
as the TV is invisible), it doesn't bother to set the Expanded State of each
Node.

So I thought I'd try setting the State of the TVITEM structure directly and
Bingo! all nodes expanded in around 50 tics with no scrolling. You do need
to force a redraw of the TV afterwards though otherwise the Nodes won't
actually appear as expanded even though they have the Collapse image. Code
is below if anyone's interested (would welcome any more comments on the
TVITEM code as I'm not that familair with bit masking but I think I've done
this correctly).

Regarding your comments about wrapping API calls in recallable functions, as
far as I can tell it makes no significant execution speed difference in this
kind of scenario.

Jon

Private Sub cmdExpand_Click()
Screen.MousePointer = 11
With Me.TreeView1
TreeView_ExpandAll .hwnd, True
End With
Screen.MousePointer = 0
End Sub

Public Function TreeView_ExpandAll(hwndTV As Long, bExpand As Boolean) As
Boolean
Dim hItem As Long

hItem = TreeView_GetNextItem(hwndTV, 0, TVGN_ROOT)
Call TreeView_SetExpandState(hwndTV, hItem, bExpand)

Do Until hItem <= 0
hItem = TreeView_GetNextItem(hwndTV, hItem, TVGN_NEXT)
Call TreeView_SetExpandState(hwndTV, hItem, bExpand)

Redraw hwndTV, True
End Function

Private Function TreeView_GetNextItem(hwnd As Long, hItem As Long, flag As
Long) As Long
TreeView_GetNextItem = SendMessageLong(hwnd, TVM_GETNEXTITEM, ByVal flag,
ByVal hItem)
End Function

Private Function TreeView_SetExpandState(hwndTV As Long, hItem As Long,
bExpand As Boolean)
Dim pitem As TVITEM
With pitem
..mask = TVIF_HANDLE Or TVIF_STATE
..hItem = hItem
..stateMask = TVIS_EXPANDED
..State = bExpand
End With
TreeView_SetExpandState = TreeView_SetItem(hwndTV, pitem)
End Function

Private Function TreeView_SetItem(hwnd As Long, pitem As TVITEM) As Boolean
TreeView_SetItem = SendMessage(hwnd, TVM_SETITEM, 0&, pitem)
End Function





"DaveO" <djo@dial.pipex.com> wrote in message
news:j0mi7g$anl$1@dont-email.me...
>
> "Jon Lewis" <jon.lewis@cutthespambtinternet.com> wrote in message
> news:2eudnUEjB6HAJ7PTnZ2dnUVZ8vOdnZ2d@bt.com...
>> I'm using the V5 Treeview with a manifest pointing to Windows Common
>> Controls 6 using mostly Win API methods. The TV displays a 2 tier
>> Access recordset (about 5K parent noads each of which has between 0 and 5
>> children). I've got it loading reasonably fast and it has checkbox's
>> which I
>> can check all (parent and child) using an API based routine (similar to
>> the expand code below) virtually
>> instantaneously. (c. 100 ticks). The problem is that a expand/collapse
>> all routine is taking
>> to long (c. 2000 ticks for expand 4000 ticks for collapse). It may be
>> because the TV scrolls when expanding all whereas it
>> doesn't when checking all. I've tried ensuring that the root node is
>> visible in the expand loop but this just slows things down further.
>> Anyone
>> got any suggestions (other than load/expand nodes on demand) please?
>> I'd imagine that preventing the scrolling would do the trick but this
>> seems
>> to be built into the TVM_EXPAND message.
>>
>> Here's the expand code:
>>
>> Public Function TreeView_ExpandAll(hwnd As Long) As Boolean
>> Dim hItem As Long
>> Redraw hwnd, False
>> hItem = TreeView_GetNextItem(hwnd, 0, TVGN_ROOT)
>> Call SendMessageLong(hwnd, TVM_EXPAND, TVE_EXPAND, hItem)
>> Do Until hItem <= 0
>> hItem = TreeView_GetNextItem(hwnd, hItem, TVGN_NEXT)
>> Call SendMessageLong(hwnd, TVM_EXPAND, TVE_EXPAND, hItem)
>> Loop
>> Redraw hwnd, True
>> End Function
>>
>> Private Sub Redraw(Hwnd As Long, Enabled As Boolean)
>> If Enabled Then
>> SendMessageLong Hwnd, WM_SETREDRAW, True, &H0
>> Else
>> SendMessageLong Hwnd, WM_SETREDRAW, False, &H0
>> End If
>> End Sub
>>
>> Private Function TreeView_GetNextItem(hwnd As Long, hItem As Long, flag
>> As
>> Long) As Long
>> TreeView_GetNextItem = SendMessage(hwnd, TVM_GETNEXTITEM, ByVal flag,
>> ByVal hItem)
>> End Function
>>
>
> Quick and easy test
>
> Try adding: (and maybe lose your "ReDraw" stuff)
> TreeView.Visible = False
> Do stuff
> TreeView.Visible = True
>
> Make sure the routines that "Do Stuff" are free from DoEvents or the
> TreeView will flicker or possibly actually go away for a bit.
> It seems counter-intuitve but if you make the control invisible but
> prevent redraws the control will actually stay (apparently) visible, but
> as the code thinks the control is not visible it won't try to update it so
> things should speed up a bit.
>
> Also is there any reason to have the GetNextItem stuff in a seperate
> function, just jumping to and returning from a function takes a small but
> measurable time, not a problem for a few calls but if you have lots of
> nodes it could add up.
>
> Regards
> DaveO.
>
>


DaveO

7/27/2011 3:47:00 PM

0


"Jon Lewis" <jon.lewis@cutthespambtinternet.com> wrote in message
news:d_6dnR5SPoTara3TnZ2dnUVZ7r2dnZ2d@bt.com...
> Hi Dave and thanks for the response.
>
> Regarding your comments about wrapping API calls in recallable functions,
> as far as I can tell it makes no significant execution speed difference in
> this kind of scenario.

Yes, you need to be making thousands of calls before you'd notice any
difference between a separate function and doing it in-line.

It's one of those things that make a tiny difference but if you are doing
something time-sensitive and have several processes that could be optimised
to save a trivial amount of time, well several times trivial becomes
noticeable.

Glad you've worked out a way to speed it up - well done.



Regards

DaveO

..