Popup Menü auf Listvieweintrag

  • Hi allz,

    ich hab mir das Beispiel zum Befehl _GUICtrlMenu_CreatePopup aus der AutoIt Hilfe ein wenig angepasst, indem ich der GUI noch ein Listview hinzu gefügt habe. :)

    Wenn man mit rechts auf die GUI clickt und einen Eintrag auswählt klappt alles.
    Was nicht klappt ist der Rechtsclick auf das Listview. Das Popupmenü wird zwar angezeigt, aber wenn man einen Eintrag des Menüs auswählt, wird so wie es aussieht die Func WM_COMMAND nicht aufgerufen.
    Woran liegt das? ?(

    Hat jemand eine Idee oder muß man dass komplett anders machen??

    Thx

    cu Ari

    Mein Code:

    Spoiler anzeigen
    [autoit]

    #include <GuiMenu.au3>
    #include <GuiConstantsEx.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <ListViewConstants.au3>

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

    Opt('MustDeclareVars', 1)

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

    Global Enum $idOpen = 1000, $idSave, $idInfo
    Local $List

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

    _Main()

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

    Func _Main()
    Local $hGUI

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

    ; Create GUI
    $hGUI = GUICreate("Menu", 400, 300)
    $List = GUICtrlCreateListView("1|2", 30, 20, 341, 241)
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 50)
    GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 50)
    GUICtrlCreateListViewItem("1|1.1", $List)
    GUICtrlCreateListViewItem("2|2.1", $List)

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

    GUISetState()

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

    ; Register message handlers
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")

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

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    EndFunc ;==>_Main

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

    ; Handle WM_COMMAND messages
    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    Switch $iwParam
    Case $idOpen
    _WinAPI_ShowMsg ("Open")
    Case $idSave
    _WinAPI_ShowMsg ("Save")
    Case $idInfo
    _WinAPI_ShowMsg ("Info")
    EndSwitch
    EndFunc ;==>WM_COMMAND

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

    ; Handle WM_CONTEXTMENU messages
    Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hMenu;, $hWndFrom = $iwParam

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

    ;If GUICtrlGetHandle($List) = $hWndFrom Then
    $hMenu = _GUICtrlMenu_CreatePopup ()
    _GUICtrlMenu_InsertMenuItem ($hMenu, 0, "Open", $idOpen)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 1, "Save", $idSave)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 3, "", 0)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 3, "Info", $idInfo)
    _GUICtrlMenu_TrackPopupMenu ($hMenu, $iwParam)
    _GUICtrlMenu_DestroyMenu ($hMenu)
    Return True
    ;EndIf
    EndFunc ;==>WM_CONTEXTMENU

    [/autoit]

    Einmal editiert, zuletzt von ari (30. November 2008 um 13:40)

  • Moin ari,

    schön dich mal wieder im Netz zu sehen ...

    In WM_COMMAND besteht wParam aus zwei Werten: das höherwertige (16bit)Wort enthält bei einem Menü Null, das niederwertige (16bit)Wort enthält die ID des Menü(element)s.
    WM_COMMAND

    So sollte es gehen.

    Spoiler anzeigen
    [autoit]

    ; Handle WM_COMMAND messages
    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)

    Switch LOWORD($iwParam)
    Case $idOpen
    _WinAPI_ShowMsg ("Open")
    Case $idSave
    _WinAPI_ShowMsg ("Save")
    Case $idInfo
    _WinAPI_ShowMsg ("Info")
    EndSwitch
    EndFunc ;==>WM_COMMAND

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

    Func LOWORD ($DWORD)
    Return BitAND($DWORD, 0xFFFF)
    EndFunc

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

    Func HIWORD ($DWORD)
    Return BitShift($DWORD, 16)
    EndFunc

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


    Die IDs der Steuerelemente würde ich als Global deklarieren. ;)

    EDIT:
    Ich habe noch einmal nachgesehen ...
    Du solltest es mal mit WM_MENUCOMMAND versuchen ...


    LG
    Greenhorn


    2 Mal editiert, zuletzt von Greenhorn (30. November 2008 um 13:44)

  • thx Greenhorn,

    leider funzt das auch nicht.

    ich hab in d. WM_COMMAND jetzt mal nen ConsoleWrite("...") mit eingetragen (als 1. Befehl). Nicht mal der wird ausgeführt beim Rechtsclick auf die Liste.
    Beim Rechtsclick auf die GUI wird der Text in die Console geschrieben.

    Zitat von Greenhorn

    Die IDs der Steuerelemente würde ich als Global deklarieren. ;)

    Das hab ich auch gerade hier gelesen, nur noch nicht verstanden warum. Ich bin immer davon ausgegangen, dass man das nur machen muß, wenn man in einer UDF deklariert, damit man nach dem includen auf die Variablen zugreifen kann.
    Wenn ich aber in einer v. mir selbst erstellten *au3 am Anfang alles LOCAL deklariere gelten die Variablen dann ja in allen Funktionen etc.
    Deswegen verstehe den Sinn noch nicht ganz. :(

    • Offizieller Beitrag

    am Anfang alles LOCAL deklariere gelten die Variablen dann ja in allen Funktionen etc.


    Das ist ein Irrtum. Lokale Variablen des Mainprogrammes sind nur von diesem lesbar. Sollen auch im Skript erstellte Funktionen auf die Variablen zugreifen, müssen sie mit Dim oder Global deklariert werden. Da Dim eine nicht eindeutige Position einnimmt, verwende ich lieber Global mit eindeutigen Variablennamen, die mit großer Wahrscheinlichkeit von anderen laufenden Programmen nicht genutzt werden.


  • Das ist ein Irrtum. Lokale Variablen des Mainprogrammes sind nur von diesem lesbar. Sollen auch im Skript erstellte Funktionen auf die Variablen zugreifen, müssen sie mit Dim oder Global deklariert werden. Da Dim eine nicht eindeutige Position einnimmt, verwende ich lieber Global mit eindeutigen Variablennamen, die mit großer Wahrscheinlichkeit von anderen laufenden Programmen nicht genutzt werden.

    Ich weiß zwar nicht genau, ob ihr das so meint, aber so wie ich es gedacht hab, funzt es, auch wenn man die Variable LOCAL deklariert.
    Man kann in der Func auf die Variable bzw. deren Inhalt zugreifen.

    [autoit]

    AutoItSetOption("MustDeclareVars", 1)

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

    Local $sTest = "Das ist ein Test"

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

    _TestFunc()

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

    Func _TestFunc()
    MsgBox(4096, "nix", $sTest)
    EndFunc

    [/autoit]

    Greenhorn,

    ich hab deinen Edit zu spät gelesen, ich krieg das auch nicht mit WM_MENUCOMMAND hin.

    falls mal jemand ein funktionierendes Beispiel für mich hat, wäre ich sehr dankbar.
    Ich meld mich später aus'm Zug ich muß jetzt packen.

    Cu Ari

  • So, ich hab's hinbekommen ...

    Spoiler anzeigen
    [autoit]


    #include <GuiMenu.au3>
    #include <WinAPI.au3>
    #include <ListViewConstants.au3>

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

    Opt ('MustDeclareVars', 1)

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

    Global $IDC_LIST
    Global Enum $IDM_OPEN = 40000, _
    $IDM_SAVE, _
    $IDM_INFO

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

    _Main ()

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

    Func _Main ( )

    Local $hGUI

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

    ; Create GUI
    $hGUI = GUICreate ("Menu", 400, 300)
    $IDC_LIST = GUICtrlCreateListView ("1|2", 30, 20, 341, 241)
    GUICtrlSendMsg ($IDC_LIST, $LVM_SETCOLUMNWIDTH, 0, 50)
    GUICtrlSendMsg ($IDC_LIST, $LVM_SETCOLUMNWIDTH, 1, 50)
    GUICtrlCreateListViewItem ("1|1.1", $IDC_LIST)
    GUICtrlCreateListViewItem ("2|2.1", $IDC_LIST)

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

    GUISetState ()

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

    ; Register message handlers
    GUIRegisterMsg ($WM_COMMAND , "WM_COMMAND")
    GUIRegisterMsg ($WM_CONTEXTMENU, "WM_CONTEXTMENU")

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

    ; Loop until user exits
    Do
    Until GUIGetMsg ( ) = $GUI_EVENT_CLOSE

    Return 0

    EndFunc ;==>_Main

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

    ; Handle WM_CONTEXTMENU messages
    Func WM_CONTEXTMENU ($hWnd, $iMsg, $iwParam, $ilParam)

    Local $hMenu
    ; ConsoleWrite ('hwnd = ' & $hWnd &@crlf) ; ... unser Fenster hGUI.
    ; ConsoleWrite ('hwndContrl = ' & $iwParam &@crlf) ; Fensterhandle des Steuerelements auf das geklickt wurde.
    ; ConsoleWrite ('xPos Mouse = ' & LOWORD($ilParam) &@crlf)
    ; ConsoleWrite ('yPos Mouse = ' & HIWORD($ilParam) &@crlf)

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

    $hMenu = _GUICtrlMenu_CreatePopup ()
    _GUICtrlMenu_InsertMenuItem ($hMenu, 0, "Open", $IDM_OPEN)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 1, "Save", $IDM_SAVE)
    _GUICtrlMenu_InsertMenuItem ($hMenu, 3, "" , 0) ; Separator
    _GUICtrlMenu_InsertMenuItem ($hMenu, 4, "Info", $IDM_INFO)
    ; Der Eigentümer des Menüs muß dein Hauptfenster sein.
    ; Wenn Du wParam einsetzt ist das jeweilige Steuerelement
    ; der Eigentümer des Menüs und somit wird die WM_COMMAND
    ; an das Steuerelement gesendet und nicht an unsere Fensterprozedur
    _GUICtrlMenu_TrackPopupMenu ($hMenu, $hWnd) ; ... hier war der Hund begraben.

    _GUICtrlMenu_DestroyMenu ($hMenu)

    Return True

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

    EndFunc ;==>WM_CONTEXTMENU

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

    ; Handle WM_COMMAND messages
    Func WM_COMMAND ($hWnd, $iMsg, $iwParam, $ilParam)
    ; ConsoleWrite ('hwnd = ' & $hWnd &@crlf) ; ... unser Fenster hGUI.
    ; ConsoleWrite ('ID = ' & LOWORD($iwParam) &@crlf) ; ID des Steuerelements/Abkürzungsbefehls
    ; ConsoleWrite ('0 bei Menü = ' & HIWORD($iwParam) &@crlf) ; Steuerelement-spezifischer Wert
    ; ConsoleWrite ('0 bei Menü = ' & $ilParam &@crlf) ; Steuerelement-spezifischer Wert

    Switch LOWORD($iwParam)
    Case $IDM_OPEN
    _WinAPI_ShowMsg ("Open")
    Case $IDM_SAVE
    _WinAPI_ShowMsg ("Save")
    Case $IDM_INFO
    _WinAPI_ShowMsg ("Info")
    EndSwitch
    EndFunc ;==>WM_COMMAND

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

    Func LOWORD ($DWORD)
    Return BitAND($DWORD, 0xFFFF)
    EndFunc

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

    Func HIWORD ($DWORD)
    Return BitShift($DWORD, 16)
    EndFunc

    [/autoit]


    Außerdem hatten deine IDs für die Subelemente des Kontextmenüs keinen Wert !
    Bei InsertMenuItem () wird die ID nicht wie bei den GUICtrl... () Funktionen automatisch gesetzt und zurückgegeben, sondern Du musst den Identifizierer selbst bestimmen. ;)
    AutoIt verwöhnt einen zu sehr ... :D


    LG
    Greenhorn


    5 Mal editiert, zuletzt von Greenhorn (30. November 2008 um 20:40)

    • Offizieller Beitrag


    Man kann in der Func auf die Variable bzw. deren Inhalt zugreifen.

    [autoit]

    AutoItSetOption("MustDeclareVars", 1)

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

    Local $sTest = "Das ist ein Test"

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

    _TestFunc()

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

    Func _TestFunc()
    MsgBox(4096, "nix", $sTest)
    EndFunc

    [/autoit]

    Äh?! Das funktioniert ja tatsächlich! Seit wann geht das denn? Das ist doch ein Bug! :wacko: