Solved

Using CTreeCtrl From A Derived Class

Posted on 2000-02-15
20
444 Views
Last Modified: 2013-11-20
I've created an Explorer like application using MFC wizard. I then created a generic class which is derived from CLeftView. I can then add this code -

CTreeCtrl &pTree = GetTreeCtrl();
pTree.ModifyStyle(0, TVS_HASBUTTONS | TVS_HASLINES, SWP_SHOWWINDOW);

to a function in the new class which will compile okay but when I run it and access the function I get "Debug Assertion Failed!".

Is it possible to control a tree from any other class than CLeftView and if so how?

Thanks in advance.
0
Comment
Question by:skyhook8
  • 7
  • 7
  • 4
  • +1
20 Comments
 
LVL 8

Expert Comment

by:VinExpert
ID: 2522792
Hi,

I assume u r doing it in Ur derived class. Then u r not checking for the validity of pointer, thats why it is crashing do as

CTreeCtrl &pTree = GetTreeCtrl();
if(pTree)
pTree.ModifyStyle(0, TVS_HASBUTTONS | TVS_HASLINES, SWP_SHOWWINDOW);

That will solve the crash.
VinExpert
0
 
LVL 1

Expert Comment

by:ScottyDawg
ID: 2522835
Also,

Where are you modifying the style - are you doing this in the constructor? If so, the tree ctrl hasn’t been created at this point. You should be modifying this style in the function PreCreateWindow(…)

Something like

CleftViewDerivation::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= TVS_HASBUTTONS | TVS_HASLINES;
return CleftView::PreCreatewindow(cs);
}
0
 

Author Comment

by:skyhook8
ID: 2522950
You guys are responding faster than I can try your ideas!

I added the "if(pTree)" and it runs without crashing now but nothing shows up in the left pane.

void CTreeEx::PutTree()
{
CTreeCtrl &pTree = GetTreeCtrl();
if(pTree)pTree.ModifyStyle(0, TVS_HASBUTTONS | TVS_HASLINES, SWP_SHOWWINDOW);

TV_INSERTSTRUCT tvinsert;
tvinsert.hParent = NULL;
tvinsert.item.mask = TVIF_SELECTEDIMAGE | TVIF_TEXT;
tvinsert.item.pszText = "Org";
if(pTree)HTREEITEM hRoot = pTree.InsertItem(&tvinsert);
return;
}

This is being called from OnInitialUpdate() in CLeftView.
0
 
LVL 1

Expert Comment

by:ScottyDawg
ID: 2522975
Can you show us the OnInitialUpdate() code. Is this a dialog or form?
0
 
LVL 8

Expert Comment

by:VinExpert
ID: 2523122
HI,

Try modifying ur PutTree() code as
void CTreeviewView::PutTree()
{
      CTreeCtrl *pTree = &(this->GetTreeCtrl());
      if(pTree)
      {
            long wd = GetWindowLong(pTree->GetSafeHwnd(), GWL_STYLE);
            wd += TVS_HASBUTTONS + TVS_HASLINES;
            SetWindowLong(pTree->GetSafeHwnd(), GWL_STYLE, wd );            
      }

      TV_INSERTSTRUCT tvinsert;
      tvinsert.hParent = TVI_ROOT ;
      tvinsert.hInsertAfter = TVI_LAST;

      tvinsert.item.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_CHILDREN | TVIF_STATE | TVS_CHECKBOXES;
      tvinsert.item.hItem = NULL;
      tvinsert.item.state = 0;
      tvinsert.item.stateMask = 0x03;
      tvinsert.item.cchTextMax = 60;
      tvinsert.item.iSelectedImage = 0;
      tvinsert.item.cChildren = 1;
      tvinsert.item.lParam = 0;

      tvinsert.item.pszText = "NUMBERS";
      HTREEITEM Par1 ;
      if(pTree)
            Par1 = pTree->InsertItem(&tvinsert);

      tvinsert.hParent = Par1 ;
      tvinsert.item.cChildren = 0;
      tvinsert.item.pszText = "child";
      if(pTree)
            HTREEITEM child = pTree->InsertItem(&tvinsert);

      return;
}

Try it out.
VinExpert
0
 
LVL 1

Expert Comment

by:ScottyDawg
ID: 2523139
sorry - ignore my bit about is this a dialog or form.

But I would still like to see where you are trying to modify the tree style. The reason why it's not asserting anymore is simply because that code is now no longer being called - which really doesn't help you much...
0
 

Author Comment

by:skyhook8
ID: 2523201
Tried the new code. Getting a "Debug Assertion Failed!" again. This line causes the problem:

if(pTree)
Par1 = pTree->InsertItem(&tvinsert);

Here's the OnInitialUpdate() code:

void CLeftView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
CTreeEx te;
te.PutTree();
}

Ideas?
0
 
LVL 1

Expert Comment

by:ScottyDawg
ID: 2523244
skyhook, I think you might be a little confused about what you trying to achieve and how to go about it using OOP and MFC.

