?
Solved

CTreeView / CTreeCtrl

Posted on 2002-05-07
19
Medium Priority
?
2,851 Views
Last Modified: 2013-11-20
I'm about to implement a tree, which is in a dockable "toolbar" type window in an MDI app.  The elements will be changed dynamically.  My working prototype uses a CTreeCtrl.

The catch is that I need to implement a dialog window, containing two trees, both the same as the floating tree view.  The idea is for the user to be able to select two tree elements to link together on this dialog.

Can I base two CTreeViews on the floating CTreeCtrl?  Is it an acceptable solution?  How do I connect the two views to the original CTreeCtrl?
0
Comment
Question by:IainHere
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 4
  • +2
19 Comments
 
LVL 1

Expert Comment

by:Yechezkel
ID: 6993693
I don't really see where CTreeView comes into the question. So far as I understand, CTreeView is only for the Document/View architecture and wouldn't be used in a dialog.

My suggestion would be to copy the entire tree structure from the floating CTreeCtrl to the two CTreeCtrls in the dialog by hand. Tedious, but I can't see any better way.
0
 
LVL 4

Author Comment

by:IainHere
ID: 6994298
What I want is a way to get a new view on a CTreeCtrl.  If I can't use a dialog for that (which I'm a little suprised by - the document exists in the for of the CTreeCtrl, so why not just plop a view on a dialog?) then I'll just have to derive my "dialog" from CMDIChildWnd or whatever.

The question is - how do I do it?
0
 
LVL 16

Expert Comment

by:AlexNek
ID: 6994603
2 IainHere
Could I please you a little expand your task. As I understood you have one CTreeView with document and you want to create the same tree twice on the dialog.
You can realize what you need if you:
- Create class CMyTreeData that hold your tree data.
- Create class CMyTreeFiller that create tree based on CTreeCtrl and CMyTreeData classes.
- CMyTreeData must be data member of your document.

When you need tree in the CTreeView get CTreeCtrl /*CTreeCtrl& CTreeView::GetTreeCtrl()*/ and fill it with CMyTreeFiller. When you create the dialog set pointer in dialog to your document and fills two trees with CMyTreeFiller.

Yet another idea: create splitter on the view and you show 2 or 3 CTreeView simultaneously.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 49

Expert Comment

