Modify

#2252 closed Bug (Fixed)

_GUICtrlListView_DeleteAllItems Bug

Reported by: Melba23 Owned by: guinness
Milestone: 3.3.9.5 Component: Standard UDFs
Version: 3.3.8.1 Severity: None
Keywords: Cc:

Description

The current implementation of _GUICtrlListView_DeleteAllItems assumes that if the ListView is created with the native function GUICtrlCreateListView then the items are created with the native GUICtrlCreateListViewItem function - and that a UDF created ListView (GUICtrlListView_Create) has UDF created items. This means that the function does not work when a native created ListView has UDF added items.

I have modified the function so that it checks that the items have been removed from a native created ListView by GUICtrlDelete and, if they have not because they were created by the UDF functions, uses the $LVM_DELETEALLITEMS message to remove them. The following script should demonstrate the problem and my suggested solution:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

$hGUI = GUICreate("Test", 500, 500)
GUISetBkColor(0xC4C4C4)

; Native ListView with native Items
$cLV_1 = GUICtrlCreateListView("Col 1|Col 2|Col 3|Col 4", 10, 10, 400, 150)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 100)
For $i = 0 To 3
	GUICtrlCreateListViewItem("Item " & $i & "1|Item " & $i & "2|Item " & $i & "3|Item " & $i & "4", $cLV_1)
Next

; Native ListView with UDF Items
$cLV_2 = GUICtrlCreateListView("Col 1|Col 2|Col 3|Col 4", 10, 170, 400, 150)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 100)
Local $aTable[4][4] = [[1, 2, 3, 4],[2, 3, 4, 5],[3, 4, 5, 6],[4, 5, 6, 7]]
_GUICtrlListView_AddArray($cLV_2, $aTable)

; UDF ListView with UDF Items
$hLV_3 = _GUICtrlListView_Create($hGUI, "", 10, 330, 400, 150)
_GUICtrlListView_SetExtendedListViewStyle($hLV_3, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_InsertColumn($hLV_3, 0, "Col 1", 100)
_GUICtrlListView_InsertColumn($hLV_3, 1, "Col 2", 100)
_GUICtrlListView_InsertColumn($hLV_3, 2, "Col 3", 100)
_GUICtrlListView_InsertColumn($hLV_3, 3, "Col 4", 100)
Local $aTable[4][4] = [[1, 2, 3, 4],[2, 3, 4, 5],[3, 4, 5, 6],[4, 5, 6, 7]]
_GUICtrlListView_AddArray($hLV_3, $aTable)

$cButton_Old_1 = GUICtrlCreateButton("Delete All Old", 420, 30, 80, 30)
$cButton_New_1 = GUICtrlCreateButton("Delete All New", 420, 70, 80, 30)
$cButton_Old_2 = GUICtrlCreateButton("Delete All Old", 420, 190, 80, 30)
$cButton_New_2 = GUICtrlCreateButton("Delete All New", 420, 230, 80, 30)
$cButton_Old_3 = GUICtrlCreateButton("Delete All Old", 420, 350, 80, 30)
$cButton_New_3 = GUICtrlCreateButton("Delete All New", 420, 390, 80, 30)

GUISetState()

While 1

	Switch GUIGetMsg()
		Case $cButton_Old_1
			_Old_GUICtrlListView_DeleteAllItems($cLV_1)
		Case $cButton_Old_2
			_Old_GUICtrlListView_DeleteAllItems($cLV_2)
		Case $cButton_Old_3
			_Old_GUICtrlListView_DeleteAllItems($hLV_3)
		Case $GUI_EVENT_CLOSE
			Exit
		Case $cButton_New_1
			_New_GUICtrlListView_DeleteAllItems($cLV_1)
		Case $cButton_New_2
			_New_GUICtrlListView_DeleteAllItems($cLV_2)
		Case $cButton_New_3
			_New_GUICtrlListView_DeleteAllItems($hLV_3)
	EndSwitch

WEnd

; New function
Func _New_GUICtrlListView_DeleteAllItems($hWnd)
	If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)

	If _GUICtrlListView_GetItemCount($hWnd) = 0 Then Return True
	; If a ControlID is passed
	If Not IsHWnd($hWnd) Then
		Local $ctrlID
		; Delete and remove the items from AutoIt internal array if created with native function
		For $index = _GUICtrlListView_GetItemCount($hWnd) - 1 To 0 Step -1
			$ctrlID = _GUICtrlListView_GetItemParam($hWnd, $index)
			If $ctrlID Then GUICtrlDelete($ctrlID)
		Next
		; If all removed then they were created with native function so return
		If _GUICtrlListView_GetItemCount($hWnd) = 0 Then Return True
		; Must have been created with UDF function so convert ControlID to handle
		$hWnd = GUICtrlGetHandle($hWnd)
	EndIf
	; And remove UDF created items - which also works for UDF ListViews
	Return _SendMessage($hWnd, $LVM_DELETEALLITEMS) <> 0
	Return True
EndFunc   ;==>_New_GUICtrlListView_DeleteAllItems

; Current UDF function
Func _Old_GUICtrlListView_DeleteAllItems($hWnd)
	If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)

	If _GUICtrlListView_GetItemCount($hWnd) == 0 Then Return True
	If IsHWnd($hWnd) Then
		; If a handle is passed - assume all UDF functions
		Return _SendMessage($hWnd, $LVM_DELETEALLITEMS) <> 0
	Else
		; If not then assume all native functions
		Local $ctrlID
		For $index = _GUICtrlListView_GetItemCount($hWnd) - 1 To 0 Step -1
			$ctrlID = _GUICtrlListView_GetItemParam($hWnd, $index)
			If $ctrlID Then GUICtrlDelete($ctrlID)
		Next
		If _GUICtrlListView_GetItemCount($hWnd) == 0 Then Return True
	EndIf
	Return False
EndFunc   ;==>_Old_GUICtrlListView_DeleteAllItems

I have added the current UDF function to the script to show the flawed logic within it more easily.

M23

Attachments (0)

Change History (2)

comment:2 by guinness, on Sep 3, 2012 at 7:10:46 AM

Milestone: 3.3.9.5
Owner: set to guinness
Resolution: Fixed
Status: newclosed

Fixed by revision [7210] in version: 3.3.9.5

Modify Ticket

Action
as closed The owner will remain guinness.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.