What exactly are you trying to do? Are you just trying to modify the style of the CLeftView class?


0
 

Author Comment

by:skyhook8
ID: 2523449
Adjusted points to 70
0
 

Author Comment

by:skyhook8
ID: 2523450
I'm attempting to add items to the tree in the left window pane using "void CTreeEx::PutTree()".

I can do it easily from "void CLeftView::OnInitialUpdate()" but when I call the previous function from the latter I get into trouble. CTreeEx is derived from CLeftView.

There's no doubt that I'm confused. But I've come a long way and I don't intend to stop here.{:>

The "rowlist" example from MSDN adds items to a list from a derived class but I can't figure out why it works.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Expert Comment

by:ScottyDawg
ID: 2523483
Okay, well your trouble is OOP in general I think :-) For the time being I suggest you forget entirely about your derived CLeftTree (CTreeEx).

What you should do to get things working is first override PreCreateWindow() in CLeftTree like the following:

BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.Style |= TVS_HASBUTTONS | TVS_HASLINES;
      return CTreeView::PreCreateWindow(cs);
}

This will get the styles you want. Then in OnInitialUpdate(..) add the items to the tree.

As far as I can tell, you have no need to derive a class from CLeftTree and if you did, you go about it in a different way entirly.
0
 

Author Comment

by:skyhook8
ID: 2523590
I'm going to be calling ldap lookups from the derived class and I want to be able to add items to the tree while in a ldap_next_entry loop. I could do the loop from within CLeftView but I figured that a separate class for the ldap functions would be a more organized way of doing things.

Does that make sense?
0
 
LVL 2

Expert Comment

by:waseemanis
ID: 2525592
I guess Scotty is right in saying that your problem is actually OOP in general.

Because...the very code you have written works on my machine.

The situation...SDI, two panes, left CMyTree(derived from CTreeView) and right CMyListView(from CListView).
CMyTreeView::::OnInitialUpdate()
{
      CTreeView::OnInitialUpdate();
      PutTree();
}

PutTree is your function. Works well.



Luck,
Waseem.
0
 
LVL 8

Expert Comment

by:VinExpert
ID: 2525683
Hi,

From InitialUpdate just call PutTree();

OR
do one more thing(of which I am not so comfertable)
In InitialUpdate() set the timer as
SetTimer(1, 10, NULL);

Then map the WM_TIMER message and do
KillTimer(1);
PutTree();

Try it out.
VinExpert
0
 
LVL 2

Expert Comment

by:waseemanis
ID: 2525728
What is it that you are actually trying to suggest VinExpert...I guess the guy already is in a soup....


Waseem.
0
 
LVL 8

Expert Comment

by:VinExpert
ID: 2525753
Hi,

I am sorry skyhook8, if I am confusing U. But I thought to put it.

VinExpert
0
 

Author Comment

by:skyhook8
ID: 2526493
Okay, let's start over:

Using MFC AppWizard (exe), create an Explorer like application. Now create a new class and then from that class add tree items to the left pane.

Is it possible? Details please.

BTW: Thanks to all for your time and patience.
0
 
LVL 1

Accepted Solution

by:
ScottyDawg earned 70 total points
ID: 2526517
Yes, now you can do this in OnInitialUpdate() or as you have suggested by using a seperate class. However, this seperate class needs to know about the treectrl that has been created. Simply deriving from CLeftView will not do.

What you need to do is have a CTreeCtrl* member in your new class like so.


class CTreeHelper
{
public:
    CTreeHelper(CTreeCtrl* pTreeCtrl);
    void Populate();

private:
    CTreeCtrl* m_pTreeCtrl;
}


CTreeHelper::CTreeHelper(CTreeCtrl* pTreeCtrl)
{
    ASSERT(pTreeCtrl != NULL);
    m_pTreeCtrl = pTreeCtrl;
}

void CTreeHelper::Populate()
{
  // do you tree insertion here
  HTREEITEM hItem = m_pTreeCtrl->InsertItem("Parent");

  m_pTreeCtrl->InsertItem("Child", hItem);
}


Now in oninitialupdate

void CLeftView::OnInitialUpdate()
{
    CLeftView::OnInitialUpdate();
 
    CTreeCtrl& TreeCtrl = GetTreeCtrl();
    CTreeHelper TreeHelper(&TreeCtrl);
   
    TreeCtrl.Populate();
}


Is this waht you are looking for?
0
 

Author Comment

by:skyhook8
ID: 2526724
Eureka! Thanks so much!

For archival purposes, please note the change I had to make to OnInitialUpdate():

void CLeftView::OnInitialUpdate()
{
    CTreeView::OnInitialUpdate();
 
    CTreeCtrl& TreeCtrl = GetTreeCtrl();
    CTreeHelper CTreeHelper(&TreeCtrl);
     
    CTreeHelper.Populate();
}


Thanks again and everyone please forgive me for not making my question clearer from the beginning.


0
 
LVL 1

Expert Comment

by:ScottyDawg
ID: 2526753
Ooops yes - sorry I knocked it up hastily.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

706 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now