MenuItems auf ListViewItems

  • Habe folgendes Problem:

    Ich habe eine ListView mit mehreren Items erstellt und jetzt möchte ich für jedes ListViewItem mehrere MenuItems erzeugen, die bei einem Click etwas bestimmtes aufrufen.

    Also habe ich mir eine Funktion GUICreateItemMenu($Item) geschrieben, die als Übergabewert das ListViewItem bekommt. Klappt auch alles wunderbar soweit, bloß nun will ich ja, dass bei einem Click etwas ausgeführt wird. Mit GUIOnEventMode wäre das kein Problem, aber das möchte ich vermeiden.

    Kann mir da einer weiterhelfen?

    • Offizieller Beitrag

    Hallo!

    Zeig vielleicht mal ein bisschen Code. Möglicherweise solltest du die IDs in einem (2-dim) Array speichern, dann kann man in der While-Schleife daraufhin prüfen. Das würde man dann mit For-Schleife oder dergleichen machen, denke ich.
    Kann aber auch sein, dass ich dich komplett falsch verstanden habe :schild4:

    Hoffen wir es mal nicht ;)

    peethebee

  • Hallo nochmal,

    ganz vergessen, das ich diesen Post mal eröffnet habe, auf jedenfall muss ich grade wieder etwas mit Kontextmenüs in ListViews machen und frage mich, wie ich das mit dem MessageLoop-Modus realisieren kann.

    Der Funktion _GUICreateClientContext übergebe ich den ItemIndex der ListView!

    Hier ein wenig Code:

    Code
    Func _GUICreateClientContext($clientid)
    	Local $clientcontext, $pingcmitem, $rdpcmitem
    
    
    	$clientcontext = GUICtrlCreateContextMenu($clientid)
    	$pingcmitem = GUICtrlCreateMenuitem("Ping", $clientcontext, 1, 0)
    	$rdpcmitem = GUICtrlCreateMenuitem("RDP", $clientcontext, 2, 0)

    Drauf zugreifen möchte ich nun aus meine GUI-While-Schleife, folgendes klappt aber (logischerweise) nicht:

    Code
    Case $msg[0] == $pingcmitem
    		_PingClient($clientid)


    Wie PeeTheBee bereits erwähnte muss ich irgendwie ein zweidimensionales Array erschaffen, dass die ClientID mit der jeweiligen MenuItemID verbinde.

    Ich weiß bloß nicht, wie ich das realisieren kann!

    Wie immer für jeden Vorschlag zu haben!

  • Dim clientcontext[20][20]
    Dim pingcmitem[20][20]
    Dim rdpcmitem[20][20]

    Global $IpAdresse = "192.168.6."

    Func _GUICreateClientContext($clientid)


    $clientcontext[1][$clientid] = GUICtrlCreateContextMenu($IpAdresse&$clientid)

    Case $msg[0] == $pingcmitem
    _PingClient($ipAdresse&$clientid)

  • Ähh ja, sowas in der RIchtung schwebte mir auch vor. Folgendes Testbeispiel:

    Jedesmal, wenn ein Item erzeugt wird, soll ein Contexmenü mit einer eindeutigen ID erstellt werden. Das klappt auch schon mal nicht.
    Doof ist auch, dass die MenuItems global deklariert werden müssen, da ich diese in der While 1-GUI Schleife abfragen muss.

    Irgendwie bereitet mir das momentan doch leichte Probleme.

  • Hi again,

    das Thema hier lässt mir keine Ruhe. Habe jetzt mal folgendes probiert:

    [autoit]


    Local $maxclients = 256
    Local $clientarray[$maxclients]
    Local $clientcontext[$maxclients]
    Local $pingcmitem[$maxclients]
    Local $rdpcmitem[$maxclients]
    Local $clientindex = 0

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

    $clientlistview = GUICtrlCreateListView("Status|Hostname|IP-Address", 10, 30, 780, 400, $LVS_NOSORTHEADER + $LVS_SHOWSELALWAYS, $LVS_EX_FULLROWSELECT + $LVS_EX_SUBITEMIMAGES)
    $clientarray[$clientindex] = GUICtrlCreateListViewItem("Icon|Test1|192.168.0.1, $clientlistview)

    $clientcontext[$clientindex] = GUICtrlCreateContextMenu($clientarray[$clientindex])

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

    $pingcmitem[$clientindex] = GUICtrlCreateMenuitem("Ping", $clientcontext[$clientindex], 1, 0)
    $rdpcmitem[$clientindex] = GUICtrlCreateMenuitem("RDP", $clientcontext[$clientindex], 2, 0)

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

    While 1
    $msg = GUIGetMsg(1)
    For $i = 1 To $pingcmitem[0] Step 1
    If $msg[0] == $pingcmitem[$i] Then
    _GetSelectionAndCallFunc("_PingClient")
    EndIf
    Next
    WEnd

    [/autoit]

    Jedes MenuItem ist somit eindeutig identifizierbar (z.B. $pingcmitem[0] = 4167, wobei 4167 der control-identifier ist). Wie frage ich dieses aber nun in der GUI-While-Schleife ab? Der obige Versuch bricht in der Zeile

    [autoit]

    If $msg[0] == $pingcmitem[$i] Then

    [/autoit]

    mit der Fehlermeldung ab, dass das Skript ausserhalb des Arrays läuft. Hier gibt es doch sicherlich eine Möglichkeit das Ganze abzufangen, oder nicht?

    Alternativ wäre mir auch damit geholfen, dass es eine Möglichkeit gibt, das beim Rechtsclicken auf die ListView überprüft wird, ob ein ListViewItem darunter liegt. Das Kontextmenü darf dann nur gezeigt werden, wenn dies der Fall ist. Beim clicken auf eine leere Stelle der ListView dürfte KEIN KontextMenü erscheinen. Lässt sich dies irgendwie realisieren=

    Dies sind die beiden Dinge die mir einfallen, weil es so doch etwas unglücklich ist!

    MFG

    PS: Sry, hab bisher gar nicht gesehen, dass es hier einen Extra-Tag für AutoIt-Code gibt. Bisher immer den normalen [CODE]-Tag genommen.

  • Hi,

    hab letztens doch noch die Kurve gekriegt. ^^

    Musste aber einen Workaround anwenden, da mir wie gesagt zwar die Erschaffung des/der jeweiligen Menu/MenuItems für jedes ListViewItem gelang, nicht aber die Abfrage dieser im Falle eines Clicks.

    Hier nun (die nicht ganz perfekte Lösung):

    [autoit]

    Local $clientundercursor = -1
    Local $contextenabled = False

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

    [...]

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

    While 1
    [...]

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

    $clientundercursor = _GUICtrlListViewGetHotItem($clientlistview)
    If $clientundercursor == -1 And $contextenabled == True Then
    GUICtrlDelete($clientcontext)
    $contextenabled = False
    ElseIf $clientundercursor <> -1 And $contextenabled == False Then
    _GUICreateClientContext()
    $contextenabled = True
    EndIf
    WEnd

    [/autoit]

    Ich prüfe die ganze Zeit über, ob sich ein ListViewItem unter dem Cursor befindet. Ist dies nicht der Fall (-1), dann wird das komplette ContextMenu gelöscht. Befindet sich jedoch ein ListViewItem unter dem Cursor so wird das ContextMenu einfach neu erstellt.

    Somit habe ich nur ein ContextMenu, kann aber trotzdem alle ListViewItems anwählen, da ich über die ContextMenuItems die ID des ListViewItems auslese und damit weiter mache.

    Einziger Nachteil dabei ist folgender:

    Klickt man direkt mit der rechten Maustaste (aus dem geöffneten ContextMenu heraus) auf eine Stelle der ListView ohne ListViewItem so erscheint das ContextMenu trotzdem, da die Abfrage dies nicht berücksichtigt.

    Einmal editiert, zuletzt von teh_hahn (27. März 2007 um 19:14)