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.

2541 lines
67 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*******************************************************************************
  3. *
  4. * servpgs.cpp
  5. *
  6. * implementations for the server info pages
  7. *
  8. *
  9. *******************************************************************************/
  10. #include "stdafx.h"
  11. #include "afxpriv.h"
  12. #include "winadmin.h"
  13. #include "servpgs.h"
  14. #include "admindoc.h"
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. ////////////////////////////////
  21. // MESSAGE MAP: CUsersPage
  22. //
  23. IMPLEMENT_DYNCREATE(CUsersPage, CFormView)
  24. BEGIN_MESSAGE_MAP(CUsersPage, CFormView)
  25. //{{AFX_MSG_MAP(CUsersPage)
  26. ON_WM_SIZE()
  27. ON_NOTIFY(LVN_ITEMCHANGED, IDC_USER_LIST, OnUserItemChanged)
  28. ON_NOTIFY(LVN_COLUMNCLICK, IDC_USER_LIST, OnColumnClick)
  29. ON_WM_CONTEXTMENU()
  30. ON_NOTIFY(NM_SETFOCUS, IDC_USER_LIST, OnSetfocusUserList)
  31. //ON_NOTIFY(NM_KILLFOCUS, IDC_USER_LIST, OnKillfocusUserList)
  32. //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34. IMPLEMENT_DYNCREATE(CAdminPage, CFormView)
  35. CAdminPage::CAdminPage(UINT id)
  36. : CFormView(id)
  37. {
  38. }
  39. CAdminPage::CAdminPage()
  40. : CFormView((UINT)0)
  41. {
  42. }
  43. /////////////////////////////
  44. // F'N: CUsersPage ctor
  45. //
  46. CUsersPage::CUsersPage()
  47. : CAdminPage(CUsersPage::IDD)
  48. {
  49. //{{AFX_DATA_INIT(CUsersPage)
  50. // NOTE: the ClassWizard will add member initialization here
  51. //}}AFX_DATA_INIT
  52. m_pServer = NULL;
  53. m_bSortAscending = TRUE;
  54. } // end CUsersPage ctor
  55. /////////////////////////////
  56. // F'N: CUsersPage dtor
  57. //
  58. CUsersPage::~CUsersPage()
  59. {
  60. } // end CUsersPage dtor
  61. ////////////////////////////////////////
  62. // F'N: CUsersPage::DoDataExchange
  63. //
  64. void CUsersPage::DoDataExchange(CDataExchange* pDX)
  65. {
  66. CFormView::DoDataExchange(pDX);
  67. //{{AFX_DATA_MAP(CUsersPage)
  68. DDX_Control(pDX, IDC_USER_LIST, m_UserList);
  69. //}}AFX_DATA_MAP
  70. } // end CUsersPage::DoDataExchange
  71. #ifdef _DEBUG
  72. /////////////////////////////////////
  73. // F'N: CUsersPage::AssertValid
  74. //
  75. void CUsersPage::AssertValid() const
  76. {
  77. CFormView::AssertValid();
  78. } // end CUsersPage::AssertValid
  79. //////////////////////////////
  80. // F'N: CUsersPage::Dump
  81. //
  82. void CUsersPage::Dump(CDumpContext& dc) const
  83. {
  84. CFormView::Dump(dc);
  85. } // end CUsersPage::Dump
  86. #endif //_DEBUG
  87. //////////////////////////////
  88. // F'N: CUsersPage::OnSize
  89. //
  90. void CUsersPage::OnSize(UINT nType, int cx, int cy)
  91. {
  92. RECT rect;
  93. GetClientRect(&rect);
  94. rect.top += LIST_TOP_OFFSET;
  95. if(m_UserList.GetSafeHwnd())
  96. m_UserList.MoveWindow(&rect, TRUE);
  97. //CFormView::OnSize(nType, cx, cy);
  98. } // end CUsersPage::OnSize
  99. static ColumnDef UserColumns[] = {
  100. CD_USER3,
  101. CD_SESSION,
  102. CD_ID,
  103. CD_STATE,
  104. CD_IDLETIME,
  105. CD_LOGONTIME
  106. };
  107. #define NUM_USER_COLUMNS sizeof(UserColumns)/sizeof(ColumnDef)
  108. //////////////////////////////
  109. // F'N: CUsersPage::OnInitialUpdate
  110. //
  111. void CUsersPage::OnInitialUpdate()
  112. {
  113. CFormView::OnInitialUpdate();
  114. BuildImageList(); // builds the image list for the list control
  115. CString columnString;
  116. for(int col = 0; col < NUM_USER_COLUMNS; col++) {
  117. columnString.LoadString(UserColumns[col].stringID);
  118. m_UserList.InsertColumn(col, columnString, UserColumns[col].format, UserColumns[col].width, col);
  119. }
  120. m_CurrentSortColumn = USERS_COL_USER;
  121. } // end CUsersPage::OnInitialUpdate
  122. //////////////////////////////
  123. // F'N: CUsersPage::OnUserItemChanged
  124. //
  125. void CUsersPage::OnUserItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  126. {
  127. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  128. if(pLV->uNewState & LVIS_SELECTED) {
  129. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(pLV->iItem);
  130. pWinStation->SetSelected();
  131. }
  132. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  133. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(pLV->iItem);
  134. pWinStation->ClearSelected();
  135. }
  136. *pResult = 0;
  137. } // end CUsersPage::OnUserItemChanged
  138. /////////////////////////////////////
  139. // F'N: CUsersPage::BuildImageList
  140. //
  141. // - calls m_ImageList.Create(..) to create the image list
  142. // - calls AddIconToImageList(..) to add the icons themselves and save
  143. // off their indices
  144. // - attaches the image list to the list ctrl
  145. //
  146. void CUsersPage::BuildImageList()
  147. {
  148. m_ImageList.Create(16, 16, TRUE, 2, 0);
  149. m_idxUser = AddIconToImageList(IDI_USER);
  150. m_idxCurrentUser = AddIconToImageList(IDI_CURRENT_USER);
  151. m_UserList.SetImageList(&m_ImageList, LVSIL_SMALL);
  152. } // end CUsersPage::BuildImageList
  153. /////////////////////////////////////////
  154. // F'N: CUsersPage::AddIconToImageList
  155. //
  156. // - loads the appropriate icon, adds it to m_ImageList, and returns
  157. // the newly-added icon's index in the image list
  158. //
  159. int CUsersPage::AddIconToImageList(int iconID)
  160. {
  161. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  162. return m_ImageList.Add(hIcon);
  163. } // end CUsersPage::AddIconToImageList
  164. //////////////////////////////
  165. // F'N: CUsersPage::Reset
  166. //
  167. void CUsersPage::Reset(void *pServer)
  168. {
  169. m_pServer = (CServer*)pServer;
  170. DisplayUsers();
  171. } // end CUsersPage::Reset
  172. //////////////////////////////
  173. // F'N: CUsersPage::UpdateWinStations
  174. //
  175. void CUsersPage::UpdateWinStations(CServer *pServer)
  176. {
  177. if(pServer != m_pServer) return;
  178. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  179. BOOL bAnyChanged = FALSE;
  180. BOOL bAnyAdded = FALSE;
  181. // Loop through the WinStations
  182. m_pServer->LockWinStationList();
  183. CObList *pWinStationList = m_pServer->GetWinStationList();
  184. POSITION pos = pWinStationList->GetHeadPosition();
  185. while(pos) {
  186. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  187. LV_FINDINFO FindInfo;
  188. FindInfo.flags = LVFI_PARAM;
  189. FindInfo.lParam = (LPARAM)pWinStation;
  190. // Find the WinStation in our list
  191. int item = m_UserList.FindItem(&FindInfo, -1);
  192. // If the process is new and isn't currently in the list,
  193. // add it to the list
  194. if(pWinStation->IsNew() && pWinStation->HasUser() && item == -1) {
  195. AddUserToList(pWinStation);
  196. bAnyAdded = TRUE;
  197. continue;
  198. }
  199. // If the WinStation is no longer current or no longer has a user,
  200. // remove it from the list
  201. if((!pWinStation->IsCurrent() || !pWinStation->HasUser()) && item != -1) {
  202. // Remove the WinStation from the list
  203. m_UserList.DeleteItem(item);
  204. pWinStation->ClearSelected();
  205. continue;
  206. }
  207. // If the WinStation info has changed, change
  208. // it's info in our tree
  209. if(pWinStation->IsChanged() && item != -1) {
  210. // change the user name
  211. m_UserList.SetItemText(item, USERS_COL_USER, pWinStation->GetUserName());
  212. // change the WinStation Name
  213. // WinStation Name
  214. if(pWinStation->GetName()[0])
  215. m_UserList.SetItemText(item, USERS_COL_WINSTATION, pWinStation->GetName());
  216. else {
  217. CString NameString(" ");
  218. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  219. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  220. m_UserList.SetItemText(item, USERS_COL_WINSTATION, NameString);
  221. }
  222. // change the Connect State
  223. m_UserList.SetItemText(item, USERS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  224. // change the Idle Time
  225. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  226. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  227. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  228. {
  229. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  230. }
  231. else wcscpy(IdleTimeString, TEXT("."));
  232. m_UserList.SetItemText(item, USERS_COL_IDLETIME, IdleTimeString);
  233. // change the Logon Time
  234. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  235. // We don't want to pass a 0 logon time to DateTimeString()
  236. // It will blow up if the timezone is GMT
  237. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  238. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  239. pDoc->FixUnknownString(LogonTimeString);
  240. }
  241. else LogonTimeString[0] = '\0';
  242. // change the
  243. m_UserList.SetItemText(item, USERS_COL_LOGONTIME, LogonTimeString);
  244. if(m_CurrentSortColumn != USERS_COL_ID)
  245. bAnyChanged = TRUE;
  246. continue;
  247. }
  248. // If the WinStation is not in the list but now has a user, add it to the list
  249. if(item == -1 && pWinStation->IsCurrent() && pWinStation->HasUser()) {
  250. AddUserToList(pWinStation);
  251. bAnyAdded = TRUE;
  252. }
  253. }
  254. m_pServer->UnlockWinStationList();
  255. if(bAnyChanged || bAnyAdded) SortByColumn(VIEW_SERVER, PAGE_USERS, &m_UserList, m_CurrentSortColumn, m_bSortAscending);
  256. } // end CUsersPage::UpdateWinStations
  257. //////////////////////////////
  258. // F'N: CUsersPage::AddUserToList
  259. //
  260. int CUsersPage::AddUserToList(CWinStation *pWinStation)
  261. {
  262. int item = -1;
  263. if( pWinStation != NULL )
  264. {
  265. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  266. LockListControl();
  267. //////////////////////
  268. // Fill in the columns
  269. //////////////////////
  270. // User - put at the end of the list
  271. item = m_UserList.InsertItem(m_UserList.GetItemCount(), pWinStation->GetUserName(),
  272. pWinStation->IsCurrentUser() ? m_idxCurrentUser : m_idxUser);
  273. // WinStation Name
  274. if(pWinStation->GetName()[0])
  275. m_UserList.SetItemText(item, USERS_COL_WINSTATION, pWinStation->GetName());
  276. else {
  277. CString NameString(" ");
  278. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  279. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  280. m_UserList.SetItemText(item, USERS_COL_WINSTATION, NameString);
  281. }
  282. // Logon ID
  283. CString ColumnString;
  284. ColumnString.Format(TEXT("%lu"), pWinStation->GetLogonId());
  285. m_UserList.SetItemText(item, USERS_COL_ID, ColumnString);
  286. // Connect State
  287. m_UserList.SetItemText(item, USERS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  288. // Idle Time
  289. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  290. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  291. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  292. {
  293. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  294. }
  295. else wcscpy(IdleTimeString, TEXT("."));
  296. m_UserList.SetItemText(item, USERS_COL_IDLETIME, IdleTimeString);
  297. // Logon Time
  298. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  299. // We don't want to pass a 0 logon time to DateTimeString()
  300. // It will blow up if the timezone is GMT
  301. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  302. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  303. pDoc->FixUnknownString(LogonTimeString);
  304. }
  305. else LogonTimeString[0] = '\0';
  306. m_UserList.SetItemText(item, USERS_COL_LOGONTIME, LogonTimeString);
  307. // Attach a pointer to the CWinStation structure to the list item
  308. m_UserList.SetItemData(item, (DWORD_PTR)pWinStation);
  309. // m_UserList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  310. UnlockListControl();
  311. }
  312. return item;
  313. } // end CUsersPage::AddUserToList
  314. /////////////////////////////////////
  315. // F'N: CUsersPage::DisplayUsers
  316. //
  317. void CUsersPage::DisplayUsers()
  318. {
  319. LockListControl();
  320. // Clear out the list control
  321. m_UserList.DeleteAllItems();
  322. m_pServer->LockWinStationList();
  323. // Get a pointer to this server's list of WinStations
  324. CObList *pWinStationList = m_pServer->GetWinStationList();
  325. // Iterate through the WinStation list
  326. POSITION pos = pWinStationList->GetHeadPosition();
  327. while(pos) {
  328. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  329. // only show the WinStation if it has a user
  330. if(pWinStation->HasUser()) {
  331. AddUserToList(pWinStation);
  332. }
  333. } // end while(pos)
  334. //bug #191727
  335. //m_UserList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  336. m_pServer->UnlockWinStationList();
  337. UnlockListControl();
  338. } // end CUsersPage::DisplayUsers
  339. //////////////////////////////
  340. // F'N: CUsersPage::OnColumnClick
  341. //
  342. void CUsersPage::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
  343. {
  344. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  345. // TODO: Add your control notification handler code here
  346. // If the sort column hasn't changed, flip the ascending mode.
  347. if(m_CurrentSortColumn == pNMListView->iSubItem)
  348. m_bSortAscending = !m_bSortAscending;
  349. else // New sort column, start in ascending mode
  350. m_bSortAscending = TRUE;
  351. m_CurrentSortColumn = pNMListView->iSubItem;
  352. LockListControl();
  353. SortByColumn(VIEW_SERVER, PAGE_USERS, &m_UserList, m_CurrentSortColumn, m_bSortAscending);
  354. UnlockListControl();
  355. *pResult = 0;
  356. } // end CUsersPage::OnColumnClick
  357. //////////////////////////////
  358. // F'N: CUsersPage::OnContextMenu
  359. //
  360. void CUsersPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  361. {
  362. // TODO: Add your message handler code here
  363. UINT flags;
  364. UINT Item;
  365. CPoint ptClient = ptScreen;
  366. ScreenToClient(&ptClient);
  367. // If we got here from the keyboard,
  368. if(ptScreen.x == -1 && ptScreen.y == -1) {
  369. UINT iCount = m_UserList.GetItemCount( );
  370. RECT rc;
  371. for( Item = 0 ; Item < iCount ; Item++ )
  372. {
  373. if( m_UserList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  374. {
  375. m_UserList.GetItemRect( Item , &rc , LVIR_ICON );
  376. ptScreen.x = rc.left;
  377. ptScreen.y = rc.bottom + 5;
  378. ClientToScreen( &ptScreen );
  379. break;
  380. }
  381. }
  382. if(ptScreen.x == -1 && ptScreen.y == -1)
  383. {
  384. return;
  385. }
  386. /*
  387. m_UserList.GetClientRect(&rect);
  388. ptScreen.x = (rect.right - rect.left) / 2;
  389. ptScreen.y = (rect.bottom - rect.top) / 2;
  390. ClientToScreen(&ptScreen);
  391. */
  392. }
  393. else {
  394. Item = m_UserList.HitTest(ptClient, &flags);
  395. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  396. {
  397. //
  398. // ListView HitTest bug? return -1 but item display as selected.
  399. // workaround for now, Al can fix this later
  400. //
  401. UINT iCount = m_UserList.GetItemCount( );
  402. RECT rc;
  403. for( Item = 0 ; Item < iCount ; Item++ )
  404. {
  405. if( m_UserList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  406. {
  407. break;
  408. }
  409. }
  410. if( Item >= iCount )
  411. {
  412. return;
  413. }
  414. }
  415. //
  416. // NM_RCLICK (WM_NOTIFY) then WM_CNTEXTMENU but no NM_ITEMCHANGED message
  417. // manually set it to selected state
  418. //
  419. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(Item);
  420. if( !pWinStation )
  421. return;
  422. if( m_UserList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  423. {
  424. pWinStation->SetSelected();
  425. }
  426. }
  427. CMenu menu;
  428. menu.LoadMenu(IDR_USER_POPUP);
  429. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  430. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  431. menu.DestroyMenu();
  432. } // end CUsersPage::OnContextMenu
  433. /////////////////////////////////////
  434. // F'N: CUsersPage::ClearSelections
  435. //
  436. void CUsersPage::ClearSelections()
  437. {
  438. if(m_UserList.m_hWnd != NULL)
  439. {
  440. POSITION pos = m_UserList.GetFirstSelectedItemPosition();
  441. while (pos)
  442. {
  443. int nItem = m_UserList.GetNextSelectedItem(pos);
  444. m_UserList.SetItemState(nItem,0,LVIS_SELECTED);
  445. }
  446. }
  447. }
  448. ////////////////////////////////
  449. // MESSAGE MAP: CServerWinStationsPage
  450. //
  451. IMPLEMENT_DYNCREATE(CServerWinStationsPage, CFormView)
  452. BEGIN_MESSAGE_MAP(CServerWinStationsPage, CFormView)
  453. //{{AFX_MSG_MAP(CServerWinStationsPage)
  454. ON_WM_SIZE()
  455. ON_NOTIFY(LVN_ITEMCHANGED, IDC_WINSTATION_LIST, OnWinStationItemChanged)
  456. ON_NOTIFY(LVN_COLUMNCLICK, IDC_WINSTATION_LIST, OnColumnClick)
  457. ON_WM_CONTEXTMENU()
  458. ON_NOTIFY(NM_SETFOCUS, IDC_WINSTATION_LIST, OnSetfocusWinstationList)
  459. //ON_NOTIFY(NM_KILLFOCUS, IDC_WINSTATION_LIST, OnKillfocusWinstationList)
  460. //}}AFX_MSG_MAP
  461. END_MESSAGE_MAP()
  462. /////////////////////////////
  463. // F'N: CServerWinStationsPage ctor
  464. //
  465. CServerWinStationsPage::CServerWinStationsPage()
  466. : CAdminPage(CServerWinStationsPage::IDD)
  467. {
  468. //{{AFX_DATA_INIT(CServerWinStationsPage)
  469. // NOTE: the ClassWizard will add member initialization here
  470. //}}AFX_DATA_INIT
  471. m_pServer = NULL;
  472. m_bSortAscending = TRUE;
  473. } // end CServerWinStationsPage ctor
  474. /////////////////////////////
  475. // F'N: CServerWinStationsPage dtor
  476. //
  477. CServerWinStationsPage::~CServerWinStationsPage()
  478. {
  479. } // end CServerWinStationsPage dtor
  480. ////////////////////////////////////////
  481. // F'N: CServerWinStationsPage::DoDataExchange
  482. //
  483. void CServerWinStationsPage::DoDataExchange(CDataExchange* pDX)
  484. {
  485. CFormView::DoDataExchange(pDX);
  486. //{{AFX_DATA_MAP(CServerWinStationsPage)
  487. DDX_Control(pDX, IDC_WINSTATION_LIST, m_StationList);
  488. //}}AFX_DATA_MAP
  489. } // end CServerWinStationsPage::DoDataExchange
  490. #ifdef _DEBUG
  491. /////////////////////////////////////
  492. // F'N: CServerWinStationsPage::AssertValid
  493. //
  494. void CServerWinStationsPage::AssertValid() const
  495. {
  496. CFormView::AssertValid();
  497. } // end CServerWinStationsPage::AssertValid
  498. //////////////////////////////
  499. // F'N: CServerWinStationsPage::Dump
  500. //
  501. void CServerWinStationsPage::Dump(CDumpContext& dc) const
  502. {
  503. CFormView::Dump(dc);
  504. } // end CServerWinStationsPage::Dump
  505. #endif //_DEBUG
  506. //////////////////////////////
  507. // F'N: CServerWinStationsPage::OnWinStationItemChanged
  508. //
  509. void CServerWinStationsPage::OnWinStationItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  510. {
  511. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  512. if(pLV->uNewState & LVIS_SELECTED) {
  513. CWinStation *pWinStation = (CWinStation*)m_StationList.GetItemData(pLV->iItem);
  514. pWinStation->SetSelected();
  515. }
  516. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  517. CWinStation *pWinStation = (CWinStation*)m_StationList.GetItemData(pLV->iItem);
  518. pWinStation->ClearSelected();
  519. }
  520. *pResult = 0;
  521. } // end CServerWinStationsPage::OnWinStationItemChanged
  522. //////////////////////////////
  523. // F'N: CServerWinStationsPage::OnSize
  524. //
  525. void CServerWinStationsPage::OnSize(UINT nType, int cx, int cy)
  526. {
  527. RECT rect;
  528. GetClientRect(&rect);
  529. rect.top += LIST_TOP_OFFSET;
  530. if(m_StationList.GetSafeHwnd())
  531. m_StationList.MoveWindow(&rect, TRUE);
  532. // CFormView::OnSize(nType, cx, cy);
  533. } // end CServerWinStationsPage::OnSize
  534. static ColumnDef WinsColumns[] = {
  535. CD_SESSION2,
  536. CD_USER2,
  537. CD_ID,
  538. CD_STATE,
  539. CD_TYPE,
  540. CD_CLIENT_NAME,
  541. CD_IDLETIME,
  542. CD_LOGONTIME,
  543. CD_COMMENT
  544. };
  545. #define NUM_WINS_COLUMNS sizeof(WinsColumns)/sizeof(ColumnDef)
  546. //////////////////////////////
  547. // F'N: CServerWinStationsPage::OnInitialUpdate
  548. //
  549. void CServerWinStationsPage::OnInitialUpdate()
  550. {
  551. // Call the parent class
  552. CFormView::OnInitialUpdate();
  553. // builds the image list for the list control
  554. BuildImageList();
  555. // Add the column headings
  556. CString columnString;
  557. for(int col = 0; col < NUM_WINS_COLUMNS; col++) {
  558. columnString.LoadString(WinsColumns[col].stringID);
  559. m_StationList.InsertColumn(col, columnString, WinsColumns[col].format, WinsColumns[col].width, col);
  560. }
  561. m_CurrentSortColumn = WS_COL_WINSTATION;
  562. } // end CServerWinStationsPage::OnInitialUpdate
  563. /////////////////////////////////////
  564. // F'N: CServerWinStationsPage::BuildImageList
  565. //
  566. // - calls m_ImageList.Create(..) to create the image list
  567. // - calls AddIconToImageList(..) to add the icons themselves and save
  568. // off their indices
  569. // - attaches the image list to the list ctrl
  570. //
  571. void CServerWinStationsPage::BuildImageList()
  572. {
  573. m_ImageList.Create(16, 16, TRUE, 11, 0);
  574. m_idxBlank = AddIconToImageList(IDI_BLANK);
  575. m_idxCitrix = AddIconToImageList(IDR_MAINFRAME);
  576. m_idxServer = AddIconToImageList(IDI_SERVER);
  577. m_idxConsole = AddIconToImageList(IDI_CONSOLE);
  578. m_idxNet = AddIconToImageList(IDI_NET);
  579. m_idxAsync = AddIconToImageList(IDI_ASYNC);
  580. m_idxCurrentConsole = AddIconToImageList(IDI_CURRENT_CONSOLE);
  581. m_idxCurrentNet = AddIconToImageList(IDI_CURRENT_NET);
  582. m_idxCurrentAsync = AddIconToImageList(IDI_CURRENT_ASYNC);
  583. m_idxDirectAsync = AddIconToImageList(IDI_DIRECT_ASYNC);
  584. m_idxCurrentDirectAsync = AddIconToImageList(IDI_CURRENT_DIRECT_ASYNC);
  585. m_StationList.SetImageList(&m_ImageList, LVSIL_SMALL);
  586. } // end CServerWinStationsPage::BuildImageList
  587. /////////////////////////////////////////
  588. // F'N: CServerWinStationsPage::AddIconToImageList
  589. //
  590. // - loads the appropriate icon, adds it to m_ImageList, and returns
  591. // the newly-added icon's index in the image list
  592. //
  593. int CServerWinStationsPage::AddIconToImageList(int iconID)
  594. {
  595. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  596. return m_ImageList.Add(hIcon);
  597. } // end CServerWinStationsPage::AddIconToImageList
  598. //////////////////////////////
  599. // F'N: CServerWinStationsPage::Reset
  600. //
  601. void CServerWinStationsPage::Reset(void *pServer)
  602. {
  603. m_pServer = (CServer*)pServer;
  604. DisplayStations();
  605. } // end CServerWinStationsPage::Reset
  606. //////////////////////////////
  607. // F'N: CServerWinStationsPage::UpdateWinStations
  608. //
  609. void CServerWinStationsPage::UpdateWinStations(CServer *pServer)
  610. {
  611. if(pServer != m_pServer) return;
  612. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  613. BOOL bAnyChanged = FALSE;
  614. BOOL bAnyAdded = FALSE;
  615. // Loop through the WinStations
  616. m_pServer->LockWinStationList();
  617. CObList *pWinStationList = m_pServer->GetWinStationList();
  618. POSITION pos = pWinStationList->GetHeadPosition();
  619. while(pos) {
  620. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  621. LV_FINDINFO FindInfo;
  622. FindInfo.flags = LVFI_PARAM;
  623. FindInfo.lParam = (LPARAM)pWinStation;
  624. // Find the WinStation in our list
  625. int item = m_StationList.FindItem(&FindInfo, -1);
  626. // If the process is new and not currently in the list,
  627. // add it to the list
  628. if(pWinStation->IsNew() && item == -1) {
  629. AddWinStationToList(pWinStation);
  630. bAnyAdded = TRUE;
  631. continue;
  632. }
  633. // If the WinStation is no longer current,
  634. // remove it from the list
  635. if(!pWinStation->IsCurrent() && item != -1) {
  636. // Remove the WinStation from the list
  637. m_StationList.DeleteItem(item);
  638. pWinStation->ClearSelected();
  639. continue;
  640. }
  641. // If the WinStation info has changed, change
  642. // it's info in our tree
  643. if(pWinStation->IsChanged() && item != -1) {
  644. // Figure out which icon to use
  645. int WhichIcon = m_idxBlank;
  646. BOOL CurrentWinStation = pWinStation->IsCurrentWinStation();
  647. if(pWinStation->GetState() != State_Disconnected
  648. && pWinStation->GetState() != State_Idle) {
  649. switch(pWinStation->GetSdClass()) {
  650. case SdAsync:
  651. if(pWinStation->IsDirectAsync())
  652. WhichIcon = CurrentWinStation ? m_idxCurrentDirectAsync : m_idxDirectAsync;
  653. else
  654. WhichIcon = CurrentWinStation ? m_idxCurrentAsync : m_idxAsync;
  655. break;
  656. case SdNetwork:
  657. WhichIcon = CurrentWinStation ? m_idxCurrentNet : m_idxNet;
  658. break;
  659. default:
  660. WhichIcon = CurrentWinStation ? m_idxCurrentConsole : m_idxConsole;
  661. break;
  662. }
  663. }
  664. m_StationList.SetItem(item, 0, LVIF_IMAGE, 0, WhichIcon, 0, 0, 0L);
  665. // WinStation Name
  666. if(pWinStation->GetName()[0])
  667. m_StationList.SetItemText(item, WS_COL_WINSTATION, pWinStation->GetName());
  668. else {
  669. CString NameString(" ");
  670. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  671. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  672. m_StationList.SetItemText(item, WS_COL_WINSTATION, NameString);
  673. }
  674. // User
  675. m_StationList.SetItemText(item, WS_COL_USER, pWinStation->GetUserName());
  676. // Logon ID
  677. CString ColumnString;
  678. ColumnString.Format(TEXT("%lu"), pWinStation->GetLogonId());
  679. m_StationList.SetItemText(item, WS_COL_ID, ColumnString);
  680. // Connect State
  681. m_StationList.SetItemText(item, WS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  682. // Type
  683. m_StationList.SetItemText(item, WS_COL_TYPE, pWinStation->GetWdName());
  684. // Client Name
  685. m_StationList.SetItemText(item, WS_COL_CLIENTNAME, pWinStation->GetClientName());
  686. // Idle Time
  687. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  688. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  689. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  690. {
  691. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  692. }
  693. else wcscpy(IdleTimeString, TEXT("."));
  694. m_StationList.SetItemText(item, WS_COL_IDLETIME, IdleTimeString);
  695. // Logon Time
  696. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  697. // We don't want to pass a 0 logon time to DateTimeString()
  698. // It will blow up if the timezone is GMT
  699. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  700. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  701. pDoc->FixUnknownString(LogonTimeString);
  702. }
  703. else LogonTimeString[0] = '\0';
  704. m_StationList.SetItemText(item, WS_COL_LOGONTIME, LogonTimeString);
  705. // Comment
  706. m_StationList.SetItemText(item, WS_COL_COMMENT, pWinStation->GetComment());
  707. if(m_CurrentSortColumn != WS_COL_ID)
  708. bAnyChanged = TRUE;
  709. }
  710. }
  711. m_pServer->UnlockWinStationList();
  712. if(bAnyChanged || bAnyAdded) SortByColumn(VIEW_SERVER, PAGE_WINSTATIONS, &m_StationList, m_CurrentSortColumn, m_bSortAscending);
  713. }
  714. //////////////////////////////
  715. // F'N: CServerWinStationsPage::AddWinStationToList
  716. //
  717. int CServerWinStationsPage::AddWinStationToList(CWinStation *pWinStation)
  718. {
  719. CServer *pServer = pWinStation->GetServer();
  720. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  721. // Figure out which icon to use
  722. int WhichIcon = m_idxBlank;
  723. BOOL CurrentWinStation = pWinStation->IsCurrentWinStation();
  724. if(pWinStation->GetState() != State_Disconnected
  725. && pWinStation->GetState() != State_Idle) {
  726. switch(pWinStation->GetSdClass()) {
  727. case SdAsync:
  728. if(pWinStation->IsDirectAsync())
  729. WhichIcon = CurrentWinStation ? m_idxCurrentDirectAsync : m_idxDirectAsync;
  730. else
  731. WhichIcon = CurrentWinStation ? m_idxCurrentAsync : m_idxAsync;
  732. break;
  733. case SdNetwork:
  734. WhichIcon = CurrentWinStation ? m_idxCurrentNet : m_idxNet;
  735. break;
  736. default:
  737. WhichIcon = CurrentWinStation ? m_idxCurrentConsole : m_idxConsole;
  738. break;
  739. }
  740. }
  741. //////////////////////
  742. // Fill in the columns
  743. //////////////////////
  744. LockListControl();
  745. int item;
  746. // WinStation Name
  747. if(pWinStation->GetName()[0])
  748. item = m_StationList.InsertItem(m_StationList.GetItemCount(), pWinStation->GetName(), WhichIcon);
  749. else {
  750. CString NameString(" ");
  751. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  752. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  753. item = m_StationList.InsertItem(m_StationList.GetItemCount(), NameString, WhichIcon);
  754. }
  755. // User
  756. m_StationList.SetItemText(item, WS_COL_USER, pWinStation->GetUserName());
  757. // Logon ID
  758. CString ColumnString;
  759. ColumnString.Format(TEXT("%lu"), pWinStation->GetLogonId());
  760. m_StationList.SetItemText(item, WS_COL_ID, ColumnString);
  761. // Connect State
  762. m_StationList.SetItemText(item, WS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  763. // Type
  764. m_StationList.SetItemText(item, WS_COL_TYPE, pWinStation->GetWdName());
  765. // Client Name
  766. m_StationList.SetItemText(item, WS_COL_CLIENTNAME, pWinStation->GetClientName());
  767. // Idle Time
  768. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  769. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  770. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  771. {
  772. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  773. }
  774. else wcscpy(IdleTimeString, TEXT("."));
  775. m_StationList.SetItemText(item, WS_COL_IDLETIME, IdleTimeString);
  776. // Logon Time
  777. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  778. // We don't want to pass a 0 logon time to DateTimeString()
  779. // It will blow up if the timezone is GMT
  780. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  781. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  782. pDoc->FixUnknownString(LogonTimeString);
  783. }
  784. else LogonTimeString[0] = '\0';
  785. m_StationList.SetItemText(item, WS_COL_LOGONTIME, LogonTimeString);
  786. // Comment
  787. m_StationList.SetItemText(item, WS_COL_COMMENT, pWinStation->GetComment());
  788. // Attach a pointer to the CWinStation structure to the list item
  789. m_StationList.SetItemData(item, (DWORD_PTR)pWinStation);
  790. // m_StationList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  791. UnlockListControl();
  792. return item;
  793. } // end CServerWinStationsPage::AddWinStationToList
  794. /////////////////////////////////////
  795. // F'N: CServerWinStationsPage::DisplayStations
  796. //
  797. void CServerWinStationsPage::DisplayStations()
  798. {
  799. LockListControl();
  800. // Clear out the list control
  801. m_StationList.DeleteAllItems();
  802. m_pServer->LockWinStationList();
  803. // Get a pointer to this server's list of WinStations
  804. CObList *pWinStationList = m_pServer->GetWinStationList();
  805. // Iterate through the WinStation list
  806. POSITION pos2 = pWinStationList->GetHeadPosition();
  807. while(pos2) {
  808. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos2);
  809. AddWinStationToList(pWinStation);
  810. }
  811. //bug #191727
  812. //m_StationList.SetItemState( m_StationList.GetItemCount() - 1 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  813. // We don't want the same order as the tree list, but an alphabetical order instead
  814. SortByColumn(VIEW_SERVER, PAGE_WINSTATIONS, &m_StationList, m_CurrentSortColumn, m_bSortAscending);
  815. m_pServer->UnlockWinStationList();
  816. UnlockListControl();
  817. } // end CServerWinStationsPage::DisplayStations
  818. //////////////////////////////
  819. // F'N: CServerWinStationsPage::OnColumnClick
  820. //
  821. void CServerWinStationsPage::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
  822. {
  823. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  824. // TODO: Add your control notification handler code here
  825. // If the sort column hasn't changed, flip the ascending mode.
  826. if(m_CurrentSortColumn == pNMListView->iSubItem)
  827. m_bSortAscending = !m_bSortAscending;
  828. else // New sort column, start in ascending mode
  829. m_bSortAscending = TRUE;
  830. m_CurrentSortColumn = pNMListView->iSubItem;
  831. LockListControl();
  832. SortByColumn(VIEW_SERVER, PAGE_WINSTATIONS, &m_StationList, m_CurrentSortColumn, m_bSortAscending);
  833. UnlockListControl();
  834. *pResult = 0;
  835. } // end CServerWinStationsPage::OnColumnClick
  836. //////////////////////////////
  837. // F'N: CServerWinStationsPage::OnContextMenu
  838. //
  839. void CServerWinStationsPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  840. {
  841. // TODO: Add your message handler code here
  842. UINT flags;
  843. UINT Item;
  844. CPoint ptClient = ptScreen;
  845. ScreenToClient(&ptClient);
  846. // If we got here from the keyboard,
  847. if(ptScreen.x == -1 && ptScreen.y == -1) {
  848. UINT iCount = m_StationList.GetItemCount( );
  849. RECT rc;
  850. for( Item = 0 ; Item < iCount ; Item++ )
  851. {
  852. if( m_StationList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  853. {
  854. m_StationList.GetItemRect( Item , &rc , LVIR_ICON );
  855. ptScreen.x = rc.left;
  856. ptScreen.y = rc.bottom + 5;
  857. ClientToScreen( &ptScreen );
  858. break;
  859. }
  860. }
  861. if(ptScreen.x == -1 && ptScreen.y == -1)
  862. {
  863. return;
  864. }
  865. /*
  866. RECT rect;
  867. m_StationList.GetClientRect(&rect);
  868. ptScreen.x = (rect.right - rect.left) / 2;
  869. ptScreen.y = (rect.bottom - rect.top) / 2;
  870. ClientToScreen(&ptScreen);
  871. */
  872. }
  873. else {
  874. Item = m_StationList.HitTest(ptClient, &flags);
  875. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  876. return;
  877. }
  878. CMenu menu;
  879. menu.LoadMenu(IDR_WINSTATION_POPUP);
  880. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  881. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  882. menu.DestroyMenu();
  883. } // end CServerWinStationsPage::OnContextMenu
  884. /////////////////////////////////////
  885. // F'N: CServerWinStationsPage::ClearSelections
  886. //
  887. void CServerWinStationsPage::ClearSelections()
  888. {
  889. if(m_StationList.m_hWnd != NULL)
  890. {
  891. POSITION pos = m_StationList.GetFirstSelectedItemPosition();
  892. while (pos)
  893. {
  894. int nItem = m_StationList.GetNextSelectedItem(pos);
  895. m_StationList.SetItemState(nItem,0,LVIS_SELECTED);
  896. }
  897. }
  898. }
  899. //////////////////////////////////
  900. // MESSAGE MAP: CServerProcessesPage
  901. //
  902. IMPLEMENT_DYNCREATE(CServerProcessesPage, CFormView)
  903. BEGIN_MESSAGE_MAP(CServerProcessesPage, CFormView)
  904. //{{AFX_MSG_MAP(CServerProcessesPage)
  905. ON_WM_SIZE()
  906. ON_NOTIFY(LVN_COLUMNCLICK, IDC_PROCESS_LIST, OnColumnClick)
  907. ON_NOTIFY(LVN_ITEMCHANGED, IDC_PROCESS_LIST, OnProcessItemChanged)
  908. ON_WM_CONTEXTMENU()
  909. ON_NOTIFY(NM_SETFOCUS, IDC_PROCESS_LIST, OnSetfocusProcessList)
  910. //ON_NOTIFY(NM_KILLFOCUS, IDC_PROCESS_LIST, OnKillfocusProcessList)
  911. //}}AFX_MSG_MAP
  912. END_MESSAGE_MAP()
  913. ///////////////////////////////
  914. // F'N: CServerProcessesPage ctor
  915. //
  916. CServerProcessesPage::CServerProcessesPage()
  917. : CAdminPage(CServerProcessesPage::IDD)
  918. {
  919. //{{AFX_DATA_INIT(CServerProcessesPage)
  920. // NOTE: the ClassWizard will add member initialization here
  921. //}}AFX_DATA_INIT
  922. m_pServer = NULL;
  923. m_bSortAscending = TRUE;
  924. } // end CServerProcessesPage ctor
  925. ///////////////////////////////
  926. // F'N: CServerProcessesPage dtor
  927. //
  928. CServerProcessesPage::~CServerProcessesPage()
  929. {
  930. } // end CServerProcessesPage dtor
  931. //////////////////////////////////////////
  932. // F'N: CServerProcessesPage::DoDataExchange
  933. //
  934. void CServerProcessesPage::DoDataExchange(CDataExchange* pDX)
  935. {
  936. CFormView::DoDataExchange(pDX);
  937. //{{AFX_DATA_MAP(CServerProcessesPage)
  938. DDX_Control(pDX, IDC_PROCESS_LIST, m_ProcessList);
  939. //}}AFX_DATA_MAP
  940. } // end CServerProcessesPage::DoDataExchange
  941. #ifdef _DEBUG
  942. ///////////////////////////////////////
  943. // F'N: CServerProcessesPage::AssertValid
  944. //
  945. void CServerProcessesPage::AssertValid() const
  946. {
  947. CFormView::AssertValid();
  948. } // end CServerProcessesPage::AssertValid
  949. ////////////////////////////////
  950. // F'N: CServerProcessesPage::Dump
  951. //
  952. void CServerProcessesPage::Dump(CDumpContext& dc) const
  953. {
  954. CFormView::Dump(dc);
  955. } // end CServerProcessesPage::Dump
  956. #endif //_DEBUG
  957. ///////////////////////////////
  958. // F'N: CServerProcessesPage::Reset
  959. //
  960. void CServerProcessesPage::Reset(void *pServer)
  961. {
  962. m_pServer = (CServer*)pServer;
  963. m_pServer->EnumerateProcesses();
  964. DisplayProcesses();
  965. } // end CServerProcessesPage::Reset
  966. ///////////////////////////////
  967. // F'N: CServerProcessesPage::OnSize
  968. //
  969. void CServerProcessesPage::OnSize(UINT nType, int cx, int cy)
  970. {
  971. RECT rect;
  972. GetClientRect(&rect);
  973. rect.top += LIST_TOP_OFFSET;
  974. if(m_ProcessList.GetSafeHwnd())
  975. m_ProcessList.MoveWindow(&rect, TRUE);
  976. // CFormView::OnSize(nType, cx, cy);
  977. } // end CServerProcessesPage::OnSize
  978. static ColumnDef ProcColumns[] = {
  979. CD_USER,
  980. CD_SESSION,
  981. CD_PROC_ID,
  982. CD_PROC_PID,
  983. CD_PROC_IMAGE
  984. };
  985. #define NUM_PROC_COLUMNS sizeof(ProcColumns)/sizeof(ColumnDef)
  986. ///////////////////////////////
  987. // F'N: CServerProcessesPage::OnInitialUpdate
  988. //
  989. void CServerProcessesPage::OnInitialUpdate()
  990. {
  991. // Call the parent class
  992. CFormView::OnInitialUpdate();
  993. // Add the column headings
  994. CString columnString;
  995. for(int col = 0; col < NUM_PROC_COLUMNS; col++) {
  996. columnString.LoadString(ProcColumns[col].stringID);
  997. m_ProcessList.InsertColumn(col, columnString, ProcColumns[col].format, ProcColumns[col].width, col);
  998. }
  999. m_CurrentSortColumn = PROC_COL_USER;
  1000. } // end CServerProcessesPage::OnInitialUpdate
  1001. ///////////////////////////////
  1002. // F'N: CServerProcessesPage::UpdateProcesses
  1003. //
  1004. void CServerProcessesPage::UpdateProcesses()
  1005. {
  1006. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1007. BOOL bAnyChanged = FALSE;
  1008. BOOL bAnyAdded = FALSE;
  1009. LockListControl();
  1010. // Loop through the processes
  1011. m_pServer->LockProcessList();
  1012. CObList *pProcessList = m_pServer->GetProcessList();
  1013. POSITION pos = pProcessList->GetHeadPosition();
  1014. while(pos) {
  1015. CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos);
  1016. // If this is a 'system' process and we aren't currently showing them,
  1017. // go to the next process
  1018. if(pProcess->IsSystemProcess() && !pApp->ShowSystemProcesses())
  1019. continue;
  1020. // If this user is not an Admin, don't show him someone else's processes unless it
  1021. // is a System process
  1022. if(!pApp->IsUserAdmin() && !pProcess->IsCurrentUsers() && !pProcess->IsSystemProcess())
  1023. continue;
  1024. // If the process is new, add it to the list
  1025. if(pProcess->IsNew()) {
  1026. AddProcessToList(pProcess);
  1027. bAnyAdded = TRUE;
  1028. continue;
  1029. }
  1030. LV_FINDINFO FindInfo;
  1031. FindInfo.flags = LVFI_PARAM;
  1032. FindInfo.lParam = (LPARAM)pProcess;
  1033. // Find the Process in our list
  1034. int item = m_ProcessList.FindItem(&FindInfo, -1);
  1035. // If the process is no longer current,
  1036. // remove it from the list
  1037. if(!pProcess->IsCurrent() && item != -1) {
  1038. // Remove the Process from the list
  1039. m_ProcessList.DeleteItem(item);
  1040. pProcess->ClearSelected();
  1041. }
  1042. // If the process info has changed, change
  1043. // it's info in our tree
  1044. if(pProcess->IsChanged() && item != -1)
  1045. {
  1046. // WinStation Name
  1047. CWinStation *pWinStation = pProcess->GetWinStation();
  1048. if(pWinStation)
  1049. {
  1050. if(pWinStation->GetName()[0])
  1051. m_ProcessList.SetItemText(item, PROC_COL_WINSTATION, pWinStation->GetName());
  1052. else
  1053. {
  1054. CString NameString(" ");
  1055. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  1056. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  1057. m_ProcessList.SetItemText(item, PROC_COL_WINSTATION, NameString);
  1058. }
  1059. }
  1060. if(m_CurrentSortColumn == PROC_COL_WINSTATION)
  1061. bAnyChanged = TRUE;
  1062. }
  1063. }
  1064. m_pServer->UnlockProcessList();
  1065. if(bAnyChanged || bAnyAdded) SortByColumn(VIEW_SERVER, PAGE_PROCESSES, &m_ProcessList, m_CurrentSortColumn, m_bSortAscending);
  1066. UnlockListControl();
  1067. } // end CServerProcessesPage::UpdateProcesses
  1068. //////////////////////////////////////////
  1069. // F'N: CServerProcessesPage::RemoveProcess
  1070. //
  1071. void CServerProcessesPage::RemoveProcess(CProcess *pProcess)
  1072. {
  1073. ASSERT(pProcess);
  1074. // If the server isn't the server the process is running on,
  1075. // there's nothing to do
  1076. if(m_pServer != pProcess->GetServer()) return;
  1077. LockListControl();
  1078. // Find out how many items in the list
  1079. int ItemCount = m_ProcessList.GetItemCount();
  1080. // Go through the items and remove this process
  1081. for(int item = 0; item < ItemCount; item++) {
  1082. CProcess *pListProcess = (CProcess*)m_ProcessList.GetItemData(item);
  1083. if(pListProcess == pProcess) {
  1084. m_ProcessList.DeleteItem(item);
  1085. break;
  1086. }
  1087. }
  1088. UnlockListControl();
  1089. }
  1090. ///////////////////////////////
  1091. // F'N: CServerProcessesPage::AddProcessToList
  1092. //
  1093. int CServerProcessesPage::AddProcessToList(CProcess *pProcess)
  1094. {
  1095. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1096. LockListControl();
  1097. // User - put at the end of the list
  1098. int item = m_ProcessList.InsertItem(m_ProcessList.GetItemCount(), pProcess->GetUserName(), NULL);
  1099. // WinStation Name
  1100. CWinStation *pWinStation = pProcess->GetWinStation();
  1101. if(pWinStation) {
  1102. if(pWinStation->GetName()[0])
  1103. m_ProcessList.SetItemText(item, PROC_COL_WINSTATION, pWinStation->GetName());
  1104. else {
  1105. CString NameString(" ");
  1106. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  1107. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  1108. m_ProcessList.SetItemText(item, PROC_COL_WINSTATION, NameString);
  1109. }
  1110. }
  1111. // ID
  1112. CString ProcString;
  1113. ProcString.Format(TEXT("%lu"), pProcess->GetLogonId());
  1114. m_ProcessList.SetItemText(item, PROC_COL_ID, ProcString);
  1115. // PID
  1116. ProcString.Format(TEXT("%lu"), pProcess->GetPID());
  1117. m_ProcessList.SetItemText(item, PROC_COL_PID, ProcString);
  1118. // Image
  1119. m_ProcessList.SetItemText(item, PROC_COL_IMAGE, pProcess->GetImageName());
  1120. m_ProcessList.SetItemData(item, (DWORD_PTR)pProcess);
  1121. // m_ProcessList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  1122. UnlockListControl();
  1123. return item;
  1124. } // end CServerProcessesPage::AddProcessToList
  1125. ///////////////////////////////
  1126. // F'N: CServerProcessesPage::DisplayProcesses
  1127. //
  1128. void CServerProcessesPage::DisplayProcesses()
  1129. {
  1130. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1131. LockListControl();
  1132. // Clear out the list control
  1133. m_ProcessList.DeleteAllItems();
  1134. m_pServer->LockProcessList();
  1135. CObList *pProcessList = m_pServer->GetProcessList();
  1136. POSITION pos = pProcessList->GetHeadPosition();
  1137. while(pos) {
  1138. CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos);
  1139. // If this is a 'system' process and we aren't currently showing them,
  1140. // go to the next process
  1141. if(pProcess->IsSystemProcess() && !pApp->ShowSystemProcesses())
  1142. continue;
  1143. // If this user is not an Admin, don't show him someone else's processes unless it is
  1144. // a System process
  1145. if(!pApp->IsUserAdmin() && !pProcess->IsCurrentUsers() && !pProcess->IsSystemProcess())
  1146. continue;
  1147. AddProcessToList(pProcess);
  1148. }
  1149. m_ProcessList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  1150. m_pServer->UnlockProcessList();
  1151. SortByColumn(VIEW_SERVER, PAGE_PROCESSES, &m_ProcessList, m_CurrentSortColumn, m_bSortAscending);
  1152. UnlockListControl();
  1153. } // end CServerProcessesPage::DisplayProcesses
  1154. ///////////////////////////////
  1155. // F'N: CServerProcessesPage::OnProcessItemChanged
  1156. //
  1157. void CServerProcessesPage::OnProcessItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  1158. {
  1159. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  1160. if(pLV->uNewState & LVIS_SELECTED) {
  1161. CProcess *pProcess = (CProcess*)m_ProcessList.GetItemData(pLV->iItem);
  1162. pProcess->SetSelected();
  1163. }
  1164. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  1165. CProcess *pProcess = (CProcess*)m_ProcessList.GetItemData(pLV->iItem);
  1166. pProcess->ClearSelected();
  1167. }
  1168. *pResult = 0;
  1169. } // end CServerProcessesPage::OnProcessItemChanged
  1170. ///////////////////////////////
  1171. // F'N: CServerProcessesPage::OnColumnClick
  1172. //
  1173. void CServerProcessesPage::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
  1174. {
  1175. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1176. // TODO: Add your control notification handler code here
  1177. // If the sort column hasn't changed, flip the ascending mode.
  1178. if(m_CurrentSortColumn == pNMListView->iSubItem)
  1179. m_bSortAscending = !m_bSortAscending;
  1180. else // New sort column, start in ascending mode
  1181. m_bSortAscending = TRUE;
  1182. m_CurrentSortColumn = pNMListView->iSubItem;
  1183. LockListControl();
  1184. SortByColumn(VIEW_SERVER, PAGE_PROCESSES, &m_ProcessList, m_CurrentSortColumn, m_bSortAscending);
  1185. UnlockListControl();
  1186. *pResult = 0;
  1187. } // end CServerProcessesPage::OnColumnClick
  1188. //////////////////////////////
  1189. // F'N: CServerProcessesPage::OnContextMenu
  1190. //
  1191. void CServerProcessesPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  1192. {
  1193. // TODO: Add your message handler code here
  1194. UINT flags;
  1195. UINT Item;
  1196. CPoint ptClient = ptScreen;
  1197. ScreenToClient(&ptClient);
  1198. // If we got here from the keyboard,
  1199. if(ptScreen.x == -1 && ptScreen.y == -1) {
  1200. UINT iCount = m_ProcessList.GetItemCount( );
  1201. RECT rc;
  1202. for( Item = 0 ; Item < iCount ; Item++ )
  1203. {
  1204. if( m_ProcessList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  1205. {
  1206. m_ProcessList.GetItemRect( Item , &rc , LVIR_ICON );
  1207. ptScreen.x = rc.left;
  1208. ptScreen.y = rc.bottom + 5;
  1209. ClientToScreen( &ptScreen );
  1210. break;
  1211. }
  1212. }
  1213. if(ptScreen.x == -1 && ptScreen.y == -1)
  1214. {
  1215. return;
  1216. }
  1217. /*
  1218. RECT rect;
  1219. m_ProcessList.GetClientRect(&rect);
  1220. ptScreen.x = (rect.right - rect.left) / 2;
  1221. ptScreen.y = (rect.bottom - rect.top) / 2;
  1222. ClientToScreen(&ptScreen);
  1223. */
  1224. }
  1225. else {
  1226. Item = m_ProcessList.HitTest(ptClient, &flags);
  1227. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  1228. return;
  1229. }
  1230. CMenu menu;
  1231. menu.LoadMenu(IDR_PROCESS_POPUP);
  1232. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  1233. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  1234. menu.DestroyMenu();
  1235. } // end CServerProcessesPage::OnContextMenu
  1236. ////////////////////////////////
  1237. // MESSAGE MAP: CServerLicensesPage
  1238. //
  1239. IMPLEMENT_DYNCREATE(CServerLicensesPage, CFormView)
  1240. BEGIN_MESSAGE_MAP(CServerLicensesPage, CFormView)
  1241. //{{AFX_MSG_MAP(CServerLicensesPage)
  1242. ON_WM_SIZE()
  1243. ON_NOTIFY(LVN_COLUMNCLICK, IDC_LICENSE_LIST, OnColumnClick)
  1244. ON_NOTIFY(NM_SETFOCUS, IDC_LICENSE_LIST, OnSetfocusLicenseList)
  1245. //ON_NOTIFY(NM_KILLFOCUS, IDC_LICENSE_LIST, OnKillfocusLicenseList)
  1246. //}}AFX_MSG_MAP
  1247. END_MESSAGE_MAP()
  1248. /////////////////////////////
  1249. // F'N: CServerLicensesPage ctor
  1250. //
  1251. CServerLicensesPage::CServerLicensesPage()
  1252. : CAdminPage(CServerLicensesPage::IDD)
  1253. {
  1254. //{{AFX_DATA_INIT(CServerLicensesPage)
  1255. // NOTE: the ClassWizard will add member initialization here
  1256. //}}AFX_DATA_INIT
  1257. m_pServer = NULL;
  1258. m_bSortAscending = TRUE;
  1259. } // end CServerLicensesPage ctor
  1260. /////////////////////////////
  1261. // F'N: CServerLicensesPage dtor
  1262. //
  1263. CServerLicensesPage::~CServerLicensesPage()
  1264. {
  1265. } // end CServerLicensesPage dtor
  1266. ////////////////////////////////////////
  1267. // F'N: CServerLicensesPage::DoDataExchange
  1268. //
  1269. void CServerLicensesPage::DoDataExchange(CDataExchange* pDX)
  1270. {
  1271. CFormView::DoDataExchange(pDX);
  1272. //{{AFX_DATA_MAP(CServerLicensesPage)
  1273. DDX_Control(pDX, IDC_LICENSE_LIST, m_LicenseList);
  1274. //}}AFX_DATA_MAP
  1275. } // end CServerLicensesPage::DoDataExchange
  1276. #ifdef _DEBUG
  1277. /////////////////////////////////////
  1278. // F'N: CServerLicensesPage::AssertValid
  1279. //
  1280. void CServerLicensesPage::AssertValid() const
  1281. {
  1282. CFormView::AssertValid();
  1283. } // end CServerLicensesPage::AssertValid
  1284. //////////////////////////////
  1285. // F'N: CServerLicensesPage::Dump
  1286. //
  1287. void CServerLicensesPage::Dump(CDumpContext& dc) const
  1288. {
  1289. CFormView::Dump(dc);
  1290. } // end CServerLicensesPage::Dump
  1291. #endif //_DEBUG
  1292. /////////////////////////////
  1293. // F'N: CServerLicensesPage::OnSize
  1294. //
  1295. void CServerLicensesPage::OnSize(UINT nType, int cx, int cy)
  1296. {
  1297. RECT rect;
  1298. GetWindowRect(&rect);
  1299. CWnd *pWnd = GetDlgItem(IDC_LOCAL_AVAILABLE);
  1300. if(pWnd) {
  1301. RECT rect2;
  1302. pWnd->GetWindowRect(&rect2);
  1303. rect.top = rect2.bottom + 5;
  1304. }
  1305. ScreenToClient(&rect);
  1306. if(m_LicenseList.GetSafeHwnd())
  1307. m_LicenseList.MoveWindow(&rect, TRUE);
  1308. // CFormView::OnSize(nType, cx, cy);
  1309. } // end CServerLicensesPage::OnSize
  1310. static ColumnDef LicenseColumns[] = {
  1311. CD_LICENSE_DESC,
  1312. CD_LICENSE_REG,
  1313. CD_USERCOUNT,
  1314. CD_POOLCOUNT,
  1315. CD_LICENSE_NUM
  1316. };
  1317. #define NUM_LICENSE_COLUMNS sizeof(LicenseColumns)/sizeof(ColumnDef)
  1318. /////////////////////////////
  1319. // F'N: CServerLicensesPage::OnInitialUpdate
  1320. //
  1321. void CServerLicensesPage::OnInitialUpdate()
  1322. {
  1323. CFormView::OnInitialUpdate();
  1324. BuildImageList(); // builds the image list for the list control
  1325. CString columnString;
  1326. for(int col = 0; col < NUM_LICENSE_COLUMNS; col++) {
  1327. columnString.LoadString(LicenseColumns[col].stringID);
  1328. m_LicenseList.InsertColumn(col, columnString, LicenseColumns[col].format, LicenseColumns[col].width, col);
  1329. }
  1330. m_CurrentSortColumn = LICENSE_COL_DESCRIPTION;
  1331. } // end CServerLicensesPage::OnInitialUpdate
  1332. /////////////////////////////////////
  1333. // F'N: CServerLicensePage::BuildImageList
  1334. //
  1335. // - calls m_ImageList.Create(..) to create the image list
  1336. // - calls AddIconToImageList(..) to add the icons themselves and save
  1337. // off their indices
  1338. // - attaches the image list to the list ctrl
  1339. //
  1340. void CServerLicensesPage::BuildImageList()
  1341. {
  1342. m_ImageList.Create(16, 16, TRUE, 5, 0);
  1343. m_idxBase = AddIconToImageList(IDI_BASE);
  1344. m_idxBump = AddIconToImageList(IDI_BUMP);
  1345. m_idxEnabler = AddIconToImageList(IDI_ENABLER);
  1346. m_idxUnknown = AddIconToImageList(IDI_UNKNOWN);
  1347. m_idxBlank = AddIconToImageList(IDI_BLANK);
  1348. m_LicenseList.SetImageList(&m_ImageList, LVSIL_SMALL);
  1349. } // end CServerLicensesPage::BuildImageList
  1350. /////////////////////////////////////////
  1351. // F'N: CServerLicensesPage::AddIconToImageList
  1352. //
  1353. // - loads the appropriate icon, adds it to m_ImageList, and returns
  1354. // the newly-added icon's index in the image list
  1355. //
  1356. int CServerLicensesPage::AddIconToImageList(int iconID)
  1357. {
  1358. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  1359. return m_ImageList.Add(hIcon);
  1360. } // end CServerLicensesPage::AddIconToImageList
  1361. /////////////////////////////
  1362. // F'N: CServerLicensesPage::Reset
  1363. //
  1364. void CServerLicensesPage::Reset(void *pServer)
  1365. {
  1366. m_pServer = (CServer*)pServer;
  1367. DisplayLicenseCounts();
  1368. DisplayLicenses();
  1369. } // end CServerLicensesPage::Reset
  1370. /////////////////////////////////////
  1371. // F'N: CServerLicensesPage::DisplayLicenseCounts
  1372. //
  1373. void CServerLicensesPage::DisplayLicenseCounts()
  1374. {
  1375. // Fill in the static text fields
  1376. CString LicenseString;
  1377. if(m_pServer->IsWinFrame()) {
  1378. // If the user is not an admin, the values are garbage (show N/A)
  1379. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1380. if(!((CWinAdminApp*)AfxGetApp())->IsUserAdmin()) {
  1381. LicenseString.LoadString(IDS_NOT_APPLICABLE);
  1382. SetDlgItemText(IDC_LOCAL_INSTALLED, LicenseString);
  1383. SetDlgItemText(IDC_LOCAL_INUSE, LicenseString);
  1384. SetDlgItemText(IDC_LOCAL_AVAILABLE, LicenseString);
  1385. SetDlgItemText(IDC_POOL_INSTALLED, LicenseString);
  1386. SetDlgItemText(IDC_POOL_INUSE, LicenseString);
  1387. SetDlgItemText(IDC_POOL_AVAILABLE, LicenseString);
  1388. SetDlgItemText(IDC_TOTAL_INSTALLED, LicenseString);
  1389. SetDlgItemText(IDC_TOTAL_INUSE, LicenseString);
  1390. SetDlgItemText(IDC_TOTAL_AVAILABLE, LicenseString);
  1391. } else {
  1392. ExtServerInfo *pExtServerInfo = m_pServer->GetExtendedInfo();
  1393. if(pExtServerInfo) {
  1394. BOOL bUnlimited = FALSE;
  1395. if((pExtServerInfo->Flags & ESF_UNLIMITED_LICENSES) > 0) {
  1396. bUnlimited = TRUE;
  1397. }
  1398. if(bUnlimited)
  1399. LicenseString.LoadString(IDS_UNLIMITED);
  1400. else
  1401. LicenseString.Format(TEXT("%lu"), pExtServerInfo->ServerLocalInstalled);
  1402. SetDlgItemText(IDC_LOCAL_INSTALLED, LicenseString);
  1403. LicenseString.Format(TEXT("%lu"), pExtServerInfo->ServerLocalInUse);
  1404. SetDlgItemText(IDC_LOCAL_INUSE, LicenseString);
  1405. if(bUnlimited) {
  1406. LicenseString.LoadString(IDS_UNLIMITED);
  1407. SetDlgItemText(IDC_LOCAL_AVAILABLE, LicenseString);
  1408. SetDlgItemText(IDC_TOTAL_INSTALLED, LicenseString);
  1409. SetDlgItemText(IDC_TOTAL_AVAILABLE, LicenseString);
  1410. LicenseString.LoadString(IDS_NOT_APPLICABLE);
  1411. SetDlgItemText(IDC_POOL_INSTALLED, LicenseString);
  1412. SetDlgItemText(IDC_POOL_INUSE, LicenseString);
  1413. SetDlgItemText(IDC_POOL_AVAILABLE, LicenseString);
  1414. } else {
  1415. LicenseString.Format(TEXT("%lu"), pExtServerInfo->ServerLocalAvailable);
  1416. SetDlgItemText(IDC_LOCAL_AVAILABLE, LicenseString);
  1417. LicenseString.Format(TEXT("%lu"), pExtServerInfo->ServerPoolInstalled);
  1418. SetDlgItemText(IDC_POOL_INSTALLED, LicenseString);
  1419. LicenseString.Format(TEXT("%lu"), pExtServerInfo->ServerPoolInUse);
  1420. SetDlgItemText(IDC_POOL_INUSE, LicenseString);
  1421. LicenseString.Format(TEXT("%lu"), pExtServerInfo->ServerPoolAvailable);
  1422. SetDlgItemText(IDC_POOL_AVAILABLE, LicenseString);
  1423. LicenseString.Format(TEXT("%lu"),
  1424. pExtServerInfo->ServerPoolInstalled + pExtServerInfo->ServerLocalInstalled);
  1425. SetDlgItemText(IDC_TOTAL_INSTALLED, LicenseString);
  1426. LicenseString.Format(TEXT("%lu"),
  1427. pExtServerInfo->ServerPoolAvailable + pExtServerInfo->ServerLocalAvailable);
  1428. SetDlgItemText(IDC_TOTAL_AVAILABLE, LicenseString);
  1429. }
  1430. LicenseString.Format(TEXT("%lu"),
  1431. pExtServerInfo->ServerPoolInUse + pExtServerInfo->ServerLocalInUse);
  1432. SetDlgItemText(IDC_TOTAL_INUSE, LicenseString);
  1433. }
  1434. }
  1435. }
  1436. } // end CServerLicensesPage::DisplayLicenseCounts()
  1437. /////////////////////////////////////
  1438. // F'N: CServerLicensesPage::DisplayLicenses
  1439. //
  1440. void CServerLicensesPage::DisplayLicenses()
  1441. {
  1442. // Clear out the list control
  1443. m_LicenseList.DeleteAllItems();
  1444. if(m_pServer->IsWinFrame()) {
  1445. ExtServerInfo *pExtServerInfo = m_pServer->GetExtendedInfo();
  1446. if(pExtServerInfo && ((pExtServerInfo->Flags & ESF_NO_LICENSE_PRIVILEGES) > 0)) {
  1447. CString AString;
  1448. AString.LoadString(IDS_NO_LICENSE_PRIVILEGES);
  1449. m_LicenseList.InsertItem(0, AString, m_idxBlank);
  1450. return;
  1451. }
  1452. }
  1453. m_pServer->LockLicenseList();
  1454. // Get a pointer to this server's list of Licenses
  1455. CObList *pLicenseList = m_pServer->GetLicenseList();
  1456. // Iterate through the License list
  1457. POSITION pos = pLicenseList->GetHeadPosition();
  1458. while(pos) {
  1459. CLicense *pLicense = (CLicense*)pLicenseList->GetNext(pos);
  1460. //////////////////////
  1461. // Fill in the columns
  1462. //////////////////////
  1463. int WhichIcon;
  1464. switch(pLicense->GetClass()) {
  1465. case LicenseBase:
  1466. WhichIcon = m_idxBase;
  1467. break;
  1468. case LicenseBump:
  1469. WhichIcon = m_idxBump;
  1470. break;
  1471. case LicenseEnabler:
  1472. WhichIcon = m_idxEnabler;
  1473. break;
  1474. case LicenseUnknown:
  1475. WhichIcon = m_idxUnknown;
  1476. break;
  1477. }
  1478. // License Description
  1479. int item = m_LicenseList.InsertItem(m_LicenseList.GetItemCount(), pLicense->GetDescription(), WhichIcon);
  1480. // Registered
  1481. CString RegString;
  1482. RegString.LoadString(pLicense->IsRegistered() ? IDS_YES : IDS_NO);
  1483. m_LicenseList.SetItemText(item, LICENSE_COL_REGISTERED, RegString);
  1484. BOOL bUnlimited = (pLicense->GetClass() == LicenseBase
  1485. && pLicense->GetTotalCount() == 4095
  1486. && m_pServer->GetCTXVersionNum() == 0x00000040);
  1487. // User (Total) Count
  1488. CString CountString;
  1489. if(bUnlimited)
  1490. CountString.LoadString(IDS_UNLIMITED);
  1491. else
  1492. CountString.Format(TEXT("%lu"), pLicense->GetTotalCount());
  1493. m_LicenseList.SetItemText(item, LICENSE_COL_USERCOUNT, CountString);
  1494. // Pool Count
  1495. if(bUnlimited)
  1496. CountString.LoadString(IDS_NOT_APPLICABLE);
  1497. else
  1498. CountString.Format(TEXT("%lu"), pLicense->GetPoolCount());
  1499. m_LicenseList.SetItemText(item, LICENSE_COL_POOLCOUNT, CountString);
  1500. // License Number
  1501. m_LicenseList.SetItemText(item, LICENSE_COL_NUMBER, pLicense->GetLicenseNumber());
  1502. m_LicenseList.SetItemData(item, (DWORD_PTR)pLicense);
  1503. } // end while(pos)
  1504. m_pServer->UnlockLicenseList();
  1505. } // end CServerLicensesPage::DisplayLicenses
  1506. /////////////////////////////
  1507. // F'N: CServerLicensesPage::OnColumnClick
  1508. //
  1509. void CServerLicensesPage::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
  1510. {
  1511. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1512. // TODO: Add your control notification handler code here
  1513. // If the sort column hasn't changed, flip the ascending mode.
  1514. if(m_CurrentSortColumn == pNMListView->iSubItem)
  1515. m_bSortAscending = !m_bSortAscending;
  1516. else // New sort column, start in ascending mode
  1517. m_bSortAscending = TRUE;
  1518. m_CurrentSortColumn = pNMListView->iSubItem;
  1519. SortByColumn(VIEW_SERVER, PAGE_LICENSES, &m_LicenseList, m_CurrentSortColumn, m_bSortAscending);
  1520. *pResult = 0;
  1521. } // end CServerLicensesPage::OnColumnClick
  1522. ////////////////////////////////
  1523. // MESSAGE MAP: CServerInfoPage
  1524. //
  1525. IMPLEMENT_DYNCREATE(CServerInfoPage, CFormView)
  1526. BEGIN_MESSAGE_MAP(CServerInfoPage, CFormView)
  1527. //{{AFX_MSG_MAP(CServerInfoPage)
  1528. ON_WM_SIZE()
  1529. ON_NOTIFY(LVN_COLUMNCLICK, IDC_HOTFIX_LIST, OnColumnClick)
  1530. ON_NOTIFY(NM_SETFOCUS, IDC_HOTFIX_LIST, OnSetfocusHotfixList)
  1531. //ON_NOTIFY(NM_KILLFOCUS, IDC_HOTFIX_LIST, OnKillfocusHotfixList)
  1532. ON_COMMAND(ID_HELP1, OnCommandHelp)
  1533. //}}AFX_MSG_MAP
  1534. END_MESSAGE_MAP()
  1535. /////////////////////////////
  1536. // F'N: CServerInfoPage ctor
  1537. //
  1538. CServerInfoPage::CServerInfoPage()
  1539. : CAdminPage(CServerInfoPage::IDD)
  1540. {
  1541. //{{AFX_DATA_INIT(CServerInfoPage)
  1542. // NOTE: the ClassWizard will add member initialization here
  1543. //}}AFX_DATA_INIT
  1544. m_pServer = NULL;
  1545. m_bSortAscending = TRUE;
  1546. } // end CUsersPage ctor
  1547. /////////////////////////////
  1548. // F'N: CServerInfoPage dtor
  1549. //
  1550. CServerInfoPage::~CServerInfoPage()
  1551. {
  1552. } // end CServerInfoPage dtor
  1553. ////////////////////////////////////////
  1554. // F'N: CServerInfoPage::DoDataExchange
  1555. //
  1556. void CServerInfoPage::DoDataExchange(CDataExchange* pDX)
  1557. {
  1558. CFormView::DoDataExchange(pDX);
  1559. //{{AFX_DATA_MAP(CServerInfoPage)
  1560. DDX_Control(pDX, IDC_HOTFIX_LIST, m_HotfixList);
  1561. //}}AFX_DATA_MAP
  1562. } // end CServerInfoPage::DoDataExchange
  1563. #ifdef _DEBUG
  1564. /////////////////////////////////////
  1565. // F'N: CServerInfoPage::AssertValid
  1566. //
  1567. void CServerInfoPage::AssertValid() const
  1568. {
  1569. CFormView::AssertValid();
  1570. } // end CServerInfoPage::AssertValid
  1571. //////////////////////////////
  1572. // F'N: CServerInfoPage::Dump
  1573. //
  1574. void CServerInfoPage::Dump(CDumpContext& dc) const
  1575. {
  1576. CFormView::Dump(dc);
  1577. } // end CServerInfoPage::Dump
  1578. #endif //_DEBUG
  1579. /////////////////////////////
  1580. // F'N: CServerInfoPage::OnSize
  1581. //
  1582. void CServerInfoPage::OnSize(UINT nType, int cx, int cy)
  1583. {
  1584. RECT rect;
  1585. GetWindowRect(&rect);
  1586. int control = IDC_HOTFIX_LABEL;
  1587. if(m_pServer && m_pServer->IsWinFrame()) control = IDC_HOTFIX_LABEL2;
  1588. CWnd *pWnd = GetDlgItem(control);
  1589. if(pWnd) {
  1590. RECT rect2;
  1591. pWnd->GetWindowRect(&rect2);
  1592. rect.top = rect2.bottom + 5;
  1593. }
  1594. ScreenToClient(&rect);
  1595. if(m_HotfixList.GetSafeHwnd())
  1596. m_HotfixList.MoveWindow(&rect, TRUE);
  1597. // CFormView::OnSize(nType, cx, cy);
  1598. } // end CServerInfoPage::OnSize
  1599. /////////////////////////////
  1600. // F'N: CServerInfoPage::OnCommandHelp
  1601. //
  1602. void CServerInfoPage::OnCommandHelp(void)
  1603. {
  1604. AfxGetApp()->WinHelp(CServerInfoPage::IDD + HID_BASE_RESOURCE);
  1605. } // CServerInfoPage::OnCommandHelp
  1606. static ColumnDef HotfixColumns[] = {
  1607. CD_HOTFIX,
  1608. CD_INSTALLED_BY,
  1609. CD_INSTALLED_ON
  1610. };
  1611. #define NUM_HOTFIX_COLUMNS sizeof(HotfixColumns)/sizeof(ColumnDef)
  1612. /////////////////////////////
  1613. // F'N: CServerInfoPage::OnInitialUpdate
  1614. //
  1615. void CServerInfoPage::OnInitialUpdate()
  1616. {
  1617. CFormView::OnInitialUpdate();
  1618. BuildImageList();
  1619. CString columnString;
  1620. for(int col = 0; col < NUM_HOTFIX_COLUMNS; col++) {
  1621. columnString.LoadString(HotfixColumns[col].stringID);
  1622. m_HotfixList.InsertColumn(col, columnString, HotfixColumns[col].format, HotfixColumns[col].width, col);
  1623. }
  1624. m_CurrentSortColumn = HOTFIX_COL_NAME;
  1625. } // end CServerInfoPage::OnInitialUpdate
  1626. /////////////////////////////
  1627. // F'N: CServerInfoPage::BuildImageList
  1628. //
  1629. void CServerInfoPage::BuildImageList()
  1630. {
  1631. m_StateImageList.Create(16, 16, TRUE, 1, 0);
  1632. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_NOTSIGN));
  1633. m_StateImageList.Add(hIcon);
  1634. if( hIcon != NULL )
  1635. {
  1636. m_HotfixList.SetImageList(&m_StateImageList, LVSIL_STATE);
  1637. }
  1638. } // end CServerInfoPage::BuildImageList
  1639. /////////////////////////////
  1640. // F'N: CServerInfoPage::Reset
  1641. //
  1642. void CServerInfoPage::Reset(void *pServer)
  1643. {
  1644. m_pServer = (CServer*)pServer;
  1645. int control = IDC_HOTFIX_LABEL;
  1646. // If the server is a WinFrame server,
  1647. // we want to show the load balancing stuff and
  1648. // make the hotfix list smaller
  1649. if(m_pServer && m_pServer->IsWinFrame()) {
  1650. GetDlgItem(IDC_LOAD_BALANCING_GROUP)->ShowWindow(SW_SHOW);
  1651. GetDlgItem(IDC_TCP_LABEL)->ShowWindow(SW_SHOW);
  1652. GetDlgItem(IDC_TCP_LOAD)->ShowWindow(SW_SHOW);
  1653. GetDlgItem(IDC_IPX_LABEL)->ShowWindow(SW_SHOW);
  1654. GetDlgItem(IDC_IPX_LOAD)->ShowWindow(SW_SHOW);
  1655. GetDlgItem(IDC_NETBIOS_LABEL)->ShowWindow(SW_SHOW);
  1656. GetDlgItem(IDC_NETBIOS_LOAD)->ShowWindow(SW_SHOW);
  1657. GetDlgItem(IDC_HOTFIX_LABEL)->ShowWindow(SW_HIDE);
  1658. GetDlgItem(IDC_HOTFIX_LABEL2)->ShowWindow(SW_SHOW);
  1659. control = IDC_HOTFIX_LABEL2;
  1660. } else {
  1661. GetDlgItem(IDC_LOAD_BALANCING_GROUP)->ShowWindow(SW_HIDE);
  1662. GetDlgItem(IDC_TCP_LABEL)->ShowWindow(SW_HIDE);
  1663. GetDlgItem(IDC_TCP_LOAD)->ShowWindow(SW_HIDE);
  1664. GetDlgItem(IDC_IPX_LABEL)->ShowWindow(SW_HIDE);
  1665. GetDlgItem(IDC_IPX_LOAD)->ShowWindow(SW_HIDE);
  1666. GetDlgItem(IDC_NETBIOS_LABEL)->ShowWindow(SW_HIDE);
  1667. GetDlgItem(IDC_NETBIOS_LOAD)->ShowWindow(SW_HIDE);
  1668. GetDlgItem(IDC_HOTFIX_LABEL)->ShowWindow(SW_SHOW);
  1669. GetDlgItem(IDC_HOTFIX_LABEL2)->ShowWindow(SW_HIDE);
  1670. }
  1671. // Resize the list control
  1672. RECT rect;
  1673. GetWindowRect(&rect);
  1674. CWnd *pWnd = GetDlgItem(control);
  1675. if(pWnd) {
  1676. RECT rect2;
  1677. pWnd->GetWindowRect(&rect2);
  1678. rect.top = rect2.bottom + 5;
  1679. }
  1680. ScreenToClient(&rect);
  1681. if(m_HotfixList.GetSafeHwnd())
  1682. m_HotfixList.MoveWindow(&rect, TRUE);
  1683. Invalidate();
  1684. DisplayInfo();
  1685. } // end CServerInfoPage::Reset
  1686. /////////////////////////////
  1687. // F'N: CServerInfoPage::OnColumnClick
  1688. //
  1689. void CServerInfoPage::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
  1690. {
  1691. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1692. // TODO: Add your control notification handler code here
  1693. // If the sort column hasn't changed, flip the ascending mode.
  1694. if(m_CurrentSortColumn == pNMListView->iSubItem)
  1695. m_bSortAscending = !m_bSortAscending;
  1696. else // New sort column, start in ascending mode
  1697. m_bSortAscending = TRUE;
  1698. m_CurrentSortColumn = pNMListView->iSubItem;
  1699. SortByColumn(VIEW_SERVER, PAGE_INFO, &m_HotfixList, m_CurrentSortColumn, m_bSortAscending);
  1700. *pResult = 0;
  1701. } // end CServerInfoPage::OnColumnClick
  1702. void CServerInfoPage::TSAdminDateTimeString(
  1703. LONG InstallDate,
  1704. LPTSTR TimeString,
  1705. BOOL LongDate
  1706. )
  1707. {
  1708. //
  1709. // buffer is wide enough
  1710. CTime tmpTime((time_t) InstallDate);
  1711. SYSTEMTIME stime;
  1712. // Why not use GetAsSystemTime method ?
  1713. stime.wYear = (WORD)tmpTime.GetYear( ) ;
  1714. stime.wMonth = (WORD)tmpTime.GetMonth( ) ;
  1715. stime.wDayOfWeek = (WORD)tmpTime.GetDayOfWeek( ) ;
  1716. stime.wDay = (WORD)tmpTime.GetDay( ) ;
  1717. stime.wHour = (WORD)tmpTime.GetHour( ) ;
  1718. stime.wMinute = (WORD)tmpTime.GetMinute( ) ;
  1719. stime.wSecond = (WORD)tmpTime.GetSecond( ) ;
  1720. LPTSTR lpTimeStr;
  1721. int nLen;
  1722. //Get DateFormat
  1723. nLen = GetDateFormat(
  1724. LOCALE_USER_DEFAULT,
  1725. LongDate ? DATE_LONGDATE : DATE_SHORTDATE,
  1726. &stime,
  1727. NULL,
  1728. NULL,
  1729. 0);
  1730. lpTimeStr = (LPTSTR) GlobalAlloc(GPTR, (nLen + 1) * sizeof(TCHAR));
  1731. if( lpTimeStr != NULL )
  1732. {
  1733. nLen = GetDateFormat(
  1734. LOCALE_USER_DEFAULT,
  1735. LongDate ? DATE_LONGDATE : DATE_SHORTDATE,
  1736. &stime,
  1737. NULL,
  1738. lpTimeStr,
  1739. nLen);
  1740. wcscpy(TimeString, lpTimeStr);
  1741. wcscat(TimeString, L" ");
  1742. GlobalFree(lpTimeStr);
  1743. lpTimeStr = NULL;
  1744. //Get Time Format
  1745. nLen = GetTimeFormat(
  1746. LOCALE_USER_DEFAULT,
  1747. NULL,
  1748. &stime,
  1749. NULL,
  1750. NULL,
  1751. 0);
  1752. lpTimeStr = (LPTSTR) GlobalAlloc(GPTR, (nLen + 1) * sizeof(TCHAR));
  1753. if( lpTimeStr != NULL )
  1754. {
  1755. nLen = GetTimeFormat(
  1756. LOCALE_USER_DEFAULT,
  1757. NULL,
  1758. &stime,
  1759. NULL,
  1760. lpTimeStr,
  1761. nLen);
  1762. wcscat(TimeString, lpTimeStr);
  1763. GlobalFree(lpTimeStr);
  1764. }
  1765. }
  1766. }
  1767. #define PST 60*60*8
  1768. /////////////////////////////////////
  1769. // F'N: CServerInfoPage::DisplayInfo
  1770. //
  1771. void CServerInfoPage::DisplayInfo()
  1772. {
  1773. m_HotfixList.DeleteAllItems();
  1774. if(!m_pServer->IsRegistryInfoValid()) {
  1775. if(!m_pServer->BuildRegistryInfo()) return;
  1776. }
  1777. CString InfoString, FormatString;
  1778. FormatString.LoadString(IDS_PRODUCT_VERSION);
  1779. if (m_pServer->GetMSVersionNum() < 5)
  1780. {
  1781. SetDlgItemText(IDC_PRODUCT_NAME, m_pServer->GetCTXProductName());
  1782. InfoString.Format( FormatString,
  1783. m_pServer->GetMSVersion(),
  1784. m_pServer->GetCTXBuild() );
  1785. }
  1786. else
  1787. {
  1788. SetDlgItemText(IDC_PRODUCT_NAME, m_pServer->GetMSProductName());
  1789. InfoString.Format( FormatString,
  1790. m_pServer->GetMSVersion(),
  1791. m_pServer->GetMSBuild() );
  1792. }
  1793. SetDlgItemText(IDC_PRODUCT_VERSION, InfoString);
  1794. LONG InstallDate = (LONG)m_pServer->GetInstallDate();
  1795. if (InstallDate != 0xFFFFFFFF)
  1796. {
  1797. // The install date in the registry appears to be saved in
  1798. // Pacific Standard Time. Subtract the difference between the
  1799. // current time zone and PST from the install date
  1800. InstallDate -= (PST - _timezone);
  1801. TCHAR TimeString[MAX_DATE_TIME_LENGTH];
  1802. TSAdminDateTimeString(InstallDate, TimeString);
  1803. SetDlgItemText(IDC_INSTALL_DATE, TimeString);
  1804. }
  1805. SetDlgItemText(IDC_SERVICE_PACK, m_pServer->GetServicePackLevel());
  1806. if(m_pServer->IsWinFrame()) {
  1807. ExtServerInfo *pExtServerInfo = m_pServer->GetExtendedInfo();
  1808. if(pExtServerInfo && ((pExtServerInfo->Flags & ESF_LOAD_BALANCING) > 0)) {
  1809. GetDlgItem(IDC_TCP_LABEL)->ShowWindow(SW_SHOW);
  1810. GetDlgItem(IDC_IPX_LABEL)->ShowWindow(SW_SHOW);
  1811. GetDlgItem(IDC_NETBIOS_LABEL)->ShowWindow(SW_SHOW);
  1812. GetDlgItem(IDC_TCP_LOAD)->ShowWindow(SW_SHOW);
  1813. GetDlgItem(IDC_NETBIOS_LOAD)->ShowWindow(SW_SHOW);
  1814. CString LoadLevelString;
  1815. if(pExtServerInfo->TcpLoadLevel == 0xFFFFFFFF) {
  1816. LoadLevelString.LoadString(IDS_NOT_APPLICABLE);
  1817. }
  1818. else LoadLevelString.Format(TEXT("%lu"), pExtServerInfo->TcpLoadLevel);
  1819. SetDlgItemText(IDC_TCP_LOAD, LoadLevelString);
  1820. if(pExtServerInfo->IpxLoadLevel == 0xFFFFFFFF) {
  1821. LoadLevelString.LoadString(IDS_NOT_APPLICABLE);
  1822. }
  1823. else LoadLevelString.Format(TEXT("%lu"), pExtServerInfo->IpxLoadLevel);
  1824. SetDlgItemText(IDC_IPX_LOAD, LoadLevelString);
  1825. if(pExtServerInfo->NetbiosLoadLevel == 0xFFFFFFFF) {
  1826. LoadLevelString.LoadString(IDS_NOT_APPLICABLE);
  1827. }
  1828. else LoadLevelString.Format(TEXT("%lu"), pExtServerInfo->NetbiosLoadLevel);
  1829. SetDlgItemText(IDC_NETBIOS_LOAD, LoadLevelString);
  1830. } else {
  1831. GetDlgItem(IDC_TCP_LABEL)->ShowWindow(SW_HIDE);
  1832. GetDlgItem(IDC_IPX_LABEL)->ShowWindow(SW_HIDE);
  1833. GetDlgItem(IDC_NETBIOS_LABEL)->ShowWindow(SW_HIDE);
  1834. GetDlgItem(IDC_TCP_LOAD)->ShowWindow(SW_HIDE);
  1835. CString NoString;
  1836. NoString.LoadString(IDS_NO_LOAD_LICENSE);
  1837. SetDlgItemText(IDC_IPX_LOAD, NoString);
  1838. GetDlgItem(IDC_NETBIOS_LOAD)->ShowWindow(SW_HIDE);
  1839. }
  1840. }
  1841. // Get a pointer to this Server's list of Hotfixes
  1842. CObList *pHotfixList = m_pServer->GetHotfixList();
  1843. // Iterate through the Hotfix list
  1844. POSITION pos = pHotfixList->GetHeadPosition();
  1845. while(pos) {
  1846. CHotfix *pHotfix = (CHotfix*)pHotfixList->GetNext(pos);
  1847. //////////////////////
  1848. // Fill in the columns
  1849. //////////////////////
  1850. // Hotfix Name - put at the end of the list
  1851. int item = m_HotfixList.InsertItem(m_HotfixList.GetItemCount(), pHotfix->m_Name, NULL);
  1852. // If this hotfix is not marked as Valid, put a not-sign next to it's name
  1853. if(!pHotfix->m_Valid)
  1854. m_HotfixList.SetItemState(item, 0x1000, 0xF000);
  1855. // Installed by
  1856. m_HotfixList.SetItemText(item, HOTFIX_COL_INSTALLEDBY, pHotfix->m_InstalledBy);
  1857. // Installed on
  1858. if (pHotfix->m_InstalledOn != 0xFFFFFFFF)
  1859. {
  1860. TCHAR TimeString[MAX_DATE_TIME_LENGTH];
  1861. TSAdminDateTimeString(pHotfix->m_InstalledOn, TimeString);
  1862. if (TimeString != NULL)
  1863. {
  1864. m_HotfixList.SetItemText(item, HOTFIX_COL_INSTALLEDON, TimeString);
  1865. }
  1866. }
  1867. m_HotfixList.SetItemData(item, (DWORD_PTR)pHotfix);
  1868. }
  1869. } // end CServerInfoPage::DisplayInfo
  1870. void CUsersPage::OnSetfocusUserList(NMHDR* pNMHDR, LRESULT* pResult)
  1871. {
  1872. ODS( L"CUsersPage::OnSetfocusUserListt\n" );
  1873. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  1874. m_UserList.Invalidate();
  1875. pDoc->RegisterLastFocus( PAGED_ITEM );
  1876. *pResult = 0;
  1877. }
  1878. void CServerWinStationsPage::OnSetfocusWinstationList(NMHDR* pNMHDR, LRESULT* pResult)
  1879. {
  1880. ODS( L"CServerWinStationsPage::OnSetfocusWinstationList\n" );
  1881. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  1882. m_StationList.Invalidate( );
  1883. pDoc->RegisterLastFocus( PAGED_ITEM );
  1884. *pResult = 0;
  1885. }
  1886. void CServerProcessesPage::OnSetfocusProcessList(NMHDR* pNMHDR, LRESULT* pResult)
  1887. {
  1888. ODS( L"CServerProcessesPage::OnSetfocusProcessList\n" );
  1889. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  1890. m_ProcessList.Invalidate( );
  1891. pDoc->RegisterLastFocus( PAGED_ITEM );
  1892. *pResult = 0;
  1893. }
  1894. void CServerLicensesPage::OnSetfocusLicenseList(NMHDR* pNMHDR, LRESULT* pResult)
  1895. {
  1896. ODS( L"CServerLicensesPage::OnSetfocusLicenseList\n" );
  1897. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  1898. m_LicenseList.Invalidate( );
  1899. pDoc->RegisterLastFocus( PAGED_ITEM );
  1900. *pResult = 0;
  1901. }
  1902. void CServerInfoPage::OnSetfocusHotfixList(NMHDR* pNMHDR, LRESULT* pResult)
  1903. {
  1904. ODS( L"ServerInfoPage::OnSetfocusHotfixList\n" );
  1905. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  1906. m_HotfixList.Invalidate( );
  1907. pDoc->RegisterLastFocus( PAGED_ITEM );
  1908. *pResult = 0;
  1909. }
  1910. void CServerInfoPage::OnKillfocusHotfixList(NMHDR* pNMHDR, LRESULT* pResult)
  1911. {
  1912. m_HotfixList.Invalidate( );
  1913. *pResult = 0;
  1914. }
  1915. void CUsersPage::OnKillfocusUserList(NMHDR* pNMHDR, LRESULT* pResult)
  1916. {
  1917. *pResult = 0;
  1918. m_UserList.Invalidate( );
  1919. }
  1920. void CServerWinStationsPage::OnKillfocusWinstationList(NMHDR* pNMHDR, LRESULT* pResult)
  1921. {
  1922. *pResult = 0;
  1923. m_StationList.Invalidate( );
  1924. }
  1925. void CServerProcessesPage::OnKillfocusProcessList(NMHDR* pNMHDR, LRESULT* pResult)
  1926. {
  1927. *pResult = 0;
  1928. m_ProcessList.Invalidate( );
  1929. }
  1930. void CServerLicensesPage::OnKillfocusLicenseList(NMHDR* pNMHDR, LRESULT* pResult)
  1931. {
  1932. *pResult = 0;
  1933. m_LicenseList.Invalidate( );
  1934. }