supersonic Posted January 30, 2019 Share Posted January 30, 2019 (edited) Hi - How to select a LV item by using a LV item control ID (-- meaning NOT a LV item index! --). This - obvious - won't work (logic only): $iID = GUICtrlCreateListViewItem("test1|test2", $iLV) _GUICtrlListView_EnsureVisible($iLV, $iID) _GUICtrlListView_SetItemSelected($iLV, $iID) _GUICtrlListView_SetItemFocused($iLV, $iID) Can a LV item index be retrieved by its item ID? I have a sortable LV (50+ columns, 150+ rows) and like to select LV items (after search for a specific item). Using _GUICtrlListView_FindInText() takes too much time. But I have LV item IDs already. Edited January 31, 2019 by supersonic Link to comment Share on other sites More sharing options...
BugFix Posted January 30, 2019 Share Posted January 30, 2019 (edited) The item-ID will stored as item param. You can ask for this by using the item index. ListView_Get_Item_Param() Func ListView_Get_Item_Param() Local $hGUI, $hListView $hGUI = GUICreate("ListView Get Item Param", 400, 300) $hListView = GUICtrlCreateListView("Column 1|Column 2", 2, 2, 394, 268) GUISetState(@SW_SHOW) ; Add items Local $ID1, $ID2, $ID3 $ID1 = GUICtrlCreateListViewItem('Item-1|Item-1.1', $hListview) $ID2 = GUICtrlCreateListViewItem('Item-2|Item-2.1', $hListview) $ID3 = GUICtrlCreateListViewItem('Item-3|Item-3.1', $hListview) ConsoleWrite('ID Item-1: ' & $ID1 & @CRLF) ConsoleWrite('ID Item-2: ' & $ID2 & @CRLF) ConsoleWrite('ID Item-3: ' & $ID3 & @CRLF) ; Get ID from item parameter by item index ConsoleWrite('Item-param-1: ' & _GUICtrlListView_GetItemParam($hListView, 0) & @CRLF) ConsoleWrite('Item-param-2: ' & _GUICtrlListView_GetItemParam($hListView, 1) & @CRLF) ConsoleWrite('Item-param-3: ' & _GUICtrlListView_GetItemParam($hListView, 2) & @CRLF) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc But please note that the ID will only be saved as param if the listview item is created with the function GUICtrlCreateListViewItem! Edited January 30, 2019 by BugFix Best Regards BugFix Link to comment Share on other sites More sharing options...
supersonic Posted January 30, 2019 Author Share Posted January 30, 2019 @BugFix - Thank you. Regarding to your example (as is): If $ID3 = 6 Then _GUICtrlListView_SetItemSelected($hListview, $ID3) won't work. There is no LV index with a value of 6. I need something like _GUICtrlListView_GetItemIndexByItemID($hListview, $ID3). Using _GUICtrlListView_SetItemParam/_GUICtrlListView_GetItemParam won't help because after LV is sorted (whatever column/direction) there's no 1 to 1 relationship any longer... Any help still appreciated Link to comment Share on other sites More sharing options...
BugFix Posted January 30, 2019 Share Posted January 30, 2019 (edited) OK, there exists since many, many years the bug, that the SimpleSort function NOT sorts the item param too. But with sort callback it works: expandcollapse popupGlobal $hListView ListView_Get_Item_Param() Func ListView_Get_Item_Param() Local $hGUI $hGUI = GUICreate("ListView Get Item Param", 400, 300) $hListView = GUICtrlCreateListView("Column 1|Column 2", 2, 2, 394, 268, $LVS_SORTASCENDING) GUISetState(@SW_SHOW) _GUICtrlListView_RegisterSortCallBack($hListView) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; Add items Local $ID1, $ID2, $ID3 $ID1 = GUICtrlCreateListViewItem('B|B.1', $hListview) $ID2 = GUICtrlCreateListViewItem('C|C.1', $hListview) $ID3 = GUICtrlCreateListViewItem('A|A.1', $hListview) ConsoleWrite('ID Item-A: ' & $ID3 & @CRLF) ConsoleWrite('ID Item-B: ' & $ID1 & @CRLF) ConsoleWrite('ID Item-C: ' & $ID2 & @CRLF) ; Get ID from item parameter by item index ;~ ConsoleWrite('Item-param-Index 0 [' & _GUICtrlListView_GetItemText($hListView, 0) & ']: ' & _GUICtrlListView_GetItemParam($hListView, 0) & @CRLF) ;~ ConsoleWrite('Item-param-Index 1 [' & _GUICtrlListView_GetItemText($hListView, 1) & ']: ' & _GUICtrlListView_GetItemParam($hListView, 1) & @CRLF) ;~ ConsoleWrite('Item-param-Index 2 [' & _GUICtrlListView_GetItemText($hListView, 2) & ']: ' & _GUICtrlListView_GetItemParam($hListView, 2) & @CRLF) ; Loop until the user exits. Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _GUICtrlListView_UnRegisterSortCallBack($hListView) GUIDelete() EndFunc Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView $hWndListView = $hListView If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $LVN_COLUMNCLICK ; A column was clicked _GUICtrlListView_SortItems($hWndListView, 0) Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) Local $iIndex = DllStructGetData($tInfo, "Index") ConsoleWrite('Clicked Index: ' & $iIndex & ' [' & _GUICtrlListView_GetItemText($hWndListView, $iIndex) & '], ID: ' & _GUICtrlListView_GetItemParam($hWndListView, $iIndex) & @CRLF) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Or you use my modified version for simple sort, it sorts the param too. expandcollapse popupFunc __GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol) ; modified to sort also IParam Local $x, $Y, $Z, $b_desc, $columns, $items, $v_item, $temp_item, $iFocused = -1 Local $SeparatorChar = Opt('GUIDataSeparatorChar') If _GUICtrlListView_GetItemCount($hWnd) Then If (IsArray($vDescending)) Then $b_desc = $vDescending[$iCol] Else $b_desc = $vDescending EndIf $columns = _GUICtrlListView_GetColumnCount($hWnd) $items = _GUICtrlListView_GetItemCount($hWnd) For $x = 1 To $columns $temp_item = $temp_item & " " & $SeparatorChar Next $temp_item = StringTrimRight($temp_item, 1) Local $a_lv[$items][$columns + 2], $i_selected ; add column for IParam ### MODIFIED ### $i_selected = StringSplit(_GUICtrlListView_GetSelectedIndices($hWnd), $SeparatorChar) For $x = 0 To UBound($a_lv) - 1 Step 1 If $iFocused = -1 Then If _GUICtrlListView_GetItemFocused($hWnd, $x) Then $iFocused = $x EndIf _GUICtrlListView_SetItemSelected($hWnd, $x, False) For $Y = 0 To UBound($a_lv, 2) - 3 Step 1 ; ### MODIFIED ### $v_item = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $x, $Y), 2) If (StringIsFloat($v_item) Or StringIsInt($v_item)) Then $a_lv[$x][$Y] = Number($v_item) Else $a_lv[$x][$Y] = $v_item EndIf Next $a_lv[$x][$Y] = $x $a_lv[$x][$Y+1] = _GUICtrlListView_GetItemParam($hWnd, $x) ; ### NEW ### Next _ArraySort($a_lv, $b_desc, 0, 0, $iCol) For $x = 0 To UBound($a_lv) - 1 Step 1 For $Y = 0 To UBound($a_lv, 2) - 3 Step 1 ; ### MODIFIED ### _GUICtrlListView_SetItemText($hWnd, $x, $a_lv[$x][$Y], $Y) Next _GUICtrlListView_SetItemParam($hWnd, $x, $a_lv[$x][$Y+1]) ; ### NEW ### For $Z = 1 To $i_selected[0] If $a_lv[$x][UBound($a_lv, 2) - 2] = $i_selected[$Z] Then ; ### MODIFIED ### If $a_lv[$x][UBound($a_lv, 2) - 2] = $iFocused Then ; ### MODIFIED ### _GUICtrlListView_SetItemSelected($hWnd, $x, True, True) Else _GUICtrlListView_SetItemSelected($hWnd, $x, True) EndIf ExitLoop EndIf Next Next If (IsArray($vDescending)) Then $vDescending[$iCol] = Not $b_desc Else $vDescending = Not $b_desc EndIf EndIf EndFunc ;==>__GUICtrlListView_SimpleSort EDIT: Here is an full working example, that exactly does, what you want: expandcollapse popupGlobal $hListView ListView_Get_Item_Param() Func ListView_Get_Item_Param() Local $hGUI $hGUI = GUICreate("ListView Get Item Param", 400, 300) GUICtrlCreateLabel('Sort by column click', 10, 50) GUICtrlCreateLabel('List of Ctrl-ID', 10, 13, 75) Local $combo = GUICtrlCreateCombo('', 85, 10, 60) Local $select = GUICtrlCreateButton('Select ID in listview', 165, 10, 120, 22) $hListView = GUICtrlCreateListView("Column 1|Column 2", 2, 72, 394, 218, $LVS_SORTASCENDING, $LVS_EX_FULLROWSELECT) Local $sCombo = StringFormat('%s|%s|%s', $hListview +1, $hListview +2, $hListview +3) GUICtrlSetData($combo, $sCombo) GUISetState(@SW_SHOW) _GUICtrlListView_RegisterSortCallBack($hListView) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; Add items Local $aID[3] $aID[0] = GUICtrlCreateListViewItem('B|B.1 [ID '& $hListview + 1 &']', $hListview) $aID[1] = GUICtrlCreateListViewItem('C|C.1 [ID '& $hListview + 2 &']', $hListview) $aID[2] = GUICtrlCreateListViewItem('A|A.1 [ID '& $hListview + 3 &']', $hListview) While 1 Switch GUIGetMsg() Case $select _GuiCtrlListview_SelectByID($hListView, GUICtrlRead($combo)) ControlFocus($hGui, '', $hListView) Case $GUI_EVENT_CLOSE _GUICtrlListView_UnRegisterSortCallBack($hListView) GUIDelete() Exit EndSwitch WEnd EndFunc Func _GuiCtrlListview_SelectByID($hWnd, $ID) ; unselect all item For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) -1 _GUICtrlListView_SetItemSelected($hWnd, $i, False) Next For $i = 0 To _GUICtrlListView_GetItemCount($hWnd) -1 If _GUICtrlListView_GetItemParam($hWnd, $i) = $ID Then _GUICtrlListView_SetItemSelected($hWnd, $i, True) ExitLoop EndIf Next EndFunc Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView $hWndListView = $hListView If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $LVN_COLUMNCLICK ; A column was clicked _GUICtrlListView_SortItems($hWndListView, 0) Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) Local $iIndex = DllStructGetData($tInfo, "Index") ConsoleWrite('Clicked Index: ' & $iIndex & ' [' & _GUICtrlListView_GetItemText($hWndListView, $iIndex) & '], ID: ' & _GUICtrlListView_GetItemParam($hWndListView, $iIndex) & @CRLF) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Edited January 30, 2019 by BugFix Best Regards BugFix Link to comment Share on other sites More sharing options...
supersonic Posted January 31, 2019 Author Share Posted January 31, 2019 (edited) @BugFix: Many thanks for your examples! I ended up using a modified version of _GuiCtrlListview_SelectByID provided in your last example. And it is fast enough - even if handling a larger LV (60+ columns, 1000+ rows). Initially I hoped there is a structure (or whatever magical function I missed until now) which can be feeded by a LV item ID to return the current/real position (= index) of a LV item. Looping through a LV is OK (~ somehow practical)... Thanks again! Edited January 31, 2019 by supersonic Link to comment Share on other sites More sharing options...
supersonic Posted February 1, 2019 Author Share Posted February 1, 2019 @BugFix: Your modified _GUICtrlListView_SimpleSort is useful too. I'm not sure if this is a bug but a worthwhile enhancement. Did you opened a feature request? Is this issue already discussed in this forum? Link to comment Share on other sites More sharing options...
BugFix Posted February 1, 2019 Share Posted February 1, 2019 1 hour ago, supersonic said: @BugFix: Your modified _GUICtrlListView_SimpleSort is useful too. I'm not sure if this is a bug but a worthwhile enhancement. Did you opened a feature request? Is this issue already discussed in this forum? My feature request was rejected without giving reasons. Best Regards BugFix Link to comment Share on other sites More sharing options...
BrewManNH Posted February 2, 2019 Share Posted February 2, 2019 On 2/1/2019 at 4:29 AM, BugFix said: was rejected without giving reasons. There was a reason, you never explained what your code modification was doing, or how it improved the function. It was also 8 years ago during which time you were free to add to the bug fix report with more information which you never did. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
BugFix Posted February 3, 2019 Share Posted February 3, 2019 18 hours ago, BrewManNH said: with more information which you never did. Really?! What more information you need as: _GUICtrlListView_SimpleSort doesn't sort ItemParam Quote you never explained what your code modification was doing, or how it improved the function. Sometimes, it helps to read the feature request. There I wrote: "I've changed this function, so that it also sort ItemParam." pixelsearch 1 Best Regards BugFix Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 3, 2019 Moderators Share Posted February 3, 2019 BugFix, Your modified code posted above is not based on the current version of the SimpleSort function - which looks to me as if it should correctly reset the ItemParam value when rewriting the ListView contents. However, testing shows that although the function appears to correctly set the ItemParam value within the function, it most definitely does not return the same value when asked in the main script! Could you please take a look at the example script below (which actually uses the slightly changed SVN version of the function) and see if you can spot where the problem lies - I have been playing with the code for a while and it has me beaten: expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> Global $aSortSense[] = [0] Global $cItem_3 $hGUI = GUICreate("Test", 500, 500) $cLV = GUICtrlCreateListView("Sortable Value|Initial CID|Init Param|Post Sort", 10, 10, 400, 300) $cButton = GUICtrlCreateButton("Sort", 10, 450, 80, 30) $cStart = GUICtrlCreateDummy() For $i = 0 To 9 $cLVI_CID = GUICtrlCreateListViewItem(Random(1, 9, 1) & "|", $cLV) $iParam = _GUICtrlListView_GetItemParam($cLV, $i) GUICtrlSetData($cLVI_CID, "|" & $cLVI_CID & "|" & $iParam) If $i = 3 Then $cItem_3 = $cLVI_CID EndIf Next GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $cButton ConsoleWrite("Before: " & GUICtrlRead($cItem_3) & @CRLF) _GUICtrlListView_SimpleSort_SVN($cLV, $aSortSense, 0) For $i = 0 To 9 $iParam = _GUICtrlListView_GetItemParam($cLV, $i) GUICtrlSetData($cStart + 1 + $i, "|||" & $iParam) Next ConsoleWrite("After : " & GUICtrlRead($cItem_3) & @CRLF) EndSwitch WEnd Func _GUICtrlListView_SimpleSort_SVN($hWnd, ByRef $vSortSense, $iCol, $bToggleSense = True) Local $iItemCount = _GUICtrlListView_GetItemCount($hWnd) If $iItemCount Then Local $iDescending = 0 If UBound($vSortSense) Then $iDescending = $vSortSense[$iCol] Else $iDescending = $vSortSense EndIf Local $vSeparatorChar = Opt('GUIDataSeparatorChar') Local $iColumnCount = _GUICtrlListView_GetColumnCount($hWnd) Local Enum $iIndexValue = $iColumnCount, $iItemParam ; Additional columns for the index value and ItemParam Local $aListViewItems[$iItemCount][$iColumnCount + 2] Local $sSelectedItems = _GUICtrlListView_GetSelectedIndices($hWnd) Local $aSelectedItems[1] = [0] ; No selection If Not $sSelectedItems = "" Then $aSelectedItems = StringSplit($sSelectedItems, $vSeparatorChar) Local $aCheckedItems = __GUICtrlListView_GetCheckedIndices($hWnd) Local $sItemText, $iFocused = -1 For $i = 0 To $iItemCount - 1 ; Rows If $iFocused = -1 Then If _GUICtrlListView_GetItemFocused($hWnd, $i) Then $iFocused = $i EndIf _GUICtrlListView_SetItemSelected($hWnd, $i, False) _GUICtrlListView_SetItemChecked($hWnd, $i, False) For $j = 0 To $iColumnCount - 1 ; Columns $sItemText = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $i, $j), $STR_STRIPTRAILING) If (StringIsFloat($sItemText) Or StringIsInt($sItemText)) Then $aListViewItems[$i][$j] = Number($sItemText) Else $aListViewItems[$i][$j] = $sItemText EndIf Next $aListViewItems[$i][$iIndexValue] = $i ; Index value $aListViewItems[$i][$iItemParam] = _GUICtrlListView_GetItemParam($hWnd, $i) ; ItemParam Next ; Sort the ListView array _ArraySort($aListViewItems, $iDescending, 0, 0, $iCol) For $i = 0 To $iItemCount - 1 ; Rows For $j = 0 To $iColumnCount - 1 ; Columns _GUICtrlListView_SetItemText($hWnd, $i, $aListViewItems[$i][$j], $j) Next _GUICtrlListView_SetItemParam($hWnd, $i, $aListViewItems[$i][$iItemParam]) ; ItemParam For $j = 1 To $aSelectedItems[0] If $aListViewItems[$i][$iIndexValue] = $aSelectedItems[$j] Then If $aListViewItems[$i][$iIndexValue] = $iFocused Then _GUICtrlListView_SetItemSelected($hWnd, $i, True, True) Else _GUICtrlListView_SetItemSelected($hWnd, $i, True) EndIf ExitLoop EndIf Next For $j = 1 To $aCheckedItems[0] If $aListViewItems[$i][$iIndexValue] = $aCheckedItems[$j] Then _GUICtrlListView_SetItemChecked($hWnd, $i, True) ExitLoop EndIf Next Next If $bToggleSense Then ; Automatic sort sense toggle If UBound($vSortSense) Then $vSortSense[$iCol] = Not $iDescending Else $vSortSense = Not $iDescending EndIf EndIf EndIf EndFunc ;==>_GUICtrlListView_SimpleSort_SVN M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
BugFix Posted February 3, 2019 Share Posted February 3, 2019 @Melba23 Oh, you're right. I've overseen, that the issue was already fixed 2.5 years after rejecting my request. But after that time I did not really reckon with a renewed interest in the problem and did not pursue the story any further. I hope you can forgive my impatience. Best Regards BugFix Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 3, 2019 Moderators Share Posted February 3, 2019 BugFix, No problem. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now