Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

453 lines
12 KiB

  1. /*******************************************************************************
  2. *
  3. * basetree.cpp
  4. *
  5. * implementation of the CBaseTreeView class
  6. *
  7. * copyright notice: Copyright 1997, Citrix Systems Inc.
  8. * Copyright (c) 1998 - 1999 Microsoft Corporation
  9. *
  10. * $Author: donm $ Don Messerli
  11. *
  12. * $Log: N:\nt\private\utils\citrix\winutils\tsadmin\VCS\basetree.cpp $
  13. *
  14. * Rev 1.4 19 Feb 1998 17:39:58 donm
  15. * removed latest extension DLL support
  16. *
  17. * Rev 1.2 19 Jan 1998 17:03:10 donm
  18. * new ui behavior for domains and servers
  19. *
  20. * Rev 1.1 03 Nov 1997 15:21:28 donm
  21. * update
  22. *
  23. * Rev 1.0 13 Oct 1997 22:31:30 donm
  24. * Initial revision.
  25. *
  26. *******************************************************************************/
  27. #include "stdafx.h"
  28. #include "winadmin.h"
  29. #include "admindoc.h"
  30. #include "basetree.h"
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. /////////////////////////////
  37. // MESSAGE MAP: CBaseTreeView
  38. //
  39. IMPLEMENT_DYNCREATE(CBaseTreeView, CTreeView)
  40. BEGIN_MESSAGE_MAP(CBaseTreeView, CTreeView)
  41. //{{AFX_MSG_MAP(CBaseTreeView)
  42. ON_MESSAGE(WM_ADMIN_EXPANDALL, OnExpandAll)
  43. ON_MESSAGE(WM_ADMIN_COLLAPSEALL, OnCollapseAll)
  44. ON_MESSAGE(WM_ADMIN_COLLAPSETOSERVERS, OnCollapseToThirdLevel)
  45. ON_MESSAGE(WM_ADMIN_COLLAPSETODOMAINS, OnCollapseToRootChildren)
  46. ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChange)
  47. ON_WM_DESTROY()
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. //////////////////////////
  51. // F'N: CBaseTreeView ctor
  52. //
  53. CBaseTreeView::CBaseTreeView()
  54. {
  55. m_bInitialExpand = FALSE;
  56. } // end CBaseTreeView ctor
  57. //////////////////////////
  58. // F'N: CBaseTreeView dtor
  59. //
  60. CBaseTreeView::~CBaseTreeView()
  61. {
  62. } // end CBaseTreeView dtor
  63. /////////////////////////////
  64. // F'N: CBaseTreeView::OnDraw
  65. //
  66. void CBaseTreeView::OnDraw(CDC* pDC)
  67. {
  68. CWinAdminDoc* pDoc = (CWinAdminDoc*)GetDocument();
  69. ASSERT(pDoc != NULL);
  70. ASSERT_VALID(pDoc);
  71. } // end CBaseTreeView::OnDraw
  72. #ifdef _DEBUG
  73. //////////////////////////////////
  74. // F'N: CBaseTreeView::AssertValid
  75. //
  76. void CBaseTreeView::AssertValid() const
  77. {
  78. CTreeView::AssertValid();
  79. } // end CBaseTreeView::AssertValid
  80. ///////////////////////////
  81. // F'N: CBaseTreeView::Dump
  82. //
  83. void CBaseTreeView::Dump(CDumpContext& dc) const
  84. {
  85. CTreeView::Dump(dc);
  86. } // end CBaseTreeView::Dump
  87. #endif
  88. //////////////////////////////////////
  89. // F'N: CBaseTreeView::PreCreateWindow
  90. //
  91. BOOL CBaseTreeView::PreCreateWindow(CREATESTRUCT& cs)
  92. {
  93. // Set the style bits for the CTreeCtrl
  94. cs.style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP
  95. | TVS_SHOWSELALWAYS;
  96. return CTreeView::PreCreateWindow(cs);
  97. } // end CBaseTreeView::PreCreateWindow
  98. /////////////////////////////////////
  99. // F'N: CBaseTreeView::BuildImageList
  100. //
  101. void CBaseTreeView::BuildImageList()
  102. {
  103. // do nothing
  104. } // end CBaseTreeView::BuildImageList
  105. //////////////////////////////////////
  106. // F'N: CBaseTreeView::OnInitialUpdate
  107. //
  108. // - constructs the image list for the tree, saving indices to each icon
  109. // in member variables (m_idxCitrix, m_idxServer, etc.)
  110. //
  111. void CBaseTreeView::OnInitialUpdate()
  112. {
  113. CTreeView::OnInitialUpdate();
  114. // build the image list for the tree control
  115. BuildImageList();
  116. } // end CBaseTreeView::OnInitialUpdate
  117. /////////////////////////////////////////
  118. // F'N: CBaseTreeView::AddIconToImageList
  119. //
  120. // - loads the appropriate icon, adds it to m_ImageList, and returns
  121. // the newly-added icon's index in the image list
  122. //
  123. int CBaseTreeView::AddIconToImageList(int iconID)
  124. {
  125. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  126. return m_ImageList.Add(hIcon);
  127. } // end CBaseTreeView::AddIconToImageList
  128. ////////////////////////////////////
  129. // F'N: CBaseTreeView::AddItemToTree
  130. //
  131. // Adds an item with the given attributes to the CTreeCtrl
  132. //
  133. HTREEITEM CBaseTreeView::AddItemToTree(HTREEITEM hParent, CString szText, HTREEITEM hInsAfter, int iImage, LPARAM lParam)
  134. {
  135. HTREEITEM hItem;
  136. TV_ITEM tvItem = {0};
  137. TV_INSERTSTRUCT tvInsert;
  138. ASSERT(lParam);
  139. tvItem.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  140. TCHAR temp[255];
  141. wcscpy(temp, szText);
  142. tvItem.pszText = temp;
  143. tvItem.cchTextMax = lstrlen(szText);
  144. tvItem.iImage = iImage;
  145. tvItem.iSelectedImage = iImage;
  146. tvItem.lParam = lParam;
  147. tvInsert.item = tvItem;
  148. tvInsert.hInsertAfter = hInsAfter;
  149. tvInsert.hParent = hParent;
  150. hItem = GetTreeCtrl().InsertItem(&tvInsert);
  151. if(!m_bInitialExpand && hItem) {
  152. m_bInitialExpand = GetTreeCtrl().Expand(GetTreeCtrl().GetRootItem(), TVE_EXPAND);
  153. }
  154. return hItem;
  155. } // end CBaseTreeView::AddItemToTree
  156. ///////////////////////////////////
  157. // F'N: CBaseTreeView::GetCurrentNode
  158. //
  159. DWORD_PTR CBaseTreeView::GetCurrentNode()
  160. {
  161. LockTreeControl();
  162. HTREEITEM hCurr = GetTreeCtrl().GetSelectedItem();
  163. DWORD_PTR node = GetTreeCtrl().GetItemData(hCurr);
  164. UnlockTreeControl();
  165. return node;
  166. } // end CBaseTreeView::GetCurrentNode
  167. ///////////////////////////////////
  168. // F'N: CBaseTreeView::OnSelChange
  169. //
  170. // - this f'n posts a WM_ADMIN_CHANGEVIEW message to the mainframe, passing along
  171. // a pointer to the newly selected tree item's info structure in lParam so
  172. // that the mainframe can make an intelligent decision as far as how to
  173. // interpret the message
  174. //
  175. // Passes TRUE as wParam for WM_ADMIN_CHANGEVIEW message to signify
  176. // that the message was caused by a user mouse click
  177. //
  178. void CBaseTreeView::OnSelChange(NMHDR* pNMHDR, LRESULT* pResult)
  179. {
  180. LockTreeControl();
  181. HTREEITEM hCurr = GetTreeCtrl().GetSelectedItem();
  182. DWORD_PTR value = GetTreeCtrl().GetItemData(hCurr);
  183. UnlockTreeControl();
  184. // Tell the document that the current item in the tree has changed
  185. CTreeNode *pNode = (CTreeNode*)value;
  186. if( pNode != NULL )
  187. {
  188. ((CWinAdminDoc*)GetDocument())->SetCurrentView(VIEW_CHANGING);
  189. ((CWinAdminDoc*)GetDocument())->SetTreeCurrent( pNode->GetTreeObject(), pNode->GetNodeType());
  190. // send a "change view" msg to the mainframe with the info structure ptr as a parm
  191. CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd();
  192. pMainWnd->PostMessage(WM_ADMIN_CHANGEVIEW, *pResult == 0xc0 ? TRUE : FALSE , (LPARAM)pNode); // SendMessage causes blank pages
  193. }
  194. *pResult = 0;
  195. } // end CBaseTreeView::OnSelChange
  196. ///////////////////////////////////
  197. // F'N: CBaseTreeView::ForceSelChange
  198. //
  199. // Called by treeview when the state of an item in the tree has changed
  200. // which is likely to cause the current view in the right pane to change.
  201. //
  202. // This f'n posts a WM_ADMIN_CHANGEVIEW message to the mainframe, passing along
  203. // a pointer to the newly selected tree item's info structure in lParam so
  204. // that the mainframe can make an intelligent decision as far as how to
  205. // interpret the message
  206. //
  207. // Puts a FALSE in wParam of the WM_ADMIN_CHANGEVIEW message which
  208. // tells the right pane that this was not caused by a user clicking
  209. // on the item in the tree
  210. //
  211. void CBaseTreeView::ForceSelChange()
  212. {
  213. LockTreeControl();
  214. HTREEITEM hCurr = GetTreeCtrl().GetSelectedItem();
  215. DWORD_PTR value = GetTreeCtrl().GetItemData(hCurr);
  216. UnlockTreeControl();
  217. // Tell the document that the current item in the tree has changed
  218. ((CWinAdminDoc*)GetDocument())->SetCurrentView(VIEW_CHANGING);
  219. ((CWinAdminDoc*)GetDocument())->SetTreeCurrent(((CTreeNode*)value)->GetTreeObject(), ((CTreeNode*)value)->GetNodeType());
  220. // send a "change view" msg to the mainframe with the info structure ptr as a parm
  221. CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd();
  222. pMainWnd->PostMessage(WM_ADMIN_CHANGEVIEW, FALSE, (LPARAM)value); // SendMessage causes blank pages
  223. } // end CBaseTreeView::ForceSelChange
  224. ////////////////////////////////
  225. // F'N: CBaseTreeView::OnExpandAll
  226. //
  227. // Expands all levels of the tree, starting at the root
  228. //
  229. LRESULT CBaseTreeView::OnExpandAll(WPARAM wParam, LPARAM lParam)
  230. {
  231. LockTreeControl();
  232. // get a count of the items in the tree
  233. UINT itemCount = GetTreeCtrl().GetCount();
  234. // get the handle of the root item and Expand it
  235. HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem();
  236. for(UINT i = 0; i < itemCount; i++) {
  237. GetTreeCtrl().Expand(hTreeItem, TVE_EXPAND);
  238. hTreeItem = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_NEXTVISIBLE);
  239. }
  240. UnlockTreeControl();
  241. return 0;
  242. } // end CBaseTreeView::OnExpandAll
  243. ////////////////////////////////
  244. // F'N: CBaseTreeView::Collapse
  245. //
  246. // Helper function to collapse a tree item
  247. // NOTE: This function calls itself recursively
  248. //
  249. void CBaseTreeView::Collapse(HTREEITEM hItem)
  250. {
  251. LockTreeControl();
  252. CTreeCtrl &tree = GetTreeCtrl();
  253. // Get his first child and collapse him
  254. HTREEITEM hChild = tree.GetNextItem(hItem, TVGN_CHILD);
  255. if(hChild) Collapse(hChild);
  256. // Collapse him
  257. tree.Expand(hItem, TVE_COLLAPSE);
  258. // Get his first sibling and collapse him
  259. HTREEITEM hSibling = tree.GetNextItem(hItem, TVGN_NEXT);
  260. if(hSibling) Collapse(hSibling);
  261. UnlockTreeControl();
  262. } // end CBaseTreeView::Collapse
  263. ////////////////////////////////
  264. // F'N: CBaseTreeView::OnCollapseAll
  265. //
  266. // Collapses all levels of the tree, starting at the root
  267. //
  268. LRESULT CBaseTreeView::OnCollapseAll(WPARAM wParam, LPARAM lParam)
  269. {
  270. // Call the recursive function to do all
  271. // the collapsing
  272. Collapse(GetTreeCtrl().GetRootItem());
  273. return 0;
  274. } // end CBaseTreeView::OnCollapseAll
  275. ////////////////////////////////
  276. // F'N: CBaseTreeView::OnCollapseToThirdLevel
  277. //
  278. // Collapses tree down to show just root children and their children
  279. //
  280. LRESULT CBaseTreeView::OnCollapseToThirdLevel(WPARAM wParam, LPARAM lParam)
  281. {
  282. LockTreeControl();
  283. // Get the root item
  284. HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem();
  285. // Get the first node
  286. HTREEITEM hRootChild = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_CHILD);
  287. while(hRootChild) {
  288. HTREEITEM hThirdLevel = GetTreeCtrl().GetNextItem(hRootChild, TVGN_CHILD);
  289. while(hThirdLevel) {
  290. // collapse him
  291. GetTreeCtrl().Expand(hThirdLevel, TVE_COLLAPSE);
  292. // go to the next one
  293. hThirdLevel = GetTreeCtrl().GetNextItem(hThirdLevel, TVGN_NEXT);
  294. }
  295. hRootChild = GetTreeCtrl().GetNextItem(hRootChild, TVGN_NEXT);
  296. }
  297. UnlockTreeControl();
  298. return 0;
  299. } // end CBaseTreeView::OnCollapseToThirdLevel
  300. ////////////////////////////////
  301. // F'N: CBaseTreeView::OnCollapseToRootChildren
  302. //
  303. // Collapses tree down to show just root and it's immediate children
  304. //
  305. LRESULT CBaseTreeView::OnCollapseToRootChildren(WPARAM wParam, LPARAM lParam)
  306. {
  307. LockTreeControl();
  308. // Get the root item
  309. HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem();
  310. // Get the first node
  311. HTREEITEM hNode = GetTreeCtrl().GetNextItem(hTreeItem, TVGN_CHILD);
  312. while(hNode) {
  313. Collapse(hNode);
  314. // go to the next node
  315. hNode = GetTreeCtrl().GetNextItem(hNode, TVGN_NEXT);
  316. }
  317. UnlockTreeControl();
  318. return 0;
  319. } // end CBaseTreeView::OnCollapseToRootChildren
  320. ////////////////////////////////
  321. // F'N: CBaseTreeView::OnDestroy
  322. //
  323. void CBaseTreeView::OnDestroy()
  324. {
  325. LockTreeControl();
  326. UINT itemCount = GetTreeCtrl().GetCount();
  327. HTREEITEM hTreeItem = GetTreeCtrl().GetRootItem();
  328. for(UINT i = 0; i < itemCount; i++) {
  329. CTreeNode *node = ((CTreeNode*)GetTreeCtrl().GetItemData(hTreeItem));
  330. delete (CTreeNode*)(GetTreeCtrl().GetItemData(hTreeItem));
  331. hTreeItem = GetNextItem(hTreeItem);
  332. }
  333. UnlockTreeControl();
  334. } // end CBaseTreeView::OnDestroy
  335. ////////////////////////////////
  336. // F'N: CBaseTreeView::GetNextItem
  337. //
  338. // GetNextItem - Get next item as if outline was completely expanded
  339. // Returns - The item immediately below the reference item
  340. // hItem - The reference item
  341. //
  342. HTREEITEM CBaseTreeView::GetNextItem( HTREEITEM hItem )
  343. {
  344. HTREEITEM hti;
  345. CTreeCtrl &tree = GetTreeCtrl();
  346. if(tree.ItemHasChildren( hItem ) )
  347. return tree.GetChildItem( hItem ); // return first child
  348. else { // return next sibling item
  349. // Go up the tree to find a parent's sibling if needed.
  350. while( (hti = tree.GetNextSiblingItem( hItem )) == NULL ) {
  351. if( (hItem = tree.GetParentItem( hItem ) ) == NULL )
  352. return NULL;
  353. }
  354. }
  355. return hti;
  356. } // end CBaseTreeView::GetNextItem