Opened 13 years ago
Closed 13 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:1 Changed 13 years ago by Emiel Wieldraaijer
comment:2 Changed 13 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.

Thnx Melba233
http://www.autoitscript.com/trac/autoit/ticket/1639