Norm73 Posted December 6, 2020 Share Posted December 6, 2020 (edited) Hello, I can't find an alternative for the _GUICtrlListView_MapIndexToID function that doesn't work for me. Is it even possible to find the index from ID-Control in ListView? I thank you in advance expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> Example() Func Example() GUICreate("listview items", 320, 450, -1, -1, -1, $WS_EX_ACCEPTFILES) GUISetBkColor(0x00E0FFFF) ; will change background color Local $sLb = GUICtrlCreateLabel("Number Item-Index", 20, 335) Local $nImp = GUICtrlCreateInput("", 20, 350, 150, 24, 0x2000) ;$ES_NUMBER Local $idButton = GUICtrlCreateButton("Index -> Control-ID"& @CRLF &"Control-ID -> Index ?", 20, 380, 150, 48, BitOR(0x2000, 0x0100)) ;$BS_MULTILINE GUICtrlSetFont(-1, 11) Local $idListview = GUICtrlCreateListView("col 1 |col 2 |col 3 |col 4 |", 10, 10, 300, 300) ;,$LVS_SORTDESCENDING) Local $nP = 0 For $nN = 0 To 10 GUICtrlCreateListViewItem("item "& $nN &"|col "& $nP+1 &"|col "& $nP+2 &"|col "& $nP+3, $idListview) $nP += 1 Next GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButton Local $nNr = Number(GUICtrlRead($nImp)) If $nNr >= 0 And $nNr < 11 Then Local $nID = _GUICtrlListView_GetItemParam($idListview, $nNr) Local $nIndex = _GUICtrlListView_MapIndexToID($idListview, $nID) MsgBox($MB_SYSTEMMODAL, "listview", "Input Index = "& $nNr & @CRLF &"Index To ID-Control -> "& $nID & @CRLF &"ID-Control To Index -> "& $nIndex) EndIf EndSwitch WEnd EndFunc ;==>Example Edited December 7, 2020 by Norm73 Link to comment Share on other sites More sharing options...
Dan_555 Posted December 6, 2020 Share Posted December 6, 2020 (edited) You have to approach this in a different way. In your code, you are assuming that the number 1 is the ListViewItem number 1, which is not. I have changed the creation of items to display the ID's which are created, by outputting it to the console. expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> Example() Func Example() GUICreate("listview items", 320, 450, -1, -1, -1, $WS_EX_ACCEPTFILES) GUISetBkColor(0x00E0FFFF) ; will change background color Local $sLb = GUICtrlCreateLabel("Number Item-Index", 20, 335) Local $idButton = GUICtrlCreateButton("Index -> Control-ID"& @CRLF &"Control-ID -> Index ?", 20, 380, 150, 48, BitOR(0x2000, 0x0100)) ;$BS_MULTILINE GUICtrlSetFont(-1, 11) Local $idListview = GUICtrlCreateListView("col 1 |col 2 |col 3 |col 4 |", 10, 10, 300, 300) ;,$LVS_SORTDESCENDING) Local $nP = 0 ConsoleWrite ("*********************" & @CRLF) ConsoleWrite ("Added list view ID's:"& @CRLF) For $nN = 0 To 10 ConsoleWrite($nN & " = " & GUICtrlCreateListViewItem("item "& $nN &"|col "& $nP+1 &"|col "& $nP+2 &"|col "& $nP+3, $idListview) & @CRLF) $nP += 1 Next ConsoleWrite ("*********************" & @CRLF) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButton Local $nNr = _GUICtrlListView_GetSelectionMark($idListview) Local $idx = _GUICtrlListView_MapIndexToID($idListview, $nNr) Local $aItem = _GUICtrlListView_GetItem($idListview, $idx) ;_ArrayDisplay ($aItem) if IsArray($aItem) Then ConsoleWrite ( "Selected Nr = "& $nNr & @CRLF &"Selected Id = "& $aItem[5] & @CRLF &"Item Text: "& chr(34) &$aItem[3] & chr(34) & @crlf) EndIf $aItem="" ConsoleWrite ("*********************" & @CRLF) EndSwitch WEnd EndFunc ;==>Example I have, as well, modified the code, and removed the input button so that now you have to select an LW-item with the mouse, and to click on the button, to display some information. To see all information which _GUICtrlListView outputs, uncomment the _ArrayDisplay line. I hope this helps you. Edited December 6, 2020 by Dan_555 Some of my script sourcecode Link to comment Share on other sites More sharing options...
pixelsearch Posted December 6, 2020 Share Posted December 6, 2020 (edited) ... Edited December 6, 2020 by pixelsearch please delete as I mistakenly answered in 2 posts, thx Link to comment Share on other sites More sharing options...
Nine Posted December 6, 2020 Share Posted December 6, 2020 (edited) I must admit, it is quite confusing at first, as there is 4 types of ID in ListView : 1- GUI IDs : all controls get a separate ID in a given moment. But a specific ID can be reuse if another control got deleted. 2- LV Index : all list view items get a separate ID in a given moment based on its position in the LV. If items get inserted then all indexes after insertion point are modified. 3- LV ID : all list view items get a unique internal ID (within the LV, starting at 0) that do not change over lifetime of the GUI. 4- LV Param : all list view items get a place to register a parameter. If the LV item is created by native GUI function, parameter is automatically assign to the GUI ID of the item. If the LV item is created by UDF function, parameter is unassigned (0 by default) but is managed by script. To illustrate this you may take a look at this : expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> Example() Func Example() Local $iID, $idListview GUICreate("ListView Map ID To Index", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, 268) GUISetState(@SW_SHOW) ; Add column _GUICtrlListView_AddColumn($idListview, "Items", 100) ConsoleWrite ("GUI ID " & GUICtrlCreateListViewItem ("Item 0", $idListview) & @CRLF) ; Add items For $i = 1 to 4 ConsoleWrite ("Creation index " & _GUICtrlListView_AddItem($idListview, "Item " & $i, -1, $idListview+$i+1) & @CRLF) Next ConsoleWrite ("Insertion index " & _GUICtrlListView_InsertItem($idListview, "Item 2-3", 3) & @CRLF) ConsoleWrite ("****************" & @CRLF) For $i = 0 to 5 ConsoleWrite ("LV ID " & _GUICtrlListView_MapIndexToID($idListview, $i) & @CRLF) Next ConsoleWrite ("****************" & @CRLF) _GUICtrlListView_DeleteItem($idListview, 2) ConsoleWrite ("Insertion index " & _GUICtrlListView_InsertItem($idListview, "Item 3-4", 4) & @CRLF) ConsoleWrite ("GUI ID " & GUICtrlCreateListViewItem ("Item 5", $idListview) & @CRLF) For $i = 0 to 6 ConsoleWrite ("LV ID " & _GUICtrlListView_MapIndexToID($idListview, $i) & @CRLF) Next ConsoleWrite ("****************" & @CRLF) For $i = 0 to 6 ConsoleWrite ("Param " & _GUICtrlListView_GetItemParam($idListview, $i) & @CRLF) Next Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>Example Edited December 6, 2020 by Nine Norm73 and pixelsearch 1 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
pixelsearch Posted December 6, 2020 Share Posted December 6, 2020 (edited) 6 hours ago, Norm73 said: Is it even possible to find the index from ID-Control in ListView? It should be possible, by creating a 2D array during the native listview Items creation phase (1st column = item ID-control, 2nd column = listview index), but as Nine just wrote, you better not delete or insert items after this. The question is : do you have a special need to map all listview indexes to their original creation ID's ? The only time I used it was before/after a column sort in ListView, because I wanted the cell that was selected before the sort to be focused on after the sort. As AutoIt changes all indexes of the items during the sort, then these 2 commands did the job : * _GUICtrlListView_MapIndexToID() used just before the sort, on 1 item. * _GUICtrlListView_MapIDToIndex() used just after the sort, on 1 item. In fact it's not AutoIt that changes the indexes, but Windows : MSDN: "LVM_SORTITEMSEX message will use an application-defined comparison function to sort the items of the list-view control. The index of each item will change to reflect the new sequence." Edited December 6, 2020 by pixelsearch typo Link to comment Share on other sites More sharing options...
Norm73 Posted December 6, 2020 Author Share Posted December 6, 2020 2 hours ago, Dan_555 said: I have, as well, modified the code, and removed the input button so that now you have to select an LW-item with the mouse, and to click on the button, to display some information. many thanks for the explanation and very good example. I've been busy with the question for a week and now I also know the difference between the Autoit ID and the ID from GuiListView.au3. I'm making a big list of native features. If I choose a separate item, this is not a problem. I have to find out without picking a point. The list is static and does not change, nothing is deleted. I have an array list with all the internal autoit IDs of the list so I don't have to keep track of how the list is sorted. I can read out a point immediately or put a check mark. But that's where it ends. All other options (native or not) work with index and not IDs. I cannot use the _GUICtrlListView_SetItemParam option because I work with it natively. Of course I can query every point in a cycle, but that will take a long time in a large table. The best way would be to get the index directly. But how, I don't know. Link to comment Share on other sites More sharing options...
pixelsearch Posted December 6, 2020 Share Posted December 6, 2020 (edited) On 12/6/2020 at 4:22 PM, Norm73 said: I have an array list with all the internal autoit IDs of the list so I don't have to keep track of how the list is sorted. Well... maybe one you'll need your listview sorted, who knows... If it happens, please have a look at the 3 pics below : The pic above could represent a 2D array of your listview items just after it has been created (with only one data column on the right, to make these explanations simpler) 11 rows, 1 column in LV, content of the column (unsorted) => "CC" , "MM" ... "HH" Gui ID's for your items start at 7 because : * Gui ID's always start at 3 and... * ...you already created 4 controls before ($sLb, $nImp, $idButton, $idListview) which were assigned to GUI ID's 3, 4, 5, 6 LV ID and LV Index got the same value just after the LV is created (from 0 to 10) The pic above shows what happens when you sort using the _GUICtrlListView_SimpleSort() function : Content of cells is now sorted "AA" , "CC" ... "ZZ" LV ID = LV index because Windows didn't make the sort, all the sorting part is included in the UDF's (it would be same if you ever use one day ArrayMultiColSort() from Melba23 : LV ID = LV Index after the MultiColSort) The pic above shows what happens when you sort using _GUICtrlListView_SortItems() Content of cells is sorted "AA" , "CC" ... "ZZ" but all LV indexes have changed (they're no more equals to LV ID's) because Windows did the sort when LVM_SORTITEMSEX message was called (MSDN's explanations in my precedent post) So if you ever use this way of sorting, then you'll need _GUICtrlListView_MapIndexToID() and _GUICtrlListView_MapIDToIndex() to update your array accordingly. On 12/6/2020 at 4:22 PM, Norm73 said: The best way would be to get the index directly. But how, I don't know. I think the quickest way to access a value directly in an Array is to use ArrayBinarySearch() but if you do this, the search column must be sorted in ascending order before the search is done (help file, topic ArrayBinarySearch) As you're saying that you won't sort the LV, why don't you just use ArrayBinarySearch() in the 1st pic, where both GUI ID column and LV Index column are already sorted ? Checking quickly a value in the GUI ID column will indicate you its corresponding LV index value... and vice-versa Hope it helps and good luck Edited December 7, 2020 by pixelsearch changed pic #2, it should be ok now. Musashi and Norm73 1 1 Link to comment Share on other sites More sharing options...
Norm73 Posted December 6, 2020 Author Share Posted December 6, 2020 (edited) You have done a great job. Many thanks. I would like to use these functions _GUICtrlListView_MapIndexToID () _GUICtrlListView_MapIDToIndex () unfortunately they do not work with natural functions. I used the _GUICtrlListView_MapIDToIndex in my example above and it only returns -1. It may be that the control ID is changed in the other script when sorting, but it works for me, as in the instructions. Quote _GUICtrlListView_MapIDToIndex ListView-Controls erfassen Items intern durch einen Index. Dies kann Probleme verursachen, weil sich Indizes ändern können. Das ListView-Control kann ein Item mit einer ID kennzeichnen, wenn das Item erstellt wird. Diese ID kann verwendet werden, um die Eindeutigkeit während der Laufzeit des Controls zu garantieren. ArrayBinarySearch -> very good advice, I'll keep that out of sight. Unfortunately, the question is always not resolved whether there is an alternative to the _GUICtrlListView_MapIDToIndex function that will work in my example.😢 Edited December 6, 2020 by Norm73 Link to comment Share on other sites More sharing options...
pixelsearch Posted December 6, 2020 Share Posted December 6, 2020 57 minutes ago, Norm73 said: I used the _GUICtrlListView_MapIDToIndex in my example above and it only returns -1. It returns -1 (when you input 4 or more) because you got the 2nd parameter wrong in your script : Local $nIndex = _GUICtrlListView_MapIndexToID($idListview, $nID) ; ? 2nd parameter should be the "0-based index of an item" (help file) which means 0-10 (as shown in 1st pic of my post), not the controlID of the native-created ListView item (the "GUI ID" column in the pic) which goes from 7 to 17 _GUICtrlListView_MapIDToIndex maps the 2 columns "LV ID" and "LV index", it has nothing to do with the "GUI ID" column. In your script. When the following line is encountered... Local $nID = _GUICtrlListView_GetItemParam($idListview, $nNr) ... then $nID contains the "GUI ID" value, which has nothing to do with _GUICtrlListView_MapIndexToID()... I guess Also, please take care of this line : If $nNr > 0 And $nNr < 11 Then ; 1 to 10 Because 0 is a valid item index that can be keyed in the Input field, then it should be : If $nNr >= 0 And $nNr < 11 Then ; 0 to 10 Link to comment Share on other sites More sharing options...
Norm73 Posted December 7, 2020 Author Share Posted December 7, 2020 (edited) Of course my example is not ideal. (It could be better)☹️ I finally found what I needed. And it was in front of your nose, so to speak, the whole time The _GUICtrlListView_FindParam () function from the same library returns the index of the point from the control-ID (GUI-Autoit). It also works fine with the sorting. Spoiler expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> Example() Func Example() GUICreate("listview items", 320, 450, -1, -1, -1, $WS_EX_ACCEPTFILES) GUISetBkColor(0x00E0FFFF) ; will change background color Local $sLb = GUICtrlCreateLabel("Number Item-Index", 20, 335) Local $nImp = GUICtrlCreateInput("", 20, 350, 150, 24, 0x2000) ;$ES_NUMBER Local $idButton = GUICtrlCreateButton("Index -> Control-ID"& @CRLF &"Control-ID -> Index ?", 20, 380, 150, 48, BitOR(0x2000, 0x0100)) ;$BS_MULTILINE GUICtrlSetFont(-1, 11) Global $idListview = GUICtrlCreateListView("col 1 |col 2 |col 3 |col 4 |", 10, 10, 300, 300) ;,$LVS_SORTDESCENDING) Local $nP = 0 For $nN = 0 To 9 GUICtrlCreateListViewItem("item "& $nN &"|col "& $nP+1 &"|col "& $nP+2 &"|col "& $nP+3, $idListview) $nP += 1 Next GUISetState(@SW_SHOW) _GUICtrlListView_RegisterSortCallBack($idListview) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GUICtrlListView_UnRegisterSortCallBack($idListview) GUIDelete() ExitLoop Case $idButton Local $nNr = Number(GUICtrlRead($nImp)) If $nNr >= 0 And $nNr < 11 Then Local $nID = _GUICtrlListView_GetItemParam($idListview, $nNr) Local $nIndex = _GUICtrlListView_FindParam($idListview, $nID) MsgBox($MB_SYSTEMMODAL, "listview", "Input Index = "& $nNr & @CRLF &"Index To ID-Control -> "& $nID & @CRLF &"ID-Control To Index -> "& $nIndex) EndIf Case $idListview _GUICtrlListView_SortItems($idListview, 0) EndSwitch WEnd EndFunc ;==>Example Edited December 7, 2020 by Norm73 pixelsearch 1 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