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.

791 lines
13 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. prdppgs.cpp
  5. Abstract:
  6. Product property page (servers) implementation.
  7. Author:
  8. Don Ryan (donryan) 02-Feb-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 30-Jan-1996
  13. o Added refresh when service info is updated.
  14. o Added new element to LV_COLUMN_ENTRY to differentiate the string
  15. used for the column header from the string used in the menus
  16. (so that the menu option can contain hot keys).
  17. --*/
  18. #include "stdafx.h"
  19. #include "llsmgr.h"
  20. #include "prdppgs.h"
  21. #include "srvpsht.h"
  22. #define LVID_SERVER 0
  23. #define LVID_PURCHASED 1
  24. #define LVID_REACHED 2
  25. #define LVCX_SERVER 40
  26. #define LVCX_PURCHASED 30
  27. #define LVCX_REACHED -1
  28. static LV_COLUMN_INFO g_serverColumnInfo = {
  29. 0, 0, 3,
  30. {{LVID_SERVER, IDS_SERVER_NAME, 0, LVCX_SERVER },
  31. {LVID_PURCHASED, IDS_PURCHASED, 0, LVCX_PURCHASED},
  32. {LVID_REACHED, IDS_REACHED, 0, LVCX_REACHED }},
  33. };
  34. #ifdef _DEBUG
  35. #undef THIS_FILE
  36. static char BASED_CODE THIS_FILE[] = __FILE__;
  37. #endif
  38. IMPLEMENT_DYNCREATE(CProductPropertyPageServers, CPropertyPage)
  39. BEGIN_MESSAGE_MAP(CProductPropertyPageServers, CPropertyPage)
  40. //{{AFX_MSG_MAP(CProductPropertyPageServers)
  41. ON_BN_CLICKED(IDC_PP_PRODUCT_SERVERS_EDIT, OnEdit)
  42. ON_NOTIFY(NM_DBLCLK, IDC_PP_PRODUCT_SERVERS_SERVERS, OnDblClkServers)
  43. ON_NOTIFY(NM_RETURN, IDC_PP_PRODUCT_SERVERS_SERVERS, OnReturnServers)
  44. ON_NOTIFY(NM_SETFOCUS, IDC_PP_PRODUCT_SERVERS_SERVERS, OnSetFocusServers)
  45. ON_NOTIFY(NM_KILLFOCUS, IDC_PP_PRODUCT_SERVERS_SERVERS, OnKillFocusServers)
  46. ON_NOTIFY(LVN_COLUMNCLICK, IDC_PP_PRODUCT_SERVERS_SERVERS, OnColumnClickServers)
  47. ON_NOTIFY(LVN_GETDISPINFO, IDC_PP_PRODUCT_SERVERS_SERVERS, OnGetDispInfoServers)
  48. ON_WM_DESTROY()
  49. //}}AFX_MSG_MAP
  50. END_MESSAGE_MAP()
  51. CProductPropertyPageServers::CProductPropertyPageServers()
  52. : CPropertyPage(CProductPropertyPageServers::IDD)
  53. /*++
  54. Routine Description:
  55. Constructor for product property page (servers).
  56. Arguments:
  57. None.
  58. Return Values:
  59. None.
  60. --*/
  61. {
  62. //{{AFX_DATA_INIT(CProductPropertyPageServers)
  63. //}}AFX_DATA_INIT
  64. m_pProduct = NULL;
  65. m_pUpdateHint = NULL;
  66. m_bAreCtrlsInitialized = FALSE;
  67. }
  68. CProductPropertyPageServers::~CProductPropertyPageServers()
  69. /*++
  70. Routine Description:
  71. Destructor for product property page (servers).
  72. Arguments:
  73. None.
  74. Return Values:
  75. None.
  76. --*/
  77. {
  78. //
  79. // Nothing to do here...
  80. //
  81. }
  82. void CProductPropertyPageServers::DoDataExchange(CDataExchange* pDX)
  83. /*++
  84. Routine Description:
  85. Called by framework to exchange dialog data.
  86. Arguments:
  87. pDX - data exchange object.
  88. Return Values:
  89. None.
  90. --*/
  91. {
  92. CPropertyPage::DoDataExchange(pDX);
  93. //{{AFX_DATA_MAP(CProductPropertyPageServers)
  94. DDX_Control(pDX, IDC_PP_PRODUCT_SERVERS_EDIT, m_editBtn);
  95. DDX_Control(pDX, IDC_PP_PRODUCT_SERVERS_SERVERS, m_serverList);
  96. //}}AFX_DATA_MAP
  97. }
  98. void CProductPropertyPageServers::InitCtrls()
  99. /*++
  100. Routine Description:
  101. Initializes property page controls.
  102. Arguments:
  103. None.
  104. Return Values:
  105. None.
  106. --*/
  107. {
  108. m_serverList.SetFocus();
  109. m_editBtn.EnableWindow(FALSE);
  110. m_bAreCtrlsInitialized = TRUE;
  111. ::LvInitColumns(&m_serverList, &g_serverColumnInfo);
  112. }
  113. void CProductPropertyPageServers::InitPage(CProduct* pProduct, DWORD* pUpdateHint)
  114. /*++
  115. Routine Description:
  116. Initializes property page.
  117. Arguments:
  118. pProduct - product object.
  119. pUpdateHint - update hint.
  120. Return Values:
  121. None.
  122. --*/
  123. {
  124. ASSERT(pUpdateHint);
  125. VALIDATE_OBJECT(pProduct, CProduct);
  126. m_pProduct = pProduct;
  127. m_pUpdateHint = pUpdateHint;
  128. }
  129. void CProductPropertyPageServers::AbortPageIfNecessary()
  130. /*++
  131. Routine Description:
  132. Displays status and aborts if connection lost.
  133. Arguments:
  134. None.
  135. Return Values:
  136. None.
  137. --*/
  138. {
  139. theApp.DisplayLastStatus();
  140. if (IsConnectionDropped(LlsGetLastStatus()))
  141. {
  142. AbortPage(); // bail...
  143. }
  144. }
  145. void CProductPropertyPageServers::AbortPage()
  146. /*++
  147. Routine Description:
  148. Aborts property page.
  149. Arguments:
  150. None.
  151. Return Values:
  152. None.
  153. --*/
  154. {
  155. *m_pUpdateHint = UPDATE_INFO_ABORT;
  156. GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
  157. }
  158. void CProductPropertyPageServers::OnEdit()
  159. /*++
  160. Routine Description:
  161. View properties of server.
  162. Arguments:
  163. None.
  164. Return Values:
  165. None.
  166. --*/
  167. {
  168. ViewServerProperties();
  169. }
  170. BOOL CProductPropertyPageServers::OnInitDialog()
  171. /*++
  172. Routine Description:
  173. Message handler for WM_INITDIALOG.
  174. Arguments:
  175. None.
  176. Return Values:
  177. Returns false if focus set to control manually.
  178. --*/
  179. {
  180. CPropertyPage::OnInitDialog();
  181. SendMessage(WM_COMMAND, ID_INIT_CTRLS);
  182. return TRUE;
  183. }
  184. void CProductPropertyPageServers::OnDestroy()
  185. /*++
  186. Routine Description:
  187. Message handler for WM_DESTROY.
  188. Arguments:
  189. None.
  190. Return Values:
  191. None.
  192. --*/
  193. {
  194. ::LvReleaseObArray(&m_serverList); // release now...
  195. CPropertyPage::OnDestroy();
  196. }
  197. BOOL CProductPropertyPageServers::OnSetActive()
  198. /*++
  199. Routine Description:
  200. Activates property page.
  201. Arguments:
  202. None.
  203. Return Values:
  204. Returns true if focus accepted.
  205. --*/
  206. {
  207. BOOL bIsActivated;
  208. if (bIsActivated = CPropertyPage::OnSetActive())
  209. {
  210. if ( ( IsServerInfoUpdated( *m_pUpdateHint )
  211. || IsServiceInfoUpdated( *m_pUpdateHint ) )
  212. && !RefreshCtrls() )
  213. {
  214. AbortPageIfNecessary(); // display error...
  215. }
  216. }
  217. return bIsActivated;
  218. }
  219. BOOL CProductPropertyPageServers::RefreshCtrls()
  220. /*++
  221. Routine Description:
  222. Refreshs property page controls.
  223. Arguments:
  224. None.
  225. Return Values:
  226. Returns true if controls refreshed.
  227. --*/
  228. {
  229. VALIDATE_OBJECT(m_pProduct, CProduct);
  230. BOOL bIsRefreshed = FALSE;
  231. VARIANT va;
  232. VariantInit(&va);
  233. BeginWaitCursor(); // hourglass...
  234. CServerStatistics* pStatistics = (CServerStatistics*)MKOBJ(m_pProduct->GetServerStatistics(va));
  235. if (pStatistics)
  236. {
  237. VALIDATE_OBJECT(pStatistics, CServerStatistics);
  238. bIsRefreshed = ::LvRefreshObArray(
  239. &m_serverList,
  240. &g_serverColumnInfo,
  241. pStatistics->m_pObArray
  242. );
  243. pStatistics->InternalRelease(); // add ref'd individually...
  244. }
  245. if (!bIsRefreshed)
  246. {
  247. ::LvReleaseObArray(&m_serverList); // reset list now...
  248. }
  249. EndWaitCursor(); // hourglass...
  250. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  251. return bIsRefreshed;
  252. }
  253. void CProductPropertyPageServers::ViewServerProperties()
  254. /*++
  255. Routine Description:
  256. View properties of server.
  257. Arguments:
  258. None.
  259. Return Values:
  260. None.
  261. --*/
  262. {
  263. CServerStatistic* pStatistic;
  264. if (pStatistic = (CServerStatistic*)::LvGetSelObj(&m_serverList))
  265. {
  266. VALIDATE_OBJECT(pStatistic, CServerStatistic);
  267. CServer* pServer = new CServer(NULL, pStatistic->m_strEntry);
  268. if (pServer)
  269. {
  270. CString strTitle;
  271. AfxFormatString1(strTitle, IDS_PROPERTIES_OF, pServer->m_strName);
  272. CServerPropertySheet serverProperties(strTitle);
  273. serverProperties.InitPages(pServer);
  274. serverProperties.DoModal();
  275. *m_pUpdateHint |= serverProperties.m_fUpdateHint;
  276. if (IsUpdateAborted(serverProperties.m_fUpdateHint))
  277. {
  278. AbortPage(); // don't display error...
  279. }
  280. else if ( ( IsServerInfoUpdated( serverProperties.m_fUpdateHint )
  281. || IsServiceInfoUpdated( serverProperties.m_fUpdateHint ) )
  282. && !RefreshCtrls() )
  283. {
  284. AbortPageIfNecessary(); // display error...
  285. }
  286. }
  287. else
  288. {
  289. AbortPageIfNecessary(); // display error...
  290. }
  291. if (pServer)
  292. pServer->InternalRelease(); // delete object...
  293. }
  294. }
  295. BOOL CProductPropertyPageServers::OnCommand(WPARAM wParam, LPARAM lParam)
  296. /*++
  297. Routine Description:
  298. Message handler for WM_COMMAND.
  299. Arguments:
  300. wParam - message specific.
  301. lParam - message specific.
  302. Return Values:
  303. Returns true if message processed.
  304. --*/
  305. {
  306. if (wParam == ID_INIT_CTRLS)
  307. {
  308. if (!m_bAreCtrlsInitialized)
  309. {
  310. InitCtrls();
  311. if (!RefreshCtrls())
  312. {
  313. AbortPageIfNecessary(); // display error...
  314. }
  315. }
  316. ::SafeEnableWindow(
  317. &m_editBtn,
  318. &m_serverList,
  319. CDialog::GetFocus(),
  320. m_serverList.GetItemCount()
  321. );
  322. return TRUE; // processed...
  323. }
  324. return CDialog::OnCommand(wParam, lParam);
  325. }
  326. void CProductPropertyPageServers::OnDblClkServers(NMHDR* pNMHDR, LRESULT* pResult)
  327. /*++
  328. Routine Description:
  329. Notification handler for NM_DBLCLK.
  330. Arguments:
  331. pNMHDR - notification header.
  332. pResult - return code.
  333. Return Values:
  334. None.
  335. --*/
  336. {
  337. ViewServerProperties();
  338. *pResult = 0;
  339. }
  340. void CProductPropertyPageServers::OnReturnServers(NMHDR* pNMHDR, LRESULT* pResult)
  341. /*++
  342. Routine Description:
  343. Notification handler for NM_RETURN.
  344. Arguments:
  345. pNMHDR - notification header.
  346. pResult - return code.
  347. Return Values:
  348. None.
  349. --*/
  350. {
  351. ViewServerProperties();
  352. *pResult = 0;
  353. }
  354. void CProductPropertyPageServers::OnSetFocusServers(NMHDR* pNMHDR, LRESULT* pResult)
  355. /*++
  356. Routine Description:
  357. Notification handler for NM_SETFOCUS.
  358. Arguments:
  359. pNMHDR - notification header.
  360. pResult - return code.
  361. Return Values:
  362. None.
  363. --*/
  364. {
  365. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  366. *pResult = 0;
  367. }
  368. void CProductPropertyPageServers::OnKillFocusServers(NMHDR* pNMHDR, LRESULT* pResult)
  369. /*++
  370. Routine Description:
  371. Notification handler for NM_KILLFOCUS.
  372. Arguments:
  373. pNMHDR - notification header.
  374. pResult - return code.
  375. Return Values:
  376. None.
  377. --*/
  378. {
  379. ::LvSelObjIfNecessary(&m_serverList); // ensure selection...
  380. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  381. *pResult = 0;
  382. }
  383. void CProductPropertyPageServers::OnColumnClickServers(NMHDR* pNMHDR, LRESULT* pResult)
  384. /*++
  385. Routine Description:
  386. Notification handler for LVN_COLUMNCLICK.
  387. Arguments:
  388. pNMHDR - notification header.
  389. pResult - return code.
  390. Return Values:
  391. None.
  392. --*/
  393. {
  394. g_serverColumnInfo.bSortOrder = GetKeyState(VK_CONTROL) < 0;
  395. g_serverColumnInfo.nSortedItem = ((NM_LISTVIEW*)pNMHDR)->iSubItem;
  396. m_serverList.SortItems(CompareProductServers, 0); // use column info
  397. *pResult = 0;
  398. }
  399. void CProductPropertyPageServers::OnGetDispInfoServers(NMHDR* pNMHDR, LRESULT* pResult)
  400. /*++
  401. Routine Description:
  402. Notification handler for LVN_GETDISPINFO.
  403. Arguments:
  404. pNMHDR - notification header.
  405. pResult - return code.
  406. Return Values:
  407. None.
  408. --*/
  409. {
  410. LV_ITEM* plvItem = &((LV_DISPINFO*)pNMHDR)->item;
  411. ASSERT(plvItem);
  412. CServerStatistic* pStatistic = (CServerStatistic*)plvItem->lParam;
  413. VALIDATE_OBJECT(pStatistic, CServerStatistic);
  414. switch (plvItem->iSubItem)
  415. {
  416. case LVID_SERVER:
  417. {
  418. if (pStatistic->m_bIsPerServer)
  419. {
  420. if ((pStatistic->GetMaxUses() <= pStatistic->GetHighMark()) && pStatistic->GetMaxUses())
  421. {
  422. plvItem->iImage = BMPI_WARNING_AT_LIMIT;
  423. }
  424. else
  425. {
  426. plvItem->iImage = BMPI_PRODUCT_PER_SERVER;
  427. }
  428. }
  429. else
  430. {
  431. plvItem->iImage = BMPI_PRODUCT_PER_SEAT;
  432. }
  433. lstrcpyn(plvItem->pszText, pStatistic->m_strEntry, plvItem->cchTextMax);
  434. }
  435. break;
  436. case LVID_PURCHASED:
  437. {
  438. CString strLabel;
  439. if (pStatistic->m_bIsPerServer)
  440. {
  441. strLabel.Format(_T("%ld"), pStatistic->GetMaxUses());
  442. }
  443. else
  444. {
  445. strLabel.LoadString(IDS_NOT_APPLICABLE);
  446. }
  447. lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
  448. }
  449. break;
  450. case LVID_REACHED:
  451. {
  452. CString strLabel;
  453. strLabel.Format(_T("%ld"), pStatistic->GetHighMark());
  454. lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
  455. }
  456. break;
  457. }
  458. *pResult = 0;
  459. }
  460. int CALLBACK CompareProductServers(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  461. /*++
  462. Routine Description:
  463. Notification handler for LVM_SORTITEMS.
  464. Arguments:
  465. lParam1 - object to sort.
  466. lParam2 - object to sort.
  467. lParamSort - sort criteria.
  468. Return Values:
  469. Same as lstrcmp.
  470. --*/
  471. {
  472. #define pStatistic1 ((CServerStatistic*)lParam1)
  473. #define pStatistic2 ((CServerStatistic*)lParam2)
  474. VALIDATE_OBJECT(pStatistic1, CServerStatistic);
  475. VALIDATE_OBJECT(pStatistic2, CServerStatistic);
  476. int iResult;
  477. switch (g_serverColumnInfo.nSortedItem)
  478. {
  479. case LVID_SERVER:
  480. iResult = pStatistic1->m_strEntry.CompareNoCase(pStatistic2->m_strEntry);
  481. break;
  482. case LVID_PURCHASED:
  483. iResult = pStatistic1->GetMaxUses() - pStatistic2->GetMaxUses();
  484. break;
  485. case LVID_REACHED:
  486. iResult = pStatistic1->GetHighMark() - pStatistic2->GetHighMark();
  487. break;
  488. default:
  489. iResult = 0;
  490. break;
  491. }
  492. return g_serverColumnInfo.bSortOrder ? -iResult : iResult;
  493. }