Jump to content
Sign in to follow this  
Lars

Drag, Drop listview to treeview

Recommended Posts

Lars

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

Share this post


Link to post
Share on other sites
Lars

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

Share this post


Link to post
Share on other sites
Mat

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

Share this post


Link to post
Share on other sites
Lars

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

Share this post


Link to post
Share on other sites
Lars

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

Share this post


Link to post
Share on other sites
Mat

A few bugs left:

* Flashing treeview items??

* Dropping on empty space presumes its dropping on 1

other than that very nice!

MDiesel

Share this post


Link to post
Share on other sites
Lars

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

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.