Что нового

Функция для определение индекса пункта в ListView из Control-ID (GUI-Autoit)

Norm

Продвинутый
Сообщения
269
Репутация
70
Помогите пожалуйста уважаемые профессионалы.

В библиотеке GuiListView.au3 есть функция _GUICtrlListView_MapIDToIndex
Эта функция не работает, об этом я уже здесь писал.
Обратная функция __GUICtrlListView_MapIndexToID тоже не работает, но её можно спокойно заменить на _GUICtrlListView_GetItemParam
Проблему с определением индекса пункта через ID похожим способом решить не получилось и из за этого снижается надежность в некоторых ситуациях.

Оригинальная функция из библиотеки выглядит так:
Код:
Func _GUICtrlListView_MapIDToIndex($hWnd, $iID)
    If IsHWnd($hWnd) Then
        Return _SendMessage($hWnd, $LVM_MAPIDTOINDEX, $iID)
    Else
        Return GUICtrlSendMsg($hWnd, $LVM_MAPIDTOINDEX, $iID, 0)
    EndIf
EndFunc   ;==>_GUICtrlListView_MapIDToIndex
Всё просто, но как я и говорил не работает, а альтернативную функцию я сам не осилю.
 

Tempo

AutoIT Гуру
Сообщения
616
Репутация
205
Эта функция не работает, об этом я уже здесь писал.
Эта функция работает корректно. Вы должны понимать что ID (который упоминается в справке к этой функции) и ControlID это разные значения и они никак не связаны.
ControlID это затычка от обертки по имени AutoIt.
ID который возвращает _GUICtrlListView_MapIndexToID, реализован на уровне самого элемента управления.

Если вы не хотите обрабатывать WM_NOTIFY, а обойтись OnEvent режимом и при нажатии вам нужен индекс, тогда самые простые/очевидные решения это либо поиск перебором нужного Param (где AutoIt хранит ControlID), либо поиск выделенного элемента (этот вариант иногда дает некорректный результат).

Код:
;~ AutoIt Version: 3.3.14.5
;~ Author:         Tempo
#include <GUIConstants.au3>
#include <GuiListView.au3>

Opt("GUIOnEventMode", 1)
Global $g_hGUI = GUICreate(@ScriptName, 400, 400)
GUISetOnEvent($GUI_EVENT_CLOSE, Close)

Global $g_idListView = GUICtrlCreateListView("Items", 0, 0, 400, 400)
For $i = 0 To 10
    GUICtrlCreateListViewItem("Item " & $i + 1, $g_idListView)
    GUICtrlSetOnEvent(-1, Click)
Next
GUISetState()


While Sleep(10)
WEnd


Func Click()
    Local $iIndex = _GUICtrlListView_ControlIDToIndex($g_idListView, @GUI_CtrlId) ;#1
    Local $iSelectedIndex = _GUICtrlListView_GetNextItem($g_idListView) ;#2
    MsgBox(0, Default, StringFormat("@GUI_CtrlId: %i\r\nIndex: %i\r\nSelectedIndex: %i", @GUI_CtrlId, $iIndex, $iSelectedIndex), 0, $g_hGUI)
EndFunc   ;==>Click

Func Close()
    Exit
EndFunc   ;==>Close



Func _GUICtrlListView_ControlIDToIndex($idListView, $idListViewItem)
    Local $tLVITEM = DllStructCreate($tagLVITEM)
    DllStructSetData($tLVITEM, "Mask", $LVIF_PARAM)
    Local $pLVITEM = DllStructGetPtr($tLVITEM)
    Local $iMsg = GUICtrlSendMsg($idListView, $LVM_GETUNICODEFORMAT, 0, 0) ? $LVM_GETITEMW : $LVM_GETITEMA
    For $iIndex = 0 To GUICtrlSendMsg($idListView, $LVM_GETITEMCOUNT, 0, 0) - 1
        DllStructSetData($tLVITEM, "Item", $iIndex)
        GUICtrlSendMsg($idListView, $iMsg, 0, $pLVITEM)
        If DllStructGetData($tLVITEM, "Param") = $idListViewItem Then Return $iIndex
    Next
    Return SetError(1, 0, -1)
EndFunc   ;==>_GUICtrlListView_ControlIDToIndex
 
Последнее редактирование:
  • Like
Реакции: Norm
Автор
N

Norm

Продвинутый
Сообщения
269
Репутация
70
Огромное Вам спасибо за разъяснение моей ошибки и сделанную Вами функцию.
Вы прекрасно поняли чего я добиваюсь и в очередной раз помогли мне.
Сообщение автоматически объединено:

Наконец то нашел, то что мне нужно.
И было оно, можно так сказать, всё время под носом
функция _GUICtrlListView_FindParam() из той же библиотеки возвращает индекс пункта из Control-ID созданного с помощью GUI Autoit
Вот сделал пример, который в независимости от сортировки позволяет определить оба параметра.
Код:
#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
 
Последнее редактирование:
Верх