Wie bekomme ich das Item(Handle) eines TreeView Items innerhalb von WM_NOTIFY heraus.

    • Offizieller Beitrag

    Hi.
    Ich will die Message $NM_CLICK und $NM_DBLCLK auswerten, habe dabei aber das Problem, das ich nicht weis, wie ich an das Item herankommen soll.

    Spoiler anzeigen
    [autoit]

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

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

    Global $g_hTreeView

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

    Example()

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

    Func Example()
    Local $hGUI, $hItem
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
    $hGUI = GUICreate("(UDF Created) TreeView Create", 400, 300)

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

    $g_hTreeView = _GUICtrlTreeView_Create($hGUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState(@SW_SHOW)

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

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

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

    _GUICtrlTreeView_BeginUpdate($g_hTreeView)
    For $x = 1 To Random(2, 10, 1)
    $hItem = _GUICtrlTreeView_Add($g_hTreeView, 0, StringFormat("[%02d] New Item", $x))
    For $y = 1 To Random(2, 10, 1)
    _GUICtrlTreeView_AddChild($g_hTreeView, $hItem, StringFormat("[%02d] New Child", $y))
    Next
    Next
    _GUICtrlTreeView_EndUpdate($g_hTreeView)

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

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
    EndFunc ;==>Example

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

    Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview
    $hWndTreeview = $g_hTreeView
    If Not IsHWnd($g_hTreeView) Then $hWndTreeview = GUICtrlGetHandle($g_hTreeView)

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

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
    Case $hWndTreeview
    Switch $iCode
    Case $NM_CLICK ; The user has clicked the left mouse button within the control
    _DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
    "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
    "-->Code:" & @TAB & $iCode)
    ; Return 1 ; nonzero to not allow the default processing
    Return 0 ; zero to allow the default processing
    Case $NM_DBLCLK ; The user has double-clicked the left mouse button within the control
    _DebugPrint("$NM_DBLCLK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
    "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
    "-->Code:" & @TAB & $iCode)
    ; Return 1 ; nonzero to not allow the default processing
    Return 0 ; zero to allow the default processing
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

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

    Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber)
    ConsoleWrite( _
    "!===========================================================" & @CRLF & _
    "+======================================================" & @CRLF & _
    "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _
    "+======================================================" & @CRLF)
    EndFunc ;==>_DebugPrint

    [/autoit]

    Eigentlich sollte in $tagNMHDR unter IDFrom die ITEMID stehen, aber es wird immer nur 10000 zurückgeliefert, egal welches Item man anklickt.
    Hab jetzt versucht es mittels _GUICtrlTreeView_GetSelection hinzubekommen, funzt aber auch nicht, weil $NM_CLICK vor dem Wechsel des slektiertem Items abgefeuert wird.
    Hat wer eine Idee?

    • Offizieller Beitrag

    Also IDFrom ist die ControlID das Controls in dem Fall 10000 für das TreeView.
    Habe jetzt ein wenig die Message NM_SETCURSOR mißbraucht um das Item unter dem Mauscursor zurückzubekommen.
    Das Item unter dem Mauszeiger wird in einer Static Variable gespeichert und kann somit bei $NM_CLICK und $NM_DBLCLK ausgewertet werden.
    So sieht meine Lösung aus, vielleicht kann sie jemand gebrauchen:

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
    #include <GuiConstantsEx.au3>
    #include <GuiTreeView.au3>
    #include <WindowsConstants.au3>

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

    Opt('MustDeclareVars', 1)

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

    $Debug_TV = False ; Check ClassName being passed to functions, set to True and use a handle to another control to see it work

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

    Global $hTreeView

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

    _Main()

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

    Func _Main()

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

    Local $GUI, $hItem
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
    $GUI = GUICreate("(UDF Created) TreeView Create", 400, 300)

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

    $hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState()

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

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

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

    _GUICtrlTreeView_BeginUpdate($hTreeView)
    For $x = 1 To Random(2, 10, 1)
    $hItem = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x))
    For $y = 1 To Random(2, 10, 1)
    _GUICtrlTreeView_AddChild($hTreeView, $hItem, StringFormat("[%02d] New Child", $y))
    Next
    Next
    _GUICtrlTreeView_EndUpdate($hTreeView)

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

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

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

    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local Static $iItemSel
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)

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

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = hwnd(DllStructGetData($tNMHDR, "IDFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
    Case $hWndTreeview
    Switch $iCode
    Case $NM_CLICK ; The user has clicked the left mouse button within the control
    If $iItemSel Then ;Wenn $iItemSel ungleich 0 ist, wurde der Klick auf einem Item ausgeführt
    _DebugPrint("$NM_CLICK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
    "-->IDFrom:" & @TAB & $iItemSel & @LF & _
    "-->ItemText:" & @TAB & _GUICtrlTreeView_GetText ( $hWndFrom, $iItemSel ))
    EndIf
    ConsoleWrite($iIDFRom & @CRLF)
    Return 0 ; zero to allow the default processing
    Case $NM_DBLCLK ; The user has double-clicked the left mouse button within the control
    If $iItemSel Then;Wenn $iItemSel ungleich 0 ist, wurde der Klick auf einem Item ausgeführt
    _DebugPrint("$NM_DBLCLK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
    "-->IDFrom:" & @TAB & $iItemSel & @LF & _
    "-->Code:" & @TAB & _GUICtrlTreeView_GetText ( $hWndFrom, $iItemSel ))
    EndIF
    Return 0 ; zero to allow the default processing
    Case $NM_SETCURSOR
    Local $tinfo = DllStructCreate($tagNMMOUSE, $ilParam)
    Local $ItemSpec =DllStructGetData($tinfo, "ItemSpec")
    IF $ItemSpec <> "" THen
    $iItemSel = $ItemSpec; Maus ist auf einem Item
    Else
    $iItemSel = 0; Maus befindet sich nicht auf einem Item
    EndIf

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

    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

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

    Func _DebugPrint($s_text, $line = @ScriptLineNumber)
    ConsoleWrite( _
    "!===========================================================" & @LF & _
    "+======================================================" & @LF & _
    "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
    "+======================================================" & @LF)
    EndFunc ;==>_DebugPrint

    [/autoit]

    Btw, ist meine Methode sogar präziser als die normale Auswertung, es wird nur ausgewertet, wenn die Maus auf dem Item ist.
    $NM_CLICK usw wird auch gefeuert wenn irgendwo im TreeView Fenster geklickt wird.

    • Offizieller Beitrag

    Ich hatte nach so etwas gesucht. Habe jetzt eine bessere Variante gefunden, die tatsächlich zur Zeit des Klicks das Item ermittelt. Was mir nicht gefällt, ist die Tatsache, dass jeder Klick in der Zeile des Item als Item-Klick gewertet wird. Also auch Klicks auf Ein/Ausklappsymbol und Chekcbox.

    Aber sonst ganz brauchbar:

    Edit:
    Ich habe die Funktion jetzt erweitert.
    Nun kann auch zurückgegeben werden, ob Klick auf Node, Checkbox oder Text (Ergebnis Hittest)

    • Offizieller Beitrag

    @Bitnugger
    Hast du Recht, war noch nicht "durchkomponiert" ^^ - so ist es vollständig: