Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Adding CTreeCtrl to splitter window 1

Status
Not open for further replies.

titanandrews

Programmer
Feb 27, 2003
130
US
Hi,
I am attempting to create a tree control inside a splitter window, but I'm having a bit of difficulty. My code looks like this:
Code:
#include "stdafx.h"
#include "SplitterTest.h"

#include "ChildFrm.h"
#include "ATree.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CChildFrame

IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
	//{{AFX_MSG_MAP(CChildFrame)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChildFrame construction/destruction

CChildFrame::CChildFrame()
{
	// TODO: add member initialization code here
	
}

CChildFrame::~CChildFrame()
{
}

BOOL CChildFrame::OnCreateClient( LPCREATESTRUCT /*lpcs*/,CCreateContext* pContext)
{	

	ATree atree;	
	BOOL bCreate = m_wndSplitter.Create(this,1,2,CSize(50,50),pContext);
	m_wndSplitter.CreateView(0,0,atree.GetRuntimeClass(),CSize(100,100),pContext);

	return bCreate;

}

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	if( !CMDIChildWnd::PreCreateWindow(cs) )
		return FALSE;

	return TRUE;
}
I create the splitter window in the overriden OnCreateClient() function just like MFC doc says, but when I run in debug mode, I get an assertion failure in winsplit.cpp It tells me this: "Error: CreateView - pane already exists for row 0, 0"
Could someone kindly give me some guidance about what I am doing wrong? MFC doc is a little unclear (or maybe it's just me) and I can't seem to find any samples.

many thanks,

Barry
 
I did this very same thing in a program I wrote a while ago for parsing MP4 files.

I ended up making a "parent" CView class that contains a CSplitterWnd object, which I use to create two subordinate views - a CTreeView-based view and a CListView-based view.

Making the "parent" CView class was pretty straightforward. The nice thing is the subordinate views aren't even aware that they are part of a larger splitter window. They can be easily moved out of the splitter or even buried deeper in more levels of splitters.

Here are my .h and .cpp files:

------- mp4parseTreeStreamSplitView.h -------------------

class CMP4parseTreeStreamSplitView : public CView
{
DECLARE_DYNCREATE(CMP4parseTreeStreamSplitView)

public:
CMP4parseTreeStreamSplitView();

// Operations
public:
BOOL createViews (CCreateContext *pContext);

// Overrides
public:
virtual void OnDraw(CDC* /*pDC*/);

// Implementation
protected:
virtual ~CMP4parseTreeStreamSplitView();

protected:
CSplitterWnd m_wndSplitter;
bool m_wndSplitterCreated;

// Generated message map functions
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};


------- mp4parseTreeStreamSplitView.cpp -------------------



#include "stdafx.h"
#include "mp4parse.h"
#include "MP4parseTreeStreamSplitView.h"
#include "mp4parseDoc.h"
#include "mp4parseTreeView.h"
#include "mp4parseStreamView.h"


// CMP4parseTreeStreamSplitView

IMPLEMENT_DYNCREATE(CMP4parseTreeStreamSplitView, CView)
CMP4parseTreeStreamSplitView::CMP4parseTreeStreamSplitView()
: m_wndSplitterCreated (false)
{
}

CMP4parseTreeStreamSplitView::~CMP4parseTreeStreamSplitView()
{
}


BEGIN_MESSAGE_MAP(CMP4parseTreeStreamSplitView, CView)
ON_WM_SIZE()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()



// CMP4parseTreeStreamSplitView message handlers

BOOL CMP4parseTreeStreamSplitView::createViews (CCreateContext *pContext)
{
if (!m_wndSplitter.CreateStatic (this, 2, 1))
{
return FALSE;
}
if (!m_wndSplitter.CreateView
(0, 0, RUNTIME_CLASS (CMP4parseTreeView),
CSize (0, 400), pContext))
{
return FALSE;
}
if (!m_wndSplitter.CreateView
(1, 0, RUNTIME_CLASS (CMP4parseStreamView),
CSize (0, 100), pContext))
{
return FALSE;
}
m_wndSplitterCreated = true;
return TRUE;
}

void CMP4parseTreeStreamSplitView::OnDraw(CDC* /*pDC*/)
{
// TODO: Add your specialized code here and/or call the base class
}

void CMP4parseTreeStreamSplitView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

if (m_wndSplitterCreated)
{
m_wndSplitter.MoveWindow (0, 0, cx, cy);
}
}

