Opened 14 years ago
Closed 13 years ago
#2120 closed Feature Request (Completed)
Improvements to _GuiCtrlListView_DeleteAllItems
| Reported by: | Beege | Owned by: | guinness |
|---|---|---|---|
| Milestone: | 3.3.9.5 | Component: | Standard UDFs |
| Version: | Severity: | None | |
| Keywords: | _GuiCtrlListView_DeleteAllItems | Cc: |
Description
I was noticing how deleting all items it a autoit listview took almost 3x longer than it takes to add them. I came up with the following improvements below.
Time Results: _GUICtrlListView_DeleteAllItems = 3592.88679294215 _GUICtrlListView_DeleteAllItems2 = 587.438691126462
#include <GuiListView.au3>
Opt('MustDeclareVars', 1)
Local $hGUI = GUICreate('Listview Delete All Items', 250, 400)
Local $ListView = GUICtrlCreateListView('Items', 0, 0, 248, 398)
GUISetState()
For $i = 1 To 10000
GUICtrlCreateListViewItem($i, $ListView)
Next
Local $time = TimerInit()
_GUICtrlListView_DeleteAllItems($ListView)
ConsoleWrite('_GUICtrlListView_DeleteAllItems = ' & TimerDiff($time) & @LF)
For $i = 1 To 10000
GUICtrlCreateListViewItem($i, $ListView)
Next
Local $time = TimerInit()
_GUICtrlListView_DeleteAllItems2($ListView)
ConsoleWrite('_GUICtrlListView_DeleteAllItems2 = ' & TimerDiff($time) & @LF)
Do
Until GUIGetMsg() = -3
Func _GUICtrlListView_DeleteAllItems2($hWnd)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If _GUICtrlListView_GetItemCount($hWnd) = 0 Then Return True
If IsHWnd($hWnd) Then
Return _SendMessage($hWnd, $LVM_DELETEALLITEMS) <> 0
Else
Local $ctrlID
Local $tItem = DllStructCreate($tagLVITEM)
Local $pItem = DllStructGetPtr($tItem)
Local $LV_Msg = $LVM_GETITEMA
If _GUICtrlListView_GetUnicodeFormat($hWnd) Then $LV_Msg = $LVM_GETITEMW
DllStructSetData($tItem, "Mask", $LVIF_PARAM)
GUICtrlSendMsg($hWnd, 11, 0, 0);$WM_SETREDRAW
For $index = _GUICtrlListView_GetItemCount($hWnd) - 1 To 0 Step -1
DllStructSetData($tItem, "Item", $index)
GUICtrlSendMsg($hWnd, $LV_Msg, 0, $pItem)
$ctrlID = DllStructGetData($tItem, "Param")
If $ctrlID Then GUICtrlDelete($ctrlID)
Next
GUICtrlSendMsg($hWnd, 11, 1, 0);$WM_SETREDRAW
If _GUICtrlListView_GetItemCount($hWnd) = 0 Then Return True
EndIf
Return False
EndFunc ;==>__GUICtrlListView_DeleteAllItems
Attachments (0)
Change History (5)
comment:1 Changed 14 years ago by TicketCleanup
- Version 3.3.8.0 deleted
comment:2 Changed 14 years ago by BrewManNH
An even faster method is to send the function the handle of the ListView instead of sending it the handle or converting the CID to the handle with GUICtrlGetHandle, and then deleting the items. The only problem using it this way is that the ControlID's aren't deleted, so you can run out of control IDs if you do it this way. You would need to create the listview items using the _GUICtrlListView_AddItem/_GUICtrlListView_AddSubItem if you're going to be using the handle to delete them.
Below is a demo of what i'm talking about showing that using the handle is faster.
#include <GuiListView.au3>
Opt('MustDeclareVars', 1)
Local $ID
Local $hGUI = GUICreate('Listview Delete All Items', 250, 400)
Local $ListView = GUICtrlCreateListView('Items', 0, 0, 248, 398)
GUISetState()
For $i = 1 To 10000
$ID = GUICtrlCreateListViewItem($i, $ListView)
Next
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ID = ' & $ID & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
Local $time = TimerInit()
_GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($ListView))
ConsoleWrite('_GUICtrlListView_DeleteAllItems = ' & TimerDiff($time) & @LF)
For $i = 1 To 10000
$ID = GUICtrlCreateListViewItem($i, $ListView)
Next
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ID = ' & $ID & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
Local $time = TimerInit()
_GUICtrlListView_DeleteAllItems2($ListView)
ConsoleWrite('_GUICtrlListView_DeleteAllItems2 = ' & TimerDiff($time) & @LF)
$ID = GUICtrlCreateListViewItem($i, $ListView)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ID = ' & $ID & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
Do
Until GUIGetMsg() = -3
Func _GUICtrlListView_DeleteAllItems2($hWnd)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If _GUICtrlListView_GetItemCount($hWnd) = 0 Then Return True
If IsHWnd($hWnd) Then
Return _SendMessage($hWnd, $LVM_DELETEALLITEMS) <> 0
Else
Local $ctrlID
Local $tItem = DllStructCreate($tagLVITEM)
Local $pItem = DllStructGetPtr($tItem)
Local $LV_Msg = $LVM_GETITEMA
If _GUICtrlListView_GetUnicodeFormat($hWnd) Then $LV_Msg = $LVM_GETITEMW
DllStructSetData($tItem, "Mask", $LVIF_PARAM)
GUICtrlSendMsg($hWnd, 11, 0, 0);$WM_SETREDRAW
For $index = _GUICtrlListView_GetItemCount($hWnd) - 1 To 0 Step -1
DllStructSetData($tItem, "Item", $index)
GUICtrlSendMsg($hWnd, $LV_Msg, 0, $pItem)
$ctrlID = DllStructGetData($tItem, "Param")
If $ctrlID Then GUICtrlDelete($ctrlID)
Next
GUICtrlSendMsg($hWnd, 11, 1, 0);$WM_SETREDRAW
If _GUICtrlListView_GetItemCount($hWnd) = 0 Then Return True
EndIf
Return False
EndFunc ;==>_GUICtrlListView_DeleteAllItems2
{{{
}}}
comment:3 Changed 14 years ago by Beege
BrewManNH what are you doing? You are clearly missing the point here. Whats more confusing is how it seem's you know that the code you posted demonstrates bad programming by never allowing autoit to release it internal resources, yet you posted it anyway. If you really don't care about that then I'll point out to you that you don't even have to get the handle. Just send the $LVM_DELETEALLITEMS straight to the ctrl using GUICtrlSendMsg().
comment:4 Changed 14 years ago by BrewManNH
I appologize for that, I really need to stop posting when under the influence of pain killers. Forget what I just posted it was clearly a moment of intense stupidity on my part.
comment:5 Changed 13 years ago by guinness
- Milestone set to 3.3.9.5
- Owner set to guinness
- Resolution set to Completed
- Status changed from new to closed
Added by revision [7249] in version: 3.3.9.5
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.

Automatic ticket cleanup.