Что нового

В ListView не работают _GUICtrlListView_MapIDToIndex и .... _MapIndexToID

Norm

Продвинутый
Сообщения
278
Репутация
74
Добрый день уважаемые профессионалы

Не получается разобраться почему не работают функции:
_GUICtrlListView_MapIDToIndex
_GUICtrlListView_MapIndexToID

из стандартной библиотеки GuiListView.au3

При запуске примеров из справки всегда возвращается индекс или -1, если попытаться подставить настоящий ID.
Код:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

$Debug_LV = False ; Проверяет ClassName передаваемый в ListView функции. Установите True и используйте дескриптор от другого элемента, чтобы увидеть как это работает

_Main()

Func _Main()
    Local $iID, $hListView

    GUICreate("Преобразует идентификатор в индекс", 400, 300)
    $hListView = GUICtrlCreateListView("", 2, 2, 394, 268)
    GUISetState()

    ; Добавляет колонку
    _GUICtrlListView_AddColumn($hListView, "Пункты", 100)

    ; Добавляет пункты
    _GUICtrlListView_AddItem($hListView, "Пункт 1")
    _GUICtrlListView_AddItem($hListView, "Пункт 2")
    _GUICtrlListView_AddItem($hListView, "Пункт 3")

    ; Показывает ID 2-го пункта
    $iID = _GUICtrlListView_MapIndexToID($hListView, 2)
    MsgBox(4160, "Информация", "Индекс в ID: " & $iID &@CRLF& _
    "ID в индекс: " & _GUICtrlListView_MapIDToIndex($hListView, $iID))

    ; Цикл выполняется, пока окно не будет закрыто
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>_Main
По идее должен вернуть ID который согласно @GUI_CtrlId равен 5, но возвращает индекс пункта 1.
Код:
; Показывает ID 2-го пункта
$iID = _GUICtrlListView_MapIndexToID($hListView, 2)

Тоже самое и с _GUICtrlListView_MapIDToIndex
Если подставить в качестве $iID настоящий ID, то есть 5, то возвращается -1

Проверял на версии 3.3.14.5
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
а где в примере пятый пункт? там всего лишь три
и причем тут @GUI_CtrlId ?
у меня все нормально работает
 
Автор
N

Norm

Продвинутый
Сообщения
278
Репутация
74
а где в примере пятый пункт? там всего лишь три
Не пункт, а возвращаемый ID

Переделал в более понятный пример. Нажмите на второй пункт

Объясните пожалуйста, что я не правильно понял, или эти функции похоже не работают, как заявлено
Код:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>


Local $nN, $hListView, $ID[3]
Opt("GUIOnEventMode", 1)
Local $Gui_Test = GUICreate("Преобразует идентификатор в индекс", 400, 300)
GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
$hListView = GUICtrlCreateListView("Пункты", 2, 2, 394, 268)

For $nN = 0 To 2
    $ID[$nN] = GUICtrlCreateListViewItem("Пункт - "& $nN+1, $hListView)
    GUICtrlSetOnEvent($ID[$nN], "_ID_Test")
Next
GUISetState()

While 1
    Sleep(500)
WEnd


Func _EXIT()
    Exit
EndFunc

Func _ID_Test()
    Local $Real_ID = @GUI_CtrlId
    Local $iID = _GUICtrlListView_MapIndexToID($hListView, 1)
    Local $nInx = _GUICtrlListView_MapIDToIndex($hListView, $Real_ID)
    MsgBox(4160, "Информация", "Реальный ID: " & $Real_ID & @CRLF & _
    "Index To ID: "& $iID &"  хотя должен быть: "& $Real_ID & @CRLF & _
    "ID To Index: "& $nInx &"  хотя должен быть: 2")
EndFunc
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
заметь, что в примере пункты создаются функциями из библиотеки, а не нативными. Да и вообще, для обработки нажатия на пункты есть нормальный метод. Пример
Код:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
Local $Gui_Test = GUICreate("Преобразует идентификатор в индекс", 400, 300)
GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
Local $ListView = GUICtrlCreateListView("Пункты", 2, 2, 394, 268)

