ListView Elementen Funktionen zuweisen

  • Hi,

    Ich programiere mir gerade ein kleines Adressbuch mit AutoII
    Die verschiedenen Adressbücher lasse mit ListView am linken Bildschirmrand auflisten

    Das einfügen der Elemente, wenn ich ein Adressbuch erstelle funktioniert soweit ohne Probleme.
    Die Namen der Gästebücher speichere ich in einer TXT datei ab -->

    [autoit]

    @scriptdir & "\Data\AdressBook & $Count\Name.txt

    [/autoit]

    Die Variable "$Count" wird nach jedem eintrag um 1 erhöt und in eine Datei gespeichert.
    So entstehen Also vortlaufende Ordnernamen je Adressbuch.

    Wenn dass Programm wieder gestartet wird, lese ich die Namen in ein Array ein:

    [autoit]

    dim $AdressbuchNamen[100]
    dim $Count = FileRead(@scriptdir & "\Data\Count.txt")
    dim $i = 1

    [/autoit][autoit][/autoit][autoit]

    While($i <= $Count)
    $Adressbuchnamen[$i] = FileRead(@scriptdir & "\Data\AdressBook" & $i & "\Name.txt")
    $i = $i + 1
    WEND

    [/autoit]

    anschließend trage ich sie wiederum mit einer Schleife in die ListView ein.
    Funktioniert wunderbar, nur wie schaffe ich es nun, dass jedem der ListView Eintäge eine Funktion zugewiesen wird? Es soll immer die selbe funkion sein, es muss aber erkannt werden, welcher eintrag aktiviert wurde.

    Ich hoffe ich hab mich einigermaßen verständlich ausgedrückt ;)

    mfg *mow*

  • Hi, und schonmal danke für die schnelle Antwort.

    Verstehen tu ichs aber leider nich so ganz :(

    Ich poste mein Problem einfach einmal etwas ausführlicher, vll hab ich ja schon im Ansazt alles falsch gemacht ? ;)


    Also: ich erstelle neue Einträge in der Liste über eine InputBox.
    Dafür ist eine eigene Funktion definiert:#

    [autoit]

    Func NewAdressBook ()
    ;Name einlesen
    $New_Adress_Book_Name = GUICtrlRead($Input_Name_NewAdressBook)

    [/autoit][autoit][/autoit][autoit]

    ;Letzen Counter einlesen
    $Counter_Old = FileRead(@scriptdir & "\Data\Counter.txt")

    [/autoit][autoit][/autoit][autoit]

    ;Neuen Counter berechnen (+1)
    $Counter_New = $Counter_Old + 1

    [/autoit][autoit][/autoit][autoit]

    ;Counter wieder in Datei schreiben
    FileDelete(@scriptdir & "\Data\Counter.txt")
    FileWrite(@scriptdir & "\Data\Counter.txt", $Counter_New)

    [/autoit][autoit][/autoit][autoit]

    ;Verzeichnis für neues Adressbuch erstellen
    DirCreate(@scriptdir & "\Data\AdressBooks\AB_" & $Counter_New)

    [/autoit][autoit][/autoit][autoit]

    ;Namen in Datei speichern
    FileWrite(@scriptdir & "\Data\AdressBooks\AB_" & $Counter_New & "\Name.txt" , $New_Adress_Book_Name)

    [/autoit][autoit][/autoit][autoit]

    ;In List View Eintragen
    Global $ListViewEntry = GUICtrlCreateListViewItem($New_Adress_Book_Name, $ListView_Adressbuecher)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;GUI schließen
    GUIDelete("Neues Adressbuch")

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit]

    Die Daten werden aus einer GUI ausgelesen, die in einer anderen Function definiert wurde.
    Funktioniert auch alles wunderbar. Wenn das Programm neu gestartet wird lese ich die Daten wie
    gesagt mit einer Schleife in ein Array ein.

    [autoit]

    ;Alle Infos in ein Array einlesen
    ;Counter einlesen (Anzahl einträge)
    $counter2 = FileRead(@scriptdir & "\Data\Counter.txt")
    $i = 0
    ;Array für Einträge erstellen
    Global $ListView[1000]

    [/autoit][autoit][/autoit][autoit]

    ;Einlesen solange bis counter erreicht
    While($i <= $counter2)

    [/autoit][autoit][/autoit][autoit]

    $ListView[$i] = FileRead(@scriptdir & "\Data\AdressBooks\AB_" & $i & "\Name.txt")
    $i = $i + 1

    [/autoit][autoit][/autoit][autoit]

    WEnd

    [/autoit]

    Als nächstes trage ich sie mit einer ähnlichen Schleife in Die ListView ein:

    [autoit]

    ;In ListView eintragen
    $i2 = 0
    Global $ListView2[1000] ;bis zu 1000 Einträge möglich
    While($i2 <= $counter2)
    $ListView2[1] = GUICtrlCreateListViewItem($ListView[$i2], $ListView_Adressbuecher)
    $i2 = $i2 + 1
    WEnd

    [/autoit]

    Soweit sogut: Die EInträge erscheinen wie beabsichtigt auch nach neuem Programmstart in der ListView.

    Nun soll sich aber bei einem Klick auf einen ListView-Eintrag ein Fenster mit Infos usw. öffnen. Nun komme
    ich einfach nicht darauf, wie ich den einzelnen Einträgen Funktionen zuweisen kann . . . . wobei ja auch noch erkannt werden muss, welcher EIntrag benötigt wird . . .

    Wie soll ich das mit GUI-Read und einer "For-Schleife" bewerkstelligen ?

    Mfg *mow*

  • wenn ich das richtig verstanden habe, dann in etwa so

    Spoiler anzeigen
    [autoit][/autoit] [autoit][/autoit] [autoit]

    ...

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    [/autoit] [autoit][/autoit] [autoit]

    ...

    [/autoit] [autoit][/autoit] [autoit]

    ;checks double-click on listviewitem
    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $ListView1
    If Not IsHWnd($ListView1) Then $hWndListView = GUICtrlGetHandle($ListView1)

    [/autoit] [autoit][/autoit] [autoit]

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
    Case $hWndListView
    Switch $iCode
    Case $LVN_COLUMNCLICK ; A column was clicked
    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
    _GUICtrlListView_SimpleSort ($hWndListView, $B_DESCENDING, DllStructGetData($tInfo, "SubItem"))
    Case $NM_DBLCLK ; Sent by a list-view control when the user double-clicks an item with the left mouse button
    If IniRead($ini, "Settings", "Action for double-click on Item", "4") = 1 Then
    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    $Window = _GUICtrlListView_GetItemText($hWndFrom, DllStructGetData($tInfo, "Index"), 1)
    Select
    Case $DoubleAction = "do Nothing"
    Case $DoubleAction = "Show/Hide Window"
    _WindowHide($Window)
    Case $DoubleAction = "Set on Top/Back"
    _ToggleTop($Window)
    Case $DoubleAction = "Set Trans/ Back"
    _ToogleTrans($Window)
    Case $DoubleAction = "Set TTI/Back"
    _WindowTransNoClick($Window)
    Case $DoubleAction = "Move to Tray/Back"
    _WindowTray($Window)
    Case Else
    EndSelect
    EndIf
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

    [/autoit]

    ist ein teil aus einem meiner scripte, wenn du das ganz sehen willst, guck mal in den thread (https://autoit.de/index.php?page…action=firstNew)

    bei mir wird quasi 1 von 5 funktionen bei einem doppelklick ausgeführt. welche funktion, ist im gui festgelegt. wenn bei dir immer das gleiche passieren soll, kannst dir das
    select case natürlich sparen und da einfach deine funktion reinhauen.

    PS: funktion wird in "_GUICtrlListView_Create" in der hilfe erklärt.

  • Hi,

    Mein größtes Problem ist ja eingentlich, das immer wieder neue Einträge in die ListView hinzugefügt werden.
    Wüßte ich die Anzahl, könnte ich ja einfach fest definieren: Listvieweintrag 1 -->Function 1 usw.


    Aber es kommen ja immer wieder neue einträge hinzu UND: Es werden bei jedem Eintrag andere Informationen geladen, was sich aber mit einer Funktion machen lassen müsste oder ?


    Natürlich könnte ich pauschal einfach mal 200 Einträgen eine Funktion zuweisen, was aber höchst unsauber wäre und früher oder Später zwangsläufig zu Problemen führt^^, und irgendwie muss ich in der Funktion, die aufgerufen wird auch noch die Info haben, auf welchen Eintrag geklickt wurde.

    Bin jetzt auch nicht unbedingt Experte in AutoIT, deshalb habe ich auch nicht deinen kompletten Quelltext versteanden.

    danke für die antworten, erstaunt mich immer wieder wie schnell einem hier geantwortet wird =)

    gruß

    *mow*

    • Offizieller Beitrag

    Hier mal eine modifizierte Form der "WM_NOTIFY".
    Alle notwendigen Infos bekommst du als Array aus der jeweiligen Funktion zurückgegeben und kannst diese auswerten.
    Hier im Bsp. wird dir bei Mausklick auf ein ListView-Element der Text dieses Elements (also z.B. aus Spalte2, Zeile5) wiedergegeben.
    Kannst du dann ja beliebig weiterverarbeiten.

    Aber Frage am Rande: Warum verwendest du keine Datenbank für Adressbücher? SQLite bietet sich da an und hat gute AutoIt-Unterstützung.

    Spoiler anzeigen
    [autoit]

    #include<GUIConstantsEx.au3>
    #include<WindowsConstants.au3>
    #include <GUIListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $gui = GUICreate('test')
    $hListView = GUICtrlCreateListView('Spalte1|Spalte2', 10, 10, 300, 200)
    _GUICtrlListView_SetColumnWidth($hListView, 0, 146)
    _GUICtrlListView_SetColumnWidth($hListView, 1, $LVSCW_AUTOSIZE_USEHEADER)
    For $i = 1 To 10
    GUICtrlCreateListViewItem('Zeile ' & $i & ' Spalte 1|Zeile ' & $i & ' Spalte 2', $hListView)
    Next
    GUISetState()
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    Do
    $msg = GUIGetMsg()
    Until $msg = $GUI_EVENT_CLOSE

    [/autoit] [autoit][/autoit] [autoit]

    Func _LeftClick($Info)
    MsgBox(0, 'Text in Spalte', _GUICtrlListView_GetItemText($Info[1], $Info[3], $Info[4]) )
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    [/autoit] [autoit][/autoit] [autoit]

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
    Case $hWndListView
    Switch $iCode
    Case $LVN_COLUMNCLICK ; A column was clicked
    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
    Local $aInfo[11] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "Param")]
    ;~ _ColumnClick($aInfo)
    Case $LVN_DELETEITEM ; An item is about to be deleted
    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
    Local $aInfo[11] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "Param")]
    ;~ _ItemDeleted($aInfo)
    Case $LVN_HOTTRACK ; Sent by a list-view control when the user moves the mouse over an item
    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
    Local $aInfo[11] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "Param")]
    Return 0 ; allow the list view to perform its normal track select processing.
    ;Return 1 ; the item will not be selected.
    ;~ _HottTrackItem($aInfo)
    Case $LVN_KEYDOWN ; A key has been pressed
    Local $tInfo = DllStructCreate($tagNMLVKEYDOWN, $ilParam)
    Local $aInfo[5] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "VKey"), _
    DllStructGetData($tInfo, "KeyFlags")]
    ;~ _KeyDown($aInfo)
    Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    Local $aInfo[12] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "lParam"), _
    DllStructGetData($tInfo, "KeyFlags")]
    _LeftClick($aInfo)
    Case $NM_DBLCLK ; Sent by a list-view control when the user double-clicks an item with the left mouse button
    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    Local $aInfo[12] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "lParam"), _
    DllStructGetData($tInfo, "KeyFlags")]
    ;~ _LeftDblClick($aInfo)
    Case $NM_KILLFOCUS ; The control has lost the input focus
    Local $aInfo[3] = [$hWndFrom, _
    $iIDFrom, _
    $iCode]
    ;~ _LostFocus($aInfo)
    Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    Local $aInfo[12] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "lParam"), _
    DllStructGetData($tInfo, "KeyFlags")]
    ; Return 1 ; not to allow the default processing
    Return 0 ; allow the default processing
    ;~ _RightClick($aInfo)
    Case $NM_RDBLCLK ; Sent by a list-view control when the user double-clicks an item with the right mouse button
    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    Local $aInfo[12] = [$hWndFrom, _
    $iIDFrom, _
    $iCode, _
    DllStructGetData($tInfo, "Index"), _
    DllStructGetData($tInfo, "SubItem"), _
    DllStructGetData($tInfo, "NewState"), _
    DllStructGetData($tInfo, "OldState"), _
    DllStructGetData($tInfo, "Changed"), _
    DllStructGetData($tInfo, "ActionX"), _
    DllStructGetData($tInfo, "ActionY"), _
    DllStructGetData($tInfo, "lParam"), _
    DllStructGetData($tInfo, "KeyFlags")]
    ;~ _RightDblClick($aInfo)
    Case $NM_RETURN ; The control has the input focus and that the user has pressed the ENTER key
    Local $aInfo[3] = [$hWndFrom, _
    $iIDFrom, _
    $iCode]
    ;~ _InputFocusReturn($aInfo)
    Case $NM_SETFOCUS ; The control has received the input focus
    Local $aInfo[3] = [$hWndFrom, _
    $iIDFrom, _
    $iCode]
    ;~ _SetFocus($aInfo)
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

    [/autoit]
  • also die funktion bewirkt erstmal, dass bei allen einträgen im listview, bei einem doppelklick was gemacht wird.
    also brauchst du dir um die anzahl schonmal keine gedanken machen.

    die funktion bleibt ja die gleiche, es müssen nur jeweils andere informationen angezeigt werden.
    in der funktion wird aber quasi das listviewitem, was doppelt geklickt wurde, mit übergeben. anhand davon kannst
    du dann die individuellen infos suchen.

    ich bin mir nicht sicher, aber ich glaube das einzelne item wird hierüber definiert

    [autoit]

    $Window = _GUICtrlListView_GetItemText($hWndFrom, DllStructGetData($tInfo, "Index"), 1)

    [/autoit]

    ich würde den code erstmal so in das script einbauen, meinen quatsch löschen und dann mit ner msgbox mal ausprobieren,
    was für infos zB über die funktion oben, zurückgegeben werden und wie du weiter damit arbeiten kannst.

  • Daaanke leute, habs mir jetzt mit eurer hilfe zusammengeschustert =)

    Aber gleich des nächste problem, obwohl es wahrscheinlich ganz simpel ist und ich nur zu dumm bin um es zu sehen :D

    Ich hab jetzt n Backgroundimage eingebunden.
    Auf meiner Main_GUI war vorher ein Input. Dieser erscheint nun nur noch, wenn ich mit der Maus darüber gehe, genauso der Button
    der sich neben dem Input befand. . . .

    [autoit][/autoit][autoit][/autoit][autoit]

    ...............

    [/autoit][autoit][/autoit][autoit]

    ;Buttons
    $Button_Aufrufen = GUICtrlCreateButton("aufrufen", 70, 550, 50, 20)


    ;ListViews
    Global $ListView_AllEntries = GUICtrlCreateListView(" " & $Standard_Categories[0] & " |" & " " & $Standard_Categories[1] & " |" & " " & $Standard_Categories[2] & " |" & " " & $Standard_Categories[3] & " |" & " " & $Standard_Categories[4] & " |" & " " & $Standard_Categories[5] & " |" & " " & $Standard_Categories[6] & " |" & " " & $Extra_Categories[0] & " |" & " " & $Extra_Categories[1] & " |" & " " & $Extra_Categories[2] & " |" & " " & $Extra_Categories[3] & " |" & " " & $Extra_Categories[4] & " |" , 15, 30, 995, 500)

    [/autoit][autoit][/autoit][autoit]

    ;Inputs
    Global $Input_Aufrufen = GUICtrlCreateInput("", 15, 570, 50, 20)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;HIntergrundbild
    $Backgroundimage = GUICtrlCreatePic($GUI_BackgroundImage, 0, 0, $GUI_Width, $GUI_Height)

    [/autoit]

    Hab schon einiges versucht, auch die Reihenfolge der Elemente schon getauscht usw . . . .
    Wahrscheinlich n dummer Leichtsinnsfehler, den ich ständig übersehe ?

    mfg *mow*

  • Aaaaargh bin ich blöd :D, bei der Reihenfolge falsch herum gedacht -.-, Also Stop -->Problem gelöst

    Aber danke für die Erfolgreiche Hilfe bei meinem "ListView" - Problem =)

    mfg *mow*