Modify

Opened 7 years ago

Closed 7 years ago

#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 Changed 7 years ago by guinness

  • Milestone set to 3.3.9.5
  • Owner set to guinness
  • Resolution set to Fixed
  • Status changed from new to closed

Fixed by revision [7210] 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.