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.

1323 lines
39 KiB

  1. /*++
  2. Copyright (C) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. ctrsprop.cpp
  5. Abstract:
  6. Implementation of the counters general property page.
  7. --*/
  8. #include "stdafx.h"
  9. #include <pdh.h>
  10. #include <pdhmsg.h>
  11. #include "smlogs.h"
  12. #include "smcfgmsg.h"
  13. #include "smctrqry.h"
  14. #include "ctrsprop.h"
  15. #include "smlogres.h"
  16. #include <pdhp.h>
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. USE_HANDLE_MACROS("SMLOGCFG(ctrsprop.cpp)");
  23. static ULONG
  24. s_aulHelpIds[] =
  25. {
  26. IDC_CTRS_COUNTER_LIST, IDH_CTRS_COUNTER_LIST,
  27. IDC_CTRS_ADD_BTN, IDH_CTRS_ADD_BTN,
  28. IDC_CTRS_ADD_OBJ_BTN, IDH_CTRS_ADD_OBJ_BTN,
  29. IDC_CTRS_REMOVE_BTN, IDH_CTRS_REMOVE_BTN,
  30. IDC_CTRS_FILENAME_DISPLAY, IDH_CTRS_FILENAME_DISPLAY,
  31. IDC_CTRS_SAMPLE_SPIN, IDH_CTRS_SAMPLE_EDIT,
  32. IDC_CTRS_SAMPLE_EDIT, IDH_CTRS_SAMPLE_EDIT,
  33. IDC_CTRS_SAMPLE_UNITS_COMBO,IDH_CTRS_SAMPLE_UNITS_COMBO,
  34. IDC_RUNAS_EDIT, IDH_RUNAS_EDIT,
  35. IDC_SETPWD_BTN, IDH_SETPWD_BTN,
  36. 0,0
  37. };
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CCountersProperty property page
  40. IMPLEMENT_DYNCREATE(CCountersProperty, CSmPropertyPage)
  41. CCountersProperty::CCountersProperty(MMC_COOKIE mmcCookie, LONG_PTR hConsole)
  42. : CSmPropertyPage ( CCountersProperty::IDD, hConsole )
  43. // lCookie is really the pointer to the Log Query object
  44. {
  45. //::OutputDebugStringA("\nCCountersProperty::CCountersProperty");
  46. // save pointers from arg list
  47. m_pCtrLogQuery = reinterpret_cast <CSmCounterLogQuery *>(mmcCookie);
  48. ZeroMemory ( &m_dlgConfig, sizeof(m_dlgConfig) );
  49. m_szCounterListBuffer = NULL;
  50. m_dwCounterListBufferSize = 0;
  51. m_lCounterListHasStars = 0;
  52. m_dwMaxHorizListExtent = 0;
  53. m_fHashTableSetup = FALSE;
  54. // EnableAutomation();
  55. //{{AFX_DATA_INIT(CCountersProperty)
  56. m_nSampleUnits = 0;
  57. //}}AFX_DATA_INIT
  58. }
  59. CCountersProperty::CCountersProperty() : CSmPropertyPage ( CCountersProperty::IDD )
  60. {
  61. ASSERT (FALSE); // the constructor w/ args should be used instead
  62. }
  63. CCountersProperty::~CCountersProperty()
  64. {
  65. // ::OutputDebugStringA("\nCCountersProperty::~CCountersProperty");
  66. if (m_szCounterListBuffer != NULL) {
  67. delete (m_szCounterListBuffer);
  68. }
  69. ClearCountersHashTable();
  70. }
  71. void CCountersProperty::OnFinalRelease()
  72. {
  73. // When the last reference for an automation object is released
  74. // OnFinalRelease is called. The base class will automatically
  75. // deletes the object. Add additional cleanup required for your
  76. // object before calling the base class.
  77. CPropertyPage::OnFinalRelease();
  78. }
  79. void CCountersProperty::DoDataExchange(CDataExchange* pDX)
  80. {
  81. CString strTemp;
  82. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  83. CPropertyPage::DoDataExchange(pDX);
  84. //{{AFX_DATA_MAP(CCountersProperty)
  85. DDX_Text(pDX, IDC_CTRS_LOG_SCHED_TEXT, m_strStartDisplay);
  86. ValidateTextEdit(pDX, IDC_CTRS_SAMPLE_EDIT, 6, &m_SharedData.stiSampleTime.dwValue, eMinSampleInterval, eMaxSampleInterval);
  87. DDX_CBIndex(pDX, IDC_CTRS_SAMPLE_UNITS_COMBO, m_nSampleUnits);
  88. DDX_Text(pDX, IDC_RUNAS_EDIT, m_strUserDisplay );
  89. //}}AFX_DATA_MAP
  90. if ( pDX->m_bSaveAndValidate ) {
  91. m_SharedData.stiSampleTime.dwUnitType =
  92. (DWORD)((CComboBox *)GetDlgItem(IDC_CTRS_SAMPLE_UNITS_COMBO))->
  93. GetItemData(m_nSampleUnits);
  94. }
  95. }
  96. BEGIN_MESSAGE_MAP(CCountersProperty, CSmPropertyPage)
  97. //{{AFX_MSG_MAP(CCountersProperty)
  98. ON_BN_CLICKED(IDC_CTRS_ADD_BTN, OnCtrsAddBtn)
  99. ON_BN_CLICKED(IDC_CTRS_ADD_OBJ_BTN, OnCtrsAddObjBtn)
  100. ON_BN_CLICKED(IDC_CTRS_REMOVE_BTN, OnCtrsRemoveBtn)
  101. ON_LBN_DBLCLK(IDC_CTRS_COUNTER_LIST, OnDblclkCtrsCounterList)
  102. ON_EN_CHANGE(IDC_CTRS_SAMPLE_EDIT, OnKillfocusSchedSampleEdit)
  103. ON_EN_KILLFOCUS(IDC_CTRS_SAMPLE_EDIT, OnKillfocusSchedSampleEdit)
  104. ON_EN_CHANGE( IDC_RUNAS_EDIT, OnChangeUser )
  105. ON_NOTIFY(UDN_DELTAPOS, IDC_CTRS_SAMPLE_SPIN, OnDeltaposSchedSampleSpin)
  106. ON_CBN_SELENDOK(IDC_CTRS_SAMPLE_UNITS_COMBO, OnSelendokSampleUnitsCombo)
  107. ON_BN_CLICKED(IDC_SETPWD_BTN, OnPwdBtn)
  108. ON_WM_DESTROY()
  109. //}}AFX_MSG_MAP
  110. END_MESSAGE_MAP()
  111. BEGIN_DISPATCH_MAP(CCountersProperty, CSmPropertyPage)
  112. //{{AFX_DISPATCH_MAP(CCountersProperty)
  113. // NOTE - the ClassWizard will add and remove mapping macros here.
  114. //}}AFX_DISPATCH_MAP
  115. END_DISPATCH_MAP()
  116. // Note: we add support for IID_ICountersProperty to support typesafe binding
  117. // from VBA. This IID must match the GUID that is attached to the
  118. // dispinterface in the .ODL file.
  119. // {65154EA9-BDBE-11D1-BF99-00C04F94A83A}
  120. static const IID IID_ICountersProperty =
  121. { 0x65154ea9, 0xbdbe, 0x11d1, { 0xbf, 0x99, 0x0, 0xc0, 0x4f, 0x94, 0xa8, 0x3a } };
  122. BEGIN_INTERFACE_MAP(CCountersProperty, CSmPropertyPage)
  123. INTERFACE_PART(CCountersProperty, IID_ICountersProperty, Dispatch)
  124. END_INTERFACE_MAP()
  125. ULONG
  126. CCountersProperty::HashCounter(
  127. LPTSTR szCounterName
  128. )
  129. {
  130. ULONG h = 0;
  131. ULONG a = 31415; //a, b, k are primes
  132. const ULONG k = 16381;
  133. const ULONG b = 27183;
  134. LPTSTR szThisChar;
  135. if (szCounterName) {
  136. for (szThisChar = szCounterName; * szThisChar; szThisChar ++) {
  137. h = (a * h + ((ULONG) (* szThisChar))) % k;
  138. a = a * b % (k - 1);
  139. }
  140. }
  141. return (h % eHashTableSize);
  142. }
  143. //++
  144. // Description:
  145. // Remove a counter path from hash table. One counter
  146. // path must exactly match the given one in order to be
  147. // removed, even it is one with wildcard
  148. //
  149. // Parameters:
  150. // pszCounterPath - Pointer to counter path to be removed
  151. //
  152. // Return:
  153. // Return TRUE if the counter path is removed, otherwis return FALSE
  154. //--
  155. BOOL
  156. CCountersProperty::RemoveCounterFromHashTable(
  157. LPTSTR szCounterName,
  158. PPDH_COUNTER_PATH_ELEMENTS pCounterPath
  159. )
  160. {
  161. ULONG lHashValue;
  162. PHASH_ENTRY pEntry = NULL;
  163. PHASH_ENTRY pPrev = NULL;
  164. BOOL bReturn = FALSE;
  165. SetLastError(ERROR_SUCCESS);
  166. if (szCounterName == NULL || pCounterPath == NULL) {
  167. SetLastError(ERROR_INVALID_PARAMETER);
  168. goto ErrorOut;
  169. }
  170. lHashValue = HashCounter(szCounterName);
  171. pEntry = m_HashTable[lHashValue];
  172. //
  173. // Check if there is a counter path which is exactly the same
  174. // as the given one
  175. //
  176. while (pEntry) {
  177. if (pEntry->pCounter == pCounterPath)
  178. break;
  179. pPrev = pEntry;
  180. pEntry = pEntry->pNext;
  181. }
  182. //
  183. // If we found it, remove it
  184. //
  185. if (pEntry) {
  186. if (pPrev == NULL) {
  187. m_HashTable[lHashValue] = pEntry->pNext;
  188. }
  189. else {
  190. pPrev->pNext = pEntry->pNext;
  191. }
  192. G_FREE(pEntry->pCounter);
  193. G_FREE(pEntry);
  194. bReturn = TRUE;
  195. }
  196. ErrorOut:
  197. return bReturn;
  198. }
  199. //++
  200. // Description:
  201. // Insert a counter path into hash table.
  202. //
  203. // Parameters:
  204. // pszCounterPath - Pointer to counter path to be inserted
  205. //
  206. // Return:
  207. // Return the pointer to new inserted PDH_COUNTER_PATH_ELEMENTS structure
  208. //--
  209. PPDH_COUNTER_PATH_ELEMENTS
  210. CCountersProperty::InsertCounterToHashTable(
  211. LPTSTR pszCounterPath
  212. )
  213. {
  214. ULONG lHashValue;
  215. PHASH_ENTRY pNewEntry = NULL;
  216. PPDH_COUNTER_PATH_ELEMENTS pCounter = NULL;
  217. PDH_STATUS pdhStatus;
  218. if (pszCounterPath == NULL) {
  219. SetLastError(ERROR_INVALID_PARAMETER);
  220. goto ErrorOut;
  221. }
  222. pdhStatus = AllocInitCounterPath ( pszCounterPath, &pCounter );
  223. if (pdhStatus != ERROR_SUCCESS) {
  224. SetLastError( pdhStatus );
  225. goto ErrorOut;
  226. }
  227. //
  228. // Insert at head of bucket list
  229. //
  230. lHashValue = HashCounter(pszCounterPath);
  231. pNewEntry = (PHASH_ENTRY) G_ALLOC(sizeof(HASH_ENTRY));
  232. if (pNewEntry == NULL) {
  233. SetLastError( ERROR_OUTOFMEMORY );
  234. goto ErrorOut;
  235. }
  236. pNewEntry->pCounter = pCounter;
  237. pNewEntry->pNext = m_HashTable[lHashValue];
  238. m_HashTable[lHashValue] = pNewEntry;
  239. return pCounter;
  240. ErrorOut:
  241. if (pCounter != NULL)
  242. G_FREE (pCounter);
  243. return NULL;
  244. }
  245. //++
  246. // Description:
  247. // Check if the new counter path overlaps with a existing
  248. // one in logical sense
  249. //
  250. // Parameters:
  251. // pCounter - Pointer to counter path to be inserted
  252. //
  253. // Return:
  254. // Return the relation between the new and existing counter
  255. // paths. Possible relation is as following:
  256. // ERROR_SUCCESS - The two counter paths are different
  257. // SMCFG_DUPL_FIRST_IS_WILD - The first counter path has wildcard name
  258. // SMCFG_DUPL_SECOND_IS_WILD - The second counter path has wildcard name
  259. // SMCFG_DUPL_SINGLE_PATH - The two counter paths are the same(may
  260. // contain wildcard)
  261. //--
  262. DWORD
  263. CCountersProperty::CheckDuplicate( PPDH_COUNTER_PATH_ELEMENTS pCounter)
  264. {
  265. ULONG lHashValue;
  266. PHASH_ENTRY pHead;
  267. PHASH_ENTRY pEntry;
  268. DWORD dwStatus = ERROR_SUCCESS;
  269. for (lHashValue = 0; lHashValue < eHashTableSize; lHashValue++) {
  270. pHead = m_HashTable[lHashValue];
  271. if (pHead == NULL)
  272. continue;
  273. pEntry = pHead;
  274. while (pEntry) {
  275. dwStatus = CheckDuplicateCounterPaths ( pEntry->pCounter, pCounter );
  276. if ( dwStatus != ERROR_SUCCESS ) {
  277. return dwStatus;
  278. }
  279. pEntry = pEntry->pNext;
  280. }
  281. }
  282. return dwStatus;
  283. }
  284. //++
  285. // Description:
  286. // The function inserts all the current counter paths into
  287. // hash table as a way to accelerate looking.
  288. //
  289. // Parameters:
  290. // None
  291. //
  292. // Return:
  293. // None
  294. //--
  295. void
  296. CCountersProperty::SetupCountersHashTable( void )
  297. {
  298. INT iListIndex;
  299. INT iItemCnt;
  300. TCHAR szPath[MAX_PATH];
  301. CListBox* pCounterList;
  302. //
  303. // If the hash table is already set up, return
  304. if (m_fHashTableSetup) {
  305. return;
  306. }
  307. //
  308. // Initialize the hash table
  309. //
  310. memset(&m_HashTable, 0, sizeof(m_HashTable));
  311. //
  312. // Loop throuth all the items in the list box and
  313. // put them into hash table.
  314. //
  315. pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  316. if (pCounterList == NULL) {
  317. return;
  318. }
  319. iItemCnt = pCounterList->GetCount();
  320. if (iItemCnt != LB_ERR) {
  321. for (iListIndex = 0; iListIndex < iItemCnt; iListIndex++) {
  322. if (pCounterList->GetText( iListIndex, szPath ) > 0) {
  323. InsertCounterToHashTable( szPath );
  324. }
  325. }
  326. }
  327. m_fHashTableSetup = TRUE;
  328. }
  329. //++
  330. // Description:
  331. // The function clears all the entries in hash table
  332. // and set hash-table-not-set-up flag
  333. //
  334. // Parameters:
  335. // None
  336. //
  337. // Return:
  338. // None
  339. //--
  340. void
  341. CCountersProperty::ClearCountersHashTable( void )
  342. {
  343. ULONG i;
  344. PHASH_ENTRY pEntry;
  345. PHASH_ENTRY pNext;
  346. if (m_fHashTableSetup) {
  347. for (i = 0; i < eHashTableSize; i ++) {
  348. pNext = m_HashTable[i];
  349. while (pNext != NULL) {
  350. pEntry = pNext;
  351. pNext = pEntry->pNext;
  352. G_FREE(pEntry->pCounter);
  353. G_FREE(pEntry);
  354. }
  355. }
  356. }
  357. else {
  358. memset(&m_HashTable, 0, sizeof(m_HashTable));
  359. }
  360. m_fHashTableSetup = FALSE;
  361. }
  362. static
  363. PDH_FUNCTION
  364. DialogCallBack(CCountersProperty *pDlg)
  365. {
  366. // add strings in buffer to list box
  367. LPTSTR szNewCounterName;
  368. INT iListIndex;
  369. INT iItemCnt;
  370. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  371. DWORD dwReturnStatus = ERROR_SUCCESS;
  372. CListBox *pCounterList;
  373. DWORD dwItemExtent;
  374. DWORD dwStatus = ERROR_SUCCESS;
  375. BOOL bAtLeastOneCounterRemoved = FALSE;
  376. BOOL bAtLeastOneCounterNotAdded = FALSE;
  377. TCHAR szCounterPath[MAX_PATH + 1];
  378. PPDH_COUNTER_PATH_ELEMENTS pPathInfoNew = NULL;
  379. CDC* pCDC = NULL;
  380. ResourceStateManager rsm;
  381. #define CTRBUFLIMIT (0x7fffffff)
  382. if ( PDH_MORE_DATA == pDlg->m_dlgConfig.CallBackStatus ) {
  383. if ( pDlg->m_dlgConfig.cchReturnPathLength < CTRBUFLIMIT ) {
  384. pDlg->m_dwCounterListBufferSize *= 2;
  385. delete pDlg->m_szCounterListBuffer;
  386. pDlg->m_szCounterListBuffer = NULL;
  387. try {
  388. pDlg->m_szCounterListBuffer = new WCHAR[pDlg->m_dwCounterListBufferSize];
  389. } catch ( ... ) {
  390. pDlg->m_dwCounterListBufferSize = 0;
  391. pDlg->m_dlgConfig.CallBackStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  392. dwReturnStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  393. }
  394. if ( ERROR_SUCCESS == dwReturnStatus ) {
  395. // clear buffer
  396. memset (pDlg->m_szCounterListBuffer, 0, pDlg->m_dwCounterListBufferSize);
  397. pDlg->m_dlgConfig.szReturnPathBuffer = pDlg->m_szCounterListBuffer;
  398. pDlg->m_dlgConfig.cchReturnPathLength = pDlg->m_dwCounterListBufferSize;
  399. pDlg->m_dlgConfig.CallBackStatus = PDH_RETRY;
  400. dwReturnStatus = PDH_RETRY;
  401. }
  402. } else {
  403. pDlg->m_dlgConfig.CallBackStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  404. dwReturnStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  405. }
  406. } else if ( ERROR_SUCCESS == pDlg->m_dlgConfig.CallBackStatus ) {
  407. pCounterList = (CListBox *)pDlg->GetDlgItem(IDC_CTRS_COUNTER_LIST);
  408. pCDC = pCounterList->GetDC();
  409. for (szNewCounterName = pDlg->m_szCounterListBuffer;
  410. *szNewCounterName != 0;
  411. szNewCounterName += (lstrlen(szNewCounterName) + 1)) {
  412. //
  413. // Parse new pathname
  414. //
  415. pdhStatus = pDlg->AllocInitCounterPath ( szNewCounterName, &pPathInfoNew );
  416. //
  417. // Check for duplicate
  418. //
  419. if (pdhStatus == ERROR_SUCCESS) {
  420. dwStatus = pDlg->CheckDuplicate( pPathInfoNew);
  421. if ( ERROR_SUCCESS != dwStatus ) {
  422. if ( SMCFG_DUPL_SINGLE_PATH == dwStatus
  423. || SMCFG_DUPL_FIRST_IS_WILD == dwStatus ) {
  424. // NOTE: This includes case where both first
  425. // and second are wild.
  426. bAtLeastOneCounterNotAdded = TRUE;
  427. } else {
  428. ASSERT( dwStatus == SMCFG_DUPL_SECOND_IS_WILD);
  429. }
  430. }
  431. }
  432. //
  433. // Check if there is a valid counter to add to the list
  434. //
  435. if ( ERROR_SUCCESS == pdhStatus &&
  436. ( ERROR_SUCCESS == dwStatus || SMCFG_DUPL_SECOND_IS_WILD == dwStatus)) {
  437. if ( SMCFG_DUPL_SECOND_IS_WILD == dwStatus ) {
  438. //
  439. // Scan for the duplicated items in the list box and
  440. // remove them
  441. //
  442. iItemCnt = pCounterList->GetCount();
  443. for (iListIndex = iItemCnt-1; iListIndex >= 0; iListIndex--) {
  444. PPDH_COUNTER_PATH_ELEMENTS pPathInfoExist;
  445. if ( 0 < pCounterList->GetText( iListIndex, szCounterPath ) ) {
  446. pPathInfoExist = (PPDH_COUNTER_PATH_ELEMENTS)
  447. pCounterList->GetItemDataPtr(iListIndex);
  448. if (pPathInfoExist == NULL)
  449. continue;
  450. dwStatus = CheckDuplicateCounterPaths ( pPathInfoExist, pPathInfoNew );
  451. if (dwStatus != ERROR_SUCCESS ) {
  452. ASSERT( dwStatus == SMCFG_DUPL_SECOND_IS_WILD );
  453. pDlg->RemoveCounterFromHashTable(szCounterPath, pPathInfoExist);
  454. pCounterList->DeleteString(iListIndex);
  455. }
  456. }
  457. }
  458. bAtLeastOneCounterRemoved = TRUE;
  459. }
  460. //
  461. // Add new counter name and select the current entry in the list box
  462. //
  463. iListIndex = pCounterList->AddString(szNewCounterName);
  464. if (iListIndex != LB_ERR) {
  465. if (pDlg->m_lCounterListHasStars != PDLCNFIG_LISTBOX_STARS_YES) {
  466. // save a string compare if this value is already set
  467. if (_tcsstr (szNewCounterName, TEXT("*")) == NULL) {
  468. pDlg->m_lCounterListHasStars = PDLCNFIG_LISTBOX_STARS_YES;
  469. }
  470. }
  471. if (! bAtLeastOneCounterRemoved) {
  472. // update list box extent
  473. if ( NULL != pCDC ) {
  474. dwItemExtent = (DWORD)(pCDC->GetTextExtent (szNewCounterName)).cx;
  475. if (dwItemExtent > pDlg->m_dwMaxHorizListExtent) {
  476. pDlg->m_dwMaxHorizListExtent = dwItemExtent;
  477. pCounterList->SetHorizontalExtent(dwItemExtent);
  478. }
  479. }
  480. }
  481. pCounterList->SetSel (-1, FALSE); // cancel existing selections
  482. pCounterList->SetSel (iListIndex);
  483. pCounterList->SetCaretIndex (iListIndex);
  484. pCounterList->SetItemDataPtr(iListIndex,
  485. (void*)pDlg->InsertCounterToHashTable(szNewCounterName));
  486. }
  487. }
  488. if ( ERROR_SUCCESS != pdhStatus ) {
  489. // Message box Pdh error message, go on to next
  490. CString strMsg;
  491. CString strPdhMessage;
  492. FormatSystemMessage ( pdhStatus, strPdhMessage );
  493. MFC_TRY
  494. strMsg.Format ( IDS_CTRS_PDH_ERROR, szNewCounterName );
  495. strMsg += strPdhMessage;
  496. MFC_CATCH_MINIMUM
  497. ::AfxMessageBox( strMsg, MB_OK|MB_ICONERROR, 0 );
  498. }
  499. // Go on to next path to add
  500. dwStatus = ERROR_SUCCESS;
  501. }
  502. if (bAtLeastOneCounterRemoved) {
  503. //
  504. // Clear the max extent and recalculate
  505. //
  506. pDlg->m_dwMaxHorizListExtent = 0;
  507. for ( iListIndex = 0; iListIndex < pCounterList->GetCount(); iListIndex++ ) {
  508. pCounterList->GetText(iListIndex, szCounterPath);
  509. if ( NULL != pCDC ) {
  510. dwItemExtent = (DWORD)(pCDC->GetTextExtent(szCounterPath)).cx;
  511. if (dwItemExtent > pDlg->m_dwMaxHorizListExtent) {
  512. pDlg->m_dwMaxHorizListExtent = dwItemExtent;
  513. }
  514. }
  515. }
  516. pCounterList->SetHorizontalExtent(pDlg->m_dwMaxHorizListExtent);
  517. }
  518. if ( NULL != pCDC ) {
  519. pCounterList->ReleaseDC(pCDC);
  520. pCDC = NULL;
  521. }
  522. // Message box re: duplicates not added, or duplicates were removed.
  523. if ( bAtLeastOneCounterRemoved ) {
  524. CString strMsg;
  525. strMsg.LoadString ( IDS_CTRS_DUPL_PATH_DELETED );
  526. ::AfxMessageBox ( strMsg, MB_OK | MB_ICONWARNING, 0);
  527. }
  528. if ( bAtLeastOneCounterNotAdded ) {
  529. CString strMsg;
  530. strMsg.LoadString ( IDS_CTRS_DUPL_PATH_NOT_ADDED );
  531. ::AfxMessageBox( strMsg, MB_OK|MB_ICONWARNING, 0 );
  532. }
  533. // clear buffer
  534. memset (pDlg->m_szCounterListBuffer, 0, pDlg->m_dwCounterListBufferSize);
  535. dwReturnStatus = ERROR_SUCCESS;
  536. } else {
  537. // Not successful
  538. dwReturnStatus = pDlg->m_dlgConfig.CallBackStatus;
  539. }
  540. return dwReturnStatus;
  541. }
  542. void CCountersProperty::OnPwdBtn()
  543. {
  544. CString strTempUser;
  545. UpdateData(TRUE);
  546. if (!m_bCanAccessRemoteWbem) {
  547. ConnectRemoteWbemFail(m_pCtrLogQuery, TRUE);
  548. return;
  549. }
  550. MFC_TRY
  551. strTempUser = m_strUserDisplay;
  552. m_strUserDisplay.TrimLeft();
  553. m_strUserDisplay.TrimRight();
  554. m_pCtrLogQuery->m_strUser = m_strUserDisplay;
  555. SetRunAs(m_pCtrLogQuery);
  556. m_strUserDisplay = m_pCtrLogQuery->m_strUser;
  557. if ( 0 != strTempUser.CompareNoCase ( m_strUserDisplay ) ) {
  558. SetDlgItemText ( IDC_RUNAS_EDIT, m_strUserDisplay );
  559. }
  560. MFC_CATCH_MINIMUM;
  561. }
  562. BOOL
  563. CCountersProperty::IsValidLocalData()
  564. {
  565. BOOL bIsValid = TRUE;
  566. CListBox * pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  567. long lNumCounters;
  568. ResourceStateManager rsm;
  569. lNumCounters = pCounterList->GetCount();
  570. if ( 0 == lNumCounters ) {
  571. CString strMsg;
  572. bIsValid = FALSE;
  573. strMsg.LoadString ( IDS_CTRS_REQUIRED );
  574. MessageBox ( strMsg, m_pCtrLogQuery->GetLogName(), MB_OK | MB_ICONERROR);
  575. GetDlgItem ( IDC_CTRS_ADD_BTN )->SetFocus();
  576. }
  577. if (bIsValid) {
  578. // Validate sample interval value
  579. bIsValid = ValidateDWordInterval(IDC_CTRS_SAMPLE_EDIT,
  580. m_pCtrLogQuery->GetLogName(),
  581. (long) m_SharedData.stiSampleTime.dwValue,
  582. eMinSampleInterval,
  583. eMaxSampleInterval);
  584. }
  585. if (bIsValid) {
  586. // Validate sample interval value and unit type
  587. bIsValid = SampleIntervalIsInRange(
  588. m_SharedData.stiSampleTime,
  589. m_pCtrLogQuery->GetLogName() );
  590. if ( !bIsValid ) {
  591. GetDlgItem ( IDC_CTRS_SAMPLE_EDIT )->SetFocus();
  592. }
  593. }
  594. return bIsValid;
  595. }
  596. /////////////////////////////////////////////////////////////////////////////
  597. // CCountersProperty message handlers
  598. void
  599. CCountersProperty::OnChangeUser()
  600. {
  601. //
  602. // If you can not access remote WBEM, you can not modify RunAs info,
  603. // changing the user name is not allowed.
  604. //
  605. if (m_bCanAccessRemoteWbem) {
  606. //
  607. // When the user hits OK in the password dialog,
  608. // the user name might not have changed.
  609. //
  610. UpdateData ( TRUE );
  611. m_strUserDisplay.TrimLeft();
  612. m_strUserDisplay.TrimRight();
  613. if ( 0 != m_strUserSaved.Compare ( m_strUserDisplay ) ) {
  614. m_pCtrLogQuery->m_fDirtyPassword = PASSWORD_DIRTY;
  615. SetModifiedPage(TRUE);
  616. }
  617. else {
  618. m_pCtrLogQuery->m_fDirtyPassword &= ~PASSWORD_DIRTY;
  619. }
  620. //
  621. // If default user is typed, never need to set password
  622. //
  623. if (m_strUserDisplay.IsEmpty() || m_strUserDisplay.GetAt(0) == L'<') {
  624. if (m_bPwdButtonEnabled) {
  625. GetDlgItem(IDC_SETPWD_BTN)->EnableWindow(FALSE);
  626. m_bPwdButtonEnabled = FALSE;
  627. }
  628. }
  629. else {
  630. if (!m_bPwdButtonEnabled) {
  631. GetDlgItem(IDC_SETPWD_BTN)->EnableWindow(TRUE);
  632. m_bPwdButtonEnabled = TRUE;
  633. }
  634. }
  635. }
  636. else {
  637. //
  638. // We can not modify the RunAs info, then display
  639. // an error message and retore the original user name in RunAs
  640. //
  641. UpdateData(TRUE);
  642. if (ConnectRemoteWbemFail(m_pCtrLogQuery, FALSE)) {
  643. GetDlgItem(IDC_RUNAS_EDIT)->SetWindowText(m_strUserSaved);
  644. }
  645. }
  646. }
  647. void
  648. CCountersProperty::OnCtrsAddBtn()
  649. {
  650. ImplementAdd( FALSE );
  651. }
  652. void
  653. CCountersProperty::OnCtrsAddObjBtn()
  654. {
  655. ImplementAdd( TRUE );
  656. }
  657. void CCountersProperty::OnCtrsRemoveBtn()
  658. {
  659. CListBox *pCounterList;
  660. LONG lThisItem;
  661. BOOL bDone;
  662. LONG lOrigCaret;
  663. LONG lItemStatus;
  664. LONG lItemCount;
  665. BOOL bChanged = FALSE;
  666. DWORD dwItemExtent;
  667. CString strItemText;
  668. PPDH_COUNTER_PATH_ELEMENTS pCounter;
  669. pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  670. // delete all selected items in the list box and
  671. // set the cursor to the item above the original caret position
  672. // or the first or last if that is out of the new range
  673. lOrigCaret = pCounterList->GetCaretIndex();
  674. lThisItem = 0;
  675. bDone = FALSE;
  676. // clear the max extent
  677. m_dwMaxHorizListExtent = 0;
  678. // clear the value and see if any non deleted items have a star, if so
  679. // then set the flag back
  680. do {
  681. lItemStatus = pCounterList->GetSel(lThisItem);
  682. if (lItemStatus > 0) {
  683. // then it's selected so delete it
  684. pCounterList->GetText(lThisItem, strItemText);
  685. pCounter = (PPDH_COUNTER_PATH_ELEMENTS) pCounterList->GetItemDataPtr(lThisItem);
  686. if (RemoveCounterFromHashTable(strItemText.GetBuffer(1), pCounter) == FALSE) {
  687. ClearCountersHashTable ();
  688. }
  689. pCounterList->DeleteString(lThisItem);
  690. bChanged = TRUE;
  691. } else if (lItemStatus == 0) {
  692. // get the text length of this item since it will stay
  693. pCounterList->GetText(lThisItem, strItemText);
  694. if (m_lCounterListHasStars != PDLCNFIG_LISTBOX_STARS_YES) {
  695. // save a string compare if this value is already set
  696. if (_tcsstr (strItemText, TEXT("*")) == NULL) {
  697. m_lCounterListHasStars = PDLCNFIG_LISTBOX_STARS_YES;
  698. }
  699. }
  700. dwItemExtent = (DWORD)((pCounterList->GetDC())->GetTextExtent(strItemText)).cx;
  701. if (dwItemExtent > m_dwMaxHorizListExtent) {
  702. m_dwMaxHorizListExtent = dwItemExtent;
  703. }
  704. // then it's not selected so go to the next one
  705. lThisItem++;
  706. } else {
  707. // we've run out so exit
  708. bDone = TRUE;
  709. }
  710. } while (!bDone);
  711. // update the text extent of the list box
  712. pCounterList->SetHorizontalExtent(m_dwMaxHorizListExtent);
  713. // see how many entries are left and update the
  714. // caret position and the remove button state
  715. lItemCount = pCounterList->GetCount();
  716. if (lItemCount > 0) {
  717. // the update the caret
  718. if (lOrigCaret >= lItemCount) {
  719. lOrigCaret = lItemCount-1;
  720. } else {
  721. // caret should be within the list
  722. }
  723. pCounterList->SetSel(lOrigCaret);
  724. pCounterList->SetCaretIndex(lOrigCaret);
  725. } else {
  726. // the list is empty so remove caret, selection
  727. // disable the remove button and activate the
  728. // add button
  729. pCounterList->SetSel(-1);
  730. }
  731. SetButtonState();
  732. SetModifiedPage(bChanged);
  733. }
  734. void CCountersProperty::OnDblclkCtrsCounterList()
  735. {
  736. ImplementAdd( FALSE );
  737. }
  738. BOOL CCountersProperty::OnSetActive()
  739. {
  740. BOOL bReturn;
  741. bReturn = CSmPropertyPage::OnSetActive();
  742. if (bReturn) {
  743. ResourceStateManager rsm;
  744. m_pCtrLogQuery->GetPropPageSharedData ( &m_SharedData );
  745. UpdateFileNameString();
  746. UpdateLogStartString();
  747. m_strUserDisplay = m_pCtrLogQuery->m_strUser;
  748. UpdateData(FALSE); //to load the edit & combo box
  749. }
  750. return bReturn;
  751. }
  752. BOOL CCountersProperty::OnKillActive()
  753. {
  754. BOOL bContinue = TRUE;
  755. ResourceStateManager rsm;
  756. bContinue = CPropertyPage::OnKillActive();
  757. if ( bContinue ) {
  758. m_pCtrLogQuery->m_strUser = m_strUserDisplay;
  759. bContinue = IsValidData(m_pCtrLogQuery, VALIDATE_FOCUS);
  760. if ( bContinue ) {
  761. m_pCtrLogQuery->SetPropPageSharedData ( &m_SharedData );
  762. SetIsActive ( FALSE );
  763. }
  764. }
  765. return bContinue;
  766. }
  767. void
  768. CCountersProperty::OnCancel()
  769. {
  770. m_pCtrLogQuery->SyncPropPageSharedData(); // clear memory shared between property pages.
  771. }
  772. BOOL
  773. CCountersProperty::OnApply()
  774. {
  775. CListBox * pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  776. long lThisCounter;
  777. BOOL bContinue = TRUE;
  778. WCHAR szCounterPath[MAX_PATH];
  779. ResourceStateManager rsm;
  780. bContinue = UpdateData(TRUE);
  781. if ( bContinue ) {
  782. bContinue = IsValidData(m_pCtrLogQuery, VALIDATE_APPLY );
  783. }
  784. if ( bContinue ) {
  785. bContinue = SampleTimeIsLessThanSessionTime ( m_pCtrLogQuery );
  786. if ( !bContinue ) {
  787. GetDlgItem ( IDC_CTRS_SAMPLE_EDIT )->SetFocus();
  788. }
  789. }
  790. // Write data to the query object.
  791. if ( bContinue ) {
  792. ASSERT ( 0 < pCounterList->GetCount() );
  793. // update the counter MSZ string using the counters from the list box
  794. m_pCtrLogQuery->ResetCounterList(); // clear the old counter list
  795. for ( lThisCounter = 0; lThisCounter < pCounterList->GetCount(); lThisCounter++ ) {
  796. if (pCounterList->GetTextLen(lThisCounter) < MAX_PATH) {
  797. pCounterList->GetText(lThisCounter, szCounterPath);
  798. m_pCtrLogQuery->AddCounter(szCounterPath);
  799. }
  800. }
  801. if ( bContinue ) {
  802. // Sample interval
  803. ASSERT ( SLQ_TT_TTYPE_SAMPLE == m_SharedData.stiSampleTime.wTimeType );
  804. ASSERT ( SLQ_TT_DTYPE_UNITS == m_SharedData.stiSampleTime.wDataType );
  805. bContinue = m_pCtrLogQuery->SetLogTime (&m_SharedData.stiSampleTime, (DWORD)m_SharedData.stiSampleTime.wTimeType);
  806. // Save property page shared data.
  807. m_pCtrLogQuery->UpdatePropPageSharedData();
  808. if ( bContinue ) {
  809. bContinue = UpdateService( m_pCtrLogQuery, TRUE );
  810. }
  811. }
  812. }
  813. if ( bContinue ) {
  814. bContinue = Apply(m_pCtrLogQuery);
  815. }
  816. if ( bContinue ){
  817. bContinue = CPropertyPage::OnApply();
  818. }
  819. return bContinue;
  820. }
  821. void
  822. CCountersProperty::UpdateLogStartString ()
  823. {
  824. eStartType eCurrentStartType;
  825. int nResId = 0;
  826. ResourceStateManager rsm;
  827. eCurrentStartType = DetermineCurrentStartType();
  828. if ( eStartManually == eCurrentStartType ) {
  829. nResId = IDS_LOG_START_MANUALLY;
  830. } else if ( eStartImmediately == eCurrentStartType ) {
  831. nResId = IDS_LOG_START_IMMED;
  832. } else if ( eStartSched == eCurrentStartType ) {
  833. nResId = IDS_LOG_START_SCHED;
  834. }
  835. if ( 0 != nResId ) {
  836. m_strStartDisplay.LoadString(nResId);
  837. } else {
  838. m_strStartDisplay.Empty();
  839. }
  840. return;
  841. }
  842. void CCountersProperty::UpdateFileNameString ()
  843. {
  844. m_strFileNameDisplay.Empty();
  845. // Todo: Handle failure status
  846. // Todo: Check pointers
  847. CreateSampleFileName (
  848. m_pCtrLogQuery->GetLogName(),
  849. m_pCtrLogQuery->GetLogService()->GetMachineName(),
  850. m_SharedData.strFolderName,
  851. m_SharedData.strFileBaseName,
  852. m_SharedData.strSqlName,
  853. m_SharedData.dwSuffix,
  854. m_SharedData.dwLogFileType,
  855. m_SharedData.dwSerialNumber,
  856. m_strFileNameDisplay );
  857. SetDlgItemText( IDC_CTRS_FILENAME_DISPLAY, m_strFileNameDisplay );
  858. // Clear the selection
  859. ((CEdit*)GetDlgItem( IDC_CTRS_FILENAME_DISPLAY ))->SetSel ( -1, FALSE );
  860. return;
  861. }
  862. BOOL CCountersProperty::OnInitDialog()
  863. {
  864. LPWSTR szCounterName;
  865. CListBox * pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  866. CComboBox *pCombo;
  867. int nIndex;
  868. CString strComboBoxString;
  869. int nResult;
  870. DWORD dwItemExtent;
  871. PPDH_COUNTER_PATH_ELEMENTS pCounterPath;
  872. CDC* pCDC = NULL;
  873. ResourceStateManager rsm;
  874. //
  875. // Here m_pCtrLogQuery should not be NULL, if it is,
  876. // There must be something wrong.
  877. //
  878. if ( NULL == m_pCtrLogQuery ) {
  879. return TRUE;
  880. }
  881. m_bCanAccessRemoteWbem = m_pCtrLogQuery->GetLogService()->CanAccessWbemRemote();
  882. MFC_TRY
  883. m_pCtrLogQuery->SetActivePropertyPage( this );
  884. //load counter list box from string in counter list
  885. pCounterList->ResetContent();
  886. ClearCountersHashTable();
  887. szCounterName = (LPWSTR)m_pCtrLogQuery->GetFirstCounter();
  888. pCDC = pCounterList->GetDC();
  889. while (szCounterName != NULL) {
  890. nIndex = pCounterList->AddString(szCounterName);
  891. if (nIndex < 0)
  892. continue;
  893. //
  894. // Insert counter path into hash table
  895. //
  896. pCounterPath = InsertCounterToHashTable(szCounterName);
  897. if (pCounterPath == NULL) {
  898. pCounterList->DeleteString(nIndex);
  899. continue;
  900. }
  901. pCounterList->SetItemDataPtr(nIndex, (void*)pCounterPath);
  902. // update list box extent
  903. if ( NULL != pCDC ) {
  904. dwItemExtent = (DWORD)(pCDC->GetTextExtent (szCounterName)).cx;
  905. if (dwItemExtent > m_dwMaxHorizListExtent) {
  906. m_dwMaxHorizListExtent = dwItemExtent;
  907. }
  908. }
  909. szCounterName = (LPWSTR)m_pCtrLogQuery->GetNextCounter();
  910. }
  911. if ( NULL != pCDC ) {
  912. pCounterList->ReleaseDC(pCDC);
  913. pCDC = NULL;
  914. }
  915. if (m_dwMaxHorizListExtent != 0) {
  916. pCounterList->SetHorizontalExtent(m_dwMaxHorizListExtent);
  917. }
  918. if (pCounterList->GetCount() > 0) {
  919. // select first entry
  920. pCounterList->SetSel (0, TRUE);
  921. pCounterList->SetCaretIndex (0, TRUE);
  922. }
  923. // Load the shared data to get the sample unit type selection.
  924. m_pCtrLogQuery->GetPropPageSharedData ( &m_SharedData );
  925. // load combo boxes
  926. pCombo = (CComboBox *)(GetDlgItem(IDC_CTRS_SAMPLE_UNITS_COMBO));
  927. pCombo->ResetContent();
  928. for (nIndex = 0; nIndex < (int)dwTimeUnitComboEntries; nIndex++) {
  929. strComboBoxString.LoadString( TimeUnitCombo[nIndex].nResId );
  930. nResult = pCombo->InsertString (nIndex, (LPCWSTR)strComboBoxString);
  931. ASSERT (nResult != CB_ERR);
  932. nResult = pCombo->SetItemData (nIndex, (DWORD)TimeUnitCombo[nIndex].nData);
  933. ASSERT (nResult != CB_ERR);
  934. // set selected in combo box here
  935. if ( m_SharedData.stiSampleTime.dwUnitType == (DWORD)(TimeUnitCombo[nIndex].nData)) {
  936. m_nSampleUnits = nIndex;
  937. nResult = pCombo->SetCurSel(nIndex);
  938. ASSERT (nResult != CB_ERR);
  939. }
  940. }
  941. CSmPropertyPage::OnInitDialog();
  942. Initialize( m_pCtrLogQuery );
  943. m_strUserDisplay = m_pCtrLogQuery->m_strUser;
  944. m_strUserSaved = m_strUserDisplay;
  945. if (m_pCtrLogQuery->GetLogService()->IsWindows2000Server()) {
  946. CWnd* pRunAsStatic;
  947. //
  948. // Get the static "Run As" window, you can only call this function
  949. // when "Run As" really exists
  950. //
  951. pRunAsStatic = GetRunAsWindow();
  952. if (pRunAsStatic) {
  953. pRunAsStatic->EnableWindow(FALSE);
  954. }
  955. GetDlgItem(IDC_RUNAS_EDIT)->EnableWindow(FALSE);
  956. }
  957. if ( m_pCtrLogQuery->GetLogService()->IsWindows2000Server() ||
  958. m_strUserDisplay.IsEmpty() ||
  959. m_strUserDisplay.GetAt(0) == L'<') {
  960. GetDlgItem(IDC_SETPWD_BTN)->EnableWindow(FALSE);
  961. m_bPwdButtonEnabled = FALSE;
  962. }
  963. SetHelpIds ( (DWORD*)&s_aulHelpIds );
  964. SetButtonState();
  965. MFC_CATCH_MINIMUM;
  966. return TRUE; // return TRUE unless you set the focus to a control
  967. // EXCEPTION: OCX Property Pages should return FALSE
  968. }
  969. void
  970. CCountersProperty::OnDeltaposSchedSampleSpin(NMHDR* pNMHDR, LRESULT* pResult)
  971. {
  972. OnDeltaposSpin(pNMHDR, pResult, &m_SharedData.stiSampleTime.dwValue, eMinSampleInterval, eMaxSampleInterval);
  973. }
  974. void
  975. CCountersProperty::OnSelendokSampleUnitsCombo()
  976. {
  977. int nSel;
  978. nSel = ((CComboBox *)GetDlgItem(IDC_CTRS_SAMPLE_UNITS_COMBO))->GetCurSel();
  979. if ((nSel != LB_ERR) && (nSel != m_nSampleUnits)) {
  980. UpdateData ( TRUE );
  981. SetModifiedPage ( TRUE );
  982. }
  983. }
  984. void
  985. CCountersProperty::OnKillfocusSchedSampleEdit()
  986. {
  987. DWORD dwOldValue;
  988. dwOldValue = m_SharedData.stiSampleTime.dwValue;
  989. UpdateData ( TRUE );
  990. if (dwOldValue != m_SharedData.stiSampleTime.dwValue ) {
  991. SetModifiedPage(TRUE);
  992. }
  993. }
  994. void CCountersProperty::PostNcDestroy()
  995. {
  996. // delete this;
  997. if ( NULL != m_pCtrLogQuery ) {
  998. m_pCtrLogQuery->SetActivePropertyPage( NULL );
  999. }
  1000. CPropertyPage::PostNcDestroy();
  1001. }
  1002. //
  1003. // Helper functions.
  1004. //
  1005. void
  1006. CCountersProperty::ImplementAdd( BOOL bShowObjects )
  1007. {
  1008. CListBox *pCounterList;
  1009. LONG lBeforeCount;
  1010. LONG lAfterCount;
  1011. CString strBrowseTitle;
  1012. ResourceStateManager rsm;
  1013. if (m_szCounterListBuffer == NULL) {
  1014. CString strDefaultPath;
  1015. CString strObjCounter;
  1016. try {
  1017. strObjCounter.LoadString ( IDS_DEFAULT_PATH_OBJ_CTR );
  1018. m_dwCounterListBufferSize = 0x4000;
  1019. m_szCounterListBuffer = new WCHAR[m_dwCounterListBufferSize];
  1020. if ( ((CSmLogService*)m_pCtrLogQuery->GetLogService())->IsLocalMachine() ) {
  1021. strDefaultPath = _T("\\");
  1022. } else {
  1023. strDefaultPath = _T("\\\\");
  1024. strDefaultPath += ((CSmLogService*)m_pCtrLogQuery->GetLogService())->GetMachineName();
  1025. }
  1026. strDefaultPath += strObjCounter;
  1027. lstrcpy ( m_szCounterListBuffer, strDefaultPath);
  1028. } catch ( ... ) {
  1029. m_dwCounterListBufferSize = 0;
  1030. return;
  1031. }
  1032. }
  1033. m_dlgConfig.bIncludeInstanceIndex = 1;
  1034. m_dlgConfig.bSingleCounterPerAdd = 0;
  1035. m_dlgConfig.bSingleCounterPerDialog = 0;
  1036. m_dlgConfig.bLocalCountersOnly = 0;
  1037. // allow wild cards.
  1038. // the log service should expand them if necessary.
  1039. m_dlgConfig.bWildCardInstances = 1;
  1040. m_dlgConfig.bHideDetailBox = 1;
  1041. m_dlgConfig.bInitializePath = 1;
  1042. m_dlgConfig.bDisableMachineSelection = 0;
  1043. m_dlgConfig.bIncludeCostlyObjects = 0;
  1044. m_dlgConfig.bReserved = 0;
  1045. m_dlgConfig.hWndOwner = this->m_hWnd;
  1046. m_dlgConfig.szDataSource = NULL;
  1047. m_dlgConfig.szReturnPathBuffer = m_szCounterListBuffer;
  1048. m_dlgConfig.cchReturnPathLength = m_dwCounterListBufferSize;
  1049. m_dlgConfig.pCallBack = (CounterPathCallBack)DialogCallBack;
  1050. m_dlgConfig.dwDefaultDetailLevel = PERF_DETAIL_WIZARD;
  1051. m_dlgConfig.dwCallBackArg = (UINT_PTR)this;
  1052. m_dlgConfig.CallBackStatus = ERROR_SUCCESS;
  1053. m_dlgConfig.bShowObjectBrowser = (bShowObjects ? 1 : 0);
  1054. strBrowseTitle.LoadString (bShowObjects ? IDS_ADD_OBJECTS
  1055. : IDS_ADD_COUNTERS);
  1056. m_dlgConfig.szDialogBoxCaption = strBrowseTitle.GetBuffer( strBrowseTitle.GetLength() );
  1057. pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  1058. // get count of items in the list box before calling the browser
  1059. lBeforeCount = pCounterList->GetCount();
  1060. PdhBrowseCounters (&m_dlgConfig);
  1061. strBrowseTitle.ReleaseBuffer();
  1062. // get count of items in the list box After calling the browser
  1063. // to see if the Apply button should enabled
  1064. lAfterCount = pCounterList->GetCount();
  1065. if (lAfterCount > lBeforeCount)
  1066. SetModifiedPage(TRUE);
  1067. // see if the remove button should be enabled
  1068. SetButtonState();
  1069. delete m_szCounterListBuffer;
  1070. m_szCounterListBuffer = NULL;
  1071. m_dwCounterListBufferSize = 0;
  1072. }
  1073. void
  1074. CCountersProperty::SetButtonState ()
  1075. {
  1076. BOOL bCountersExist;
  1077. CListBox *pCounterList;
  1078. pCounterList = (CListBox *)GetDlgItem(IDC_CTRS_COUNTER_LIST);
  1079. bCountersExist = ( 0 < pCounterList->GetCount()) ? TRUE : FALSE;
  1080. GetDlgItem(IDC_CTRS_SAMPLE_CAPTION)->EnableWindow(bCountersExist);
  1081. GetDlgItem(IDC_CTRS_SAMPLE_INTERVAL_CAPTION)->EnableWindow(bCountersExist);
  1082. GetDlgItem(IDC_CTRS_SAMPLE_EDIT)->EnableWindow(bCountersExist);
  1083. GetDlgItem(IDC_CTRS_SAMPLE_SPIN)->EnableWindow(bCountersExist);
  1084. GetDlgItem(IDC_CTRS_SAMPLE_UNITS_CAPTION)->EnableWindow(bCountersExist);
  1085. GetDlgItem(IDC_CTRS_SAMPLE_UNITS_COMBO)->EnableWindow(bCountersExist);
  1086. GetDlgItem(IDC_CTRS_REMOVE_BTN)->EnableWindow(bCountersExist);
  1087. if ( bCountersExist ) {
  1088. GetDlgItem(IDC_CTRS_ADD_BTN)->SetFocus();
  1089. }
  1090. }