 |
|
 |
This 'MoveTreeItem_demo' is awesome but is there same for j2ee?
Plz send me link if you found my requirement.
Thankyou.
|
|
|
|
 |
|
 |
thanks for the great article. This info is very useful.
CString* ps = (CString*)lParam;
CString* psNew = new CString(*ps);
Will leak memory?
|
|
|
|
 |
|
 |
Thank you very much for this great code. Saved me many days of research
How can I use the drag and drop feature without the imagelist (icons)? As a temporary measure I have created a blank bitmap and set the size to 1, but a thin line is still visible when I drag the items under certain conditions.
I've experimented a bit in OnBegindragTree1(), like
m_tree.SetImageList(NULL, TVSIL_NORMAL);
but without success.
|
|
|
|
 |
|
 |
this check hItemTo == tree.GetParentItem(hItem) prevents from moveng and reorganizing nodes inside one parent, so why this check is there? (i removed it and it seem to work for me)
thanks for good script anyway
|
|
|
|
 |
|
 |
It has saved me lots of time.
|
|
|
|
 |
|
 |
i had to do this job too. Too bad i havn't knew this site before.
It's really annoying to debug a moving tree control, if someone can please explain me how to do this (execpt logging what it's doing to a file..), I'll be glad.
Anyway,
I've posted my code here, called it My Tree Control. It's new and had some other bugs which i solved. Check it out it got some more features (Recursive!)
Item counting, level control, children limiter control, transferring hierarchies..
and most of all: it is a template to store your custom object!
|
|
|
|
 |
|
 |
Great article! Made the issue very easy to understand, thanks!
|
|
|
|
 |
|
 |
first I think it is a wonderful work!
Then I think you should flesh it out in two point, so as to make it more flexible, that is DragType and DropType.
DragType, I think it is the principle that which level a moving node to be placed in. For example , you can divide it into two level:ANYLEVEL and LOCALLEVEL, witch means that you can drag the node to the level of any or and the level of current. you can judge from the destinate node and the moving node if they have the same parent.
DropType, that is what the draging node should behaviour to the dest node. I think there are three type:ASSON, EXCHANGE,and FORESET. ASSON means the drag node was the son of the destinate node(the child branch); EXCHANGE means the drag node and destnode are exchanged their location; FORESET mean the drag node are placed before the dest node(in the same level, and up on it).
at last , i think you should add a function for the user to call when the drag drop is finished, that is simple , i just talking
|
|
|
|
 |
|
 |
(J)ust a question on efficiency, if we move a child tree, we should copy item first, then delete original one, one by one till all items have been recursive "moved".
(I)n fact, this is not a real move, just copy and delete, in a large scale tree moving, like file paths, recursive processing will be more difficult. it is reasonable for duplicating, not for moving. How can we realization a real moving operation, e.g. just need move the head item?
|
|
|
|
 |
|
 |
You are right in saying that copy/delete is an inefficient way of performing a move, and that the best way is to move the head item, but there is no (documented) way to move a tree item. If there was then:
1. I would not have written this article
2. I would have done it by the documented method.
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
HI all
in my project i am using JOURNALRECORD HOOK. when a control send a notification message like LBN_SELCHANGE to its parent, here my question is that can i capture this notification and process it. i mean is it possible for the programmer if yes then plz guide me in this matter
same question is for the tree control notification TVN_ITEMEXPANDED
thanx in advance
regards
Basim
|
|
|
|
 |
|
 |
Hi! This article is very interesting but I have two questions :
1) instead of copying / deleting / re-creating items, would it possible to MOVE them directly using some special (maybe undocumented) TREECTRL function ?
2) Another good thing would be to have an option to keep the state of the items moved : for example, when you move an open branch, the items are moved and restored with the open state.
Thanks.
|
|
|
|
 |
|
 |
Hi Paul
I am facing a very strange problem. If I make the MoveTreeItem a class member, then during compilation program is generating a lot of errors.
I am enclosing the errors below. Never mind the warning for generating browse.
Please tell me what should I do to make MoveTreeItem a part of the class.
thanks
--------------------Configuration: MoveTreeItemDemo - Win32 Debug--------------------
Compiling...
MoveTreeItemDemoDlg.cpp
d:\ankush\downloads\movetreeitem_demo\movetreeitemdemodlg.cpp(4) : warning C4652: compiler option 'Generate Browser Info' inconsistent with precompiled header; current command-line option will override that defined in the precompiled header
d:\ankush\downloads\movetreeitem_demo\movetreeitemdemodlg.h(35) : error C2061: syntax error : identifier 'PFNMTICOPYDATA'
D:\Ankush\Downloads\MoveTreeItem_demo\MoveTreeItemDemoDlg.cpp(78) : error C2511: 'MoveTreeItem' : overloaded member function 'struct _TREEITEM *(class CTreeCtrl &,struct _TREEITEM *,struct _TREEITEM *,int,long (__cdecl *)(const class CTreeCtrl &,str
uct _TREEITEM *,long),struct _TREEITEM *)' not found in 'CMoveTreeItemDemoDlg'
d:\ankush\downloads\movetreeitem_demo\movetreeitemdemodlg.h(14) : see declaration of 'CMoveTreeItemDemoDlg'
D:\Ankush\Downloads\MoveTreeItem_demo\MoveTreeItemDemoDlg.cpp(461) : error C2660: 'MoveTreeItem' : function does not take 5 parameters
Error executing cl.exe.
MoveTreeItemDemoDlg.obj - 3 error(s), 1 warning(s)
|
|
|
|
 |
