// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "TreeStateSaverDemo.h"
#include "ChildView.h"
#include "TBTreeStateMgr.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChildView
CChildView::CChildView()
{
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView,CWnd )
//{{AFX_MSG_MAP(CChildView)
ON_WM_PAINT()
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
}
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd ::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
wnd_Splitter.CreateStatic(this, 1,4);
// The context information is passed on from the framework
CCreateContext *pContext = (CCreateContext*)lpCreateStruct->lpCreateParams;
// Create two views
CRect rect;
GetClientRect(&rect);
int w=rect.Width()/4;
int h=rect.Height()/4;
wnd_Splitter.CreateView(0,0,RUNTIME_CLASS(CTreeView),CSize(w,h), pContext);
wnd_Splitter.CreateView(0,1,RUNTIME_CLASS(CTreeView),CSize(w,h), pContext);
wnd_Splitter.CreateView(0,2,RUNTIME_CLASS(CTreeView),CSize(w,h), pContext);
wnd_Splitter.CreateView(0,3,RUNTIME_CLASS(CTreeView),CSize(w,h), pContext);
wnd_Splitter.SetColumnInfo(0,150,80);
wnd_Splitter.SetColumnInfo(1,150,80);
wnd_Splitter.SetColumnInfo(2,150,80);
wnd_Splitter.SetColumnInfo(3,150,80);
// Set the pointers ..
wnd_Tree1= (CTreeView*) wnd_Splitter.GetPane(0,0);
wnd_Tree2= (CTreeView*) wnd_Splitter.GetPane(0,1);
wnd_Tree3= (CTreeView*) wnd_Splitter.GetPane(0,2);
wnd_Tree4= (CTreeView*) wnd_Splitter.GetPane(0,3);
// Styles
DWORD newstyle=TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP ;
wnd_Tree1->GetTreeCtrl().ModifyStyle(NULL,newstyle);
wnd_Tree2->GetTreeCtrl().ModifyStyle(NULL,newstyle);
wnd_Tree3->GetTreeCtrl().ModifyStyle(NULL,newstyle);
wnd_Tree4->GetTreeCtrl().ModifyStyle(NULL,newstyle);
ASSERT( wnd_Tree1!= NULL);
ASSERT( wnd_Tree2!= NULL);
ASSERT( wnd_Tree3!= NULL);
ASSERT( wnd_Tree4!= NULL);
LoadTree(wnd_Tree1->GetTreeCtrl());
LoadTree(wnd_Tree2->GetTreeCtrl());
LoadTree(wnd_Tree3->GetTreeCtrl());
// LoadTree(wnd_Tree4->GetTreeCtrl());
LoadGiantTree(wnd_Tree4->GetTreeCtrl());
//Load all the control states
TBTreeStateMgr::LoadTreeState(_T("My Tree Control 1"),&(wnd_Tree1->GetTreeCtrl()));
TBTreeStateMgr::LoadTreeState(_T("Second Tree"),&(wnd_Tree2->GetTreeCtrl()));
TBTreeStateMgr::LoadTreeState(_T("Bad Tree #3"),&(wnd_Tree3->GetTreeCtrl()));
TBTreeStateMgr::LoadTreeState(_T("Huge Tree 200K"),&(wnd_Tree4->GetTreeCtrl()));
return 0;
}
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd ::OnSize(nType, cx, cy);
wnd_Splitter.MoveWindow(0,0,cx,cy);
}
void CChildView::LoadTree(CTreeCtrl & ctrl)
{
HTREEITEM cars,movies,girls;
static const NODEINFO_T TREEDATA[] =
{
{NULL,"Cars"},
{NULL,"Movies"},
{NULL,"Girls"},
{"Cars","Electric"},
{"Cars","Normal"},
{"Cars","Giant Sneaker"},
{"Electric","Honda EV"},
{"Normal","Buick"},
{"Normal","Mazda"},
{"Normal","Jeep"},
{"Normal","Toyota"},
{"Buick","1994 Lesabre"},
{"Buick","1989 Lesabre"},
{"Buick","1990 Century"},
{"Buick","1994 Riviera"},
{"Mazda","1998 Protege"},
{"Mazda","2002 Protege"},
{"Mazda","Old model Protege"},
{"Mazda","Old model Protege"},
{"Mazda","Old model Miata"},
{"Jeep","1997 Cherokee Sport"},
{"Jeep","1997 Cherokee Sport"},
{"Jeep","1997 Cherokee Sport"},
{"Jeep","1997 Cherokee Sport"},
{"Giant Sneaker","Ford Expedition"},
{"Giant Sneaker","Ford Excursion [8 mpg]"},
{"Giant Sneaker","Land Rover Discovery"},
{"Movies","Best"},
{"Movies","Worst"},
{"Best","Freddy Got Fingered"},
{"Best","Dude! Wheres my car"},
{"Best","Planet of the apes - I"},
{"Worst","Planet of the apes - II"},
{"Worst","Planet of the apes - III"},
{"Worst","Planet of the apes - IV"},
{"Worst","Planet of the apes - V"},
{"Worst","Planet of the apes - VI"},
{"Girls","Hot"},
{"Girls","Cold"},
{"Hot","Anna Kournikova"},
{"Cold","Rosie O Donnell"},
{NULL,NULL},
};
//Load data
cars=ctrl.InsertItem("Cars",TVI_ROOT);
movies=ctrl.InsertItem("Movies",TVI_ROOT);
girls=ctrl.InsertItem("Girls",TVI_ROOT);
LoadTreeData(cars,"Cars",&TREEDATA[0],ctrl);
LoadTreeData(movies,"Movies",&TREEDATA[0],ctrl);
LoadTreeData(girls,"Girls",&TREEDATA[0],ctrl);
}
void CChildView::LoadTreeData(HTREEITEM hParent,
LPCSTR name,
const NODEINFO_T * pTreeData,
CTreeCtrl &ctrl)
{
const NODEINFO_T * oneNode;
HTREEITEM hItem;
oneNode=pTreeData;
while (oneNode->parentItem!=NULL||oneNode->text!=NULL)
{
if (oneNode->parentItem!=NULL&&!strcmp(oneNode->parentItem,name)){
hItem=ctrl.InsertItem(oneNode->text,hParent);
LoadTreeData(hItem,oneNode->text,pTreeData,ctrl);
}
++oneNode;
}
}
void CChildView::OnDestroy()
{
//Save all the control states
TBTreeStateMgr::SaveTreeState(_T("My Tree Control 1"),&(wnd_Tree1->GetTreeCtrl()));
TBTreeStateMgr::SaveTreeState(_T("Second Tree"),&(wnd_Tree2->GetTreeCtrl()));
TBTreeStateMgr::SaveTreeState(_T("Bad Tree #3"),&(wnd_Tree3->GetTreeCtrl()));
TBTreeStateMgr::SaveTreeState(_T("Huge Tree 200K"),&(wnd_Tree4->GetTreeCtrl()));
//For large tree to destroy quickly
ULONG otc=GetTickCount();
wnd_Tree4->GetTreeCtrl().SetRedraw(FALSE);
wnd_Tree4->GetTreeCtrl().ShowWindow(SW_HIDE);
wnd_Tree4->GetTreeCtrl().DeleteAllItems();
TRACE("Deleted the large tree in %u msecs\n",GetTickCount()-otc);
CWnd ::OnDestroy();
}
void CChildView::LoadGiantTree(CTreeCtrl &ctrl)
{
// A huge tree needs to be created as below
ctrl.ShowWindow(SW_HIDE);
ctrl.SetRedraw(FALSE);
PopulateLargeTree(TVI_ROOT,888,0,8,&ctrl);
ctrl.ShowWindow(SW_SHOW);
ctrl.SetRedraw(TRUE);
}
// Generate and populate a large tree
// Ensure top level nodes are large (at least 1000 )
void CChildView::PopulateLargeTree(HTREEITEM hParent,
ULONG nChildren,
ULONG nCurrDepth,
ULONG nMaxDepth,
CTreeCtrl * pTree)
{
const ULONG MAXITEMS = 50000;
HTREEITEM hChild;
static ULONG nRandChildren;
static TCHAR buf[32];
static ULONG nCurrItem=0L;
// If maxdepth stop recursion
if(nCurrDepth>=nMaxDepth) return;
// Add n' Children to the tree
for (ULONG j=0;j<nChildren;j++)
{
//Do we need to stop now
if(++nCurrItem>=MAXITEMS) break;
//Make a text
wsprintf(buf,"Item-#%u-%u",j,nCurrItem);
//Trace every 500
if(!(nCurrItem%2000))TRACE("%u:\t\t%s\n",nCurrItem,buf);
//Insert
hChild=pTree->InsertItem(buf,hParent);
//Recursion
//Random number of children required between 100-800
nRandChildren=rand()%200;
PopulateLargeTree(hChild,nRandChildren,nCurrDepth+1,nMaxDepth,pTree);
}
}