Solved

Using CTreeCtrl From A Derived Class

Posted on 2000-02-15
20
460 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
[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
  • 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
Industry Leaders: 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 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
 
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
haveThree challenge 22 126
Fibonacci challenge 11 140
Excel file not created as expected 7 106
How do I get Window Title of all opened process? 4 58
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 …
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.
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Suggested Courses

738 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