TV_DragAndDrop - Drag & Drop function for TreeView controls (Updated Nov, 13, 2020)

Post your working scripts, libraries and tools
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

TV_DragAndDrop - Drag & Drop function for TreeView controls (Updated Nov, 13, 2020)

20 Oct 2020, 18:45

Usage:
  • Call TV_Drag() from the TreeView's G-Label when A_GuiEvent contains "D" or "d". A line will show across the TreeView while holding the button to indicate the destination where the selected node will be dropped with its children.
  • If you point the mouse cursor to the half bottom part of the node text it will be dropped as a child of the pointed node. If you point it to the upper part it will drop it as sibling right below the pointed node.
  • TV_Drag() returns the target node id (if valid) which you can use to call TV_Drop() and effectively move the selection. Alternatively you can set AutoDrop option on as a shorthand.
  • Separating the Drag and Drop calls allows to check if the returned destination is a valid node to drop in as well as setting GuiControl, -Redraw to avoid flickering.
  • TV_Drop() may be called directly to move or copy nodes programmatically. You may pass the TreeView control's hwnd to keep icons and set Copy parameter to true if you want to copy nodes instead of moving.
:arrow: Sources, documentation and examples on GitHub

See also LV_Rows
Last edited by Pulover on 14 Nov 2020, 06:07, edited 3 times in total.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Update

21 Oct 2020, 16:31

  • Updated TV_Drop() to return the ID of the created top node.

guest3456 wrote:
21 Oct 2020, 02:17
outstanding
Thanks! :D
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Update [Fix]

21 Oct 2020, 18:51

  • Fixed children being moved in reverse order.
  • Fixed items being dropped as first child instead of last.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Update

22 Oct 2020, 08:38

  • Added DragButton parameter to TV_Drag().
  • Added Hwnd and Copy parameters to TV_Drop().
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Update

29 Oct 2020, 07:34

  • Added FirstChild parameter in TV_Drop() to allow drop as first/top sibling.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
burque505
Posts: 1396
Joined: 22 Jan 2017, 19:37

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

29 Oct 2020, 13:38

@Pulover, thanks a million for this. I have an observation about today's release: Once an item is demoted by DragAndDrop (on Win7 and Win10), it is quite difficult (impossible?) to promote it again. In the TV_Drag_Demo script, try the following.

1) You have this when the script starts.
one.PNG
one.PNG (16.55 KiB) Viewed 402 times
2) Drag the Second Parent to be a child of First Parent.
two.PNG
two.PNG (18.08 KiB) Viewed 402 times
Try to promote Second Parent again so that it is, once again, a sibling of First Parent instead of a child (i.e., a level one item). My first thought was to drag First Parent below Second Parent, but that can't be done.

Thanks again for this and all your other generous contributions.
Regards,
burque505
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

29 Oct 2020, 15:59

You're welcome, @burque505.

In fact it's not only possible, but quite easy to do. Maybe you've missed this part:
If you point it to the upper part it will drop it as sibling right below the pointed node.
Last edited by Pulover on 29 Oct 2020, 18:09, edited 1 time in total.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
burque505
Posts: 1396
Joined: 22 Jan 2017, 19:37

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

29 Oct 2020, 16:11

@Pulover, thanks a million. :facepalm: What a relief. I wasn't dragging the cursor far enough over to the left. I see now that the indicator line has to extend all the way to the left of the GUI to promote an item to Level One.
Regards, burque505
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

30 Oct 2020, 07:50

Thank you. As always, this work is great.

Thanks for the

Code: Select all

GetIcon()
Function. I was using a devious solution like creating one extension in the temp folder for each format.
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

30 Oct 2020, 17:56

Code: Select all