|
 |
It looks like you just need to move the typedef below from the cpp file into the header file:typedef LPARAM(*PFNMTICOPYDATA)(const CTreeCtrl&, HTREEITEM, LPARAM);
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Thanks Paul for your suggestion.
|
|
|
|
 |
|
 |
It is a great article Paul, but I have found a new bug in it. I used the recommendations by Matt Korth
and was able to remove some Access Violations from it, but then if you follow the steps below, there are
more Access Violations.
Step 1: Expand the tree to the fullest.
Step 2: Copy the subtree from three under Eight.
Step 3: Now the hierarchy under the item Two is as follows
Two
Five
Eight
Three
Six
Nine*
Under the last nine* nine move the original subtree under Three .
Step 4: Now the hierarchy between the item Two is as follows
Two
Five
Eight
Three
Six
Nine
Three
Six
Nine
Step 5: Now if you close the application there is an Access Violation.
As I am new to VC++ I am unable to debug the application. If you can please help me by debugging the
application.
Thanks
regard
|
|
|
|
 |
|
 |
When copying items their data also gets copied over. If the data is a pointer, as it is in my demo app, then this pointer value gets copied to the new item. When the items are deleted (in this case when the tree is destroyed), the app deletes any allocated data. As the item has been copied, the same data is deleted twice (or more), leading to the access violation.
See this paragraph in my documentation: "Care should be taken if using the function to copy (as opposed to move) items which have data which is deleted in this way to make sure that the data is deleted only once."
If moving items then the old item is deleted at that point, after it's data is zeroed out to prevent it being deleted.
I have added a callback mechanism to my code to get a safe copy of the item data if copying to get around this problem. I will publish this code here later today.
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Thanks Paul for your help!
|
|
|
|
 |
|
 |
I found one problem that can lead to an access violation (as of 2003/03/06).
The problem is that the code as it stands doesn't prevent you from trying to make a tree item a child of itself at more than one remove. To replicate the problem, try running the demo, then try to make "One" a child of "Seven". (Yes, I know it doesn't make any sense to try, but if there's one thing I've learned it's that users seem to somehow know exactly what programmers think it doesn't make sense to do... and then they go and do those things.)
From what I can tell, what happens is roughly this: "One" is copied to be a child of "Seven", then "Four" is copied to be a child of "One", then "Seven" is copied to be a child of "Four", then "One" is copied to be a child of "Seven", and so on, ad infinitum, eventually leading to an access violation.
I fixed this by adding this code to the top of MoveTreeItem():
if (IsChildOf(tree, hItem, hItemTo))
return NULL;
Here's IsChildOf():
BOOL IsChildOf(CTreeCtrl &tree, HTREEITEM hItem, HTREEITEM hChild)
{
if (hItem == hChild)
return FALSE;
else if (!tree.ItemHasChildren(hItem))
return FALSE;
else if (hChild == tree.GetParentItem(hItem))
return FALSE;
else
{
HTREEITEM hTestChild = tree.GetChildItem(hItem);
while (hTestChild != NULL)
{
if (hTestChild == hChild)
return TRUE;
else if (IsChildOf(tree, hTestChild, hChild))
return TRUE;
hTestChild = tree.GetNextSiblingItem(hTestChild);
}
}
return FALSE;
}
|
|
|
|
 |
|
 |
Thanks for pointing this out. I have posted an update to the article with a fix for this. I have included inline code instead of using a function. The code is: HTREEITEM hItemParent = hItemTo;
while (hItemParent != TVI_ROOT && (hItemParent = tree.GetParentItem(hItemParent)) != NULL)
if (hItemParent == hItem)
return NULL;
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Hi Paul,
very nice article, and a very handy function! I think there's a small bug in this part:
MoveTreeItem(tree, hItemChild, hItemNew, bCopyOnly);
hItemChild = tree.GetNextSiblingItem(hItemChild);
If there is more than one child under a parent, only the first child moves with its parent. After that child has been copied the original item (in hItemChild) is deleted, and GetNextSibling does'n return the next child of the parent.
A possible solution is retrieving the next sibling before we move the item:
HTREEITEM hItemNextChild = tree.GetNextSiblingItem(hItemChild);
MoveTreeItem(tree, hItemChild, hItemNew, bCopyOnly);
hItemChild = hItemNextChild;
Regards,
Jack
|
|
|
|
 |
|
 |
Jack,
You are very generous in describing this as a small bug: I would call it a great big fat bug!
Thanks for pointing this out. I'll post an update with it fixed.
Paul.
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
|
 |
|
 |
First of all, isn't drag&drop natively supported by tree ctrls? I have to admit I don't see the point behind your article.
auto-expand :
Please make sure to auto-expand the current drop node (after 3 seconds for instance) to mimic Windows Explorer and simplify drag&drop.
dragging&dropping in particular places :
The drag&drop procedure you introduce has limitations. For instance, let us assume we have a parent node, and three children. Now i want to drag the third children into second position. I simply can't. Using your implementation, this children will appear as child of the second node.
Vote : 4.
|
|
|
|
 |
|
 |
My article has nothing to do with drag and drop. You are correct in saying that tree controls have native support for drag and drop, and it is this native support that I am using to demonstrate the purpose of the article.
The article's sole purpose is to provide a method by which one can move a subtree programmatically, using the function MoveTreeItem. This does not have to be done by using drag and drop, indeed the application for which I wrote this function does not use this to support drag and drop, but is used to change parentage while populating a tree from a flat list of paths.
I hope this makes it clearer.
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |