15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Copying a CTreeCtrl

Jesper Spring -- jesper_spring@Merck.Com
Thursday, February 22, 1996


Hi there,

OK, here's the deal. I have created a CTreeCtrl in one of my splitter views. 
Also I have created a CTreeCtrl in my MainFrame Document. When the view with 
the CTreeCtrl is destroyed I would like to copy the tree structure to the 
CTreeCtrl member in the MainFrame document for later serialization. I have 
tried this:

void CMySplitterTreeView::OnDestroy()
{
     // Update Tree Structure to Mainframe document
     CMainFrameDoc* pDoc = (CMainFrameDoc*) GetDocument();
     UpdateData(TRUE);
     pDoc->m_Tree = m_Tree;
     GetDocument()->SetModifiedFlag();
}

The problem is that its not possible to copy a tree structure as above. Any 
suggestions? Is there a smarter way of doing this? Is there anyway I can 
detect and copy the tree every time it changes - I haven't been able to find 
a message to respond to?

Thanks very much in advance

Jesper Honig Spring
Merck & Co., Inc.
Denmark

*** Standard Disclaimer ***



Mike Blaszczak -- mikeblas@interserv.com
Saturday, February 24, 1996

On Thu, 22 Feb 1996, jesper_spring@Merck.Com (Jesper Spring) wrote:

>void CMySplitterTreeView::OnDestroy()
>{
>     // Update Tree Structure to Mainframe document
>     CMainFrameDoc* pDoc = (CMainFrameDoc*) GetDocument();
>     UpdateData(TRUE);
>     pDoc->m_Tree = m_Tree;
>     GetDocument()->SetModifiedFlag();
>}
>
>The problem is that its not possible to copy a tree structure as above.

I can't understand what you're doing from the code fragment above.  What is 
m_Tree?  Is it a CTreeCtrl object?  Or is it something else?

If it's a CTreeCtrl, you're right--you can't copy the data of a Windows 
control just by copying one instance of the MFC wrapping class to another.

You'll need to traverse the content of the tree yourself.  You can do so in a 
loop using the CTreeCtrl::GetNextItem() function.

>Is there anyway I can 
>detect and copy the tree every time it changes - I haven't been able to find 
>a message to respond to?

I don't think there's a generic "This control has changed from an unknown 
source" message. That would be a pretty impressive message--how would it tell 
you exactly what has changed? It sure would be sent pretty often, huh?

What in your application causes the tree to change?  Maybe you should just 
respond to those things indirectly, or broadcast notifications of your own.

>Thanks very much in advance

How do you know my answer won't suck?

.B ekiM
--
TCHAR sCool[]=_T("What was Fonzie like? What was Fonzie like? Cool, right?");




Tim Philip -- philip@cs.usask.ca
Monday, February 26, 1996

[Mini-digest: 2 responses]

Jesper Spring writes:
> 
> OK, here's the deal. I have created a CTreeCtrl in one of my splitter views. 
> Also I have created a CTreeCtrl in my MainFrame Document. When the view with 
> the CTreeCtrl is destroyed I would like to copy the tree structure to the 
> CTreeCtrl member in the MainFrame document for later serialization. I have 
> tried this:
> 
> void CMySplitterTreeView::OnDestroy()
> {
>      // Update Tree Structure to Mainframe document
>      CMainFrameDoc* pDoc = (CMainFrameDoc*) GetDocument();
>      UpdateData(TRUE);
>      pDoc->m_Tree = m_Tree;
>      GetDocument()->SetModifiedFlag();
> }
> 
> The problem is that its not possible to copy a tree structure as above. Any 
> suggestions? Is there a smarter way of doing this? Is there anyway I can 
> detect and copy the tree every time it changes - I haven't been able to find 
> a message to respond to?
> 

I'm not quite sure I understand *why* you are doing this, but here's a way
you can try.  Use pointers to CTreeCtrl's instead of objects.  When you
go to this OnDestroy function you just assign a pointer instead of trying
to copy the whole tree.  This requires that you change both your document
and your view to contain (CTreeCtrl *) rather than (CTreeCtrl).

-------
Tim Philip, B.Sc.           Randco Software Corporation
Consultant                  2530 Hanover Avenue   
                            Saskatoon, SK          Phone: +1-306-343-3380
philip@cs.usask.ca          Canada   S7J 1G1         Fax: +1-306-343-3341
-----From: pmoss@oxygen.bbn.com (Peter Moss)

I have been working on a similar problem although my problem is that I need to 
maintain a hierarchical list that may appear in in many different dialogs. 
When these different dialogs pop up, I want the tree to open up in the state 
the user left it in from the previous dlg.  What makes this problem a bear is 
that there may be 3,000-90,000 entries in it. It is very time consuming to 
load this control.

The approach I took (and one that you may end up having to deal with) is 
maintaining the state of the tree outside the control itself.  (In your case 
you maybe can save the state in the control and then copy the state in 
OnDestroy as you indicated in your msg.  Another reader repsonded that you 
can't just copy the instance of a control. He is absolutely right.  

The trick in maintaining the state is to respond to TVN_ITEMEXPANDING and 
TVN_ITEMEXPANDED notifications. In fact, because of the large number of tree 
elements, I load branches in response to TVN_ITEMEXPANDING and remove them 
using a

Expand(pNMTreeView->itemNew.hItem, TVE_COLLAPSE | TVE_COLLAPSERESET);

in the response func for TVN_ITEMEXPANDED.  There is an article on the MSDN CD 
that discusses this kind of CTreeCtrl memory management.  What you'll need to 
do is figure out a way to represent your hierarchy and the state it's in (if 
that's important to you), and then copy that to the new instance of your 
control.

Good luck,
Pete Moss




| Вернуться в корень Архива |