|
|
/*******************************************************************************
* * basetree.cpp * * implementation of the CBaseTreeView class * * copyright notice: Copyright 1997, Citrix Systems Inc. * Copyright (c) 1998 - 1999 Microsoft Corporation * * $Author: donm $ Don Messerli * * $Log: N:\nt\private\utils\citrix\winutils\tsadmin\VCS\basetree.cpp $ * * Rev 1.4 19 Feb 1998 17:39:58 donm * removed latest extension DLL support * * Rev 1.2 19 Jan 1998 17:03:10 donm * new ui behavior for domains and servers * * Rev 1.1 03 Nov 1997 15:21:28 donm * update * * Rev 1.0 13 Oct 1997 22:31:30 donm * Initial revision. * *******************************************************************************/
#include "stdafx.h"
#include "winadmin.h"
#include "admindoc.h"
#include "basetree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////
// MESSAGE MAP: CBaseTreeView
//
IMPLEMENT_DYNCREATE(CBaseTreeView, CTreeView)
BEGIN_MESSAGE_MAP(CBaseTreeView, CTreeView) //{{AFX_MSG_MAP(CBaseTreeView)
ON_MESSAGE(WM_ADMIN_EXPANDALL, OnExpandAll) ON_MESSAGE(WM_ADMIN_COLLAPSEALL, OnCollapseAll) ON_MESSAGE(WM_ADMIN_COLLAPSETOSERVERS, OnCollapseToThirdLevel) ON_MESSAGE(WM_ADMIN_COLLAPSETODOMAINS, OnCollapseToRootChildren) ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChange) ON_WM_DESTROY() //}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////
// F'N: CBaseTreeView ctor
//
CBaseTreeView::CBaseTreeView() { m_bInitialExpand = FALSE;
} // end CBaseTreeView ctor
//////////////////////////
// F'N: CBaseTreeView dtor
//
CBaseTreeView::~CBaseTreeView() {
} // end CBaseTreeView dtor
/////////////////////////////
// F'N: CBaseTreeView::OnDraw
//
void CBaseTreeView::OnDraw(CDC* pDC) { CWinAdminDoc* pDoc = (CWinAdminDoc*)GetDocument(); ASSERT(pDoc != NULL); ASSERT_VALID(pDoc); } // end CBaseTreeView::OnDraw
#ifdef _DEBUG
//////////////////////////////////
// F'N: CBaseTreeView::AssertValid
//
void CBaseTreeView::AssertValid() const { CTreeView::AssertValid();
} // end CBaseTreeView::AssertValid
///////////////////////////
// F'N: CBaseTreeView::Dump
//
void CBaseTreeView::Dump(CDumpContext& dc) const { CTreeView::Dump(dc);
} // end CBaseTreeView::Dump
#endif
//////////////////////////////////////
// F'N: CBaseTreeView::PreCreateWindow
//
BOOL CBaseTreeView::PreCreateWindow(CREATESTRUCT& cs) { // Set the style bits for the CTreeCtrl
cs.style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS; return CTreeView::PreCreateWindow(cs);
} // end CBaseTreeView::PreCreateWindow
/////////////////////////////////////
// F'N: CBaseTreeView::BuildImageList
//
void CBaseTreeView::BuildImageList() { // do nothing
} // end CBaseTreeView::BuildImageList
//////////////////////////////////////
// F'N: CBaseTreeView::OnInitialUpdate
//
// - constructs the image list for the tree, saving indices to each icon
// in member variables (m_idxCitrix, m_idxServer, etc.)
//
void CBaseTreeView::OnInitialUpdate() { CTreeView::OnInitialUpdate();
// build the image list for the tree control
BuildImageList(); } // end CBaseTreeView::OnInitialUpdate
/////////////////////////////////////////
// F'N: CBaseTreeView::AddIconToImageList
//
// - loads the appropriate icon, adds it to m_ImageList, and returns
// the newly-added icon's index in the image list
//
int CBaseTreeView::AddIconToImageList(int iconID) { HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID)); return m_ImageList.Add(hIcon);
} // end CBaseTreeView::AddIconToImageList
////////////////////////////////////
// F'N: CBaseTreeView::AddItemToTree
//
// Adds an item with the given attributes to the CTreeCtrl
//
HTREEITEM CBaseTreeView::AddItemToTree(HTREEITEM hParent, CString szText, HTREEITEM hInsAfter, int iImage, LPARAM lParam) { HTREEITEM hItem; TV_ITEM tvItem = {0}; TV_INSERTSTRUCT tvInsert;
ASSERT(lParam);
tvItem.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; TCHAR temp[255]; lstrcpyn(temp, szText, sizeof(temp) / sizeof(TCHAR)); tvItem.pszText = temp; tvItem.cchTextMax = lstrlen(szText); tvItem.iImage = iImage; tvItem.iSelectedImage = iImage; tvItem.lParam = lParam;
tvInsert.item = tvItem; tvInsert.hInsertAfter = hInsAfter; tvInsert.hParent = hParent;
hItem = GetTreeCtrl().InsertItem(&tvInsert);
if(!m_bInitialExpand && hItem) { m_bInitialExpand = GetTreeCtrl().Expand(GetTreeCtrl().GetRootItem(), TVE_EXPAND); }
return hItem;
} // end CBaseTreeView::AddItemToTree
///////////////////////////////////
// F'N: CBaseTreeView::GetCurrentNode
//
DWORD_PTR CBaseTreeView::GetCurrentNode() { LockTreeControl(); HTREEITEM hCurr = GetTreeCtrl().GetSelectedItem(); DWORD_PTR node = GetTreeCtrl().GetItemData(hCurr); UnlockTreeControl(); return node;
} // end CBaseTreeView::GetCurrentNode
///////////////////////////////////
// F'N: CBaseTreeView::OnSelChange
//
// - this f'n posts a WM_ADMIN_CHANGEVIEW message to the mainframe, passing along
// a pointer to the newly selected tree item's info structure in lParam so
// that the mainframe can make an intelligent decision as far as how to
// interpret the message
//
// Passes TRUE as wParam for WM_ADMIN_CHANGEVIEW message to signify
// that the message was caused by a user mouse click
//
void CBaseTreeView::OnSelChange(NMHDR* pNMHDR, LRESULT* pResult) { LockTreeControl(); HTREEITEM hCurr = GetTreeCtrl().GetSelectedItem(); DWORD_PTR value = GetTreeCtrl().GetItemData(hCurr); UnlockTreeControl();
// Tell the document that the current item in the tree has changed
CTreeNode *pNode = (CTreeNode*)value; if( pNode != NULL ) { ((CWinAdminDoc*)GetDocument())->SetCurrentView(VIEW_CHANGING);
((CWinAdminDoc*)GetDocument())->SetTreeCurrent( pNode->GetTreeObject(), pNode->GetNodeType()); // send a "change view" msg to the mainframe with the info structure ptr as a parm
CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd(); pMainWnd->SendMessage(WM_ADMIN_CHANGEVIEW, *pResult == 0xc0 ? TRUE : FALSE , (LPARAM)pNode); }
*pResult = 0;
} // end CBaseTreeView::OnSelChange
///////////////////////////////////
// F'N: CBaseTreeView::ForceSelChange
//
// Called by treeview when the state of an item in the tree has changed
// which is likely to cause the current view in the right pane to change.
//
// This f'n posts a WM_ADMIN_CHANGEVIEW message to the mainframe, passing along
// a pointer to the newly selected tree item's info structure in lParam so
// that the mainframe can make an intelligent decision as far as how to
// interpret the message
//
// Puts a FALSE in wParam of the WM_ADMIN_CHANGEVIEW message which
// tells the right pane that this was not caused by a user clicking
// on the item in the tree
//
void CBaseTreeView::ForceSelChange() { LockTreeControl(); HTREEITEM hCurr = GetTreeCtrl().GetSelectedItem(); DWORD_PTR value = GetTreeCtrl().GetItemData(hCurr); UnlockTreeControl();
// Tell the document that the current item in the tree has changed
((CWinAdminDoc*)GetDocument())->SetCurrentView(VIEW_CHANGING); ((CWinAdminDoc*)GetDocument())->SetTreeCurrent(((CTreeNode*)value)->GetTreeObject(), ((CTreeNode*)value)->GetNodeType());
// send a "change view" msg to the mainframe with the info structure ptr as a parm
CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd(); pMainWnd->PostMessage(WM_ADMIN_CHANGEVIEW, FALSE, (LPARAM)value); // SendMessage causes blank pages
} // end CBaseTreeView::ForceSelChange
////////////////////////////////
// F'N: CBaseTreeView::OnExpandAll
//
// Expands all levels of the tree, starting at the root
//
LRESULT CBaseTreeView::OnExpandAll(WPARAM wParam, LPARAM lParam) { LockTreeControl(); // get a count of the items in the tree
UINT itemCount = GetTreeCtrl().GetCount();
// get the handle of the root item and Expand it
HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem(); for(UINT i = 0; i < itemCount; i++) { GetTreeCtrl().Expand(hTreeItem, TVE_EXPAND); hTreeItem = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_NEXTVISIBLE); }
UnlockTreeControl();
return 0; } // end CBaseTreeView::OnExpandAll
////////////////////////////////
// F'N: CBaseTreeView::Collapse
//
// Helper function to collapse a tree item
// NOTE: This function calls itself recursively
//
void CBaseTreeView::Collapse(HTREEITEM hItem) { LockTreeControl();
CTreeCtrl &tree = GetTreeCtrl();
// Get his first child and collapse him
HTREEITEM hChild = tree.GetNextItem(hItem, TVGN_CHILD); if(hChild) Collapse(hChild); // Collapse him
tree.Expand(hItem, TVE_COLLAPSE); // Get his first sibling and collapse him
HTREEITEM hSibling = tree.GetNextItem(hItem, TVGN_NEXT); if(hSibling) Collapse(hSibling);
UnlockTreeControl(); } // end CBaseTreeView::Collapse
////////////////////////////////
// F'N: CBaseTreeView::OnCollapseAll
//
// Collapses all levels of the tree, starting at the root
//
LRESULT CBaseTreeView::OnCollapseAll(WPARAM wParam, LPARAM lParam) { // Call the recursive function to do all
// the collapsing
Collapse(GetTreeCtrl().GetRootItem());
return 0;
} // end CBaseTreeView::OnCollapseAll
////////////////////////////////
// F'N: CBaseTreeView::OnCollapseToThirdLevel
//
// Collapses tree down to show just root children and their children
//
LRESULT CBaseTreeView::OnCollapseToThirdLevel(WPARAM wParam, LPARAM lParam) { UINT i = 0;
LockTreeControl(); // Get the root item
HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem();
// Collapse to Root Child for First two nodes. They are This Computer and Favorite Servers
while (hTreeItem && i < 2) {
i++;
// Get the first node
HTREEITEM hNode = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_CHILD); while(hNode) { Collapse(hNode); // go to the next node
hNode = GetTreeCtrl().GetNextItem(hNode, TVGN_NEXT); }
hTreeItem = GetTreeCtrl().GetNextSiblingItem(hTreeItem); }
if (hTreeItem) { // Get the first node
HTREEITEM hRootChild = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_CHILD); while(hRootChild) { HTREEITEM hThirdLevel = GetTreeCtrl().GetNextItem(hRootChild, TVGN_CHILD); while(hThirdLevel) { // collapse him
GetTreeCtrl().Expand(hThirdLevel, TVE_COLLAPSE); // go to the next one
hThirdLevel = GetTreeCtrl().GetNextItem(hThirdLevel, TVGN_NEXT); } hRootChild = GetTreeCtrl().GetNextItem(hRootChild, TVGN_NEXT); } }
UnlockTreeControl();
return 0;
} // end CBaseTreeView::OnCollapseToThirdLevel
////////////////////////////////
// F'N: CBaseTreeView::OnCollapseToRootChildren
//
// Collapses tree down to show just root and it's immediate children
//
LRESULT CBaseTreeView::OnCollapseToRootChildren(WPARAM wParam, LPARAM lParam) { LockTreeControl();
// Get the root item
HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem();
// Skip This Computer and Favorite Servers
if (hTreeItem) { hTreeItem = GetTreeCtrl().GetNextSiblingItem(hTreeItem); if (hTreeItem) { hTreeItem = GetTreeCtrl().GetNextSiblingItem(hTreeItem); } }
if(hTreeItem) {
// Get the first node
HTREEITEM hNode = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_CHILD); while(hNode) { Collapse(hNode); // go to the next node
hNode = GetTreeCtrl().GetNextItem(hNode, TVGN_NEXT); } }
UnlockTreeControl();
return 0;
} // end CBaseTreeView::OnCollapseToRootChildren
////////////////////////////////
// F'N: CBaseTreeView::OnDestroy
//
void CBaseTreeView::OnDestroy() { LockTreeControl();
UINT itemCount = GetTreeCtrl().GetCount();
HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem(); for(UINT i = 0; i < itemCount; i++) { CTreeNode *node = ((CTreeNode*)GetTreeCtrl().GetItemData(hTreeItem)); delete (CTreeNode*)(GetTreeCtrl().GetItemData(hTreeItem)); hTreeItem = GetNextItem(hTreeItem); }
UnlockTreeControl();
} // end CBaseTreeView::OnDestroy
////////////////////////////////
// F'N: CBaseTreeView::GetNextItem
//
// GetNextItem - Get next item as if outline was completely expanded
// Returns - The item immediately below the reference item
// hItem - The reference item
//
HTREEITEM CBaseTreeView::GetNextItem( HTREEITEM hItem ) { HTREEITEM hti; CTreeCtrl &tree = GetTreeCtrl(); if(tree.ItemHasChildren( hItem ) ) return tree.GetChildItem( hItem ); // return first child
else { // return next sibling item
// Go up the tree to find a parent's sibling if needed.
while( (hti = tree.GetNextSiblingItem( hItem )) == NULL ) { if( (hItem = tree.GetParentItem( hItem ) ) == NULL ) return NULL; } }
return hti;
} // end CBaseTreeView::GetNextItem
|