For $nN = 0 To 2
    GUICtrlCreateListViewItem("Пункт - " & $nN, $ListView)
Next
$hListView = GUICtrlGetHandle($ListView)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
While 1
    Sleep(100)
WEnd

Func _EXIT()
    Exit
EndFunc   ;==>_EXIT

Func _ID_Test($iIndex)
    Switch $iIndex
        Case 0
            ConsoleWrite(0 & @LF)
        Case 1
            ConsoleWrite(1 & @LF)
        Case 2
            ConsoleWrite(2 & @LF)
    EndSwitch
EndFunc   ;==>_ID_Test

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iCode, $tNMHDR, $tInfo, $Index
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CLICK
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    $Index = DllStructGetData($tInfo, "Index")
                    If $Index > -1 Then _ID_Test($Index)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Автор
N

Norm

Продвинутый
Сообщения
278
Репутация
74
Ведь проблема не в методе, а в том что ни с нативными ни с библиотечными эти функции
_GUICtrlListView_MapIDToIndex
_GUICtrlListView_MapIndexToID

не выдают, что заявлено и похоже придется искать обходной путь.
Код:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
Local $aPU[3], $Gui_Test = GUICreate("Преобразует идентификатор в индекс", 400, 300)
GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
Local $ListView = GUICtrlCreateListView("Пункты", 2, 2, 394, 268)


For $nN = 0 To 2
    $aPU[$nN] = _GUICtrlListView_AddItem($ListView, "Пункт - " & $nN)
Next

$hListView = GUICtrlGetHandle($ListView)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    Sleep(100)
WEnd

Func _EXIT()
    Exit
EndFunc   ;==>_EXIT

Func _ID_Test($iIndex)

    Switch $iIndex
        Case 0
            ConsoleWrite(0 & @LF)
        Case 1
            Local $iID = _GUICtrlListView_MapIndexToID($hListView, 1)
            Local $nInx = _GUICtrlListView_MapIDToIndex($hListView, 5)
            MsgBox(4160, "Информация", "Реальный ID = 5"& @CRLF & _
            "Index To ID возвращает "& $iID &"  хотя должен быть равным 5"& @CRLF & _
            "ID To Index возвращает "& $nInx &" хотя должен быть 1")
        Case 2
            ConsoleWrite(2 & @LF)
    EndSwitch
EndFunc   ;==>_ID_Test

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iCode, $tNMHDR, $tInfo, $Index
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CLICK
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    $Index = DllStructGetData($tInfo, "Index")
                    If $Index > -1 Then _ID_Test($Index)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
если нужны уникальные идентификаторы, то лучше использовать
Код:
_GUICtrlListView_SetItemParam
_GUICtrlListView_GetItemParam

назначать свои числа и хранить их в массиве или объекте. И уже оперировать индексами. получили индекс, запросили параметр и выполнили нужное действие.
была такая проблема, только с TreeView
использовал указанный способ через Notify
На официальном форуме пояснений не нашел, может кто другой подскажет, если сталкивался.
С другой стороны, если макрос дает ID пункта, то зачем функции определения ID?
получил ID и в
Код:
Switch
EndSwitch

разобрал по полочкам
 
  • Like
Реакции: Norm
Автор
N

Norm

Продвинутый
Сообщения
278
Репутация
74
Эта функция _GUICtrlListView_GetItemParam возвращает также ID созданный с помощью GUICtrlCreateListViewItem

Спасибо за совет, похоже я уже в этом направлении тоже начал двигаться.
Свой скрипт делал без обработчика событий, а при сортировке только ID остаются не измененными.
Отказался от использования библиотек, и только применял нативные функции.
И похоже, что даже быстрее работать должно.
 
Последнее редактирование:
Верх