by:DanRollins
ID: 7000401
IainHere,
You can make a tree control without using CTreeView.  In the dialog box, just choose the tree control from the control palette (it's about halfway down the righthand side of the palette) and draw its rectangle in the dialog.  Then do the same for the second tree control.  Use the ClassWizard to add two CTreeControl objects e.g., m_cltTree_1 and m_cltTree_2 to your CDialog-derived class.

As to 'linking one tree control to another', you will be able to do that programmatically, based upon the current selection in each tree.  You will create OnSelChangedTree1 and OnSelChangedTree2 handlers using the ClassWizard.

If you explain a little more clearly what you mean by 'linking' the trees I'm sure we can provide more specific help.

-- Dan
0
 

Expert Comment

by:TheFriend
ID: 7004260
No you can not.
CTreeView is a subclassed SysTreeView32 CCtrlView descendant.

I think the concept of your last question is wrong.

Your best solution would be to create another tree on the dialog and then send the same messages to the floating  window dispatcher.

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7004343
>>No you can not
Yes you can.
The only reason you might say that is because you have confused CTreeView (the CView-derived object, part of the MFC document/view architecture) with the Win32 Common Control "TreeView"  There are similarities in the name, but the differences are critical.

What I have proposed is to get the CView-derived crap out of the picture (Views require special handling -- you need to do lots of tricky stuff to put a View into a dialog), and just use CTreeCtrl directly.

-- Dan
0
 

Expert Comment

by:TheFriend
ID: 7006155
Dan,
he is talking of objects, instances of classes at runtime. CTreeView is a subclassed control which takes over the control dispatcher. As far as I understand he has one CTreeCtrl object loaded with tree braches/items, and he wants to make 2 'view-ports' of the same CTreeCtrl. Well he might be able to display one CTreeCtrl through one CTreeView but, he loose the appearance of the CTreeCtrl, since the owner and the parent of the CTreeView will become the new parent/owner and the messages will be dispatch in the handler. When the second CTreeView gets into the play it will take over everything from CTreeView.

Agron
0
 
LVL 16

Expert Comment

by:AlexNek
ID: 7006740
2 TheFriend
I can't see as Dan any problem for your notice. It can be a sync problem if data stored ONLY in CTreeView. But if data stored in separately class it must be not a big problem.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7007260
If the only goal is to have two trees that show the same data (and IainHere is silent on this point), then the answer is simple:

When working with a tree control, you always end up writing a function named "PopulateTree" or something like that.  Well to copy one tree to another, just call your 'PopulateTree' function twice -- one for each of the CTreeCtrl objects.

-- Dan
0
 
LVL 4

Author Comment

by:IainHere
ID: 7007935
>>and IainHere is silent on this point
sorry - been away.

Dan, you're right.  All I want is to see the same info on the two trees within the dialog as I have on the floating one.

I thought it would be possible to make a tree view which looks at the same info as the floating one.  It seems that this is unpossible - could you confirm this for me?

The main reason I wanted to do it like that is because each tree element is mapped to some information in the program.  I would like to reuse this mapping in the two new trees.  It sounds like my only option is to store lots of copies of this mapping [HTREEITEM->instance].

>>explain a little more clearly what you mean by 'linking' the trees
I guess this might have been a red herring - the tree items represent probabilistic inputs to a model.  The dialog containing two trees is to allow the user to correlate the inputs (eg say length of thread is related to heat of debate)
0
 
LVL 16

Expert Comment

by:AlexNek
ID: 7008017
2 IainHere
>The main reason I wanted to do it like that is because each tree element is mapped to some information
in the program.
Is it mean that you already have a class with stored tree item data and hierarchy (not HTREEITEM, only data). If you already have this class try to add function FillTree(CTreeCtrl* pTree) if you don't want to use filler class.
I always divide my classes at least for two parts - data class, view class.

0
 
LVL 4

Author Comment

by:IainHere
ID: 7008030
AlexNek, I'm still in the design stage, so no code yet (except for test code for the floating tree).  What you outline is roughly what I plan.

Could you verify that I'll need to recreate the mapping HTREEITEM->instance for each of the trees, please?  Then I'll close this out.

Thanks,
Iain.
0
 
LVL 16

Expert Comment

by:AlexNek
ID: 7008625
2 IainHere
Do you want to reuse HTREEITEM handle, is that your question?
0
 
LVL 4

Author Comment

by:IainHere
ID: 7008657
Yes, I suppose that is the most transparent way of doing it.  Is that possible?

I'm currently planning (based on this thread) to store all of my information calculation info in a std::vector, passing this vector into a ConstructTree function every time I create a new tree.  I will also need a std::map HTREEITEM->instance (ie reference to element of the std::vector) for each tree.  It seems messy.
0
 
LVL 16

Expert Comment

by:AlexNek
ID: 7008915
2 IainHere
If you want to reuse HTREEITEM we need at least the function CTreeCtrl::InsertItem(HTREEITEM) as I think. So I don't know this way.
If you use vector where you store information about tree hierarchy? In object pointed via vector?
I don't know exactly you task but if I do it then I create a base data class for my tree Item, create inherited classes for different data tree item and build from this structure exactly data tree (not a vector). From this structure I can easy create the tree view. I can easy add and modify this data structure. I can pass pointer to this data structure to the tree item and use LPSTR_TEXTCALLBACK. So you can easy refresh all tree controls if text in one must be changed. For each tree control you can store mapping "data pointer"-"HTREEITEM" if you need it.
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 600 total points
ID: 7008987
IainHere,
You will need only one copy of the data.  Your code that constructs and populates the tree will use that same data for each tree.  What part of this do you not understand.  I will be glad to explain.

It would also be possible to construct a second CTreeCtrl by walking the nodes of the first CTreeCtrl and using the data to build the hieraachy of the second.  It may even be possible to provide two CTreeCtrls that view the exact same TreeView common control (I don't think so because each tree must maintain state data, so if this were possible, then the selection would change on the second when the user clicked on the first).  

So there are (or might be) several alternaives.  The point is:
     Why Bother?  
You have a function that populates a CTreeCtrl from some data.  Just call that function twice.

-- Dan
0
 

Expert Comment

by:TheFriend
ID: 7010408
2 IainHere,

if MFC were complete you could do something like this:

     CFile file( "myfile.ar", CFile::modeCreate | CFile::modeReadWrite);
     CArchive ar( &file, CArchive::store);
     m_tree1.Serialize( ar);
     ar.Close();
     ar.~CArchive();
     file.Close();
     file.~CFile();


     CFile file( "myfile.ar", CFile::modeRead);
     CArchive ar( &file, CArchive::load);
     m_tree2.Serialize( ar);
     ar.Close();
     file.Close();

-----

or maybe:

m_tree1 >> m_tree2;

You still can do things like this, just that you have to work under the hood first, and later turn the key.

If you are interested in something like this, just let me know. I would like to add this feature to the controls in my library, but I need one more (very strong) reason to start doing it.

But again, it is much easier to do the way Dan says. But, since the tree items are loaded dynamicaly, and probably they wont fit the same data structure, your MyGlobals::PopulateTree() would become very large.

Thus, I suggest again. The messages that tree1 receives, send them to the second one (tree2)

eg:

tree1::OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult )
{
  dockWindow->tree2->SendMessage( message, wParam, lParam);
}

When you add an item to tree1, the same item is automaically added to tree2 as well.

In this function (method) you can also filter messages you don't want to send to the other tree control.

eg:
if( message != TVN_BEGINDRAG &&
    message != TVN_BEGINRDRAG)
{ // this would mess up the drap&drop of the other control

  dockWindow->tree2->SendMessage( message, wParam, lParam);

}

If you have mouse-over highlighting on, then you must translate the mouse coordinates as if the mouse is passing over the other control as well. see WM_MOUSEMOVE

Don't make this feature to work both ways. Endless loop, right?



Agron
0
 
LVL 4

Author Comment

by:IainHere
ID: 7010775
Thanks for all the help, people.

I'm going to review my options and I'll close this in a couple of days.
0
 
LVL 4

Author Comment

by:IainHere
ID: 7058964
Thanks Dan.

>>You have a function that populates a CTreeCtrl from some data.  Just call that function twice.

OK.  That's what I'm doing.  I got a little confused around the Ctrl/View business, and thought I should be able to have three views of the same info.  As you say, "Why Bother".  Thanks again (+apologies for not closing sooner)
0

Featured Post

Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question