pixelsearch Posted March 9, 2021 Share Posted March 9, 2021 Hi everybody AutoIt 3.3.14.5 , File GuiListView.au3 , function _GUICtrlListView_GetSelectedIndices() Line #2618 : For $iItem = 0 To $iCount Shouldn't it be : For $iItem = 0 To $iCount - 1 mLipok and Musashi 2 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 9, 2021 Moderators Share Posted March 9, 2021 (edited) pixelsearch, I believe so. Fortunately the final unnecessary item index just gets rejected by the subsequent _SendMessage/GUICtrlSendMsg command and the function does not fail with an error. Well spotted! M23 Edit: same error in the release library too - it must have been there for a long time! Edited March 9, 2021 by Melba23 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...
pixelsearch Posted March 9, 2021 Author Share Posted March 9, 2021 (edited) Thanks Melba23 for the confirmation. Let's notice that the person(s) who scripted __ArrayDisplay_Share() did it correctly with the corresponding line, used to inspect all LV items during the "Case $idCopy_ID, $idCopy_Data" : For $i = 0 To GUICtrlSendMsg($idListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0) - 1 Edited March 9, 2021 by pixelsearch Link to comment Share on other sites More sharing options...
pixelsearch Posted March 10, 2021 Author Share Posted March 10, 2021 (edited) @Melba23 : could you please be kind enough to comment what follows, thanks The function _GUICtrlListView_GetSelectedIndices is based on a loop which checks each and every item of a Listview to retrieve indices of selected item(s), which means it will loop for example 1000 times when there are 1000 items, even if only 3 items are selected. Basically, this is how the function works actually : $iCount = _GUICtrlListView_GetItemCount($idListView) For $iItem = 0 To $iCount - 1 $iRet = GUICtrlSendMsg($idListView, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED) If $iRet Then ... ; do here what needs to be done Next What about if we script it like that, with a loop executed 3 times only instead of 1000 times, maybe it will end faster while bringing back the same result : $iSelectedCount = GUICtrlSendMsg($idListView, $LVM_GETSELECTEDCOUNT, 0, 0) If $iSelectedCount = 0 Then Return $iStart = - 1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $i = 1 To $iSelectedCount $iSelected = GUICtrlSendMsg($idListView, $LVM_GETNEXTITEM, $iStart, $LVNI_SELECTED) ; do here what needs to be done $iStart = $iSelected Next Thanks for your advice. Edit: I think the message $LVM_GETSELECTEDCOUNT is very fast (tested it on 1000 items) In case one is reluctant to use it (?) then we could do it in another way (gonna find it back in my yesterday's archive folder and post it below asap) Ok... here is the other way (I didn't find it in my archive, grr...) so let's hope I "redo" it correctly. This one is without $LVM_GETSELECTEDCOUNT and the loop is still executed 3 times (3 selected items out of 1000 rows). Then the loop may be partially executed a 4th time (exited with ExitLoop) unless the last item is one of the 3 selected items. $iCount = _GUICtrlListView_GetItemCount($idListView) $iStart = - 1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $iItem = 0 To $iCount - 1 $iSelected = GUICtrlSendMsg($idListView, $LVM_GETNEXTITEM, $iStart, $LVNI_SELECTED) If $iSelected = - 1 Then ExitLoop ; do here what needs to be done $iStart = $iSelected $iItem = $iSelected Next Edited March 10, 2021 by pixelsearch FrancescoDiMuro 1 Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted March 10, 2021 Share Posted March 10, 2021 (edited) @pixelsearch I like more the way with $LVM_GETSELECTEDCOUNT Edited March 10, 2021 by FrancescoDiMuro Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Nine Posted March 10, 2021 Share Posted March 10, 2021 (edited) Do we even need a _GUICtrlListView_GetItemCount ? Because GUICtrlSendMsg($idListView, $LVM_GETNEXTITEM, $iStart, $LVNI_SELECTED) will return an error eventually, no ? Func _GUICtrlListView_GetSelectedIndicesEX($idLV) Local $iIdx = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) While True $iIdx = GUICtrlSendMsg($idLV, $LVM_GETNEXTITEM, $iIdx, $LVNI_SELECTED) If $iIdx = - 1 Then ExitLoop ConsoleWrite ($iIdx & @CRLF) ; do here what needs to be done WEnd EndFunc Edited March 10, 2021 by Nine pixelsearch 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 March 10, 2021 Author Share Posted March 10, 2021 (edited) @FrancescoDiMuro : $LVM_GETSELECTEDCOUNT is a message I discovered when I nearly finished my scripting, that's why I had 2 different versions, one using it, the precedent one without it If we are sure that $LVM_GETSELECTEDCOUNT returns a value extremely quickly even on a big LV, then we can use it. If not, it's better to stick to other quick loops (but not to the actual loop as found in _GUICtrlListView_GetSelectedIndices which sends a message for each and every item) The only thing I'm sure of is that _GUICtrlListView_GetItemCount() will always return a value in a millisecond , no matter the LV size. Nine's way is good too, I did it like him a few hours ago (i.e a While loop) @Nine : concerning the error returned by GUICtrlSendMsg, I'm not sure of anything : see how Melba indicated above that "_SendMessage/GUICtrlSendMsg command and the function does not fail with an error" His comment concerned the function _GUICtrlListView_GetSelectedIndices with the erroneous line in it ("For $iItem = 0 To $iCount" instead of "For $iItem = 0 To $iCount - 1") So I tried to understand this kind of "error return" with an example, but I'm not sure I took a good path, here is what I did : * Amended the function _GUICtrlListView_GetSelectedIndices like this, keeping the erroneous line, adding 3 ConsoleWrite ... For $iItem = 0 To $iCount If IsHWnd($hWnd) Then $iRet = _SendMessage($hWnd, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED) If @error Then ConsoleWrite("error = " & @error & @CRLF) ConsoleWrite("(LVhnd) $iItem = " & $iItem & " $iRet = " & $iRet & @CRLF) Else $iRet = GUICtrlSendMsg($hWnd, $LVM_GETITEMSTATE, $iItem, $LVIS_SELECTED) ConsoleWrite("(LVid ) $iItem = " & $iItem & " $iRet = " & $iRet & @CRLF) EndIf ... * Amended the script example found in the help file, topic _GUICtrlListView_GetSelectedIndices, adding an optional line to call the function using the LV handle and not it's ID, so we'll try both later : MsgBox($MB_SYSTEMMODAL, "Information", "Selected Indices: " & _GUICtrlListView_GetSelectedIndices($idListview)) ; MsgBox($MB_SYSTEMMODAL, "Information", "Selected Indices: " & _GUICtrlListView_GetSelectedIndices(GUICtrlGetHandle($idListview))) Also I renamed the 3 Items captions in the example to "Item 0", "Item 1", "Item 2" (better than 1, 2, 3) to match the ConsoleWrite in the function. * Now when we run the example using the LV id, here is what appears on the screen : Console : (LVid ) $iItem = 0 $iRet = 0 (LVid ) $iItem = 1 $iRet = 2 (LVid ) $iItem = 2 $iRet = 2 (LVid ) $iItem = 3 $iRet = 0 => Items 1 and 2 are selected (the code did it) and their $Iret = 2, which corresponds to $LVIS_SELECTED = 0x0002, matching what msdn stipulates for the return value of the LVM_GETITEMSTATE message : Return value : Returns the current state for the specified item. The only valid bits in the return value are those that correspond to the bits set in the lParam parameter. => Item 0 got $iRet = 0 (not selected by the example code) => Item 3... this item doesn't even exist in the LV (that's why we kept the erroneous line "For $iItem = 0 To $iCount") and it also got $iRet = 0, which means that it's not obvious to explain a "failure = 0" when you receive it from GUICtrlSendMsg() : it will be 0 for an existing item or a non-existing item, and unfortunately @error is not an option in GUICtrlSendMsg() * If we run the example using the LV handle, then the console shows the same : (LVhnd) $iItem = 0 $iRet = 0 (LVhnd) $iItem = 1 $iRet = 2 (LVhnd) $iItem = 2 $iRet = 2 (LVhnd) $iItem = 3 $iRet = 0 Same display, but though there is a ConsoleWrite("error = " & @error) added in the function, there is no @error line appearing in the Console, which means that the _SendMessage() function (found in SendMessage.au3), though it is programmed to return an @error when it happens, doesn't return an error in this case for the non-existing $iItem = 3 (that's what Melba23 meant in his comment) Func _SendMessage($hWnd, $iMsg, $wParam = 0, $lParam = 0, $iReturn = 0, $wParamType = "wparam", $lParamType = "lparam", $sReturnType = "lresult") Local $aResult = DllCall("user32.dll", $sReturnType, "SendMessageW", "hwnd", $hWnd, "uint", $iMsg, $wParamType, $wParam, $lParamType, $lParam) If @error Then Return SetError(@error, @extended, "") ... This is a question I always wanted to ask : what's the use of setting errors in functions (like the _SendMessage() function for example) if @error isn't checked on return, immediately after each _SendMessage() call ? Edited March 10, 2021 by pixelsearch Link to comment Share on other sites More sharing options...
Nine Posted March 10, 2021 Share Posted March 10, 2021 All I was saying is the call to get a count is useless with a loop with the message $LVM_GETNEXTITEM (whatever form you send it) “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...
jpm Posted March 11, 2021 Share Posted March 11, 2021 14 hours ago, pixelsearch said: This is a question I always wanted to ask : what's the use of setting errors in functions (like the _SendMessage() function for example) if @error isn't checked on return, immediately after each _SendMessage() call ? in fact the checking if done will identify an internal error from AutoIt code or perhaps Windows code. Almost all DllCall in the standard UDF have this checking and return to isolate an error. you can find that the @error is modify when they are multiple @error checking in the same function to identify where the error occur just looking at the @error value. if _SendMessage parameters arenot valid it can be @error: 1 = unable to use the DLL file, >>> "user32.dll" = Windows pb >>> UDF error certainly an Autoit internal error if a valid UDF has been used 2 = unknown "return type", 3 = "function" not found in the DLL file , 4 = bad number of parameters, 5 = bad parameter. pixelsearch and Musashi 2 Link to comment Share on other sites More sharing options...
pixelsearch Posted March 11, 2021 Author Share Posted March 11, 2021 1 hour ago, jpm said: in fact the checking if done will identify an internal error from AutoIt code or perhaps Windows code. Thanks jpm for the explanation. It's always great to have you around... and I bolded the "if" in your answer I understand better now, it's mostly used to identify internal errors. To test this kind of error, I could reproduce one just now, by altering a line in Func _SendMessage() and replacing a correct parameter with a wrong one : Original code : Local $aResult = DllCall("user32.dll", $sReturnType, ... Wrong code : Local $aResult = DllCall("user32.dll", "mresult", ... "mresult" means nothing (it's "lresult" that is expected) After that, when running the _GUICtrlListView_GetSelectedIndices() example, calling the function with the LV handle, I'm getting a wrong result in the final display (no selected indices) because of @error = 2 (2 = unknown "return type") and if I check the error inside the UDF, then I can (finally !) display an "error 2" in the Console : $aResult = 0 VarGetType($aResult) = Int32 $aResult = 0 VarGetType($aResult) = Int32 $aResult = 0 VarGetType($aResult) = Int32 error = 2 extended = 0 $iRet = 0 If I don't add any error checking in the function _GUICtrlListView_GetSelectedIndices(), then I'll "simply" get a wrong result in the script, not being notified that @error was once equal to 2 Ok, time to replace both altered UDF's with the right ones Link to comment Share on other sites More sharing options...
jpm Posted March 12, 2021 Share Posted March 12, 2021 Hi, @pixelsearch I update _GUICtrlListView_GetSelectedIndices() according to your suggestion THanks pixelsearch and argumentum 2 Link to comment Share on other sites More sharing options...
KaFu Posted May 10, 2023 Share Posted May 10, 2023 ReDim $aIndices for every selected index is slow on large listviews. In SMF I've stripped the function down to array use, but you'll see what I mean. For 2,000 items the runtime is reduced from 680ms to 95ms on my machine. Func _GUICtrlListView_GetSelectedIndices_KAF($hWnd) Local $iSelectedCount = _GUICtrlListView_GetSelectedCount($hWnd) If $iSelectedCount Then Local $sIndices, $aIndices[500], $iEnum = 0 $aIndices[0] = 500 Local $iSelected = 1, $iStart = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $i = 1 To $iSelectedCount $iSelected = _SendMessage($hWnd, $LVM_GETNEXTITEM, $iStart, $LVNI_SELECTED) $iEnum += 1 If $iEnum > $aIndices[0] -1 Then ReDim $aIndices[$aIndices[0] + 500] $aIndices[0] += 500 endif $aIndices[$i] = $iSelected ; ConsoleWrite($i & @tab & $iEnum & @tab & $aIndices[0] & @crlf) $iStart = $iSelected Next Else Local $aIndices[1] = [0] Return $aIndices EndIf ReDim $aIndices[$i] $aIndices[0] = $i -1 Return $aIndices EndFunc ;==>_GUICtrlListView_GetSelectedIndices_KAF OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Nine Posted May 10, 2023 Share Posted May 10, 2023 (edited) @KaFu Since we already know the selected count with _GUICtrlListView_GetSelectedCount. Why not create the array with the exact size at first ? Edited May 10, 2023 by Nine KaFu 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...
KaFu Posted May 10, 2023 Share Posted May 10, 2023 (edited) Makes it something like this: Func _GUICtrlListView_GetSelectedIndices_KAF($hWnd) Local $iSelectedCount = _GUICtrlListView_GetSelectedCount($hWnd) If $iSelectedCount Then Local $aIndices[$iSelectedCount+1] $aIndices[0] = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $i = 1 To $iSelectedCount $aIndices[$i] = _SendMessage($hWnd, $LVM_GETNEXTITEM, $aIndices[$i-1], $LVNI_SELECTED) ; ConsoleWrite($i & @tab & $iEnum & @tab & $aIndices[0] & @crlf) Next $aIndices[0] = $iSelectedCount Else Local $aIndices[1] = [0] EndIf Return $aIndices EndFunc ;==>_GUICtrlListView_GetSelectedIndices_KAF Edited May 10, 2023 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Nine Posted May 10, 2023 Share Posted May 10, 2023 (edited) Here my take on it (seems SendMessage is slower) : expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> Example() Func Example() Local $idListview GUICreate("ListView Get Selected Indices", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT)) _GUICtrlListView_AddColumn($idListview, "Column 1", 100) For $i = 0 To 10000 _GUICtrlListView_AddItem($idListview, "Item " & $i) Next GUISetState(@SW_SHOW) For $i = 0 To 10000 Step 5 _GUICtrlListView_SetItemSelected($idListview, $i) Next Local $hTimer = TimerInit() Local $aList = _GUICtrlListView_GetSelectedIndices_KAF(GUICtrlGetHandle($idListview)) ConsoleWrite("Kafu = " & TimerDiff($hTimer) & @CRLF) ;_ArrayDisplay($aList) $hTimer = TimerInit() $aList = _GUICtrlListView_GetSelectedIndices9($idListview, True) ConsoleWrite("Nine = " & TimerDiff($hTimer) & @CRLF) ;ConsoleWrite($aList & @CRLF) ;_ArrayDisplay($aList) $hTimer = TimerInit() $aList = _GUICtrlListView_GetSelectedIndices($idListview, True) ConsoleWrite("Jpm = " & TimerDiff($hTimer) & @CRLF) ;ConsoleWrite($aList & @CRLF) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc ;==>Example Func _GUICtrlListView_GetSelectedIndices9($hWnd, $bArray = False) Local $iCount = _GUICtrlListView_GetSelectedCount($hWnd) Local $aSelect[$iCount + 1] = [$iCount] If Not $iCount Then Return $bArray ? $aSelect : "" Local $iIdx = -1, $sIndices If IsHWnd($hWnd) Then $hWnd = _WinAPI_GetDlgCtrlID($hWnd) For $i = 1 To $iCount $iIdx = GUICtrlSendMsg($hWnd, $LVM_GETNEXTITEM, $iIdx, $LVNI_SELECTED) If $bArray Then $aSelect[$i] = $iIdx Else $sIndices &= $iIdx & "|" EndIf Next Return $bArray ? $aSelect : StringTrimRight($sIndices, 1) EndFunc ;==>_GUICtrlListView_GetSelectedIndices9 Func _GUICtrlListView_GetSelectedIndices_KAF($hWnd) Local $iSelectedCount = _GUICtrlListView_GetSelectedCount($hWnd) If $iSelectedCount Then Local $aIndices[$iSelectedCount + 1] $aIndices[0] = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $i = 1 To $iSelectedCount $aIndices[$i] = _SendMessage($hWnd, $LVM_GETNEXTITEM, $aIndices[$i - 1], $LVNI_SELECTED) ; ConsoleWrite($i & @tab & $iEnum & @tab & $aIndices[0] & @crlf) Next $aIndices[0] = $iSelectedCount Else Local $aIndices[1] = [0] EndIf Return $aIndices EndFunc ;==>_GUICtrlListView_GetSelectedIndices_KAF Results with array : Kafu = 23.2122 Nine = 4.895 Jpm = 296.4108 Results with string : Nine = 4.6947 Jpm = 6.2971 Edited May 10, 2023 by Nine to always use control id spudw2k and KaFu 2 “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...
KaFu Posted May 10, 2023 Share Posted May 10, 2023 Good catch 👍, I'm really baffled about the bad SendMessage results, and that GUICtrlSendMsg seems much faster, would have guessed the other way around. Must be related to GUICtrlSendMsg being a native function and the dllcall "workaround" creates additional overhead. KaFu_1_SendMessage = 49.8236 Nine = 9.794 KaFu_2_DllCallAddres = 24.0897 KaFu_3_GUICtrlSendMsg = 9.5192 Jpm = 599.1251 expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <MsgBoxConstants.au3> #include <WinAPISys.au3> Example() Func Example() Local $idListview GUICreate("ListView Get Selected Indices", 400, 300) $idListview = GUICtrlCreateListView("", 2, 2, 394, 268, BitOR($LVS_SHOWSELALWAYS, $LVS_REPORT)) _GUICtrlListView_AddColumn($idListview, "Column 1", 100) For $i = 0 To 10000 _GUICtrlListView_AddItem($idListview, "Item " & $i) Next GUISetState(@SW_SHOW) For $i = 0 To 10000 Step 5 _GUICtrlListView_SetItemSelected($idListview, $i) Next Local $hTimer = TimerInit() Local $aList = _GUICtrlListView_GetSelectedIndices_KaFu_1(GUICtrlGetHandle($idListview)) ConsoleWrite("KaFu_1_SendMessage" & @TAB & @TAB & "= " & TimerDiff($hTimer) & @CRLF) ;_ArrayDisplay($aList) $hTimer = TimerInit() $aList = _GUICtrlListView_GetSelectedIndices9($idListview, True) ConsoleWrite("Nine" & @TAB & @TAB & @TAB & @TAB & "= " & TimerDiff($hTimer) & @CRLF) ;ConsoleWrite($aList & @CRLF) ; _ArrayDisplay($aList) Local $hTimer = TimerInit() Local $aList = _GUICtrlListView_GetSelectedIndices_KaFu_2(GUICtrlGetHandle($idListview)) ConsoleWrite("KaFu_2_DllCallAddress" & @TAB & @TAB & "= " & TimerDiff($hTimer) & @CRLF) ; _ArrayDisplay($aList) Local $hTimer = TimerInit() Local $aList = _GUICtrlListView_GetSelectedIndices_KaFu_3(GUICtrlGetHandle($idListview)) ConsoleWrite("KaFu_3_GUICtrlSendMsg" & @TAB & @TAB & "= " & TimerDiff($hTimer) & @CRLF) ; _ArrayDisplay($aList) $hTimer = TimerInit() $aList = _GUICtrlListView_GetSelectedIndices($idListview, True) ConsoleWrite("Jpm" & @TAB & @TAB & @TAB & @TAB & "= " & TimerDiff($hTimer) & @CRLF) ;ConsoleWrite($aList & @CRLF) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc ;==>Example Func _GUICtrlListView_GetSelectedIndices9($hWnd, $bArray = False) Local $iCount = _GUICtrlListView_GetSelectedCount($hWnd) Local $aSelect[$iCount + 1] = [$iCount] If Not $iCount Then Return $bArray ? $aSelect : "" Local $iIdx = -1, $sIndices If IsHWnd($hWnd) Then $hWnd = _WinAPI_GetDlgCtrlID($hWnd) For $i = 1 To $iCount $iIdx = GUICtrlSendMsg($hWnd, $LVM_GETNEXTITEM, $iIdx, $LVNI_SELECTED) If $bArray Then $aSelect[$i] = $iIdx Else $sIndices &= $iIdx & "|" EndIf Next Return $bArray ? $aSelect : StringTrimRight($sIndices, 1) EndFunc ;==>_GUICtrlListView_GetSelectedIndices9 Func _GUICtrlListView_GetSelectedIndices_KaFu_1($hWnd) Local $iSelectedCount = _GUICtrlListView_GetSelectedCount($hWnd) If $iSelectedCount Then Local $aIndices[$iSelectedCount + 1] $aIndices[0] = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $i = 1 To $iSelectedCount $aIndices[$i] = _SendMessage($hWnd, $LVM_GETNEXTITEM, $aIndices[$i - 1], $LVNI_SELECTED) ; ConsoleWrite($i & @tab & $iEnum & @tab & $aIndices[0] & @crlf) Next $aIndices[0] = $iSelectedCount Else Local $aIndices[1] = [0] EndIf Return $aIndices EndFunc ;==>_GUICtrlListView_GetSelectedIndices_KaFu_1 Func _GUICtrlListView_GetSelectedIndices_KaFu_2($hWnd) Local $iCount = _GUICtrlListView_GetSelectedCount($hWnd) If $iCount Then Local $h_SendMessageW = _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("user32.dll"), "SendMessageW") Local $aSelect[$iCount + 1] $aSelect[0] = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) For $i = 1 To $iCount $aSelect[$i] = DllCallAddress("int", $h_SendMessageW, "hwnd", $hWnd, "int", $LVM_GETNEXTITEM, "int", $aSelect[$i - 1], "int", $LVNI_SELECTED)[0] Next $aSelect[0] = $iCount Else Local $aSelect[1] = [0] EndIf Return $aSelect EndFunc ;==>_GUICtrlListView_GetSelectedIndices_KaFu_2 Func _GUICtrlListView_GetSelectedIndices_KaFu_3($hWnd) Local $iCount = _GUICtrlListView_GetSelectedCount($hWnd) If $iCount Then Local $aSelect[$iCount + 1] $aSelect[0] = -1 ; -1 to find the first item that matches the specified flags (msdn) ; the specified item itself is excluded from the search (+++) If IsHWnd($hWnd) Then $hWnd = _WinAPI_GetDlgCtrlID($hWnd) For $i = 1 To $iCount $aSelect[$i] = GUICtrlSendMsg($hWnd, $LVM_GETNEXTITEM, $aSelect[$i - 1], $LVNI_SELECTED) Next $aSelect[0] = $iCount Else Local $aSelect[1] = [0] EndIf Return $aSelect EndFunc ;==>_GUICtrlListView_GetSelectedIndices_KaFu_3 mLipok and Nine 2 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
jpm Posted May 11, 2023 Share Posted May 11, 2023 So the conclusion Ineed tointegrate the Nine version which support the $bArray parameter Thanks to all of you KaFu 1 Link to comment Share on other sites More sharing options...
Nine Posted May 23, 2023 Share Posted May 23, 2023 (edited) @jpm Sorry for late reply, I was outside town with no access to the net. But I was thinking that my approach of forcing the use of control id is not a good idea in the case the ListView is not owned by the script. So usage of SendMessage can be necessary. Here what I suggest then : Func _GUICtrlListView_GetSelectedIndices($hWnd, $bArray = False) Local $iCount = _GUICtrlListView_GetSelectedCount($hWnd) Local $aSelect[$iCount + 1] = [$iCount] If Not $iCount Then Return $bArray ? $aSelect : "" If IsHWnd($hWnd) And WinGetProcess(_WinAPI_GetAncestor($hWnd, $GA_ROOT)) = @AutoItPID Then $hWnd = _WinAPI_GetDlgCtrlID($hWnd) Local $iIdx = -1, $sIndices, $bHWnd = IsHWnd($hWnd) For $i = 1 To $iCount $iIdx = $bHWnd ? _SendMessage($hWnd, $LVM_GETNEXTITEM, $iIdx, $LVNI_SELECTED) : GUICtrlSendMsg($hWnd, $LVM_GETNEXTITEM, $iIdx, $LVNI_SELECTED) If $bArray Then $aSelect[$i] = $iIdx Else $sIndices &= $iIdx & "|" EndIf Next Return $bArray ? $aSelect : StringTrimRight($sIndices, 1) EndFunc ;==>_GUICtrlListView_GetSelectedIndices Edited May 24, 2023 by Nine Force the usage of control ID if the ListView is owned by the script “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...
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