Modify

Opened 12 years ago

Closed 12 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 12 years ago by TicketCleanup

  • Version 3.3.8.0 deleted

Automatic ticket cleanup.

comment:2 Changed 12 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 12 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 12 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 12 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.

Add Comment

Modify Ticket

Action
as closed The owner will remain guinness.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.