Jump to content

_GUICtrlListView_GetSelectedIndices()


Recommended Posts

  • Moderators

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 by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

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 by pixelsearch
Link to comment
Share on other sites

@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 by pixelsearch
Link to comment
Share on other sites

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 by Nine
Link to comment
Share on other sites

@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 :

2097891847_LVexample.png.cff814f93631f85efe3b8037ccda90ab.png

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 by pixelsearch
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 :D
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

  • 2 years later...

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

 

Link to comment
Share on other sites

Link to comment
Share on other sites

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 by KaFu
Link to comment
Share on other sites

Here my take on it (seems SendMessage is slower) :

#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 by Nine
to always use control id
Link to comment
Share on other sites

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

 

#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

 

Link to comment
Share on other sites

  • 2 weeks later...

@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 by Nine
Force the usage of control ID if the ListView is owned by the script
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...