Treeview - $NM_CLICK hängt nach

  • Hallo zusammen,

    ich habe schon einige male mit WM_NOTIFY etc gearbeitet allerdings will mir nun bei einem Script das klicken auf die Treeview nicht wie ich. Ich habe eine Treeview:
    A
    |-B
    |-D
    |-C

    Ich lasse mir nun in der Console ausgeben was angeklickt ist, und beim ersten Klick egal wohin wird immer A gesagt, folgend hängt der dann einen click zurück. Sprich bei Klick zwei zeigt er dann das was er bei dem ersten Klick zeigen sollte ...

    [autoit]

    Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iCode, $tNMHDR, $i_idOld, $idFrom, $tNMTOOLBAR, $tNMTBHOTITEM, $hSelected

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

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $idFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

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

    Switch $hWndFrom
    Case $hToolbar
    Switch $iCode
    Case $NM_CLICK
    $tNMTBHOTITEM = DllStructCreate($tagNMTBHOTITEM, $ilParam)
    $i_idOld = DllStructGetData($tNMTBHOTITEM, "idOld")
    Switch $i_idOld
    Case $hToolbarButtonConfigWizzard
    If $fConfigWizzardActive = True Then
    $fConfigWizzardActive = False
    _CloseConfigWizzard()
    Else
    $fConfigWizzardActive = True
    _OpenConfigWizzard()
    EndIf
    EndSwitch
    EndSwitch

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

    Case $hTreeview
    Switch $iCode
    Case $NM_CLICK
    If $fConfigWizzardActive = True Then _ConfigWizzard_FillInputs()
    Case $NM_RCLICK
    If $fConfigWizzardActive = True Then
    Local $tPoint = _WinAPI_GetMousePos(True, $hWndFrom)
    Local $tHitTest

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

    $tHitTest = _GUICtrlTreeView_HitTestEx($hWndFrom, DllStructGetData($tPoint, 1), DllStructGetData($tPoint, 2))
    If BitAND(DllStructGetData($tHitTest, "Flags"), $TVHT_ONITEM) Then
    _GUICtrlTreeView_SelectItem($hWndFrom, DllStructGetData($tHitTest, 'Item'))
    EndIf
    EndIf
    EndSwitch
    EndSwitch

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

    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_NOTIFY

    [/autoit]

    ich nutze noch ein WM_COMMAND, aber eig. sollte sich das doch nicht in die Quere kommen, oder?

    [autoit]


    Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Switch $wParam ; See if it comes from one of the inputs
    Case $hCWButtonAddProg
    _ConfigWizzard_AddProgram()
    Case $hCWButtonDelProg
    _ConfigWizzard_DelProgram()
    Case $hCWButtonEditProg
    _ConfigWizzard_EditProgram()
    EndSwitch
    EndFunc ;==>WM_COMMAND

    [/autoit]

    Hoffe mir kann jemand helfen.

    So Far

    Grüße Yaerox

    Grüne Hölle

    Einmal editiert, zuletzt von Yaerox (17. Juni 2013 um 14:03)

  • Ich denke mal dein Problem ist dass das Click Event ausgelöst wird bevor das neue Item markiert wird.
    D.h. wenn du in deiner _ConfigWizzard_FillInputs Funktion das ausgewählte Item abfrägst wird noch das alte Item als als Ergebnis geliefert.

    Gibt es einen Grund warum du das ganze über WM_Notify machst? Warum nicht einfach ein normales Event per GUIGetMsg bzw Guictrlsetonevent?

  • Ich nutze in meinem Programm den GUIOnEvent Modus, allerdings ist es mir neu, dass ich so klicks auf die Treeview abfangen kann ... habe Toolbars/Listviews/Treeviews bisher immer über NOTIFY gemacht ^^

    Ich habe das auch schon mit zig anderen Scripten verglichen, ich sehe keinen Unterschied wieso ich bei diesem 2x clicken muss ...

    Grüße Yaerox

    Grüne Hölle

  • Du willst doch nicht den Klick auf die Treeview abfangen sondern den Klick auf ein Treeviewitem oder?
    Und da würde ich wie gesagt mit Guictrlsetonevent arbeiten. Dafür gibts die Funktion ja. Und mit den Makros @GUI_CtrlId bzw. @GUI_CtrlHandle kannst du das viel leichter machen als mit deinem Versuch über WM_Notify.

    Warum dein Script nicht das macht was du willst kann man schlecht sagen, weil ich nicht weiß was du in _ConfigWizzard_FillInputs anstellst ^^
    Falls du aber etwas wie Guictrlread verwendest kann das was ich vorher beschrieben hatte der Grund sein

  • Jetzt wird mir einiges klar :D
    Du hast ja Case $NM_CLICK selbst gescriptet und $NM_RCLICK kopiert
    Und ich dachte du verstehst was bei $NM_RCLICK gemacht wird. Im Prinzip ist das nämlich eine mögliche Lösung für dein Problem.
    Da wird nämlich die Mausposition abgefragt und geprüft ob die Maus über einem Item liegt und wenn ja dann wird dieses ausgewählt.

    Eleganter fände ich für deinen Fall aber etwas wie das hier (also statt dem Case $NM_CLICK):

    [autoit]

    Case $TVN_SELCHANGEDW
    If DllStructGetData($tNMTREEVIEW, 'NewhItem') Then _ConfigWizzard_FillInputs()

    [/autoit]


    Sollte so egtl funktionieren, einfach mal ausprobiern ;)

    Aber wie gesagt ich versteh immer noch nicht so ganz wieso kein Guictrlsetonevent^^

  • [autoit]


    Case $TVN_SELCHANGEDW
    If DllStructGetData($tNMTREEVIEW, 'NewhItem') Then _ConfigWizzard_FillInputs()

    [/autoit]


    Sollte so egtl funktionieren, einfach mal ausprobiern

    Tut es leider auch nicht. Und wie bereits erwähnt, wäre es mir neu, wenn ich in einer Treeview mit GUICtrlOnEvent arbeiten kann. Ich erstelle die dynamisch und kann somit doch nicht feststellen welches ich geklickt habe ...

    Grüße Yaerox

    Grüne Hölle

    • Offizieller Beitrag
    Zitat

    Und wie bereits erwähnt, wäre es mir neu, wenn ich in einer Treeview mit GUICtrlOnEvent arbeiten kann. Ich erstelle die dynamisch und kann somit doch nicht feststellen welches ich geklickt habe ...

    Nun, da kann dein Horizont erweitert werden ;) -- Dynamisch und OnEvent, warum soll sich das beißen?

    Spoiler anzeigen
    [autoit]

    #include <GuiTreeView.au3>
    #include <File.au3>
    Opt('GUIOnEventMode', 1)

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

    $gui = GUICreate('Test')
    GUISetOnEvent(-3, '_ende')
    $cTV = GUICtrlCreateTreeView(10, 10, 300, 4000)
    $A = GUICtrlCreateTreeViewItem('C:\', $cTV)
    GUICtrlSetOnEvent(-1, '_clickTree')
    Global $aFolder = _FileListToArray('C:\', '*', 2)
    For $i = 1 To $aFolder[0]
    GUICtrlCreateTreeViewItem($aFolder[$i], $A)
    GUICtrlSetOnEvent(-1, '_clickTree')
    Next

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

    GUISetState()

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

    While True
    Sleep(50)
    WEnd

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

    Func _ende()
    Exit
    EndFunc

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

    Func _clickTree()
    $iItem = GUICtrlRead($cTV)
    If $iItem = 0 Then Return
    ConsoleWrite(GUICtrlRead($iItem, 1) & @LF)
    EndFunc

    [/autoit]
  • Ich habs gelöst indem ich die nativ functions genutzt habe und es nun OnEvent mache ... mit der UDF wollte es bei mir nicht so ^^

    Danke

    Grüße Yaerox

    Grüne Hölle

  • Weil ich dir jetzt zwei Scripte gebastelt hab poste ich die noch schnell ;)

    Erstes nutzt WM_NOTIFY und funktioniert mit dem Case den ich Freitag gepostet hatte:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <StructureConstants.au3>
    #include <TreeViewConstants.au3>
    #include <WindowsConstants.au3>
    Opt('GuiOnEventMode', 1)

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

    GUICreate('', 500, 400)
    GUISetOnEvent($GUI_EVENT_CLOSE, 'Quit')
    $TreeView = GUICtrlCreateTreeView(5, 5, 490, 390)
    $hWndTreeview = GUICtrlGetHandle(-1)
    Dim $aTreeViewItems[5] = [ GUICtrlCreateTreeViewItem('Parent1', $TreeView) , _
    GUICtrlCreateTreeViewItem('Subitem1_1', -1), _
    GUICtrlCreateTreeViewItem('Parent2', $TreeView), _
    GUICtrlCreateTreeViewItem('Subitem2_1', -1), _
    GUICtrlCreateTreeViewItem('Parent3', $TreeView)]

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

    GUISetState(@SW_SHOW)
    GUIRegisterMsg($WM_NOTIFY, '_WM_NOTIFY')

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

    While 1
    Sleep(100)
    WEnd

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

    Func Quit()
    Exit
    EndFunc

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

    Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hChild, $hITEM, $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam)
    If DllStructGetData($tNMTREEVIEW, 'hWndFrom') = $hWndTreeview Then
    Switch DllStructGetData($tNMTREEVIEW, 'Code')
    Case $TVN_SELCHANGEDW
    If DllStructGetData($tNMTREEVIEW, 'NewhItem') Then _ConfigWizzard_FillInputs()
    EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc ;==>_WM_NOTIFY

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

    Func _ConfigWizzard_FillInputs()
    $id = GUICtrlRead($TreeView)
    MsgBox(0,"", "Ausgewähltes Treeviewitem mit der ID: " & $id & @CRLF & "Text des Items: " & GUICtrlRead($id, 1))
    EndFunc

    [/autoit]


    Zweites ist ein kleines Beispiel für OnEvent:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    Opt('GuiOnEventMode', 1)

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

    GUICreate('', 500, 400)
    GUISetOnEvent($GUI_EVENT_CLOSE, 'Quit')
    $TreeView = GUICtrlCreateTreeView(5, 5, 490, 390)
    Dim $aTreeViewItems[5] = [ GUICtrlCreateTreeViewItem('Parent1', $TreeView) , _
    GUICtrlCreateTreeViewItem('Subitem1_1', -1), _
    GUICtrlCreateTreeViewItem('Parent2', $TreeView), _
    GUICtrlCreateTreeViewItem('Subitem2_1', -1), _
    GUICtrlCreateTreeViewItem('Parent3', $TreeView)]
    For $i = 0 To UBound($aTreeViewItems) -1
    GUICtrlSetOnEvent($aTreeViewItems[$i], '_Treeviewclick')
    Next

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

    GUISetState(@SW_SHOW)

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

    While 1
    Sleep(100)
    WEnd

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

    Func _Treeviewclick()
    $msg = MsgBox(4, 'Treeviewitem ausgewählt', 'Das Item mit der ID: ' & @GUI_CtrlId & ' wurde ausgewählt' & @CRLF & "Soll ein neues Subitem erstellt werden?")
    If $msg = 6 Then
    _ArrayAdd($aTreeViewItems, GUICtrlCreateTreeViewItem(InputBox("Itemtext", "Text für das neue Subitem", "Subitemx_y"), @GUI_CtrlId))
    GUICtrlSetOnEvent(-1, '_Treeviewclick')
    GUICtrlSetState($TreeView, $GUI_SHOW)
    EndIf
    EndFunc

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

    Func Quit()
    Exit
    EndFunc

    [/autoit]
  • Ich schau mir die noch auf jeden Fall an, muss nur jetzt wo es klappt auch erstmal weiter machen ... möchte endlich mal versuchen das Ende von dem Projekt zu sehen :P

    Grüße Yaerox

    Grüne Hölle