Paths :=
(
"D:\_AppData_\
D:\_AppData_\Desktop\
D:\_AppData_\Desktop\TEST\
D:\_AppData_\Desktop\TEST\TEST1\
D:\_AppData_\Desktop\TEST\TEST1\TEST 1-1\
D:\_AppData_\Desktop\TEST\TEST1\TEST 1-1\TEST 1-1-1\
D:\_AppData_\Desktop\TEST\TEST1\TEST 1-2\
D:\_AppData_\Desktop\TEST\TEST2\
D:\_AppData_\Desktop\TEST\TEST2\TEST 2-1\"
)
How is it practical to add such a list of folders that are not clear whether they are on the disk or not. I don't want them checked on disk. They just need to be added in the Tree view.
burque505
Posts: 1396
Joined: 22 Jan 2017, 19:37

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

30 Oct 2020, 18:10

@hasantr, take a look at the "TreeView Browser.ahk" file in the Examples folder. You will find a "CreateTreeView(TreeViewDefinitionString)" function by @Learning one in the script. Using your "Paths" variable described above as an argument to the function, you should be able to create your treeview.
Regards,
burque505
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

30 Oct 2020, 18:17

burque505 wrote:
30 Oct 2020, 18:10
@hasantr, take a look at the "TreeView Browser.ahk" file in the Examples folder. You will find a "CreateTreeView(TreeViewDefinitionString)" function by @Learning one in the script. Using your "Paths" variable described above as an argument to the function, you should be able to create your treeview.
Regards,
burque505
My attempts have failed.
Actually, I've been trying to do this for a long time. I wanted to ask here if there is a Function I missed.

Maybe I need to sleep now. :)
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

30 Oct 2020, 18:21

@hasantr, you should try the Save File button and check the format of the saved file. You might want to modify the LoadFile label to convert your format to the one expected by CreateTreeView(). The purpose of TreeView Browser was exactly to browse my files from another computer back when I wrote it.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

30 Oct 2020, 18:25

Thanks I will do this after I get my sleep. If I can come up with a solution that looks good I'll put it here.
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

31 Oct 2020, 04:47

Pulover wrote:
30 Oct 2020, 18:21
@hasantr, you should try the Save File button and check the format of the saved file. You might want to modify the LoadFile label to convert your format to the one expected by CreateTreeView(). The purpose of TreeView Browser was exactly to browse my files from another computer back when I wrote it.
I've created a solution, if not very good. I hope it works for someone in need.
Thanks again.

Code: Select all

Paths :=
(
"C:\Users\hasan\Desktop\
C:\Users\hasan\Desktop\WhatsApp
C:\Users\hasan\Desktop\WhatsApp\Media\WhatsApp Documents\
C:\Users\hasan\Desktop\test\
D:\TestIndex
D:\_AppData_\Desktop
D:\_AppData_\Desktop\AHK TEST\UDFS 7ZDLL İLE
D:\_AppData_\Desktop\AHK TEST\UDFS 7ZDLL İLE\BüyükUdfLer1
D:\_AppData_\Desktop\AHK TEST\UDFS 7ZDLL İLE\UDFLER"
)

Clipboard := PathListToTree(Paths)
PathListToTree(Paths){
	Paths := StrSplit(Paths,"`n")
	TO := {}
	For, K,Dir in Paths
	{	
		if(Dir == "")
			Continue
		Dir := SubStr(Dir,StrLen(Dir),1) = "\" ? SubStr(Dir,1,StrLen(Dir) - 1) : Dir ;Remove last character if "\"
		PATH := Dir
		PathBack  :=
		Loop 125 ; NO MORE "\"
		{
			SplitPath,PATH,,PATH
			if(TO.HasKey(PATH) == true){ ; this has a parent directory
				TO[Dir] := TO[PATH] + 1
				break
			}
			if(PathBack == PATH){ ; the loop should end as there are no new subdirectories left. This is the root directory
				TO[Dir] :=  1
				Break
			}
			PathBack := PATH
		}
		Loop, % TO[Dir]
			Stack .= "`t"
		Stack .= Dir . (A_Index != Paths.MaxIndex() ? "`n" : "")
	}
	return Stack
}
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

01 Nov 2020, 12:02

@Pulover I wanted to use the GetIcon() function, but is there a problem? It takes an infinite number of icons. For example, if I call 5 PDF extensions, it returns 5 separate icon numbers. I couldn't figure out where the problem was caused.
User avatar
Pulover
Posts: 499
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

