Jump to content

Drag, Drop listview to treeview


Lars
 Share

Recommended Posts

Hi everyone,

For a project I am working on, I need to drag items from a listview and drop 'em on a treeview.

In the forum I found this topic with an answer everyone can think of but doesn't give any answers.

http://www.autoitscript.com/forum/index.ph...rt=#entry527022

I only need to drop one item at the time and multiselect is turned off in the listview. How can this be done?

Someone has done it before? Is there an ondrop function i didnt find in the help?

tnx Lars

Link to comment
Share on other sites

I got a littlebit further with my test project,

In the sample code below I can drag and drop. The only thing is that I cannot see what I dragged, and on wich I item I dropped..

Someone some experience with this.

Tnx

Opt("GUIOnEventMode", 1)

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>

$Ctrl = GUICtrlCreateInput("", 10, 10)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)


$Form1 = GUICreate("Drop Test", 491, 387, 193, 125)
    $TreeView1 = GUICtrlCreateTreeView(8, 8, 233, 369, BitOR($TVS_HASBUTTONS,$TVS_HASLINES,$TVS_LINESATROOT,$TVS_SHOWSELALWAYS,$WS_GROUP,$WS_TABSTOP))
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)
        $TreeView1_0 = GUICtrlCreateTreeViewItem("Item1", $TreeView1)
        $TreeView1_1 = GUICtrlCreateTreeViewItem("Item2", $TreeView1)
        $TreeView1_2 = GUICtrlCreateTreeViewItem("Item3", $TreeView1)
    $ListView1 = GUICtrlCreateListView("LOL", 248, 8, 233, 369)
        GUICtrlSendMsg(-1, 0x101E, 0, 50)
        $ListView1_0 = GUICtrlCreateListViewItem("Item4", $ListView1)
        $ListView1_1 = GUICtrlCreateListViewItem("Item5", $ListView1)
        $ListView1_2 = GUICtrlCreateListViewItem("Item6", $ListView1)

GUISetOnEvent($GUI_EVENT_DROPPED, "myDrop")
GUISetOnEvent($GUI_EVENT_CLOSE, "myExit")
GUISetState(@SW_SHOW)

Func myExit()
    Exit
EndFunc

Func myDrop()
    $myMSG = "ID: " & @GUI_DRAGID & @CRLF & "Drop: " & @GUI_DROPID & @CRLF
    MsgBox(0, "", $myMSG)
EndFunc

While 1
    ; Do Nothing at the moment
WEnd
Link to comment
Share on other sites

Might want to mess around with this now!

Opt ("GUIOnEventMode", 1)

Global $hGUI  = GUICreate ("Testing", 400, 400)

Global $hlist = GUICtrlCreateListView ("Col 1|Col 2", 2, 2, 197, 396)
                GUICtrlCreateLabel ("Drag list item below.", 201, 2, 197, 20)
Global $hInp  = GUICtrlCreateInput ("", 201, 24, 197, 20)

For $i = 1 to 10
   GUICtrlCreateListViewItem ("Item " & $i & "|Item " & $i & " sub text", $hList)
Next

GUISetOnEvent (-3, "_Exit")
GUIRegisterMsg (0x004E, "_EventList")

GUISetState ()

While 1
   Sleep (500)
WEnd

Func _EventList ($hWnd, $msgID, $l, $w)
   Local $sCur = StringRegExpReplace (GUICtrlRead (GUICtrlRead ($hList)), "\|.*", "")
   While _IsPressed (01)
   WEnd
   $aPos = GUIGetCursorInfo ($hGUI)
   If $aPos[4] = 5 Then GUICtrlSetData ($hInp, $sCur)
   Return "GUIRunDefMsg"
EndFunc

Func _Exit ()
   Exit
EndFunc; ==> _Exit

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
    Local $a_R = DllCall($vDLL, "int", "GetAsyncKeyState", "int", '0x' & $sHexKey)
    If Not @error And BitAND($a_R[0], 0x8000) = 0x8000 Then Return 1
    Return 0
EndFunc; ==> _IsPressed

Returns the item fine, I'm working on the graphics.

Will take a lot of trial and error.

MDiesel

Link to comment
Share on other sites

Hi MDiesel,

As I can see it returns the item very well. This is a nice approach to what i need. What I am still working on at the moment

is where my item dropped in in the treeview.

So I thought lets use _GUICtrlTreeView_HitTestItem.

The hard part is that when I drop on a treeitem I can't get the _GUICtrlTreeView_HitTest

to work when using the output of MouseGetPos() as input at the moment I drop the item.

( It doesn't work as I aspected - Like ActionScript/Javascript Hittest )

I also messed around with Opt "MouseCoordMode" but doesn't do the trick yet.

So.. still trying but tnx A Lot

Link to comment
Share on other sites

Wow Done and it Works,

Gonna clean out my code and show the nice example :)

But this is what i ment to do ( tnx to Siao's code I understand treeViews better now )

Opt("GUIOnEventMode", 1)

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <Misc.au3>


$Ctrl = GUICtrlCreateInput("", 10, 10)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)

$Form1 = GUICreate("Drop Test", 491, 387, 193, 125)
    $TreeView1 = GUICtrlCreateTreeView(8, 8, 233, 369, BitOR($TVS_HASBUTTONS,$TVS_HASLINES,$TVS_LINESATROOT,$TVS_SHOWSELALWAYS,$TVS_TRACKSELECT,$WS_GROUP,$WS_TABSTOP))
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)
        $TreeView1_0 = GUICtrlCreateTreeViewItem("Item1", $TreeView1)
        $TreeView1_1 = GUICtrlCreateTreeViewItem("Item2", $TreeView1)
        $TreeView1_2 = GUICtrlCreateTreeViewItem("Item3", $TreeView1)
    $ListView1 = GUICtrlCreateListView("LOL", 248, 8, 233, 369)
        GUICtrlSendMsg(-1, 0x101E, 0, 50)
        $ListView1_0 = GUICtrlCreateListViewItem("Item4", $ListView1)
        $ListView1_1 = GUICtrlCreateListViewItem("Item5", $ListView1)
        $ListView1_2 = GUICtrlCreateListViewItem("Item6", $ListView1)


GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents")
GUISetOnEvent($GUI_EVENT_DROPPED, "myDrop")
GUISetOnEvent($GUI_EVENT_CLOSE, "myExit")
GUISetState(@SW_SHOW)

Func myExit()
    Exit
EndFunc

Func TreeItemFromPoint($hWnd)
    Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)
    Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
EndFunc

Global $hItemHover

Func SysEvents()
    Local $hTree = GUICtrlGetHandle($TreeView1)
    If _IsPressed("01") Then
       $hItemHover = TreeItemFromPoint($hTree)
        If $hItemHover = 0 Then
            ;No Hover at the moment
        Else
            $aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover)
            $iTreeY = _WinAPI_GetMousePosY(True, $hTree)
            Switch $iTreeY
                Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4)
                    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
                    $fWhere = -1
                Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3)
                    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) ;add DropTarget
                    $fWhere = 0
                Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3]
                    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
                    $fWhere = 1
            EndSwitch
        EndIf
    Else
        _WinAPI_InvalidateRect($hTree)
    EndIf
EndFunc

Func myDrop()
    ; Get selected item in the listview
    $tmpItemArr = _GUICtrlListView_GetSelectedIndices($ListView1, TRUE)
    $tmpItem = _GUICtrlListView_GetItemText($ListView1, $tmpItemArr[1])
    
    ; Get the selected item in the treeview
    $hSelected_Item = _GUICtrlTreeView_GetSelection($TreeView1)

    $myMSG = "Dragged: " & $tmpItem & @CRLF _
    & "Dropped: " & _GUICtrlTreeView_GetText($TreeView1, $hItemHover)
    MsgBox(0, "", $myMSG)
    Local $hTree = GUICtrlGetHandle($TreeView1)
    _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget
EndFunc

While 1
    ; Do Nothing at the moment
WEnd
Edited by Lars
Link to comment
Share on other sites

It works!!!

The code is pasted below... ( Last bugs are fixed )

CODE

#include <GUIConstants.au3>

#include <WindowsConstants.au3>

#include <GuiTreeView.au3>

#include <TreeViewConstants.au3>

#include <GuiListView.au3>

#include <ListViewConstants.au3>

#include <Misc.au3>

Global $hItemHover

$Form1 = GUICreate("Drop Test", 491, 387, 193, 125)

$TreeView1 = GUICtrlCreateTreeView(8, 8, 233, 369, BitOR($TVS_HASBUTTONS,$TVS_HASLINES,$TVS_LINESATROOT,$TVS_SHOWSELALWAYS,$TVS_TRACKSELECT,$WS_GROUP,$WS_TABSTOP))

GUICtrlSetState(-1, $GUI_DROPACCEPTED)

$TreeView1_0 = GUICtrlCreateTreeViewItem("Item1", $TreeView1)

$TreeView1_1 = GUICtrlCreateTreeViewItem("Item2", $TreeView1)

$TreeView1_2 = GUICtrlCreateTreeViewItem("Item3", $TreeView1)

$ListView1 = GUICtrlCreateListView("LOL", 248, 8, 233, 369)

GUICtrlSendMsg(-1, 0x101E, 0, 50)

$ListView1_0 = GUICtrlCreateListViewItem("Item4", $ListView1)

$ListView1_1 = GUICtrlCreateListViewItem("Item5", $ListView1)

$ListView1_2 = GUICtrlCreateListViewItem("Item6", $ListView1)

GUISetState(@SW_SHOW)

Func TreeItemFromPoint($hWnd)

Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)

Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))

EndFunc

Func dragEvent()

Local $hTree = GUICtrlGetHandle($TreeView1)

If _IsPressed("01") Then

$hItemHover = TreeItemFromPoint($hTree)

If $hItemHover = 0 Then

;No Hover at the moment

Else

$aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover)

$iTreeY = _WinAPI_GetMousePosY(True, $hTree)

Switch $iTreeY

Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4)

_SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget

$fWhere = -1

Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3)

_SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) ;add DropTarget

$fWhere = 0

Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3]

_SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget

$fWhere = 1

EndSwitch

EndIf

Else

_WinAPI_InvalidateRect($hTree)

EndIf

EndFunc

Func myDrop()

If $hItemHover <> 0 Then

; Get selected item in the listview

$tmpItemArr = _GUICtrlListView_GetSelectedIndices($ListView1, TRUE)

$tmpItem = _GUICtrlListView_GetItemText($ListView1, $tmpItemArr[1])

; Get the selected item in the treeview

$hSelected_Item = _GUICtrlTreeView_GetSelection($TreeView1)

$myMSG = "Dragged: " & $tmpItem & @CRLF _

& "Dropped: " & _GUICtrlTreeView_GetText($TreeView1, $hItemHover)

MsgBox(0, "", $myMSG)

; Reset drop target

_SendMessage(GUICtrlGetHandle($TreeView1), $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget

Else

MsgBox(0, "", "Oopz no drop target :) ")

EndIf

EndFunc

While 1

$nMsg = GUIGetMsg()

Switch $nMsg

Case $GUI_EVENT_MOUSEMOVE

dragEvent()

Case $GUI_EVENT_DROPPED

myDrop()

Case $GUI_EVENT_CLOSE

Exit

EndSwitch

WEnd

Everybody tnx 4 the help

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...