Opened 3 years ago
Closed 3 years ago
#3848 closed Bug (Fixed)
_GUICtrlListView_GetItemTextArray does not return an error for multi-column listview if no row is selected.
Reported by: | BugFix | Owned by: | Jpm |
---|---|---|---|
Milestone: | 3.3.15.5 | Component: | Standard UDFs |
Version: | 3.3.14.5 | Severity: | None |
Keywords: | Cc: |
Description (last modified by mLipok)
I had written a function _GUICtrlListView_SetItemTextArray as a counterpart to _GUICtrlListView_GetItemTextArray.
In doing so, I noticed that it was not possible to determine if _GUICtrlListView_GetItemTextArray was successful. In the help it says:
Failure: Array with the following format: [0] - Number of Columns in array (0).
This is only correct for the case of a listview with one column. Otherwise an empty array with column count +1 elements is returned: [iCount, '', '', ..]. But this cannot be distinguished from a valid empty array (row could be empty).
This is caused by the function _GUICtrlListView_GetItemTextString. In this function, if -1 is passed as index, the index of the selected row is used. This is returned by _GUICtrlListView_GetNextItem. However, if no line is marked, the return is -1.
Since this value is not checked, the queries of all (sub)items for index -1 are now executed with _GUICtrlListView_GetItemText. This causes empty strings and data separators to be strung together.
The result, although false, is returned without error detection.
In my modifications (_GUICtrlListView_GetItemTextArray_MOD, _GUICtrlListView_GetItemTextString_MOD) I have integrated the index check and thus it can be determined whether _GUICtrlListView_GetItemTextArray() was successful. (see my test script)
In general, I think it is recommended that all functions that work with indexes also check them for validity. Many functions call each other and the user has no possibility to check their result and find sources of errors.
#include <GuiListView.au3> #include <GUIConstants.au3> #include <WindowsConstants.au3> #include <Array.au3> $gui = GUICreate('Test') $lv = GuiCtrlCreateListView('a|b|c', 10, 10, 350, 250) For $i = 1 To 30 GUICtrlCreateListViewItem(StringFormat('%d|%d|%d', $i-1, Random(1,10,1), Random(1,10,1)), $lv) Next $hLV = GUICtrlGetHandle($lv) _GUICtrlListView_SetExtendedListViewStyle($hLV, BitOR($LVS_EX_FULLROWSELECT,$WS_EX_CLIENTEDGE,$LVS_EX_GRIDLINES)) _GUICtrlListView_SetColumnWidth($hLV, 0, 85) _GUICtrlListView_SetColumnWidth($hLV, 1, 85) _GUICtrlListView_SetColumnWidth($hLV, 2, $LVSCW_AUTOSIZE_USEHEADER) $bt1 = GUICtrlCreateButton('Set selected to 3', 10, 280, 120, 24) $bt2 = GUICtrlCreateButton('Set 5 to selected', 140, 280, 120, 24) $btRemove = GUICtrlCreateButton('Remove Selection', 270, 280, 120, 24) $cb = GUICtrlCreateCheckbox(' Use functions with Index check!', 10, 320) $bCheck = False GUISetState() $f = _GUICtrlListView_GetItemTextArray $fCheck = _GUICtrlListView_GetItemTextArray_MOD While True $bCheck = BitAND(GUICtrlRead($cb), $GUI_CHECKED) ? True : False Switch GUIGetMsg() Case -3 Exit Case $bt1 If _GUICtrlListView_SetItemTextArray($hLV, ($bCheck ? $fCheck($hLV) : $f($hLV)), 3) <> 1 Then _ MsgBox(0, 'Error', 'None Selection') Case $bt2 If _GUICtrlListView_SetItemTextArray($hLV, ($bCheck ? $fCheck($hLV, 5) : $f($hLV, 5))) <> 1 Then _ MsgBox(0, 'Error', 'None Selection') Case $btRemove _GUICtrlListView_SetItemSelected($hLV, _GUICtrlListView_GetNextItem($hLV), False, False) EndSwitch WEnd ; #FUNCTION# ==================================================================================================================== ; Author ........: Gary Frost (gafrost) ; Modified.......: @BugFix ; =============================================================================================================================== Func _GUICtrlListView_GetItemTextArray_MOD($hWnd, $iItem = -1) ;~ Local $sItems = _GUICtrlListView_GetItemTextString($hWnd, $iItem) ; Here occurs the error. This function produces a wrong output without @error. ; i.e.: listview with 3 columns, none selection but "$iItem = -1" - should use the current selection ; $sItems = "||", none error! Local $sItems = _GUICtrlListView_GetItemTextString_MOD($hWnd, $iItem) If $sItems = "" Then Local $aItems[1] = [0] Return SetError($LV_ERR, $LV_ERR, $aItems) EndIf Return StringSplit($sItems, Opt('GUIDataSeparatorChar')) EndFunc ;==>_GUICtrlListView_GetItemTextArray ; #FUNCTION# ==================================================================================================================== ; Author ........: Gary Frost (gafrost) ; Modified.......: @BugFix ; =============================================================================================================================== Func _GUICtrlListView_GetItemTextString_MOD($hWnd, $iItem = -1) Local $sRow = "", $sSeparatorChar = Opt('GUIDataSeparatorChar'), $iSelected If $iItem = -1 Then ; '$iItem = -1' says: use the current selection $iSelected = _GUICtrlListView_GetNextItem($hWnd) ; get current row selected ; But this function returns also "-1" if none item is selected Else $iSelected = $iItem ; get row EndIf ; here is required to check if _GUICtrlListView_GetNextItem() has failed If $iSelected < 0 Or $iSelected > _GUICtrlListView_GetItemCount($hWnd) - 1 Then Return SetError(1,0,0) For $x = 0 To _GUICtrlListView_GetColumnCount($hWnd) - 1 ; _GUICtrlListView_GetItemText() it does not matter at all whether a valid index was passed. ; In case of error there is no message and an empty string is returned. This cannot be distinguished from an actually empty item. ; For this reason, a wrong index must be caught before calling the function. $sRow &= _GUICtrlListView_GetItemText($hWnd, $iSelected, $x) & $sSeparatorChar Next Return StringTrimRight($sRow, 1) EndFunc ;==>_GUICtrlListView_GetItemTextString
Attachments (0)
Change History (4)
comment:1 Changed 3 years ago by BugFix
comment:2 Changed 3 years ago by mLipok
- Description modified (diff)
comment:3 Changed 3 years ago by mLipok
- Component changed from AutoIt to Standard UDFs
comment:4 Changed 3 years ago by Jpm
- Milestone set to 3.3.15.5
- Owner set to Jpm
- Resolution set to Fixed
- Status changed from new to closed
Fixed by revision [12590] in version: 3.3.15.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.
Sorry, forgot to attach my function _GUICtrlListView_SetItemTextArray, here it is.
Code highlighting: