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.

2325 lines
66 KiB

  1. /*******************************************************************************
  2. *
  3. * treeview.cpp
  4. *
  5. * implementation of the CAdminTreeView class
  6. *
  7. * copyright notice: Copyright 1997, Citrix Systems Inc.
  8. * Copyright (c) 1998 - 1999 Microsoft Corporation
  9. * $Author: donm $ Don Messerli
  10. *
  11. * $Log: N:\nt\private\utils\citrix\winutils\tsadmin\VCS\treeview.cpp $
  12. *
  13. *******************************************************************************/
  14. #include "stdafx.h"
  15. #include "winadmin.h"
  16. #include "admindoc.h"
  17. #include "treeview.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. extern DWORD g_dwTreeViewExpandedStates;
  24. /////////////////////////////
  25. // MESSAGE MAP: CAdminTreeView
  26. //
  27. IMPLEMENT_DYNCREATE(CAdminTreeView, CBaseTreeView)
  28. BEGIN_MESSAGE_MAP(CAdminTreeView, CBaseTreeView)
  29. //{{AFX_MSG_MAP(CAdminTreeView)
  30. ON_MESSAGE(WM_ADMIN_ADD_SERVER, OnAdminAddServer)
  31. ON_MESSAGE(WM_ADMIN_REMOVE_SERVER, OnAdminRemoveServer)
  32. ON_MESSAGE(WM_ADMIN_UPDATE_SERVER, OnAdminUpdateServer)
  33. ON_MESSAGE(WM_ADMIN_ADD_WINSTATION, OnAdminAddWinStation)
  34. ON_MESSAGE(WM_ADMIN_UPDATE_WINSTATION, OnAdminUpdateWinStation)
  35. ON_MESSAGE(WM_ADMIN_REMOVE_WINSTATION, OnAdminRemoveWinStation)
  36. ON_MESSAGE(WM_ADMIN_UPDATE_DOMAIN, OnAdminUpdateDomain)
  37. ON_MESSAGE(WM_ADMIN_ADD_DOMAIN, OnAdminAddDomain)
  38. ON_MESSAGE(WM_ADMIN_VIEWS_READY, OnAdminViewsReady)
  39. ON_MESSAGE( WM_ADMIN_ADDSERVERTOFAV , OnAdminAddServerToFavs )
  40. ON_MESSAGE( WM_ADMIN_REMOVESERVERFROMFAV , OnAdminRemoveServerFromFavs )
  41. ON_MESSAGE( WM_ADMIN_GOTO_SERVER , OnAdminGotoServer )
  42. ON_MESSAGE( WM_ADMIN_DELTREE_NODE , OnAdminDelFavServer )
  43. ON_MESSAGE( WM_ADMIN_GET_TV_STATES , OnGetTVStates )
  44. ON_MESSAGE( WM_ADMIN_UPDATE_TVSTATE , OnUpdateTVState )
  45. ON_MESSAGE( IDM_ALLSERVERS_EMPTYFAVORITES , OnEmptyFavorites )
  46. ON_MESSAGE( WM_ISFAVLISTEMPTY , OnIsFavListEmpty )
  47. ON_MESSAGE( WM_ADMIN_CONNECT_TO_SERVER, OnAdminConnectToServer )
  48. ON_WM_CONTEXTMENU()
  49. /*
  50. ON_WM_LBUTTONUP( )
  51. ON_WM_MOUSEMOVE( )
  52. ON_WM_TIMER( )
  53. ON_NOTIFY( TVN_BEGINDRAG , AFX_IDW_PANE_FIRST , OnBeginDrag )
  54. */
  55. ON_NOTIFY( NM_RCLICK , AFX_IDW_PANE_FIRST , OnRClick )
  56. ON_WM_LBUTTONDBLCLK()
  57. ON_COMMAND( ID_ENTER , OnEnterKey )
  58. ON_WM_SETFOCUS( )
  59. //}}AFX_MSG_MAP
  60. END_MESSAGE_MAP()
  61. //////////////////////////
  62. // F'N: CAdminTreeView ctor
  63. //
  64. CAdminTreeView::CAdminTreeView()
  65. {
  66. m_pimgDragList = NULL;
  67. m_hDragItem = NULL;
  68. } // end CAdminTreeView ctor
  69. //////////////////////////
  70. // F'N: CAdminTreeView dtor
  71. //
  72. CAdminTreeView::~CAdminTreeView()
  73. {
  74. } // end CAdminTreeView dtor
  75. #ifdef _DEBUG
  76. //////////////////////////////////
  77. // F'N: CAdminTreeView::AssertValid
  78. //
  79. void CAdminTreeView::AssertValid() const
  80. {
  81. CBaseTreeView::AssertValid();
  82. } // end CAdminTreeView::AssertValid
  83. ///////////////////////////
  84. // F'N: CAdminTreeView::Dump
  85. //
  86. void CAdminTreeView::Dump(CDumpContext& dc) const
  87. {
  88. CBaseTreeView::Dump(dc);
  89. } // end CAdminTreeView::Dump
  90. #endif
  91. /////////////////////////////////////
  92. // F'N: CAdminTreeView::BuildImageList
  93. //
  94. // - calls m_imageList.Create(..) to create the image list
  95. // - calls AddIconToImageList(..) to add the icons themselves and save
  96. // off their indices
  97. // - attaches the image list to the CTreeCtrl
  98. //
  99. void CAdminTreeView::BuildImageList()
  100. {
  101. m_ImageList.Create(16, 16, TRUE, 19, 0);
  102. m_idxBlank = AddIconToImageList(IDI_BLANK);
  103. m_idxCitrix = AddIconToImageList(IDI_WORLD);
  104. m_idxServer = AddIconToImageList(IDI_SERVER);
  105. m_idxConsole = AddIconToImageList(IDI_CONSOLE);
  106. m_idxNet = AddIconToImageList(IDI_NET);
  107. m_idxNotSign = AddIconToImageList(IDI_NOTSIGN);
  108. m_idxQuestion = AddIconToImageList(IDI_QUESTIONMARK);
  109. m_idxUser = AddIconToImageList(IDI_USER);
  110. m_idxAsync = AddIconToImageList(IDI_ASYNC);
  111. m_idxCurrentServer = AddIconToImageList(IDI_CURRENT_SERVER);
  112. m_idxCurrentNet = AddIconToImageList(IDI_CURRENT_NET);
  113. m_idxCurrentConsole = AddIconToImageList(IDI_CURRENT_CONSOLE);
  114. m_idxCurrentAsync = AddIconToImageList(IDI_CURRENT_ASYNC);
  115. m_idxDirectAsync = AddIconToImageList(IDI_DIRECT_ASYNC);
  116. m_idxCurrentDirectAsync = AddIconToImageList(IDI_CURRENT_DIRECT_ASYNC);
  117. m_idxDomain = AddIconToImageList(IDI_DOMAIN);
  118. m_idxCurrentDomain = AddIconToImageList(IDI_CURRENT_DOMAIN);
  119. m_idxDomainNotConnected = AddIconToImageList(IDI_DOMAIN_NOT_CONNECTED);
  120. m_idxServerNotConnected = AddIconToImageList(IDI_SERVER_NOT_CONNECTED);
  121. // Overlay for Servers we can't talk to
  122. m_ImageList.SetOverlayImage(m_idxNotSign, 1);
  123. // Overlay for Servers we are currently gathering information about
  124. m_ImageList.SetOverlayImage(m_idxQuestion, 2);
  125. GetTreeCtrl().SetImageList(&m_ImageList, TVSIL_NORMAL);
  126. } // end CAdminTreeView::BuildImageList
  127. /////////////////////////////////////////
  128. // F'N: CAdminTreeView::DetermineWinStationText
  129. //
  130. // determines the appropriate text to display for
  131. // a WinStation in the tree
  132. //
  133. void CAdminTreeView::DetermineWinStationText(CWinStation *pWinStation, TCHAR *NameToDisplay)
  134. {
  135. ASSERT(pWinStation);
  136. ASSERT(NameToDisplay);
  137. CString NameString;
  138. const TCHAR *pState = StrConnectState(pWinStation->GetState(), FALSE);
  139. switch(pWinStation->GetState()) {
  140. case State_Active: // user logged on to WinStation
  141. case State_Connected: // WinStation connected to client
  142. case State_ConnectQuery: // in the process of connecting to client
  143. case State_Shadow: // shadowing another WinStation
  144. if(wcslen(pWinStation->GetUserName())) {
  145. NameString.Format(TEXT("%s (%s)"), pWinStation->GetName(), pWinStation->GetUserName());
  146. wcscpy(NameToDisplay, NameString);
  147. }
  148. else
  149. {
  150. if( pWinStation->GetState() == State_ConnectQuery )
  151. {
  152. CString ConnQ;
  153. ConnQ.LoadString( IDS_CONNQ );
  154. wcscpy( NameToDisplay , ConnQ );
  155. }
  156. else
  157. {
  158. wcscpy(NameToDisplay, pWinStation->GetName());
  159. }
  160. }
  161. break;
  162. case State_Disconnected: // WinStation logged on without client
  163. if(wcslen(pWinStation->GetUserName())) {
  164. NameString.Format(TEXT("%s (%s)"), pState, pWinStation->GetUserName());
  165. }
  166. else NameString.Format(TEXT("%s (%lu)"), pState, pWinStation->GetLogonId());
  167. wcscpy(NameToDisplay, NameString);
  168. break;
  169. case State_Idle: // waiting for client to connect
  170. if(pWinStation->GetServer()->GetCTXVersionNum() < 0x200) {
  171. NameString.Format(TEXT("%s (%s)"), pWinStation->GetName(), pState);
  172. wcscpy(NameToDisplay, NameString);
  173. } else {
  174. NameString.Format(TEXT("%s (%lu)"), pState, pWinStation->GetLogonId());
  175. wcscpy(NameToDisplay, NameString);
  176. }
  177. break;
  178. case State_Down: // WinStation is down due to error
  179. NameString.Format(TEXT("%s (%lu)"), pState, pWinStation->GetLogonId());
  180. wcscpy(NameToDisplay, NameString);
  181. break;
  182. case State_Listen: // WinStation is listening for connection
  183. {
  184. CString ListenString;
  185. ListenString.LoadString(IDS_LISTENER);
  186. NameString.Format(TEXT("%s (%s)"), pWinStation->GetName(), ListenString);
  187. wcscpy(NameToDisplay, NameString);
  188. }
  189. break;
  190. case State_Reset: // WinStation is being reset
  191. case State_Init: // WinStation in initialization
  192. wcscpy(NameToDisplay, pWinStation->GetName());
  193. break;
  194. }
  195. } // end CAdminTreeView::DetermineWinStationText
  196. /////////////////////////////////////////
  197. // F'N: CAdminTreeView::DetermineWinStationIcon
  198. //
  199. // determines which icon to display for a WinStation
  200. // in the tree
  201. //
  202. int CAdminTreeView::DetermineWinStationIcon(CWinStation *pWinStation)
  203. {
  204. ASSERT(pWinStation);
  205. int WhichIcon = m_idxBlank;
  206. BOOL CurrentWinStation = pWinStation->IsCurrentWinStation();
  207. if(pWinStation->GetState() != State_Disconnected
  208. && pWinStation->GetState() != State_Idle) {
  209. switch(pWinStation->GetSdClass()) {
  210. case SdAsync:
  211. if(pWinStation->IsDirectAsync())
  212. WhichIcon = CurrentWinStation ? m_idxCurrentDirectAsync : m_idxDirectAsync;
  213. else
  214. WhichIcon = CurrentWinStation ? m_idxCurrentAsync : m_idxAsync;
  215. break;
  216. case SdNetwork:
  217. WhichIcon = CurrentWinStation ? m_idxCurrentNet : m_idxNet;
  218. break;
  219. default:
  220. WhichIcon = CurrentWinStation ? m_idxCurrentConsole : m_idxConsole;
  221. break;
  222. }
  223. }
  224. return WhichIcon;
  225. } // end CAdminTreeView::DetermineWinStationIcon
  226. /////////////////////////////////////////
  227. // F'N: CAdminTreeView::DetermineDomainIcon
  228. //
  229. // determines which icon to display for a Domain
  230. // in the tree
  231. //
  232. int CAdminTreeView::DetermineDomainIcon(CDomain *pDomain)
  233. {
  234. ASSERT(pDomain);
  235. int WhichIcon = m_idxDomain;
  236. if(pDomain->IsCurrentDomain()) return m_idxCurrentDomain;
  237. if(pDomain->GetState() != DS_ENUMERATING && pDomain->GetState() != DS_INITIAL_ENUMERATION)
  238. WhichIcon = m_idxDomainNotConnected;
  239. return WhichIcon;
  240. } // end CAdminTreeView::DetermineDomainIcon
  241. /////////////////////////////////////////
  242. // F'N: CAdminTreeView::DetermineServerIcon
  243. //
  244. // determines which icon to display for a Server
  245. // in the tree
  246. //
  247. int CAdminTreeView::DetermineServerIcon(CServer *pServer)
  248. {
  249. ASSERT(pServer);
  250. int WhichIcon = m_idxServer;
  251. // Is this the current server?
  252. if(pServer->IsCurrentServer()) {
  253. if(pServer->IsState(SS_NONE) || pServer->IsState(SS_NOT_CONNECTED))
  254. WhichIcon = m_idxServerNotConnected;
  255. else
  256. WhichIcon = m_idxCurrentServer;
  257. } else { // not the current server
  258. if(pServer->IsState(SS_NONE) || pServer->IsState(SS_NOT_CONNECTED))
  259. WhichIcon = m_idxServerNotConnected;
  260. }
  261. return WhichIcon;
  262. } // end CAdminTreeView::DetermineServerIcon
  263. /////////////////////////////////////////
  264. // F'N: CAdminTreeView::AddServerChildren
  265. //
  266. // Adds the WinStations attached to a given Server
  267. // to the tree
  268. //
  269. void CAdminTreeView::AddServerChildren(HTREEITEM hServer, CServer *pServer , NODETYPE nt)
  270. {
  271. ASSERT(hServer);
  272. ASSERT(pServer);
  273. if(pServer->IsServerSane()) {
  274. LockTreeControl();
  275. HTREEITEM hLastNode = hServer;
  276. pServer->LockWinStationList();
  277. // Get a pointer to the server's list of WinStations
  278. CObList *pWinStationList = pServer->GetWinStationList();
  279. // Iterate through the WinStation list
  280. POSITION pos = pWinStationList->GetHeadPosition();
  281. while(pos)
  282. {
  283. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  284. // Figure out which icon to use
  285. int WhichIcon = DetermineWinStationIcon(pWinStation);
  286. // Figure out what text to display
  287. TCHAR NameToDisplay[128];
  288. DetermineWinStationText(pWinStation, NameToDisplay);
  289. CTreeNode *pNode = new CTreeNode(NODE_WINSTATION, pWinStation);
  290. if( pNode != NULL )
  291. {
  292. pNode->SetSortOrder(pWinStation->GetSortOrder());
  293. hLastNode = AddItemToTree(hServer, NameToDisplay, hLastNode, WhichIcon, (LPARAM)pNode);
  294. if( hLastNode == NULL )
  295. {
  296. delete pNode;
  297. }
  298. }
  299. // The WinStation wants to know his tree item handle
  300. if( nt == NODE_FAV_LIST )
  301. {
  302. pWinStation->SetTreeItemForFav(hLastNode);
  303. }
  304. else if( nt == NODE_SERVER )
  305. {
  306. pWinStation->SetTreeItem(hLastNode);
  307. }
  308. else if( nt == NODE_THIS_COMP )
  309. {
  310. pWinStation->SetTreeItemForThisComputer( hLastNode );
  311. }
  312. }
  313. pServer->UnlockWinStationList();
  314. UnlockTreeControl();
  315. } // end if(pServer->IsServerSane())
  316. } // end CAdminTreeView::AddServerChildren
  317. /////////////////////////////////////////
  318. // F'N: CAdminTreeView::AddDomainToTree
  319. //
  320. // Adds a domain to the tree
  321. //
  322. HTREEITEM CAdminTreeView::AddDomainToTree(CDomain *pDomain)
  323. {
  324. ASSERT(pDomain);
  325. LockTreeControl();
  326. HTREEITEM hDomain;
  327. // this points to this computer root
  328. HTREEITEM hR2 = GetTreeCtrl().GetRootItem();
  329. // this points to favorite list
  330. hR2 = GetTreeCtrl().GetNextItem( hR2 , TVGN_NEXT );
  331. // this points to All servers
  332. HTREEITEM hRoot = GetTreeCtrl().GetNextItem( hR2 , TVGN_NEXT );
  333. // Add the domain to the tree
  334. // Create a CTreeNode object with info about this tree node
  335. CTreeNode* pNode = new CTreeNode(NODE_DOMAIN, pDomain);
  336. if(pNode) {
  337. hDomain = AddItemToTree(hRoot, pDomain->GetName(), TVI_SORT, DetermineDomainIcon(pDomain), (LPARAM)pNode);
  338. if(!hDomain) delete pNode;
  339. // Change the icon/overlay for the domain
  340. if(pDomain->GetState() == DS_INITIAL_ENUMERATION)
  341. GetTreeCtrl().SetItemState(hDomain, STATE_QUESTION, 0x0F00);
  342. // The domain wants to know his tree item handle
  343. pDomain->SetTreeItem(hDomain);
  344. }
  345. UnlockTreeControl();
  346. return(hDomain);
  347. } // end CAdminTreeView::AddDomainToTree
  348. //////////////////////////////////
  349. // F'N: CAdminTreeView::OnAdminViewsReady
  350. //
  351. LRESULT CAdminTreeView::OnAdminViewsReady(WPARAM wParam, LPARAM lParam)
  352. {
  353. LockTreeControl();
  354. // Get a pointer to our document
  355. CWinAdminDoc *doc = (CWinAdminDoc*)GetDocument();
  356. // We want to remember the tree item of the current server for later
  357. HTREEITEM hCurrentServer = NULL;
  358. HTREEITEM hThisComputerRootItem = NULL;
  359. HTREEITEM hThisComputer = NULL;
  360. HTREEITEM hFavRoot = NULL;
  361. // add enum for fav node
  362. CString cstrThisComputer;
  363. CString cstrFavSrv;
  364. CNodeType *pNodeType = new CNodeType( NODE_THIS_COMP );
  365. // ok to pass in null
  366. CTreeNode *pThisComp = new CTreeNode( NODE_THIS_COMP , pNodeType );
  367. if( pThisComp != NULL )
  368. {
  369. cstrThisComputer.LoadString( IDS_THISCOMPUTER );
  370. hThisComputerRootItem = AddItemToTree( NULL , cstrThisComputer , TVI_ROOT , m_idxDomain , ( LPARAM )pThisComp );
  371. }
  372. // ok to overrun
  373. pNodeType = new CNodeType( NODE_FAV_LIST );
  374. // it's ok to pass null here
  375. CTreeNode *pFavNode = new CTreeNode( NODE_FAV_LIST , pNodeType );
  376. if( pFavNode != NULL )
  377. {
  378. cstrFavSrv.LoadString( IDS_FAVSERVERS );
  379. hFavRoot = AddItemToTree( NULL , cstrFavSrv , TVI_ROOT , m_idxCitrix, ( LPARAM )pFavNode );
  380. }
  381. // add the root to the tree
  382. CString citrix;
  383. citrix.LoadString(IDS_TREEROOT);
  384. CTreeNode* pRootNode = new CTreeNode(NODE_ALL_SERVERS, NULL);
  385. if(!pRootNode) {
  386. UnlockTreeControl();
  387. return 0;
  388. }
  389. HTREEITEM hRoot = AddItemToTree(NULL, citrix, TVI_ROOT, m_idxCitrix, (LPARAM)pRootNode);
  390. if(!hRoot) delete pRootNode;
  391. // set up some 'placeholder'-style vars
  392. HTREEITEM hCurrParent = hRoot;
  393. HTREEITEM hLastConnection = hRoot;
  394. HTREEITEM hLastNode = hRoot;
  395. HTREEITEM hDomain = NULL;
  396. // Get a pointer to the list of domains
  397. CObList *pDomainList = doc->GetDomainList();
  398. POSITION dpos = pDomainList->GetHeadPosition();
  399. while(dpos) {
  400. CDomain *pDomain = (CDomain*)pDomainList->GetNext(dpos);
  401. AddDomainToTree(pDomain);
  402. }
  403. // Get a pointer to the list of servers
  404. doc->LockServerList();
  405. CObList *pServerList = doc->GetServerList();
  406. // Iterate through the server list
  407. POSITION pos = pServerList->GetHeadPosition();
  408. CServer *pCurrentServer;
  409. while(pos) {
  410. // Go to the next server in the list
  411. CServer *pServer = (CServer*)pServerList->GetNext(pos);
  412. if( pServer == NULL )
  413. {
  414. continue;
  415. }
  416. // If this Server's domain isn't in the tree, add it
  417. CDomain *pDomain = pServer->GetDomain();
  418. if(pDomain != NULL )
  419. {
  420. hDomain = pDomain->GetTreeItem();
  421. ASSERT(hDomain);
  422. }
  423. else
  424. {
  425. // server is not in a domain
  426. hDomain = hRoot;
  427. }
  428. // Add the server to the tree
  429. // Create a CTreeNode object with info about this tree node
  430. CTreeNode* pNode = new CTreeNode(NODE_SERVER, pServer);
  431. if(pNode) {
  432. if( !pServer->IsCurrentServer() )
  433. {
  434. // If the server is the current server, use a different icon
  435. hLastConnection = AddItemToTree(hDomain,
  436. pServer->GetName(),
  437. hLastConnection,
  438. DetermineServerIcon(pServer),
  439. (LPARAM)pNode);
  440. if(!hLastConnection) delete pNode;
  441. // The server wants to know his tree item handle
  442. pServer->SetTreeItem(hLastConnection);
  443. // If the server isn't sane, put a not sign over the icon
  444. if(!pServer->IsServerSane()) GetTreeCtrl().SetItemState(hLastConnection, STATE_NOT, 0x0F00);
  445. // If we aren't done getting all the information about this server,
  446. // put a question mark over the icon
  447. else if(pServer->IsState(SS_GETTING_INFO)) GetTreeCtrl().SetItemState(hLastConnection, STATE_QUESTION, 0x0F00);
  448. AddServerChildren(hLastConnection, pServer , NODE_SERVER );
  449. }
  450. // Remember if this is the current server
  451. else
  452. {
  453. hCurrentServer = hLastConnection;
  454. /* Add this item under the this computer root */
  455. hThisComputer = AddItemToTree( hThisComputerRootItem ,
  456. pServer->GetName() ,
  457. TVI_FIRST ,
  458. DetermineServerIcon(pServer),
  459. (LPARAM)pNode );
  460. CTreeNode* pItem = new CTreeNode(NODE_SERVER, pServer);
  461. // uncomment this line if you want this computer to be part of the domain tree list
  462. /*
  463. hLastConnection = AddItemToTree( hDomain,
  464. pServer->GetName(),
  465. hLastConnection,
  466. DetermineServerIcon(pServer),
  467. (LPARAM)pItem);
  468. */
  469. pServer->SetTreeItemForThisComputer( hThisComputer );
  470. // uncomment this line if you want this computer to be part of the domain tree list
  471. // pServer->SetTreeItem( hLastConnection );
  472. if( !pServer->IsServerSane() )
  473. {
  474. GetTreeCtrl().SetItemState(hThisComputer, STATE_NOT, 0x0F00);
  475. // uncomment this line if you want this computer to be part of the domain tree list
  476. // GetTreeCtrl().SetItemState(hLastConnection, STATE_NOT, 0x0F00);
  477. }
  478. // uncomment this line if you want this computer to be part of the domain tree list
  479. // AddServerChildren( hLastConnection, pServer , NODE_SERVER );
  480. AddServerChildren( hThisComputer , pServer , NODE_SERVER );
  481. }
  482. }
  483. } // end while(pos)
  484. doc->UnlockServerList();
  485. // We want to show the main server in this computer node
  486. //GetTreeCtrl().Expand(hRoot, TVE_EXPAND);
  487. GetTreeCtrl().Expand( hThisComputerRootItem , TVE_COLLAPSE );
  488. /*
  489. LRESULT lResult = 0xc0;
  490. // We want to default to having the current server being the
  491. // currently selected item in the tree and be expanded
  492. if( hThisComputerRootItem != NULL && ( g_dwTreeViewExpandedStates & TV_THISCOMP ) )
  493. {
  494. if( hThisComputer != NULL )
  495. {
  496. GetTreeCtrl().SelectItem(hThisComputer);
  497. GetTreeCtrl().Expand(hThisComputer, TVE_EXPAND);
  498. // GetTreeCtrl().Expand(hDomain, TVE_EXPAND);
  499. //lResult = 0xc0;
  500. OnSelChange( NULL , &lResult );
  501. }
  502. }
  503. if( hFavRoot != NULL && ( g_dwTreeViewExpandedStates & TV_FAVS ) )
  504. {
  505. GetTreeCtrl().SelectItem( hFavRoot );
  506. GetTreeCtrl().Expand( hFavRoot , TVE_EXPAND );
  507. OnSelChange( NULL , &lResult );
  508. }
  509. if( hRoot != NULL && ( g_dwTreeViewExpandedStates & TV_ALLSERVERS ) )
  510. {
  511. GetTreeCtrl().SelectItem( hRoot );
  512. GetTreeCtrl().Expand( hRoot , TVE_EXPAND );
  513. OnSelChange( NULL , &lResult );
  514. }
  515. */
  516. UnlockTreeControl();
  517. return 0;
  518. } // end CAdminTreeView::OnAdminViewsReady
  519. ////////////////////////////////
  520. // F'N: CAdminTreeView::OnAdminAddServer
  521. //
  522. // Message Handler to add a Server to the tree
  523. // Pointer to CServer to add is in lParam
  524. //
  525. LRESULT CAdminTreeView::OnAdminAddServer(WPARAM wParam, LPARAM lParam)
  526. {
  527. ASSERT(lParam);
  528. CServer *pServer = (CServer*)lParam;
  529. LockTreeControl();
  530. CTreeCtrl &tree = GetTreeCtrl();
  531. // If this Server's domain isn't in the tree, add it
  532. HTREEITEM hDomain = NULL;
  533. CDomain *pDomain = pServer->GetDomain();
  534. if(pDomain) {
  535. hDomain = pDomain->GetTreeItem();
  536. ASSERT(hDomain);
  537. } else {
  538. // server is not in a domain
  539. hDomain = tree.GetRootItem();
  540. }
  541. // First make sure the server isn't already in the tree
  542. // Get the first server under the domain
  543. HTREEITEM hItem = tree.GetNextItem(hDomain, TVGN_CHILD);
  544. while(hItem) {
  545. // Get the data attached to the tree item
  546. CTreeNode *node = (CTreeNode*)tree.GetItemData(hItem);
  547. if(node) {
  548. // Is this the server we want to add
  549. CServer *pServer = (CServer*)node->GetTreeObject();
  550. if(pServer == (CServer*)lParam) {
  551. UnlockTreeControl();
  552. return 0;
  553. }
  554. }
  555. hItem = tree.GetNextItem(hItem, TVGN_NEXT);
  556. }
  557. // Add the server to the tree
  558. // Create a CTreeNode object with info about this tree node
  559. CTreeNode* pNode = new CTreeNode(NODE_SERVER, pServer);
  560. if(pNode)
  561. {
  562. // If the server is the current server, use a different icon
  563. HTREEITEM hServer = AddItemToTree(hDomain, pServer->GetName(), (HTREEITEM)wParam,
  564. DetermineServerIcon(pServer), (LPARAM)pNode);
  565. if( !hServer )
  566. {
  567. delete pNode;
  568. }
  569. // The server wants to know his tree item handle
  570. pServer->SetTreeItem(hServer);
  571. // If the server isn't sane, put a not sign over the icon
  572. if( !pServer->IsServerSane() )
  573. {
  574. tree.SetItemState(hServer, STATE_NOT, 0x0F00);
  575. }
  576. // If we aren't done getting all the information about this server,
  577. // put a question mark over the icon
  578. else if(pServer->IsState(SS_GETTING_INFO))
  579. {
  580. tree.SetItemState(hServer, STATE_QUESTION, 0x0F00);
  581. }
  582. AddServerChildren(hServer, pServer , NODE_SERVER );
  583. }
  584. UnlockTreeControl();
  585. return 0;
  586. } // end CAdminTreeView::OnAdminAddServer
  587. //----------------------------------------------------------------------
  588. // ok if you traced me to here you are almost there
  589. // 1) now we need to update the server item and place it under the favorites
  590. // folder
  591. // 2) inform the server child items that it will have a new parent
  592. //
  593. LRESULT CAdminTreeView::OnAdminAddServerToFavs( WPARAM wp , LPARAM lp )
  594. {
  595. CServer *pServer = ( CServer* )lp;
  596. if( pServer == NULL )
  597. {
  598. ODS( L"CAdminTreeView::OnAdminAddServerToFavs invalid arg\n");
  599. return ( LRESULT )-1;
  600. }
  601. LockTreeControl( );
  602. if( pServer->IsServerInactive() || pServer->IsState( SS_DISCONNECTING ) )
  603. {
  604. UnlockTreeControl( );
  605. return 0;
  606. }
  607. CTreeCtrl &tree = GetTreeCtrl();
  608. HTREEITEM hFavs = GetTreeCtrl().GetRootItem( );
  609. HTREEITEM hItem;
  610. hFavs = tree.GetNextItem( hFavs , TVGN_NEXT );
  611. hItem = tree.GetNextItem( hFavs , TVGN_CHILD );
  612. // check for duplicate entry
  613. while( hItem != NULL )
  614. {
  615. // Get the data attached to the tree item
  616. CTreeNode *pTreenode = (CTreeNode*)tree.GetItemData( hItem );
  617. if( pTreenode != NULL )
  618. {
  619. // Is this the server we want to add
  620. CServer *pSvr = (CServer*)pTreenode->GetTreeObject();
  621. if( pSvr == pServer )
  622. {
  623. UnlockTreeControl();
  624. return 0;
  625. }
  626. }
  627. hItem = tree.GetNextItem(hItem, TVGN_NEXT);
  628. }
  629. CTreeNode* pNode = new CTreeNode(NODE_SERVER, pServer);
  630. if( pNode != NULL )
  631. {
  632. HTREEITEM hServer = AddItemToTree( hFavs,
  633. pServer->GetName(),
  634. TVI_SORT,
  635. DetermineServerIcon(pServer),
  636. (LPARAM)pNode);
  637. if( hServer == NULL )
  638. {
  639. delete pNode;
  640. }
  641. // The server wants to know his tree item handle
  642. pServer->SetTreeItemForFav( hServer );
  643. // If the server isn't sane, put a not sign over the icon
  644. if( !pServer->IsServerSane() )
  645. {
  646. tree.SetItemState(hServer, STATE_NOT, 0x0F00);
  647. }
  648. // If we aren't done getting all the information about this server,
  649. // put a question mark over the icon
  650. else if( pServer->IsState( SS_GETTING_INFO ) )
  651. {
  652. tree.SetItemState(hServer, STATE_QUESTION, 0x0F00);
  653. }
  654. AddServerChildren( hServer , pServer , NODE_FAV_LIST );
  655. }
  656. UnlockTreeControl();
  657. tree.Invalidate( );
  658. return 0;
  659. }
  660. //=----------------------------------------------------------------------------------
  661. LRESULT CAdminTreeView::OnAdminRemoveServerFromFavs( WPARAM wp , LPARAM lp )
  662. {
  663. LockTreeControl();
  664. CServer *pServer = ( CServer* )lp;
  665. DBGMSG( L"CAdminTreeView::OnAdminRemoveServerFromFavs -- %s\n" , pServer->GetName( ) );
  666. HTREEITEM hFavServer = pServer->GetTreeItemFromFav();
  667. #ifdef _STRESS_BUILD
  668. DBGMSG( L"Handle to hFavServer 0x%x\n" , hFavServer );
  669. #endif
  670. if( hFavServer == NULL )
  671. {
  672. UnlockTreeControl();
  673. return 0;
  674. }
  675. // Get the data attached to this tree node
  676. CTreeNode *pNode = (CTreeNode*)GetTreeCtrl().GetItemData( hFavServer );
  677. if( pNode != NULL && pNode->GetNodeType( ) == NODE_SERVER )
  678. {
  679. // Is this the server we want to update
  680. CServer *pTreeServer = ( CServer* )pNode->GetTreeObject();
  681. if( pTreeServer != pServer)
  682. {
  683. UnlockTreeControl();
  684. return 0;
  685. }
  686. }
  687. else
  688. {
  689. UnlockTreeControl();
  690. return 0;
  691. }
  692. // Loop through it's children and delete their data
  693. pServer->LockWinStationList( );
  694. HTREEITEM hChild = GetTreeCtrl().GetNextItem( hFavServer , TVGN_CHILD );
  695. while( hChild != NULL )
  696. {
  697. CTreeNode *pChildNode = ( CTreeNode* )GetTreeCtrl().GetItemData( hChild );
  698. if( pChildNode != NULL && pChildNode->GetNodeType( ) == NODE_WINSTATION )
  699. {
  700. // Tell the WinStation it is no longer in the tree
  701. CWinStation *pWinStation = ( CWinStation* )pChildNode->GetTreeObject();
  702. if( pWinStation != NULL )
  703. {
  704. pWinStation->SetTreeItemForFav(NULL);
  705. }
  706. delete pChildNode;
  707. }
  708. hChild = GetTreeCtrl().GetNextItem( hChild , TVGN_NEXT );
  709. }
  710. // Delete the data attached to the tree item
  711. delete pNode;
  712. // Let the server know he is no longer in the tree
  713. pServer->SetTreeItemForFav(NULL);
  714. GetTreeCtrl().DeleteItem( hFavServer );
  715. pServer->UnlockWinStationList( );
  716. UnlockTreeControl();
  717. return 0;
  718. }
  719. ////////////////////////////////
  720. // F'N: CAdminTreeView::OnAdminRemoveServer
  721. //
  722. // Message Handler to remove a Server from the tree
  723. // Pointer to CServer of server to remove is in lParam
  724. //
  725. LRESULT CAdminTreeView::OnAdminRemoveServer(WPARAM wParam, LPARAM lParam)
  726. {
  727. ASSERT(lParam);
  728. CServer *pServer = (CServer*)lParam;
  729. HTREEITEM hServer = pServer->GetTreeItem();
  730. if(!hServer) return 0;
  731. LockTreeControl();
  732. // Get the data attached to this tree node
  733. CTreeNode *node = (CTreeNode*)GetTreeCtrl().GetItemData(hServer);
  734. if(node) {
  735. // Is this the server we want to update
  736. CServer *pTreeServer = (CServer*)node->GetTreeObject();
  737. // Make sure the tree node is correct
  738. if(pTreeServer != pServer) {
  739. UnlockTreeControl();
  740. return 0;
  741. }
  742. }
  743. else {
  744. UnlockTreeControl();
  745. return 0;
  746. }
  747. // Loop through it's children and delete their data
  748. HTREEITEM hChild = GetTreeCtrl().GetNextItem(hServer, TVGN_CHILD);
  749. while(hChild) {
  750. CTreeNode *ChildNode = (CTreeNode*)GetTreeCtrl().GetItemData(hChild);
  751. if(ChildNode) {
  752. // Tell the WinStation it is no longer in the tree
  753. CWinStation *pWinStation = (CWinStation*)ChildNode->GetTreeObject();
  754. if(pWinStation)
  755. pWinStation->SetTreeItem(NULL);
  756. delete ChildNode;
  757. }
  758. hChild = GetTreeCtrl().GetNextItem(hChild, TVGN_NEXT);
  759. }
  760. // Delete the data attached to the tree item
  761. delete node;
  762. // Let the server know he is no longer in the tree
  763. pServer->SetTreeItem(NULL);
  764. // Remove the server from the tree
  765. // This SHOULD remove all it's children
  766. GetTreeCtrl().DeleteItem(hServer);
  767. // TODO
  768. // if this means that CServer does not exist we need to remove this from the favorite list
  769. UnlockTreeControl();
  770. return 0;
  771. } // end CAdminTreeView::OnAdminRemoveServer
  772. /*=--------------------------------------------------------------------------------------
  773. OnAdminUpdateServer
  774. Message handler to update a Server in the tree
  775. Pointer to CServer to update is in lParam
  776. Updates server item in favorites folder
  777. and if server item is this computer it gets updated as well.
  778. *=------------------------------------------------------------------------------------*/
  779. LRESULT CAdminTreeView::OnAdminUpdateServer(WPARAM wParam, LPARAM lParam)
  780. {
  781. ASSERT(lParam);
  782. LockTreeControl( );
  783. // If favorite folders is expanded don't forget to update the tree item
  784. CServer *pServer = (CServer*)lParam;
  785. HTREEITEM hServer = pServer->GetTreeItem();
  786. if( hServer != NULL )
  787. {
  788. UpdateServerTreeNodeState( hServer , pServer , NODE_SERVER );
  789. }
  790. hServer = pServer->GetTreeItemFromFav( );
  791. if( hServer != NULL )
  792. {
  793. UpdateServerTreeNodeState( hServer , pServer , NODE_FAV_LIST );
  794. }
  795. hServer = pServer->GetTreeItemFromThisComputer( );
  796. if( hServer != NULL )
  797. {
  798. UpdateServerTreeNodeState( hServer , pServer , NODE_THIS_COMP );
  799. }
  800. UnlockTreeControl( );
  801. return 0;
  802. }
  803. /*=--------------------------------------------------------------------------------------
  804. UpdateServerTreeNodeState
  805. hServer -- tree item that needs updating
  806. pServer -- server object
  807. *=------------------------------------------------------------------------------------*/
  808. LRESULT CAdminTreeView::UpdateServerTreeNodeState( HTREEITEM hServer , CServer *pServer , NODETYPE nt )
  809. {
  810. LockTreeControl( );
  811. if( hServer == NULL )
  812. {
  813. UnlockTreeControl( );
  814. return 0;
  815. }
  816. // Get the data attached to this tree node
  817. CTreeNode *node = (CTreeNode*)GetTreeCtrl().GetItemData(hServer);
  818. if( node != NULL && node->GetNodeType( ) == NODE_SERVER )
  819. {
  820. // Is this the server we want to update
  821. CServer *pTreeServer = (CServer*)node->GetTreeObject();
  822. // Make sure the tree node is correct
  823. if(pTreeServer != pServer)
  824. {
  825. UnlockTreeControl();
  826. return 0;
  827. }
  828. }
  829. else
  830. {
  831. UnlockTreeControl();
  832. return 0;
  833. }
  834. UINT NewState;
  835. // Remember the previous state
  836. UINT PreviousState = GetTreeCtrl().GetItemState(hServer, 0x0F00);
  837. // Change the icon/overlay for the server
  838. // If the server isn't sane, put a not sign over the icon
  839. if(!pServer->IsServerSane()) NewState = STATE_NOT;
  840. // If we aren't done getting all the information about this server,
  841. // put a question mark over the icon
  842. else if(pServer->IsState(SS_GETTING_INFO)) NewState = STATE_QUESTION;
  843. // If it is fine, we want to remove any overlays from the icon
  844. else NewState = STATE_NORMAL;
  845. // Set the tree item to the new state
  846. GetTreeCtrl().SetItemState(hServer, NewState, 0x0F00);
  847. // If this Server was not opened and now is GOOD,
  848. // add it's children to the tree
  849. if(PreviousState != STATE_NORMAL && pServer->IsState(SS_GOOD)) {
  850. int ServerIcon = DetermineServerIcon(pServer);
  851. GetTreeCtrl().SetItemImage(hServer, ServerIcon, ServerIcon);
  852. AddServerChildren(hServer, pServer , nt );
  853. // If this server is the server the user is sitting at and is
  854. // the currently selected tree item, expand it
  855. if(hServer == GetTreeCtrl().GetSelectedItem() && pServer->IsCurrentServer()) {
  856. GetTreeCtrl().Expand(hServer, TVE_EXPAND);
  857. }
  858. }
  859. else if(pServer->GetPreviousState() == SS_DISCONNECTING && pServer->IsState(SS_NOT_CONNECTED)) {
  860. int ServerIcon = DetermineServerIcon(pServer);
  861. GetTreeCtrl().SetItemImage(hServer, ServerIcon, ServerIcon);
  862. }
  863. // If we changed the state of this server and it is the currently
  864. // selected node in the tree, we need to send a message to change
  865. // the view
  866. if(NewState != PreviousState && hServer == GetTreeCtrl().GetSelectedItem()) {
  867. ForceSelChange();
  868. }
  869. UnlockTreeControl();
  870. return 0;
  871. } // end CAdminTreeView::OnAdminUpdateServer
  872. LRESULT CAdminTreeView::OnAdminAddWinStation(WPARAM wParam, LPARAM lParam)
  873. {
  874. ASSERT(lParam);
  875. ODS( L"**CAdminTreeView::OnAdminAddWinStation\n" );
  876. CWinStation *pWinStation = (CWinStation*)lParam;
  877. // Get the HTREEITEM of the Server this WinStation is attached to
  878. // TODO:
  879. // update the server item in the favorite list
  880. HTREEITEM hServer = pWinStation->GetServer()->GetTreeItem();
  881. if( hServer != NULL )
  882. {
  883. AddWinStation( pWinStation , hServer , ( BOOL )wParam , NODE_NONE );
  884. }
  885. hServer = pWinStation->GetServer( )->GetTreeItemFromFav( );
  886. if( hServer != NULL )
  887. {
  888. AddWinStation( pWinStation , hServer , ( BOOL )wParam , NODE_FAV_LIST );
  889. }
  890. hServer = pWinStation->GetServer( )->GetTreeItemFromThisComputer( );
  891. if( hServer != NULL )
  892. {
  893. AddWinStation( pWinStation , hServer , ( BOOL )wParam , NODE_THIS_COMP );
  894. }
  895. return 0;
  896. }
  897. ////////////////////////////////
  898. // F'N: CAdminTreeView::OnAdminAddWinStation
  899. //
  900. // Message handler to add a WinStation to the tree
  901. // lParam = pointer to CWinStation to add
  902. // wParam is TRUE if this is replacing a WinStation that was currently selected
  903. //
  904. LRESULT CAdminTreeView::AddWinStation( CWinStation * pWinStation , HTREEITEM hServer , BOOL bSel , NODETYPE nt )
  905. {
  906. ODS( L"**CAdminTreeView::AddWinStation\n" );
  907. HTREEITEM hWinStation;
  908. LockTreeControl();
  909. // Figure out which icon to use
  910. int WhichIcon = DetermineWinStationIcon(pWinStation);
  911. // Figure out what text to display
  912. TCHAR NameToDisplay[128];
  913. DetermineWinStationText(pWinStation, NameToDisplay);
  914. CTreeNode *pNode = new CTreeNode(NODE_WINSTATION, pWinStation);
  915. if(pNode) {
  916. pNode->SetSortOrder(pWinStation->GetSortOrder());
  917. // We have to insert this WinStation in sorted order
  918. // Get the first WinStation item attached to this server
  919. HTREEITEM hChild = GetTreeCtrl().GetNextItem(hServer, TVGN_CHILD);
  920. HTREEITEM hLastChild = TVI_FIRST;
  921. BOOL bAdded = FALSE;
  922. while(hChild)
  923. {
  924. CTreeNode *ChildNode = (CTreeNode*)GetTreeCtrl().GetItemData(hChild);
  925. if(ChildNode)
  926. {
  927. // Does it belong before this tree node?
  928. CWinStation *pTreeWinStation = (CWinStation*)ChildNode->GetTreeObject();
  929. if((pTreeWinStation->GetSortOrder() > pWinStation->GetSortOrder())
  930. || ((pTreeWinStation->GetSortOrder() == pWinStation->GetSortOrder()) &&
  931. (pTreeWinStation->GetSdClass() > pWinStation->GetSdClass())))
  932. {
  933. hWinStation = AddItemToTree(hServer, NameToDisplay, hLastChild, WhichIcon, (LPARAM)pNode);
  934. if(!hWinStation)
  935. {
  936. delete pNode;
  937. }
  938. // The WinStation wants to know his tree item handle
  939. if( nt == NODE_FAV_LIST )
  940. {
  941. pWinStation->SetTreeItemForFav( hWinStation );
  942. }
  943. else if( nt == NODE_THIS_COMP )
  944. {
  945. pWinStation->SetTreeItemForThisComputer( hWinStation );
  946. }
  947. else
  948. {
  949. pWinStation->SetTreeItem(hWinStation);
  950. }
  951. bAdded = TRUE;
  952. break;
  953. }
  954. }
  955. hLastChild = hChild;
  956. hChild = GetTreeCtrl().GetNextItem(hChild, TVGN_NEXT);
  957. }
  958. // If we didn't add it yet, add it at the end
  959. if(!bAdded)
  960. {
  961. hWinStation = AddItemToTree(hServer, NameToDisplay, hLastChild, WhichIcon, (LPARAM)pNode);
  962. if( hWinStation == NULL )
  963. {
  964. delete pNode;
  965. }
  966. // The WinStation wants to know his tree item handle
  967. if( nt == NODE_FAV_LIST )
  968. {
  969. pWinStation->SetTreeItemForFav( hWinStation );
  970. }
  971. else if( nt == NODE_THIS_COMP )
  972. {
  973. pWinStation->SetTreeItemForThisComputer( hWinStation );
  974. }
  975. else
  976. {
  977. pWinStation->SetTreeItem(hWinStation);
  978. }
  979. }
  980. // If this is replacing a WinStation in the tree that was the currently selected
  981. // tree item, make this new item in the tree the currently selected item
  982. if( bSel ) {
  983. GetTreeCtrl().SelectItem(hWinStation);
  984. }
  985. }
  986. UnlockTreeControl();
  987. return 0;
  988. } // end CAdminTreeView::OnAdminAddWinStation
  989. ////////////////////////////////
  990. // F'N: CAdminTreeView::OnAdminUpdateWinStation
  991. //
  992. // Message handler to update a WinStation in the tree
  993. // lParam = pointer to CWinStation to update
  994. //
  995. LRESULT CAdminTreeView::OnAdminUpdateWinStation(WPARAM wParam, LPARAM lParam)
  996. {
  997. ODS( L"CAdminTreeView::OnAdminUpdateWinStation\n" );
  998. ASSERT(lParam);
  999. CWinStation *pWinStation = (CWinStation*)lParam;
  1000. HTREEITEM hWinStation = pWinStation->GetTreeItem();
  1001. if( hWinStation != NULL )
  1002. {
  1003. UpdateWinStation( hWinStation , pWinStation );
  1004. }
  1005. hWinStation = pWinStation->GetTreeItemFromFav( );
  1006. if( hWinStation != NULL )
  1007. {
  1008. UpdateWinStation( hWinStation , pWinStation );
  1009. }
  1010. hWinStation = pWinStation->GetTreeItemFromThisComputer( );
  1011. if( hWinStation != NULL )
  1012. {
  1013. UpdateWinStation( hWinStation , pWinStation );
  1014. }
  1015. return 0;
  1016. }
  1017. LRESULT CAdminTreeView::UpdateWinStation( HTREEITEM hWinStation , CWinStation *pWinStation )
  1018. {
  1019. ODS( L"CAdminTreeView::UpdateWinStation\n" );
  1020. LockTreeControl();
  1021. // Get the data attached to this tree node
  1022. CTreeNode *node = (CTreeNode*)GetTreeCtrl().GetItemData(hWinStation);
  1023. if(node) {
  1024. // Is this the WinStation we want to update
  1025. CWinStation *pTreeWinStation = (CWinStation*)node->GetTreeObject();
  1026. // Make sure the tree node is correct
  1027. if(pTreeWinStation != pWinStation) {
  1028. UnlockTreeControl();
  1029. return 0;
  1030. }
  1031. } else {
  1032. UnlockTreeControl();
  1033. return 0;
  1034. }
  1035. // If the sort order of this WinStation has changed,
  1036. // we have to remove it from the tree and add it back in
  1037. if(node->GetSortOrder() != pWinStation->GetSortOrder())
  1038. {
  1039. OnAdminRemoveWinStation( 0 , ( LPARAM )pWinStation );
  1040. /*GetTreeCtrl().DeleteItem(hWinStation);
  1041. pWinStation->SetTreeItem(NULL);
  1042. */
  1043. OnAdminAddWinStation((GetTreeCtrl().GetSelectedItem() == hWinStation), ( LPARAM )pWinStation );
  1044. UnlockTreeControl();
  1045. return 0;
  1046. }
  1047. int WhichIcon = DetermineWinStationIcon(pWinStation);
  1048. GetTreeCtrl().SetItemImage(hWinStation, WhichIcon, WhichIcon);
  1049. TCHAR NameToDisplay[128];
  1050. DetermineWinStationText(pWinStation, NameToDisplay);
  1051. GetTreeCtrl().SetItemText(hWinStation, NameToDisplay);
  1052. UnlockTreeControl();
  1053. return 0;
  1054. } // end CAdminTreeView::OnAdminUpdateWinStation
  1055. ////////////////////////////////
  1056. // F'N: CAdminTreeView::OnAdminRemoveWinStation
  1057. //
  1058. // Message handler to remove a WinStation from the tree
  1059. // lParam = pointer to CWinStation to remove
  1060. LRESULT CAdminTreeView::OnAdminRemoveWinStation(WPARAM wParam, LPARAM lParam)
  1061. {
  1062. ODS( L"CAdminTreeView::OnAdminRemoveWinStation\n" );
  1063. ASSERT(lParam);
  1064. //TODO:
  1065. // remove winstaion from favorite list
  1066. CWinStation *pWinStation = (CWinStation*)lParam;
  1067. HTREEITEM hWinStation;
  1068. hWinStation = pWinStation->GetTreeItem();
  1069. if( hWinStation != NULL )
  1070. {
  1071. RemoveWinstation( hWinStation , pWinStation );
  1072. pWinStation->SetTreeItem( NULL );
  1073. }
  1074. hWinStation = pWinStation->GetTreeItemFromFav( );
  1075. if( hWinStation != NULL )
  1076. {
  1077. RemoveWinstation( hWinStation , pWinStation );
  1078. pWinStation->SetTreeItemForFav( NULL );
  1079. }
  1080. hWinStation = pWinStation->GetTreeItemFromThisComputer( );
  1081. if( hWinStation != NULL )
  1082. {
  1083. RemoveWinstation( hWinStation , pWinStation );
  1084. pWinStation->SetTreeItemForThisComputer( NULL );
  1085. }
  1086. return 0;
  1087. }
  1088. LRESULT CAdminTreeView::RemoveWinstation( HTREEITEM hWinStation , CWinStation *pWinStation )
  1089. {
  1090. BOOL CurrentInTree = FALSE;
  1091. LockTreeControl();
  1092. // Get the data attached to this tree node
  1093. CTreeNode *node = ( CTreeNode * )GetTreeCtrl().GetItemData(hWinStation);
  1094. if( node != NULL )
  1095. {
  1096. // Is this the WinStation we want to update
  1097. CWinStation *pTreeWinStation = (CWinStation*)node->GetTreeObject();
  1098. // Make sure the tree node is correct
  1099. if(pTreeWinStation != pWinStation)
  1100. {
  1101. UnlockTreeControl();
  1102. return 0;
  1103. }
  1104. }
  1105. else
  1106. {
  1107. UnlockTreeControl();
  1108. return 0;
  1109. }
  1110. // Delete the data attached to the tree item
  1111. delete node;
  1112. // Let the WinStation know he is no longer in the tree
  1113. // Is this WinStation currently selected in the tree?
  1114. CurrentInTree = ( GetTreeCtrl().GetSelectedItem() == hWinStation );
  1115. // Remove the WinStation from the tree
  1116. GetTreeCtrl().DeleteItem( hWinStation );
  1117. // If this WinStation is the currently selected node in the tree,
  1118. // make it not so
  1119. // This may not be necessary!
  1120. if( CurrentInTree )
  1121. {
  1122. ((CWinAdminDoc*)GetDocument())->SetCurrentView(VIEW_CHANGING);
  1123. }
  1124. UnlockTreeControl();
  1125. return 0;
  1126. } // end CAdminTreeView::OnAdminRemoveWinStation
  1127. ////////////////////////////////
  1128. // F'N: CAdminTreeView::OnAdminUpdateDomain
  1129. //
  1130. // Message handler to update a Domain in the tree
  1131. // Pointer to CDomain to update is in lParam
  1132. //
  1133. LRESULT CAdminTreeView::OnAdminUpdateDomain(WPARAM wParam, LPARAM lParam)
  1134. {
  1135. ASSERT(lParam);
  1136. CDomain *pDomain = (CDomain*)lParam;
  1137. HTREEITEM hDomain = pDomain->GetTreeItem();
  1138. if(!hDomain) return 0;
  1139. LockTreeControl();
  1140. // Get the data attached to this tree node
  1141. CTreeNode *node = (CTreeNode*)GetTreeCtrl().GetItemData(hDomain);
  1142. if(node) {
  1143. // Is this the domain we want to update
  1144. CDomain *pTreeDomain = (CDomain*)node->GetTreeObject();
  1145. // Make sure the tree node is correct
  1146. if(pTreeDomain != pDomain) {
  1147. UnlockTreeControl();
  1148. return 0;
  1149. }
  1150. } else {
  1151. UnlockTreeControl();
  1152. return 0;
  1153. }
  1154. UINT NewState;
  1155. // Remember the previous state
  1156. UINT PreviousState = GetTreeCtrl().GetItemState(hDomain, 0x0F00);
  1157. // Change the icon/overlay for the domain
  1158. if(pDomain->GetState() == DS_INITIAL_ENUMERATION) NewState = STATE_QUESTION;
  1159. // If it is fine, we want to remove any overlays from the icon
  1160. else NewState = STATE_NORMAL;
  1161. // Set the tree item to the new state
  1162. GetTreeCtrl().SetItemState(hDomain, NewState, 0x0F00);
  1163. // If the new state is STATE_NORMAL, change the icon
  1164. if(NewState == STATE_NORMAL) {
  1165. int DomainIcon = DetermineDomainIcon(pDomain);
  1166. GetTreeCtrl().SetItemImage(hDomain, DomainIcon, DomainIcon);
  1167. }
  1168. // If we changed the state of this domain and it is the currently
  1169. // selected node in the tree, we need to send a message to change
  1170. // the view
  1171. if(NewState != PreviousState && hDomain == GetTreeCtrl().GetSelectedItem()) {
  1172. ForceSelChange();
  1173. }
  1174. if(pDomain->GetState() == DS_ENUMERATING) GetTreeCtrl().Expand(hDomain, TVE_EXPAND);
  1175. UnlockTreeControl();
  1176. return 0;
  1177. } // end CAdminTreeView::OnAdminUpdateDomain
  1178. ////////////////////////////////
  1179. // F'N: CAdminTreeView::OnAdminAddDomain
  1180. //
  1181. // Message handler to update a Domain in the tree
  1182. // Pointer to CDomain to update is in lParam
  1183. //
  1184. LRESULT CAdminTreeView::OnAdminAddDomain(WPARAM wParam, LPARAM lParam)
  1185. {
  1186. ASSERT(lParam);
  1187. if(lParam)
  1188. {
  1189. CDomain *pDomain = (CDomain*)lParam;
  1190. return (LRESULT)AddDomainToTree(pDomain);
  1191. }
  1192. return 0;
  1193. } // end CAdminTreeView::OnAdminAddDomain
  1194. ////////////////////////////////
  1195. // F'N: CAdminTreeView::OnContextMenu
  1196. //
  1197. // Message handler called when user wants a context menu
  1198. // This happens when the user clicks the right mouse button,
  1199. // presses Shift-F10, or presses the menu key on a Windows keyboard
  1200. //
  1201. void CAdminTreeView::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  1202. {
  1203. LockTreeControl();
  1204. // Get a pointer to our document
  1205. CWinAdminDoc *doc = (CWinAdminDoc*)GetDocument();
  1206. CTreeCtrl &tree = GetTreeCtrl();
  1207. // TODO: Add your message handler code here
  1208. HTREEITEM hItem;
  1209. CPoint ptClient = ptScreen;
  1210. ScreenToClient(&ptClient);
  1211. // If we got here from the keyboard,
  1212. if(ptScreen.x == -1 && ptScreen.y == -1) {
  1213. hItem = tree.GetSelectedItem();
  1214. RECT rect;
  1215. tree.GetItemRect(hItem, &rect, TRUE);
  1216. ptScreen.x = rect.left + (rect.right - rect.left)/2;
  1217. ptScreen.y = rect.top + (rect.bottom - rect.top)/2;
  1218. tree.ClientToScreen(&ptScreen);
  1219. }
  1220. else {
  1221. // we shouldn't get here from the mouse
  1222. // but sometimes we do, so handle it gracefully
  1223. UnlockTreeControl();
  1224. return;
  1225. }
  1226. // Pop-up the menu for WinStations
  1227. CTreeNode *pNode = (CTreeNode*)tree.GetItemData(hItem);
  1228. ((CWinAdminDoc*)GetDocument())->SetTreeTemp(pNode->GetTreeObject(), (pNode->GetNodeType()));
  1229. if(pNode) {
  1230. CMenu menu;
  1231. UINT nIDResource = 0;
  1232. switch(pNode->GetNodeType()) {
  1233. case NODE_ALL_SERVERS:
  1234. nIDResource = IDR_ALLSERVERS_POPUP;
  1235. break;
  1236. case NODE_DOMAIN:
  1237. nIDResource = IDR_DOMAIN_POPUP;
  1238. break;
  1239. case NODE_SERVER:
  1240. nIDResource = IDR_SERVER_POPUP;
  1241. break;
  1242. case NODE_WINSTATION:
  1243. nIDResource = IDR_WINSTATION_TREE_POPUP;
  1244. break;
  1245. }
  1246. if(nIDResource)
  1247. {
  1248. if(menu.LoadMenu(nIDResource))
  1249. {
  1250. CMenu *pMenu = menu.GetSubMenu(0);
  1251. pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  1252. }
  1253. }
  1254. } // end if(pNode)
  1255. UnlockTreeControl();
  1256. } // end CAdminTreeView::OnContextMenu
  1257. ////////////////////////////////
  1258. // F'N: CAdminTreeView::OnRClick
  1259. //
  1260. // The Tree Common Control sends a WM_NOTIFY of NM_RCLICK when
  1261. // the user presses the right mouse button in the tree
  1262. //
  1263. void CAdminTreeView::OnRClick(NMHDR* pNMHDR, LRESULT* pResult)
  1264. {
  1265. CPoint ptScreen(::GetMessagePos());
  1266. LockTreeControl();
  1267. // Get a pointer to our document
  1268. CWinAdminDoc *doc = (CWinAdminDoc*)GetDocument();
  1269. CTreeCtrl &tree = GetTreeCtrl();
  1270. // TODO: Add your message handler code here
  1271. UINT flags;
  1272. HTREEITEM hItem;
  1273. CPoint ptClient = ptScreen;
  1274. ScreenToClient(&ptClient);
  1275. hItem = tree.HitTest(ptClient, &flags);
  1276. if((NULL == hItem) || !(TVHT_ONITEM & flags)) {
  1277. UnlockTreeControl();
  1278. return;
  1279. }
  1280. // Pop-up the menu
  1281. CTreeNode *pNode = (CTreeNode*)tree.GetItemData(hItem);
  1282. ((CWinAdminDoc*)GetDocument())->SetTreeTemp(pNode->GetTreeObject(), (pNode->GetNodeType()));
  1283. if(pNode) {
  1284. CMenu menu;
  1285. UINT nIDResource = 0;
  1286. tree.SelectItem( hItem );
  1287. switch(pNode->GetNodeType()) {
  1288. case NODE_ALL_SERVERS:
  1289. nIDResource = IDR_ALLSERVERS_POPUP;
  1290. break;
  1291. case NODE_DOMAIN:
  1292. nIDResource = IDR_DOMAIN_POPUP;
  1293. break;
  1294. case NODE_SERVER:
  1295. nIDResource = IDR_SERVER_POPUP;
  1296. break;
  1297. case NODE_WINSTATION:
  1298. nIDResource = IDR_WINSTATION_TREE_POPUP;
  1299. break;
  1300. }
  1301. if(menu.LoadMenu( nIDResource ) )
  1302. {
  1303. CMenu *pMenu = menu.GetSubMenu(0);
  1304. if( pMenu != NULL )
  1305. {
  1306. pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  1307. }
  1308. }
  1309. } // end if(pNode)
  1310. UnlockTreeControl();
  1311. } // end CAdminTreeView::OnRClick
  1312. //A false result means the server is disconnected
  1313. BOOL CAdminTreeView::ConnectToServer(CTreeCtrl* tree, HTREEITEM* hItem)
  1314. {
  1315. CTreeNode *pNode = (CTreeNode*)tree->GetItemData(*hItem);
  1316. if(pNode != NULL && *hItem == tree->GetSelectedItem() )
  1317. {
  1318. if( pNode->GetNodeType() == NODE_SERVER)
  1319. {
  1320. // Is this server in the "just disconnected" state
  1321. CServer *pServer = (CServer*)pNode->GetTreeObject();
  1322. // If both previous state and state are SS_NOT_CONNECTED,
  1323. // we know the user just disconnected from this server
  1324. if(pServer && pServer->IsState(SS_NOT_CONNECTED))
  1325. return false;
  1326. }
  1327. else if( pNode->GetNodeType( ) == NODE_DOMAIN )
  1328. {
  1329. CDomain *pDomain = ( CDomain * )pNode->GetTreeObject( );
  1330. if( pDomain != NULL && pDomain->GetThreadPointer() == NULL )
  1331. pDomain->StartEnumerating();
  1332. }
  1333. }
  1334. return true;
  1335. }
  1336. ////////////////////////////////
  1337. // F'N: CAdminTreeView::OnLButtonDown
  1338. //
  1339. void CAdminTreeView::OnLButtonDblClk(UINT nFlags, CPoint ptClient)
  1340. {
  1341. LockTreeControl();
  1342. CTreeCtrl &tree = GetTreeCtrl();
  1343. UINT flags;
  1344. // Figure out what they clicked on
  1345. HTREEITEM hItem = tree.HitTest(ptClient, &flags);
  1346. if((NULL != hItem) && (TVHT_ONITEM & flags))
  1347. {
  1348. if (!ConnectToServer(&tree, &hItem))
  1349. {
  1350. LRESULT Result = 0xc0;
  1351. OnSelChange(NULL, &Result);
  1352. }
  1353. }
  1354. UnlockTreeControl();
  1355. CTreeView::OnLButtonDblClk(nFlags, ptClient);
  1356. }
  1357. LRESULT CAdminTreeView::OnAdminConnectToServer( WPARAM wp , LPARAM lp )
  1358. {
  1359. OnEnterKey();
  1360. return 0;
  1361. }
  1362. void CAdminTreeView::OnEnterKey( )
  1363. {
  1364. LockTreeControl();
  1365. CTreeCtrl &tree = GetTreeCtrl();
  1366. // Figure out what's selected
  1367. HTREEITEM hItem = tree.GetSelectedItem( );
  1368. if (!ConnectToServer(&tree, &hItem))
  1369. {
  1370. LRESULT Result = 0xc0;
  1371. OnSelChange(NULL, &Result);
  1372. }
  1373. UnlockTreeControl();
  1374. }
  1375. void CAdminTreeView::OnSetFocus( CWnd *pOld )
  1376. {
  1377. CWnd::OnSetFocus( pOld );
  1378. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  1379. pDoc->RegisterLastFocus( TREE_VIEW );
  1380. }
  1381. //=---------------------------------------------------------------------------------------
  1382. // wp is the node type to expand on
  1383. // this computer
  1384. // favorite item
  1385. // domain item
  1386. LRESULT CAdminTreeView::OnAdminGotoServer( WPARAM wp , LPARAM lp )
  1387. {
  1388. // todo use wp correctly
  1389. CServer *pServer = ( CServer * )lp;
  1390. if( pServer == NULL )
  1391. {
  1392. ODS( L"CAdminTreeView::OnAdminGotoServer invalid server arg\n" );
  1393. return 0 ;
  1394. }
  1395. LockTreeControl( );
  1396. CTreeCtrl &tree = GetTreeCtrl( );
  1397. HTREEITEM hTreeItem = pServer->GetTreeItem( );
  1398. if( hTreeItem != NULL )
  1399. {
  1400. ODS( L"CAdminTreeView!OnAdminGotoServer - Server treeitem was found\n" );
  1401. tree.SelectItem(hTreeItem);
  1402. tree.Expand(hTreeItem, TVE_EXPAND);
  1403. }
  1404. UnlockTreeControl( );
  1405. return 0;
  1406. }
  1407. //=---------------------------------------------------------------------------------------
  1408. // wp and lp not used
  1409. //
  1410. LRESULT CAdminTreeView::OnAdminDelFavServer( WPARAM wp , LPARAM lp )
  1411. {
  1412. // get the current treenode
  1413. // determine if its a fav folder or if its parent a fav folder
  1414. // if so get the server and kill it
  1415. LockTreeControl( );
  1416. CTreeCtrl &tree = GetTreeCtrl( );
  1417. HTREEITEM hTreeItem = tree.GetSelectedItem();
  1418. do
  1419. {
  1420. if( hTreeItem == NULL )
  1421. {
  1422. break;
  1423. }
  1424. HTREEITEM hTreeRoot = tree.GetRootItem( );
  1425. if( hTreeRoot == NULL )
  1426. {
  1427. break;
  1428. }
  1429. // get fav folder
  1430. HTREEITEM hTreeFavRoot = tree.GetNextItem( hTreeRoot , TVGN_NEXT );
  1431. if( hTreeFavRoot == NULL )
  1432. {
  1433. break;
  1434. }
  1435. if( hTreeFavRoot == hTreeItem )
  1436. {
  1437. // not a cool thing here ignore
  1438. break;
  1439. }
  1440. hTreeRoot = tree.GetNextItem( hTreeItem , TVGN_PARENT );
  1441. if( hTreeFavRoot == hTreeRoot )
  1442. {
  1443. // yes we're talking about a fav node that the user wants to delete
  1444. CTreeNode *pNode = ( CTreeNode* )tree.GetItemData( hTreeItem );
  1445. if( pNode != NULL && pNode->GetNodeType() == NODE_SERVER )
  1446. {
  1447. CServer *pServer = ( CServer* )pNode->GetTreeObject();
  1448. // sanity check
  1449. if( pServer != NULL && pServer->GetTreeItemFromFav() == hTreeItem )
  1450. {
  1451. OnAdminRemoveServerFromFavs( 0 , ( LPARAM )pServer );
  1452. }
  1453. }
  1454. }
  1455. }while( 0 );
  1456. UnlockTreeControl( );
  1457. return 0;
  1458. }
  1459. //=-------------------------------------------------------------
  1460. LRESULT CAdminTreeView::OnGetTVStates( WPARAM , LPARAM )
  1461. {
  1462. ODS( L"CAdminTreeView::OnGetTVStates\n" );
  1463. DWORD dwStates = 0;
  1464. // find out the tri-states
  1465. HTREEITEM hRoot;
  1466. LockTreeControl( );
  1467. CTreeCtrl &tree = GetTreeCtrl( );
  1468. hRoot = tree.GetRootItem( ); // this computer
  1469. if( hRoot != NULL )
  1470. {
  1471. if( tree.GetItemState( hRoot , TVIS_EXPANDED ) & TVIS_EXPANDED )
  1472. {
  1473. dwStates = TV_THISCOMP;
  1474. }
  1475. hRoot = tree.GetNextItem( hRoot , TVGN_NEXT ); // favorites
  1476. if( hRoot != NULL && tree.GetItemState( hRoot , TVIS_EXPANDED ) & TVIS_EXPANDED )
  1477. {
  1478. dwStates |= TV_FAVS;
  1479. }
  1480. hRoot = tree.GetNextItem( hRoot , TVGN_NEXT ); // all servers
  1481. if( hRoot != NULL && tree.GetItemState( hRoot , TVIS_EXPANDED ) & TVIS_EXPANDED )
  1482. {
  1483. dwStates |= TV_ALLSERVERS;
  1484. }
  1485. }
  1486. UnlockTreeControl( );
  1487. return ( LRESULT )dwStates;
  1488. }
  1489. //=-------------------------------------------------------------
  1490. LRESULT CAdminTreeView::OnUpdateTVState( WPARAM , LPARAM )
  1491. {
  1492. LRESULT lResult = 0xc0;
  1493. HTREEITEM hThisComputerRootItem = GetTreeCtrl().GetRootItem( );
  1494. HTREEITEM hFavRoot = GetTreeCtrl().GetNextItem( hThisComputerRootItem , TVGN_NEXT );
  1495. HTREEITEM hRoot = GetTreeCtrl().GetNextItem( hFavRoot , TVGN_NEXT );
  1496. // We want to default to having the current server being the
  1497. // currently selected item in the tree and be expanded
  1498. if( hThisComputerRootItem != NULL && ( g_dwTreeViewExpandedStates & TV_THISCOMP ) )
  1499. {
  1500. HTREEITEM hThisComputer = GetTreeCtrl().GetNextItem( hThisComputerRootItem , TVGN_CHILD );
  1501. if( hThisComputer != NULL )
  1502. {
  1503. GetTreeCtrl().SelectItem(hThisComputer);
  1504. GetTreeCtrl().Expand(hThisComputer, TVE_EXPAND);
  1505. // GetTreeCtrl().Expand(hDomain, TVE_EXPAND);
  1506. //lResult = 0xc0;
  1507. OnSelChange( NULL , &lResult );
  1508. }
  1509. }
  1510. if( hFavRoot != NULL && ( g_dwTreeViewExpandedStates & TV_FAVS ) )
  1511. {
  1512. GetTreeCtrl().SelectItem( hFavRoot );
  1513. GetTreeCtrl().Expand( hFavRoot , TVE_EXPAND );
  1514. OnSelChange( NULL , &lResult );
  1515. }
  1516. if( hRoot != NULL && ( g_dwTreeViewExpandedStates & TV_ALLSERVERS ) )
  1517. {
  1518. GetTreeCtrl().SelectItem( hRoot );
  1519. GetTreeCtrl().Expand( hRoot , TVE_EXPAND );
  1520. OnSelChange( NULL , &lResult );
  1521. }
  1522. return 0;
  1523. }
  1524. //=-------------------------------------------------------------
  1525. void CAdminTreeView::OnBeginDrag( NMHDR *pNMHDR , LRESULT *pResult )
  1526. {
  1527. ODS( L"CAdminTreeView::OnBeginDrag\n" );
  1528. RECT rc;
  1529. NMTREEVIEW *pTV = ( NMTREEVIEW * )pNMHDR;
  1530. if( pTV != NULL )
  1531. {
  1532. if( m_pimgDragList != NULL )
  1533. {
  1534. // this should never happen
  1535. ODS( L"There is a possible leak CAdminTreeView!OnBeginDrag\n" );
  1536. delete m_pimgDragList;
  1537. m_pimgDragList = NULL;
  1538. }
  1539. if( pTV->itemNew.hItem != NULL )
  1540. {
  1541. m_pimgDragList = GetTreeCtrl().CreateDragImage( pTV->itemNew.hItem );
  1542. }
  1543. if( m_pimgDragList != NULL )
  1544. {
  1545. GetTreeCtrl().GetItemRect( pTV->itemNew.hItem , &rc , FALSE );
  1546. CPoint cp( pTV->ptDrag.x - rc.left , pTV->ptDrag.y - rc.top );
  1547. /*
  1548. HCURSOR hCursor = ::LoadCursor( NULL, IDC_CROSS );
  1549. ICONINFO iconinfo;
  1550. ::GetIconInfo( ( HICON )hCursor , &iconinfo );
  1551. */
  1552. m_pimgDragList->BeginDrag( 0 , CPoint( 0 , 0 ) );
  1553. /*
  1554. cp.x -= iconinfo.xHotspot;
  1555. cp.y -= iconinfo.yHotspot;
  1556. m_pimgDragList->SetDragCursorImage( 0 , cp );
  1557. */
  1558. m_pimgDragList->DragEnter( &GetTreeCtrl( ) , cp );
  1559. SetCapture();
  1560. // this is for us to check when we're not in the client area
  1561. m_nTimer = SetTimer( 1 , 50 , NULL );
  1562. //ShowCursor( FALSE );
  1563. m_hDragItem = pTV->itemNew.hItem;
  1564. }
  1565. }
  1566. *pResult = 0;
  1567. }
  1568. //=-------------------------------------------------------------
  1569. void CAdminTreeView::OnTimer( UINT nIDEvent )
  1570. {
  1571. UINT uflags;
  1572. POINT pt;
  1573. CTreeCtrl &cTree = GetTreeCtrl( );
  1574. GetCursorPos(&pt);
  1575. cTree.ScreenToClient( &pt );
  1576. if( m_nTimer == 0 )
  1577. {
  1578. return;
  1579. }
  1580. HTREEITEM hItem;
  1581. HTREEITEM hTreeItem = cTree.HitTest( CPoint( pt.x , pt.y ) , &uflags );
  1582. if( uflags & TVHT_ABOVE )
  1583. {
  1584. ODS( L"scrolling up...\n" );
  1585. hItem = cTree.GetFirstVisibleItem( );
  1586. hItem = cTree.GetNextItem( hItem , TVGN_PREVIOUSVISIBLE );
  1587. if( hItem != NULL )
  1588. {
  1589. cTree.Invalidate( );
  1590. cTree.EnsureVisible( hItem );
  1591. }
  1592. }
  1593. else if( uflags & TVHT_BELOW )
  1594. {
  1595. ODS( L"scrolling down...\n" );
  1596. hItem = cTree.GetFirstVisibleItem( );
  1597. hItem = cTree.GetNextItem( hItem , TVGN_NEXT );
  1598. if( hItem != NULL )
  1599. {
  1600. cTree.EnsureVisible( hItem );
  1601. }
  1602. }
  1603. }
  1604. //=-------------------------------------------------------------
  1605. void CAdminTreeView::OnLButtonUp( UINT uFlags , CPoint cp )
  1606. {
  1607. ODS( L"CAdminTreeView::OnLButtonUp\n" );
  1608. if( m_hDragItem != NULL && m_pimgDragList != NULL )
  1609. {
  1610. m_pimgDragList->DragLeave( &GetTreeCtrl( ) );
  1611. m_pimgDragList->EndDrag( );
  1612. m_pimgDragList->DeleteImageList( );
  1613. delete m_pimgDragList;
  1614. m_pimgDragList = NULL;
  1615. KillTimer( m_nTimer );
  1616. m_nTimer = 0;
  1617. ReleaseCapture( );
  1618. Invalidate( );
  1619. // ShowCursor( TRUE );
  1620. }
  1621. }
  1622. //=-------------------------------------------------------------
  1623. void CAdminTreeView::OnMouseMove( UINT uFlags , CPoint cp )
  1624. {
  1625. if( m_pimgDragList != NULL )
  1626. {
  1627. UINT uflags;
  1628. HTREEITEM hTreeItem = GetTreeCtrl( ).HitTest( cp , &uflags );
  1629. if( hTreeItem != GetTreeCtrl( ).GetDropHilightItem( ) )
  1630. {
  1631. ODS( L"CAdminTreeView::OnMouseMove NOT!!\n");
  1632. m_pimgDragList->DragLeave( &GetTreeCtrl( ) );
  1633. GetTreeCtrl( ).SelectDropTarget( NULL );
  1634. GetTreeCtrl( ).SelectDropTarget( hTreeItem );
  1635. m_pimgDragList->DragEnter( &GetTreeCtrl( ) , cp );
  1636. }
  1637. else
  1638. {
  1639. m_pimgDragList->DragMove( cp );
  1640. }
  1641. }
  1642. }
  1643. //=-------------------------------------------------------------
  1644. LRESULT CAdminTreeView::OnEmptyFavorites( WPARAM wp, LPARAM )
  1645. {
  1646. ODS( L"CAdminTreeView!OnEmptyFavorites\n" );
  1647. // check to see if there are any items in the view
  1648. LockTreeControl( );
  1649. CTreeCtrl &tree = GetTreeCtrl( );
  1650. int nRet;
  1651. HTREEITEM hTreeRoot = tree.GetRootItem( );
  1652. do
  1653. {
  1654. if( hTreeRoot == NULL )
  1655. {
  1656. break;
  1657. }
  1658. // get fav folder
  1659. HTREEITEM hTreeFavRoot = tree.GetNextItem( hTreeRoot , TVGN_NEXT );
  1660. if( hTreeFavRoot == NULL )
  1661. {
  1662. break;
  1663. }
  1664. HTREEITEM hItem = tree.GetNextItem( hTreeFavRoot , TVGN_CHILD );
  1665. if( hItem == NULL )
  1666. {
  1667. break;
  1668. }
  1669. // warn the user about losing the entire favorite list
  1670. CString cstrMsg;
  1671. CString cstrTitle;
  1672. cstrMsg.LoadString( IDS_EMPTYFOLDER );
  1673. cstrTitle.LoadString( AFX_IDS_APP_TITLE );
  1674. #ifdef _STRESS_BUILD
  1675. if( ( BOOL )wp != TRUE )
  1676. {
  1677. #endif
  1678. nRet = MessageBox( cstrMsg ,
  1679. cstrTitle ,
  1680. MB_YESNO | MB_ICONINFORMATION );
  1681. #ifdef _STRESS_BUILD
  1682. }
  1683. else
  1684. {
  1685. nRet = IDYES;
  1686. }
  1687. #endif
  1688. if( nRet == IDYES )
  1689. {
  1690. // loop through every item and remove the item
  1691. HTREEITEM hNextItem = hItem;
  1692. while( hItem != NULL )
  1693. {
  1694. CTreeNode *pNode = (CTreeNode*)tree.GetItemData(hItem);
  1695. hNextItem = tree.GetNextItem( hItem , TVGN_NEXT );
  1696. if( pNode != NULL )
  1697. {
  1698. // Is it the same item as is selected
  1699. if( pNode->GetNodeType() == NODE_SERVER )
  1700. {
  1701. CServer *pServer = (CServer*)pNode->GetTreeObject();
  1702. // skip this server if its being disconnected
  1703. if( !pServer->IsState( SS_DISCONNECTING ) )
  1704. {
  1705. SendMessage( WM_ADMIN_REMOVESERVERFROMFAV , 0 , ( LPARAM )pServer );
  1706. }
  1707. }
  1708. }
  1709. hItem = hNextItem;
  1710. }
  1711. }
  1712. }while( 0 );
  1713. UnlockTreeControl( );
  1714. return 0;
  1715. }
  1716. //=----------------------------------------------------------------
  1717. LRESULT CAdminTreeView::OnIsFavListEmpty( WPARAM wp , LPARAM lp )
  1718. {
  1719. LockTreeControl( );
  1720. CTreeCtrl &tree = GetTreeCtrl( );
  1721. HTREEITEM hTreeRoot = tree.GetRootItem( );
  1722. BOOL bEmpty = TRUE;
  1723. do
  1724. {
  1725. if( hTreeRoot == NULL )
  1726. {
  1727. break;
  1728. }
  1729. // get fav folder
  1730. HTREEITEM hTreeFavRoot = tree.GetNextItem( hTreeRoot , TVGN_NEXT );
  1731. if( hTreeFavRoot == NULL )
  1732. {
  1733. break;
  1734. }
  1735. HTREEITEM hItem = tree.GetNextItem( hTreeFavRoot , TVGN_CHILD );
  1736. if( hItem == NULL )
  1737. {
  1738. break;
  1739. }
  1740. bEmpty = FALSE;
  1741. } while( 0 );
  1742. UnlockTreeControl( );
  1743. return ( LRESULT )bEmpty;
  1744. }