01 Nov 2020, 16:46

hasantr wrote:
01 Nov 2020, 12:02
@Pulover I wanted to use the GetIcon() function, but is there a problem? It takes an infinite number of icons. For example, if I call 5 PDF extensions, it returns 5 separate icon numbers. I couldn't figure out where the problem was caused.
I don't remember writing that function... probably copied it from somewhere in the forum. But you're right, there is problem with it. Must have been my mistake when I modified it. Here's a fixed version:

Code: Select all

GetIcon(FileName, ImageListID)
{
	static IconArray := []

	sfi_size := A_PtrSize + 8 + (A_IsUnicode ? 680 : 340)
	VarSetCapacity(sfi, sfi_size)
	SplitPath, FileName,,, FileExt
	if FileExt in EXE,ICO,ANI,CUR
	{
		ExtID := FileExt
		IconNumber = 0
	}
	else
	{
		ExtID = 0
		Loop 7
		{
			StringMid, ExtChar, FileExt, A_Index, 1
			If not ExtChar
				break
			ExtID := ExtID | (Asc(ExtChar) << (8 * (A_Index - 1)))
		}
		IconNumber := IconArray[ExtID]
	}
	If not IconNumber
	{
		if not DllCall("Shell32\SHGetFileInfo" . (A_IsUnicode ? "W":"A"), "str",  "." FileExt
			, "uint", (FileExt ? 0x80 : 0), "ptr", &sfi, "uint", sfi_size, "uint", (FileExt ? 0x111 : 0x101))
			IconNumber = 9999999
		else
		{
			hIcon := NumGet(sfi, 0)
			IconNumber := DllCall("ImageList_ReplaceIcon", "ptr", ImageListID, "int", -1, "ptr", hIcon) + 1
			DllCall("DestroyIcon", "ptr", hIcon)
			IconArray[ExtID] := IconNumber
		}
	}
	return IconNumber
}
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
hasantr
Posts: 667
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: TV_DragAndDrop - Drag & Drop function for TreeView controls

01 Nov 2020, 18:34

Pulover wrote:
01 Nov 2020, 16:46
hasantr wrote:
01 Nov 2020, 12:02
@Pulover I wanted to use the GetIcon() function, but is there a problem? It takes an infinite number of icons. For example, if I call 5 PDF extensions, it returns 5 separate icon numbers. I couldn't figure out where the problem was caused.
I don't remember writing that function... probably copied it from somewhere in the forum. But you're right, there is problem with it. Must have been my mistake when I modified it. Here's a fixed version:

Code: Select all

GetIcon(FileName, ImageListID)
{
	static IconArray := []

	sfi_size := A_PtrSize + 8 + (A_IsUnicode ? 680 : 340)
	VarSetCapacity(sfi, sfi_size)
	SplitPath, FileName,,, FileExt
	if FileExt in EXE,ICO,ANI,CUR
	{
		ExtID := FileExt
		IconNumber = 0
	}
	else
	{
		ExtID = 0
		Loop 7
		{
			StringMid, ExtChar, FileExt, A_Index, 1
			If not ExtChar
				break
			ExtID := ExtID | (Asc(ExtChar) << (8 * (A_Index - 1)))
		}
		IconNumber := IconArray[ExtID]
	}
	If not IconNumber
	{
		if not DllCall("Shell32\SHGetFileInfo" . (A_IsUnicode ? "W":"A"), "str",  "." FileExt
			, "uint", (FileExt ? 0x80 : 0), "ptr", &sfi, "uint", sfi_size, "uint", (FileExt ? 0x111 : 0x101))
			IconNumber = 9999999
		else
		{
			hIcon := NumGet(sfi, 0)
			IconNumber := DllCall("ImageList_ReplaceIcon", "ptr", ImageListID, "int", -1, "ptr", hIcon) + 1
			DllCall("DestroyIcon", "ptr", hIcon)
			IconArray[ExtID] := IconNumber
		}
	}
	return IconNumber
}
Thanks. I tried Static array. "IconArray[ExtID]" I skipped the fix. :bravo:

Return to “Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 21 guests