BOOL CMP4parseTreeStreamSplitView::OnEraseBkgnd(CDC* pDC)
{
// Do nothing for this message, to turn off the
// default behavior where the
// window is erased with the background color.
return TRUE;
}

 
I forgot, I needed to call the createViews() method that I added, from the OnCreateClient() of my main frame. Here's my code for that:

// Create the two sub-views in the
// tree/stream splitter window.
CMP4parseTreeStreamSplitView *treeStreamSplitter
= static_cast<CMP4parseTreeStreamSplitView *>
(m_wndSplitter.GetPane (0, 0));
if (!treeStreamSplitter->createViews (pContext))
{
return FALSE;
}

In fact my tree/list splitter window is buried inside another splitter window (m_wndSplitter) which I create directly in the main frame like this:

// First create the splitter window.
if (!m_wndSplitter.CreateStatic (this, 1, 3))
{
return FALSE;
}

// Now create the three views in the splitter.
if (!m_wndSplitter.CreateView
(0, 0,
RUNTIME_CLASS (CMP4parseTreeStreamSplitView),
CSize (220, 0), pContext))
{
return FALSE;
}
if (!m_wndSplitter.CreateView
(0, 1, RUNTIME_CLASS (CMP4parseAtomView),
CSize (300, 0), pContext))
{
return FALSE;
}
if (!m_wndSplitter.CreateView
(0, 2, RUNTIME_CLASS (CMP4parseBinView),
CSize (400, 0), pContext))
{
return FALSE;
}

So this creates a static splitter in the main frame, containing three views. In the first pane I create my composite tree/list view, which is itself a splitter containing one tree view and one list view.

Sorry if it is a bit confusing but it does show how you can create splitters in either the main frame or inside one of your views.
 
In looking at the differences between your code and mine, I think mine works because I use CreateStatic() on the splitter, whereas you use Create().

Maybe if you just try CreateStatic() instead yours will work as is?
 
Hi,
Thanks for your valuable help! I used CreateStatic() and that worked. I also had to switch my CTreeCtrl to a CTreeView. But now I am a little confused about this. I tried to add an item to the tree, but I do not get a tree in my splitter window. The splitter shows fine, but there is no tree in it. Why would this be? In my CTreeView subclass constructor, I have this:
Code:
CTreeCtrl& ctrl = this->GetTreeCtrl();
ctrl.InsertItem(_T(&quot;Hello&quot;), 0, 0);
Is there anything else I need to do?

many thanks,

Barry
 
Sorry about not posting this earlier. I've been busy with the holidays. :)

I use the version of CTreeView::InsertItem that takes a &quot;TVINSERTSTRUCT&quot; argument. For example, here's the beginning of the code from my program that adds stuff to the tree. This works for me. I'm not sure why you don't see a tree in yours...

------------------------------------------------
void CMP4parseTreeView::buildTree ()
{
// Get handle to the document.
CMP4parseDoc *pDoc = GetDocument ();

// Clear out previous data in tree.
CTreeCtrl &ctrl = GetTreeCtrl ();
ctrl.DeleteAllItems ();
m_treeMap.clear ();

// Set up the root node of the tree to represent the whole file.
TVINSERTSTRUCT item;
item.hParent = TVI_ROOT;
item.hInsertAfter = TVI_LAST;
item.item.mask = TVIF_PARAM | TVIF_STATE | TVIF_TEXT;
CString fileName = pDoc->getFileName ();
item.item.pszText = fileName.GetBuffer ();
item.item.lParam = static_cast<LPARAM> (-1);
item.item.state = item.item.stateMask = TVIS_EXPANDED;
m_treeMap [0] = ctrl.InsertItem (&item);

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top