Leaked source code of windows server 2003
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.

1845 lines
53 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. report.cpp
  5. Abstract:
  6. Implements the report view.
  7. --*/
  8. //==========================================================================//
  9. // Includes //
  10. //==========================================================================//
  11. #include "polyline.h"
  12. #include <strsafe.h>
  13. #include <commctrl.h>
  14. #include <pdhmsg.h>
  15. #include "report.h"
  16. #include "grphitem.h"
  17. #include "winhelpr.h"
  18. #define eScaleValueSpace L">9999999999.0"
  19. #define szReportClass L"SysmonReport"
  20. #define szReportClassA "SysmonReport"
  21. #define HEXMASK (0x00030C00)
  22. static INT xBorderWidth = GetSystemMetrics(SM_CXBORDER);
  23. static INT yBorderHeight = GetSystemMetrics(SM_CYBORDER);
  24. static INT xColumnMargin = 10;
  25. static INT xCounterMargin = 50;
  26. static INT xObjectMargin = 25;
  27. static WCHAR LineEndStr[] = L"\n" ;
  28. static WCHAR TabStr[] = L"\t";
  29. LRESULT APIENTRY HdrWndProc (HWND, WORD, WPARAM, LONG);
  30. //==========================================================================//
  31. // Constants //
  32. //==========================================================================//
  33. #define dwReportClassStyle (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS)
  34. #define iReportWindowExtra (sizeof (PREPORT))
  35. #define dwReportWindowStyle (WS_CHILD | WS_HSCROLL | WS_VSCROLL)
  36. #define szValuePlaceholder L"-999,999,999.999"
  37. #define szValueLargeHexPlaceholder L" xBBBBBBBBDDDDDDDD"
  38. #define dLargeValueMax ((double) 999999999.0)
  39. #define szDashLine L"---"
  40. CReport::CReport (
  41. void
  42. )
  43. {
  44. m_pCtrl = NULL;
  45. m_hWnd = NULL;
  46. m_yLineHeight = 0;
  47. m_xReportWidth = 0;
  48. m_yReportHeight = 0;
  49. m_pSelect = NULL;
  50. }
  51. //
  52. // Destructor
  53. //
  54. CReport::~CReport (void )
  55. {
  56. if (m_hWnd != NULL && IsWindow(m_hWnd))
  57. DestroyWindow(m_hWnd);
  58. }
  59. //
  60. // Initialization
  61. //
  62. BOOL CReport::Init ( PSYSMONCTRL pCtrl, HWND hWndParent )
  63. {
  64. WNDCLASS wc ;
  65. LONG lExStyles;
  66. // Save pointer to parent control
  67. m_pCtrl = pCtrl;
  68. BEGIN_CRITICAL_SECTION
  69. // Register window class once
  70. if (pstrRegisteredClasses[REPORT_WNDCLASS] == NULL) {
  71. wc.style = dwReportClassStyle ;
  72. wc.lpfnWndProc = ReportWndProc ;
  73. wc.hInstance = g_hInstance ;
  74. wc.cbClsExtra = 0;
  75. wc.cbWndExtra = iReportWindowExtra ;
  76. wc.hIcon = NULL ;
  77. wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;
  78. wc.hbrBackground = NULL ;
  79. wc.lpszMenuName = NULL ;
  80. wc.lpszClassName = szReportClass ;
  81. if (RegisterClass (&wc)) {
  82. pstrRegisteredClasses[REPORT_WNDCLASS] = szReportClass;
  83. }
  84. // Ensure controls are initialized
  85. InitCommonControls();
  86. }
  87. END_CRITICAL_SECTION
  88. if (pstrRegisteredClasses[REPORT_WNDCLASS] == NULL)
  89. return FALSE;
  90. // Create our window
  91. m_hWnd = CreateWindow (szReportClass, // class
  92. NULL, // caption
  93. dwReportWindowStyle, // window style
  94. 0, 0, // position
  95. 0, 0, // size
  96. hWndParent, // parent window
  97. NULL, // menu
  98. g_hInstance, // program instance
  99. (LPVOID) this ); // user-supplied data
  100. if (m_hWnd == NULL)
  101. return FALSE;
  102. // Turn off layout mirroring if it is enabled
  103. lExStyles = GetWindowLong(m_hWnd, GWL_EXSTYLE);
  104. if ( 0 != ( lExStyles & WS_EX_LAYOUTRTL ) ) {
  105. lExStyles &= ~WS_EX_LAYOUTRTL;
  106. SetWindowLong(m_hWnd, GWL_EXSTYLE, lExStyles);
  107. }
  108. return TRUE;
  109. }
  110. void CReport::ChangeFont (
  111. void
  112. )
  113. {
  114. if (!m_bFontChange) {
  115. m_bFontChange = TRUE;
  116. if (!m_bConfigChange) {
  117. m_bConfigChange = TRUE;
  118. WindowInvalidate(m_hWnd);
  119. }
  120. }
  121. }
  122. void
  123. CReport::SizeComponents (
  124. LPRECT pRect )
  125. {
  126. INT xWidth;
  127. INT yHeight;
  128. m_rect = *pRect;
  129. xWidth = pRect->right - pRect->left;
  130. yHeight = pRect->bottom - pRect->top;
  131. // If no space, hide window and leave
  132. if (xWidth == 0 || yHeight == 0) {
  133. WindowShow(m_hWnd, FALSE);
  134. return;
  135. }
  136. // Show window to assigned position
  137. MoveWindow(m_hWnd, pRect->left, pRect->top, xWidth, yHeight, FALSE);
  138. WindowShow(m_hWnd, TRUE);
  139. WindowInvalidate(m_hWnd);
  140. SetScrollRanges();
  141. }
  142. INT
  143. CReport::SetCounterPositions (
  144. PCObjectNode pObject,
  145. HDC hDC )
  146. {
  147. PCCounterNode pCounter;
  148. INT yPos;
  149. yPos = pObject->m_yPos + m_yLineHeight;
  150. for (pCounter = pObject->FirstCounter();
  151. pCounter;
  152. pCounter = pCounter->Next()) {
  153. if (m_bFontChange || pCounter->m_xWidth == -1) {
  154. pCounter->m_xWidth = TextWidth(hDC, pCounter->Name());
  155. }
  156. if (pCounter->m_xWidth > m_xMaxCounterWidth)
  157. m_xMaxCounterWidth = pCounter->m_xWidth;
  158. pCounter->m_yPos = yPos;
  159. yPos += m_yLineHeight;
  160. }
  161. return yPos;
  162. }
  163. INT
  164. CReport::SetInstancePositions (
  165. PCObjectNode pObject,
  166. HDC hDC )
  167. {
  168. INT xPos ;
  169. PCInstanceNode pInstance;
  170. LPWSTR szParent;
  171. LPWSTR szInstance;
  172. xPos = 0;
  173. for (pInstance = pObject->FirstInstance();
  174. pInstance;
  175. pInstance = pInstance->Next()) {
  176. if (m_bFontChange || pInstance->m_xWidth == -1) {
  177. if (pInstance->HasParent()) {
  178. szParent = pInstance->GetParentName();
  179. szInstance = pInstance->GetInstanceName();
  180. pInstance->m_xWidth = max(TextWidth(hDC, szParent), TextWidth(hDC, szInstance));
  181. } else {
  182. pInstance->m_xWidth = TextWidth(hDC, pInstance->Name());
  183. }
  184. }
  185. pInstance->m_xPos = xPos + max(pInstance->m_xWidth, m_xValueWidth);
  186. xPos = pInstance->m_xPos + xColumnMargin;
  187. }
  188. if (xPos > m_xMaxInstancePos)
  189. m_xMaxInstancePos = xPos;
  190. return xPos;
  191. }
  192. INT
  193. CReport::SetObjectPositions (
  194. PCMachineNode pMachine,
  195. HDC hDC
  196. )
  197. {
  198. PCObjectNode pObject;
  199. INT yPos;
  200. INT xPos;
  201. yPos = pMachine->m_yPos + m_yLineHeight;
  202. for (pObject = pMachine->FirstObject();
  203. pObject ;
  204. pObject = pObject->Next()) {
  205. if (m_bFontChange || pObject->m_xWidth == -1) {
  206. pObject->m_xWidth = TextWidth(hDC, pObject->Name());
  207. }
  208. if (!pObject->FirstInstance()->HasParent())
  209. pObject->m_yPos = yPos;
  210. else
  211. pObject->m_yPos = yPos + m_yLineHeight;
  212. yPos = SetCounterPositions (pObject, hDC) ;
  213. xPos = SetInstancePositions(pObject, hDC);
  214. yPos += m_yLineHeight;
  215. }
  216. return yPos;
  217. }
  218. INT
  219. CReport::SetMachinePositions (
  220. PCCounterTree pTree,
  221. HDC hDC
  222. )
  223. {
  224. PCMachineNode pMachine ;
  225. INT yPos ;
  226. yPos = m_yLineHeight;
  227. for (pMachine = pTree->FirstMachine() ;
  228. pMachine ;
  229. pMachine = pMachine->Next()) {
  230. if (m_bFontChange || pMachine->m_xWidth == -1) {
  231. pMachine->m_xWidth = TextWidth(hDC, pMachine->Name());
  232. }
  233. pMachine->m_yPos = yPos;
  234. yPos = SetObjectPositions (pMachine, hDC);
  235. }
  236. m_yReportHeight = yPos + yBorderHeight;
  237. return yPos;
  238. }
  239. void
  240. CReport::DrawSelectRect (
  241. HDC hDC,
  242. BOOL bState
  243. )
  244. {
  245. BOOL bSuccess = TRUE;
  246. RECT rect = {0,0,0,0};
  247. HBRUSH hbrush;
  248. if ( NULL != m_pSelect && NULL != hDC ) {
  249. switch ( m_nSelectType ) {
  250. case MACHINE_NODE:
  251. rect.left = xColumnMargin;
  252. rect.top = ((PCMachineNode)m_pSelect)->m_yPos;
  253. rect.right = rect.left + ((PCMachineNode)m_pSelect)->m_xWidth;
  254. rect.bottom = rect.top + m_yLineHeight;
  255. break;
  256. case OBJECT_NODE:
  257. rect.left = xObjectMargin;
  258. rect.top = ((PCObjectNode)m_pSelect)->m_yPos;
  259. rect.right = rect.left + ((PCObjectNode)m_pSelect)->m_xWidth;
  260. rect.bottom = rect.top + m_yLineHeight;
  261. break;
  262. case INSTANCE_NODE:
  263. rect.right = m_xInstanceMargin + ((PCInstanceNode)m_pSelect)->m_xPos;
  264. rect.bottom = ((PCInstanceNode)m_pSelect)->m_pObject->m_yPos + m_yLineHeight;
  265. rect.left = rect.right - ((PCInstanceNode)m_pSelect)->m_xWidth;
  266. rect.top = rect.bottom -
  267. (((PCInstanceNode)m_pSelect)->HasParent() ? (2*m_yLineHeight) : m_yLineHeight);
  268. break;
  269. case COUNTER_NODE:
  270. rect.left = xCounterMargin;
  271. rect.top = ((PCCounterNode)m_pSelect)->m_yPos;
  272. rect.right = rect.left + ((PCCounterNode)m_pSelect)->m_xWidth;
  273. rect.bottom = rect.top + m_yLineHeight;
  274. break;
  275. case ITEM_NODE:
  276. rect.right = m_xInstanceMargin + ((PCGraphItem)m_pSelect)->m_pInstance->m_xPos;
  277. rect.top = ((PCGraphItem)m_pSelect)->m_pCounter->m_yPos;
  278. rect.left = rect.right - m_xValueWidth;
  279. rect.bottom = rect.top + m_yLineHeight;
  280. break;
  281. default:
  282. bSuccess = FALSE;
  283. }
  284. if ( bSuccess ) {
  285. rect.left -= 1;
  286. rect.right += 1;
  287. hbrush = CreateSolidBrush(bState ? m_pCtrl->clrFgnd() : m_pCtrl->clrBackPlot());
  288. if ( NULL != hbrush ) {
  289. FrameRect(hDC, &rect, hbrush);
  290. DeleteObject(hbrush);
  291. }
  292. }
  293. }
  294. return;
  295. }
  296. BOOL
  297. CReport::LargeHexValueExists ( void )
  298. {
  299. PCMachineNode pMachine = NULL;
  300. PCObjectNode pObject = NULL;
  301. PCInstanceNode pInstance = NULL;
  302. PCCounterNode pCounter = NULL;
  303. PCGraphItem pItem = NULL;
  304. BOOL bLargeHexValueExists = FALSE;
  305. for (pMachine = m_pCtrl->CounterTree()->FirstMachine();
  306. pMachine && !bLargeHexValueExists;
  307. pMachine = pMachine->Next()) {
  308. for (pObject = pMachine->FirstObject();
  309. pObject && !bLargeHexValueExists;
  310. pObject = pObject->Next()) {
  311. for (pInstance = pObject->FirstInstance();
  312. pInstance && !bLargeHexValueExists;
  313. pInstance = pInstance->Next()) {
  314. pItem = pInstance->FirstItem();
  315. for (pCounter = pObject->FirstCounter();
  316. pCounter && !bLargeHexValueExists;
  317. pCounter = pCounter->Next()) {
  318. PCGraphItem pCheckItem = NULL;
  319. if (pItem && pItem->m_pCounter == pCounter) {
  320. pCheckItem = pItem;
  321. pItem = pItem->m_pNextItem;
  322. }
  323. if ( pCheckItem ) {
  324. if ( !( pCheckItem->m_CounterInfo.dwType & HEXMASK ) ) {
  325. bLargeHexValueExists = pCheckItem->m_CounterInfo.dwType & PERF_SIZE_LARGE;
  326. if ( bLargeHexValueExists ) {
  327. break;
  328. }
  329. }
  330. }
  331. }
  332. }
  333. }
  334. }
  335. return bLargeHexValueExists;
  336. }
  337. void
  338. CReport::DrawReportValue (
  339. HDC hDC,
  340. PCGraphItem pItem,
  341. INT xPos,
  342. INT yPos )
  343. {
  344. double dMax;
  345. double dMin;
  346. double dValue = -1.0;
  347. WCHAR szValue [MAX_VALUE_LEN] = L"_" ;
  348. HRESULT hr;
  349. long lCtrStat;
  350. RECT rect ;
  351. INT iPrecision;
  352. if ( NULL != pItem && NULL != hDC ) {
  353. eReportValueTypeConstant eValueType;
  354. eValueType = m_pCtrl->ReportValueType();
  355. if ( sysmonDefaultValue == eValueType ) {
  356. // if log source display the average value
  357. // else display the current value
  358. if (m_pCtrl->IsLogSource()) {
  359. hr = pItem->GetStatistics(&dMax, &dMin, &dValue, &lCtrStat);
  360. } else {
  361. hr = pItem->GetValue(&dValue, &lCtrStat);
  362. }
  363. } else {
  364. if ( sysmonCurrentValue == eValueType ) {
  365. hr = pItem->GetValue(&dValue, &lCtrStat);
  366. } else {
  367. double dAvg;
  368. hr = pItem->GetStatistics(&dMax, &dMin, &dAvg, &lCtrStat);
  369. switch ( eValueType ) {
  370. case sysmonAverage:
  371. dValue = dAvg;
  372. break;
  373. case sysmonMinimum:
  374. dValue = dMin;
  375. break;
  376. case sysmonMaximum:
  377. dValue = dMax;
  378. break;
  379. default:
  380. assert (FALSE);
  381. }
  382. }
  383. }
  384. if (SUCCEEDED(hr) && IsSuccessSeverity(lCtrStat)) {
  385. assert ( 0 <= dValue );
  386. if ( ( pItem->m_CounterInfo.dwType & ( PERF_TYPE_COUNTER | PERF_TYPE_TEXT ) ) ) {
  387. (dValue > dLargeValueMax) ? iPrecision = 0 : iPrecision = 3;
  388. } else {
  389. // for Numbers, no decimal places
  390. iPrecision = 0;
  391. }
  392. if(PDH_CSTATUS_INVALID_DATA != pItem->m_CounterInfo.CStatus ) {
  393. // Check for Hex values
  394. if ( !(pItem->m_CounterInfo.dwType & HEXMASK) ) {
  395. BOOL bLarge = pItem->m_CounterInfo.dwType & PERF_SIZE_LARGE;
  396. FormatHex ( dValue, szValue, bLarge);
  397. } else {
  398. FormatNumber ( dValue, szValue, MAX_VALUE_LEN, 12, iPrecision );
  399. }
  400. }
  401. }
  402. else {
  403. StringCchCopy(szValue, MAX_VALUE_LEN, szDashLine);
  404. }
  405. }
  406. else {
  407. StringCchCopy(szValue, MAX_VALUE_LEN, szDashLine);
  408. }
  409. rect.right = xPos - 1;
  410. rect.left = xPos - m_xValueWidth + 1;
  411. rect.top = yPos;
  412. rect.bottom = yPos + m_yLineHeight;
  413. ExtTextOut (hDC, rect.right, rect.top, ETO_CLIPPED | ETO_OPAQUE,
  414. &rect, szValue, lstrlen (szValue), NULL) ;
  415. }
  416. void
  417. CReport::DrawReportValues (
  418. HDC hDC )
  419. {
  420. PCMachineNode pMachine;
  421. PCObjectNode pObject;
  422. PCInstanceNode pInstance;
  423. PCCounterNode pCounter;
  424. PCGraphItem pItem;
  425. PCGraphItem pDrawItem;
  426. if ( NULL != hDC ) {
  427. SelectFont (hDC, m_pCtrl->Font());
  428. SetTextAlign (hDC, TA_RIGHT|TA_TOP);
  429. for (pMachine = m_pCtrl->CounterTree()->FirstMachine();
  430. pMachine;
  431. pMachine = pMachine->Next()) {
  432. for (pObject = pMachine->FirstObject();
  433. pObject;
  434. pObject = pObject->Next()) {
  435. for (pInstance = pObject->FirstInstance();
  436. pInstance;
  437. pInstance = pInstance->Next()) {
  438. pItem = pInstance->FirstItem();
  439. for ( pCounter = pObject->FirstCounter();
  440. pCounter;
  441. pCounter = pCounter->Next()) {
  442. if (pItem && pItem->m_pCounter == pCounter) {
  443. pDrawItem = pItem;
  444. pItem = pItem->m_pNextItem;
  445. } else {
  446. pDrawItem = NULL;
  447. }
  448. DrawReportValue (
  449. hDC,
  450. pDrawItem,
  451. m_xInstanceMargin + pInstance->m_xPos,
  452. pCounter->m_yPos);
  453. }
  454. }
  455. }
  456. }
  457. }
  458. }
  459. LPWSTR GetBuffer(LPWSTR pBuffer, LONG* lBufSize, LONG lSize)
  460. {
  461. LPWSTR pNew;
  462. if (lSize < *(lBufSize)) {
  463. return pBuffer;
  464. }
  465. if (pBuffer) {
  466. delete [] pBuffer;
  467. *(lBufSize) = 0;
  468. }
  469. pNew = new WCHAR [lSize];
  470. if (pNew == NULL) {
  471. return NULL;
  472. }
  473. *(lBufSize) = lSize;
  474. return pNew;
  475. }
  476. BOOL
  477. CReport::WriteFileReport ( HANDLE hFile )
  478. {
  479. PCMachineNode pMachine;
  480. PCObjectNode pObject;
  481. PCInstanceNode pInstance;
  482. PCCounterNode pCounter;
  483. LPWSTR pszTemp = NULL;
  484. LONG lSize = 0;
  485. LONG lBufSize = 0;
  486. PCGraphItem pItem;
  487. BOOL bStatus = TRUE;
  488. WCHAR szValue[MAX_VALUE_LEN];
  489. lBufSize = MAX_PATH;
  490. pszTemp = new WCHAR [lBufSize];
  491. if (pszTemp == NULL) {
  492. return FALSE;
  493. }
  494. for (pMachine = m_pCtrl->CounterTree()->FirstMachine() ;
  495. pMachine && TRUE == bStatus;
  496. pMachine = pMachine->Next()) {
  497. lSize = 3 * lstrlen(LineEndStr) +
  498. lstrlen(ResourceString(IDS_COMPUTER)) +
  499. lstrlen(pMachine->Name()) + 1;
  500. pszTemp = GetBuffer(pszTemp, &lBufSize, lSize);
  501. if (pszTemp == NULL) {
  502. goto ErrorOut;
  503. }
  504. StringCchCopy(pszTemp, lBufSize, LineEndStr);
  505. StringCchCat(pszTemp, lBufSize, LineEndStr);
  506. StringCchCat(pszTemp, lBufSize, ResourceString(IDS_COMPUTER));
  507. StringCchCat(pszTemp, lBufSize, pMachine->Name());
  508. StringCchCat(pszTemp, lBufSize, LineEndStr);
  509. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  510. for (pObject = pMachine->FirstObject() ;
  511. pObject && TRUE == bStatus;
  512. pObject = pObject->Next()) {
  513. // Write the object name line.
  514. lSize = 2 * lstrlen(LineEndStr) +
  515. lstrlen(TabStr) +
  516. lstrlen(ResourceString(IDS_OBJECT_NAME)) +
  517. lstrlen(pObject->Name()) + 1;
  518. pszTemp = GetBuffer(pszTemp, &lBufSize, lSize);
  519. if (pszTemp == NULL) {
  520. goto ErrorOut;
  521. }
  522. StringCchCopy(pszTemp, lBufSize, LineEndStr);
  523. StringCchCat(pszTemp, lBufSize, ResourceString(IDS_OBJECT_NAME));
  524. StringCchCat(pszTemp, lBufSize, pObject->Name());
  525. StringCchCat(pszTemp, lBufSize, LineEndStr);
  526. // Add first tab char for instance names.
  527. StringCchCat(pszTemp, lBufSize, TabStr);
  528. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  529. if (!bStatus)
  530. break;
  531. // Write the first line of instance (parent) names.
  532. for (pInstance = pObject->FirstInstance();
  533. pInstance && TRUE == bStatus;
  534. pInstance = pInstance->Next()) {
  535. // If instance has no parent, then the parent name is null, so a tab is written.
  536. lSize = lstrlen(TabStr) +
  537. lstrlen(LineEndStr) +
  538. lstrlen(pInstance->GetParentName()) + 1;
  539. pszTemp = GetBuffer(pszTemp, &lBufSize, lSize);
  540. if (pszTemp == NULL) {
  541. goto ErrorOut;
  542. }
  543. StringCchCopy(pszTemp, lBufSize, TabStr);
  544. StringCchCat(pszTemp, lBufSize, pInstance->GetParentName());
  545. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  546. }
  547. if ( !bStatus )
  548. break;
  549. StringCchCopy(pszTemp, lBufSize, LineEndStr);
  550. // Include first tab of second instance line.
  551. StringCchCat(pszTemp, lBufSize, TabStr);
  552. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  553. // Write the second line of instance names.
  554. for (pInstance = pObject->FirstInstance();
  555. pInstance && TRUE == bStatus;
  556. pInstance = pInstance->Next()) {
  557. lSize = lstrlen(TabStr) +
  558. lstrlen(LineEndStr)+
  559. lstrlen(pInstance->GetInstanceName()) + 1;
  560. pszTemp = GetBuffer(pszTemp, &lBufSize, lSize);
  561. if (pszTemp == NULL) {
  562. goto ErrorOut;
  563. }
  564. StringCchCopy(pszTemp, lBufSize, TabStr);
  565. StringCchCat(pszTemp, lBufSize, pInstance->GetInstanceName());
  566. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  567. }
  568. if (!bStatus)
  569. break;
  570. StringCchCopy(pszTemp, lBufSize, LineEndStr);
  571. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  572. for (pCounter = pObject->FirstCounter();
  573. pCounter && TRUE == bStatus;
  574. pCounter = pCounter->Next()) {
  575. lSize = lstrlen(TabStr) +
  576. lstrlen(LineEndStr)+
  577. lstrlen(pCounter->Name()) + 1;
  578. pszTemp = GetBuffer(pszTemp, &lBufSize, lSize);
  579. if (pszTemp == NULL) {
  580. goto ErrorOut;
  581. }
  582. // Write counter name
  583. StringCchCopy(pszTemp, lBufSize, TabStr);
  584. StringCchCat(pszTemp, lBufSize, pCounter->Name());
  585. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  586. // Write values, looping on instances
  587. for ( pInstance = pObject->FirstInstance();
  588. pInstance && TRUE == bStatus;
  589. pInstance = pInstance->Next()) {
  590. // Loop on items to find the item that matches the counter.
  591. for ( pItem = pInstance->FirstItem();
  592. pItem && TRUE == bStatus;
  593. pItem = pItem->m_pNextItem) {
  594. if ( pItem->m_pCounter == pCounter && pInstance) {
  595. GetReportItemValue(pItem,szValue );
  596. lSize = lstrlen(TabStr) +
  597. lstrlen(LineEndStr)+
  598. lstrlen(szValue) + 1;
  599. pszTemp = GetBuffer(pszTemp, &lBufSize, lSize);
  600. if (pszTemp == NULL) {
  601. goto ErrorOut;
  602. }
  603. StringCchCopy(pszTemp, lBufSize, TabStr);
  604. StringCchCat(pszTemp, lBufSize, szValue);
  605. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  606. }
  607. }
  608. }
  609. if (!bStatus)
  610. break;
  611. StringCchCopy(pszTemp, lBufSize, LineEndStr);
  612. bStatus = FileWrite ( hFile, pszTemp, lstrlen (pszTemp) * sizeof(WCHAR) );
  613. }
  614. }
  615. }
  616. if (pszTemp) {
  617. delete [] pszTemp;
  618. }
  619. return bStatus;
  620. ErrorOut:
  621. if (pszTemp) {
  622. delete [] pszTemp;
  623. }
  624. return FALSE;
  625. }
  626. void
  627. CReport::GetReportItemValue(PCGraphItem pItem, LPWSTR szValue)
  628. {
  629. double dMax;
  630. double dMin;
  631. double dValue = -1.0;
  632. HRESULT hr;
  633. long lCtrStat;
  634. INT iPrecision;
  635. if (pItem) {
  636. eReportValueTypeConstant eValueType;
  637. eValueType = m_pCtrl->ReportValueType();
  638. if ( sysmonDefaultValue == eValueType ) {
  639. // if log source display the average value
  640. // else display the current value
  641. if (m_pCtrl->IsLogSource()) {
  642. hr = pItem->GetStatistics(&dMax, &dMin, &dValue, &lCtrStat);
  643. } else {
  644. hr = pItem->GetValue(&dValue, &lCtrStat);
  645. }
  646. } else {
  647. if ( sysmonCurrentValue == eValueType ) {
  648. hr = pItem->GetValue(&dValue, &lCtrStat);
  649. } else {
  650. double dAvg;
  651. hr = pItem->GetStatistics(&dMax, &dMin, &dAvg, &lCtrStat);
  652. switch ( eValueType ) {
  653. case sysmonAverage:
  654. dValue = dAvg;
  655. break;
  656. case sysmonMinimum:
  657. dValue = dMin;
  658. break;
  659. case sysmonMaximum:
  660. dValue = dMax;
  661. break;
  662. default:
  663. assert (FALSE);
  664. }
  665. }
  666. }
  667. if (SUCCEEDED(hr) && IsSuccessSeverity(lCtrStat)) {
  668. assert ( 0 <= dValue );
  669. (dValue > dLargeValueMax) ? iPrecision = 0 : iPrecision = 3;
  670. if(PDH_CSTATUS_INVALID_DATA != pItem->m_CounterInfo.CStatus ) {
  671. // Check for Hex values
  672. if ( !(pItem->m_CounterInfo.dwType & HEXMASK) ) {
  673. BOOL bLarge = pItem->m_CounterInfo.dwType & PERF_SIZE_LARGE;
  674. FormatHex (
  675. dValue,
  676. szValue,
  677. bLarge);
  678. } else {
  679. FormatNumber (
  680. dValue,
  681. szValue,
  682. MAX_VALUE_LEN,
  683. 12,
  684. iPrecision );
  685. }
  686. }
  687. } else {
  688. StringCchCopy(szValue, MAX_VALUE_LEN, szDashLine);
  689. }
  690. } else {
  691. StringCchCopy(szValue, MAX_VALUE_LEN, szDashLine);
  692. }
  693. return;
  694. }
  695. void
  696. CReport::DrawReportHeaders (
  697. HDC hDC )
  698. {
  699. PCMachineNode pMachine;
  700. PCObjectNode pObject;
  701. PCInstanceNode pInstance;
  702. PCCounterNode pCounter;
  703. INT cName;
  704. RECT rectMachine;
  705. RECT rectObject;
  706. RECT rectInstance;
  707. RECT rectCounter;
  708. if ( NULL != hDC ) {
  709. SetTextAlign(hDC, TA_LEFT|TA_TOP) ;
  710. rectMachine.left = xColumnMargin;
  711. rectObject.left = xObjectMargin;
  712. rectCounter.left = xCounterMargin;
  713. for ( pMachine = m_pCtrl->CounterTree()->FirstMachine() ;
  714. pMachine;
  715. pMachine = pMachine->Next()) {
  716. rectMachine.right = rectMachine.left + pMachine->m_xWidth;
  717. rectMachine.top = pMachine->m_yPos;
  718. rectMachine.bottom = pMachine->m_yPos + m_yLineHeight;
  719. ExtTextOut (
  720. hDC,
  721. xColumnMargin,
  722. pMachine->m_yPos,
  723. ETO_OPAQUE,
  724. &rectMachine,
  725. pMachine->Name(),
  726. lstrlen(pMachine->Name()),
  727. NULL );
  728. for ( pObject = pMachine->FirstObject() ;
  729. pObject ;
  730. pObject = pObject->Next()) {
  731. rectObject.right = rectObject.left + pObject->m_xWidth;
  732. rectObject.top = pObject->m_yPos;
  733. rectObject.bottom = pObject->m_yPos + m_yLineHeight;
  734. ExtTextOut (
  735. hDC,
  736. xObjectMargin,
  737. pObject->m_yPos,
  738. ETO_OPAQUE,
  739. &rectObject,
  740. pObject->Name(),
  741. lstrlen (pObject->Name()),
  742. NULL);
  743. SetTextAlign (hDC, TA_RIGHT) ;
  744. for ( pInstance = pObject->FirstInstance();
  745. pInstance;
  746. pInstance = pInstance->Next()) {
  747. rectInstance.left = m_xInstanceMargin + pInstance->m_xPos;
  748. rectInstance.right = rectInstance.left + max(pInstance->m_xWidth, m_xValueWidth);
  749. if ( pInstance->HasParent() ) {
  750. cName = lstrlen(pInstance->GetParentName());
  751. rectInstance.top = pObject->m_yPos - m_yLineHeight;
  752. rectInstance.bottom = rectInstance.top + m_yLineHeight;
  753. ExtTextOut (
  754. hDC,
  755. m_xInstanceMargin + pInstance->m_xPos,
  756. pObject->m_yPos - m_yLineHeight,
  757. ETO_OPAQUE,
  758. &rectInstance,
  759. pInstance->GetParentName(),
  760. cName,
  761. NULL);
  762. rectInstance.top = pObject->m_yPos;
  763. rectInstance.bottom = rectInstance.top + m_yLineHeight;
  764. cName = lstrlen(pInstance->GetInstanceName());
  765. ExtTextOut (
  766. hDC,
  767. m_xInstanceMargin + pInstance->m_xPos,
  768. pObject->m_yPos,
  769. ETO_OPAQUE,
  770. &rectInstance,
  771. pInstance->GetInstanceName(),
  772. cName,
  773. NULL );
  774. } else {
  775. rectInstance.top = pObject->m_yPos;
  776. rectInstance.bottom = rectInstance.top + m_yLineHeight;
  777. ExtTextOut (
  778. hDC,
  779. m_xInstanceMargin + pInstance->m_xPos,
  780. pObject->m_yPos,
  781. ETO_OPAQUE,
  782. &rectInstance,
  783. pInstance->Name(),
  784. lstrlen(pInstance->Name()),
  785. NULL );
  786. }
  787. }
  788. SetTextAlign (hDC, TA_LEFT) ;
  789. for (pCounter = pObject->FirstCounter();
  790. pCounter ;
  791. pCounter = pCounter->Next()) {
  792. rectCounter.right = rectCounter.left + pCounter->m_xWidth;
  793. rectCounter.top = pCounter->m_yPos;
  794. rectCounter.bottom = pCounter->m_yPos + m_yLineHeight;
  795. ExtTextOut (
  796. hDC,
  797. xCounterMargin,
  798. pCounter->m_yPos,
  799. ETO_OPAQUE,
  800. &rectCounter,
  801. pCounter->Name(),
  802. lstrlen (pCounter->Name()),
  803. NULL);
  804. }
  805. }
  806. }
  807. DrawSelectRect(hDC, TRUE);
  808. }
  809. }
  810. void
  811. CReport::ApplyChanges (
  812. HDC hDC )
  813. {
  814. if (m_bConfigChange && NULL != hDC ) {
  815. // Selected the Bold font for font change , counter add, and counter delete.
  816. // This is used for recalculating text width.
  817. SelectFont (hDC, m_pCtrl->BoldFont());
  818. m_yLineHeight = FontHeight (hDC, TRUE);
  819. if ( LargeHexValueExists ( ) ) {
  820. m_xValueWidth = TextWidth(hDC, szValueLargeHexPlaceholder);
  821. } else {
  822. m_xValueWidth = TextWidth(hDC, szValuePlaceholder);
  823. }
  824. m_xMaxCounterWidth = 0;
  825. m_xMaxInstancePos = 0;
  826. SetMachinePositions (m_pCtrl->CounterTree(), hDC);
  827. m_xInstanceMargin = xCounterMargin + m_xMaxCounterWidth + xColumnMargin;
  828. m_xReportWidth = m_xInstanceMargin + m_xMaxInstancePos;
  829. SetScrollRanges();
  830. m_bConfigChange = FALSE;
  831. m_bFontChange = FALSE;
  832. }
  833. }
  834. void
  835. CReport::Render (
  836. HDC hDC,
  837. HDC hAttribDC,
  838. BOOL /*fMetafile*/,
  839. BOOL /*fEntire*/,
  840. LPRECT prcUpdate )
  841. {
  842. ApplyChanges(hAttribDC);
  843. if ( NULL != hDC ) {
  844. SetBkColor(hDC, m_pCtrl->clrBackPlot());
  845. ClearRect(hDC, prcUpdate);
  846. Draw( hDC );
  847. }
  848. }
  849. void
  850. CReport::Draw (
  851. HDC hDC )
  852. {
  853. // if no space assigned, return
  854. if (m_rect.top != m_rect.bottom) {
  855. if ( NULL != hDC ) {
  856. SetTextColor (hDC, m_pCtrl->clrFgnd());
  857. SetBkColor(hDC, m_pCtrl->clrBackPlot());
  858. SelectFont(hDC, m_pCtrl->BoldFont());
  859. DrawReportHeaders (hDC);
  860. SelectFont (hDC, m_pCtrl->Font());
  861. DrawReportValues (hDC);
  862. m_pCtrl->DrawBorder ( hDC );
  863. }
  864. }
  865. }
  866. void
  867. CReport::AddItem (
  868. PCGraphItem /* pItem */ )
  869. {
  870. if (!m_bConfigChange) {
  871. m_bConfigChange = TRUE;
  872. WindowInvalidate(m_hWnd);
  873. }
  874. }
  875. void
  876. CReport::DeleteItem (
  877. PCGraphItem pItem )
  878. {
  879. // Calling procedure checks for NULL pItem
  880. assert ( NULL != pItem );
  881. if ( NULL != m_pSelect ) {
  882. if ( SelectionDeleted ( pItem ) ) {
  883. m_pSelect = NULL;
  884. }
  885. }
  886. if (!m_bConfigChange) {
  887. m_bConfigChange = TRUE;
  888. WindowInvalidate(m_hWnd);
  889. }
  890. }
  891. void
  892. CReport::DeleteSelection (
  893. VOID )
  894. {
  895. if (m_pSelect == NULL)
  896. return;
  897. switch (m_nSelectType) {
  898. case MACHINE_NODE:
  899. ((PCMachineNode)m_pSelect)->DeleteNode(TRUE);
  900. break;
  901. case OBJECT_NODE:
  902. ((PCObjectNode)m_pSelect)->DeleteNode(TRUE);
  903. break;
  904. case INSTANCE_NODE:
  905. ((PCInstanceNode)m_pSelect)->DeleteNode(TRUE);
  906. break;
  907. case COUNTER_NODE:
  908. ((PCCounterNode)m_pSelect)->DeleteNode(TRUE);
  909. break;
  910. case ITEM_NODE:
  911. ((PCGraphItem)m_pSelect)->Delete(TRUE);
  912. break;
  913. default:
  914. return;
  915. }
  916. // DeleteItem sets m_pSelect to NULL and invalidates the window.
  917. assert ( NULL == m_pSelect );
  918. }
  919. BOOL
  920. CReport::OnContextMenu (
  921. INT x,
  922. INT y )
  923. {
  924. HMENU hMenu;
  925. HMENU hMenuPopup;
  926. RECT clntRect;
  927. int xPos=0,yPos=0;
  928. GetWindowRect(m_hWnd,&clntRect);
  929. if (x==0){
  930. xPos = ((clntRect.right - clntRect.left)/2) ;
  931. }else{
  932. xPos = x - clntRect.left;
  933. }
  934. if (y==0){
  935. yPos = ((clntRect.bottom - clntRect.top)/2) ;
  936. }else{
  937. yPos = y - clntRect.top;
  938. }
  939. x = clntRect.left + xPos ;
  940. y = clntRect.top + yPos ;
  941. // if nothing is selected, let main window handle the menu
  942. if (m_pSelect == NULL)
  943. return FALSE;
  944. if ( m_pCtrl->ConfirmSampleDataOverwrite() ) {
  945. if ( !m_pCtrl->IsReadOnly() ) {
  946. // Get the menu for the pop-up menu from the resource file.
  947. hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_CONTEXT));
  948. if (!hMenu)
  949. return TRUE;
  950. // Get the first submenu in it for TrackPopupMenu.
  951. hMenuPopup = GetSubMenu(hMenu, 0);
  952. // Draw and track the "floating" pop-up menu.
  953. TrackPopupMenu(hMenuPopup, TPM_RIGHTBUTTON, x, y, 0, m_hWnd, NULL);
  954. // Destroy the menu.
  955. DestroyMenu(hMenu);
  956. }
  957. }
  958. return TRUE;
  959. }
  960. void
  961. CReport::Update (
  962. void )
  963. {
  964. HDC hDC;
  965. hDC = GetDC(m_hWnd);
  966. if ( NULL != hDC ) {
  967. ApplyChanges(hDC);
  968. SetWindowOrgEx (hDC,
  969. GetScrollPos (m_hWnd, SB_HORZ),
  970. GetScrollPos (m_hWnd, SB_VERT),
  971. NULL) ;
  972. if ( m_rect.bottom != m_rect.top ) {
  973. SelectFont (hDC, m_pCtrl->Font());
  974. SetTextColor (hDC, m_pCtrl->clrFgnd());
  975. SetBkColor(hDC, m_pCtrl->clrBackPlot());
  976. DrawReportValues(hDC);
  977. }
  978. ReleaseDC(m_hWnd,hDC);
  979. }
  980. }
  981. void
  982. CReport::OnPaint (
  983. void
  984. )
  985. {
  986. HDC hDC ;
  987. PAINTSTRUCT ps ;
  988. hDC = BeginPaint (m_hWnd, &ps) ;
  989. if ( NULL != hDC ) {
  990. SelectFont (hDC, m_pCtrl->Font()) ;
  991. SetWindowOrgEx (
  992. hDC,
  993. GetScrollPos (m_hWnd, SB_HORZ),
  994. GetScrollPos (m_hWnd, SB_VERT),
  995. NULL );
  996. SetTextColor (hDC, m_pCtrl->clrFgnd());
  997. SetBkColor(hDC, m_pCtrl->clrBackPlot());
  998. ApplyChanges(hDC);
  999. Draw(hDC);
  1000. EndPaint (m_hWnd, &ps) ;
  1001. }
  1002. }
  1003. void
  1004. CReport::SetScrollRanges (
  1005. void )
  1006. {
  1007. RECT rectClient ;
  1008. INT xWidth, yHeight ;
  1009. GetClientRect (m_hWnd, &rectClient) ;
  1010. xWidth = rectClient.right - rectClient.left ;
  1011. yHeight = rectClient.bottom - rectClient.top ;
  1012. SetScrollRange (m_hWnd, SB_VERT, 0, max (0, m_yReportHeight - yHeight), TRUE) ;
  1013. SetScrollRange (m_hWnd, SB_HORZ,0, max (0, m_xReportWidth - xWidth), TRUE) ;
  1014. }
  1015. BOOL
  1016. CReport::SelectName (
  1017. INT xPos,
  1018. INT yPos,
  1019. void** ppSelected,
  1020. INT* piSelectType )
  1021. {
  1022. POINT pt;
  1023. PCMachineNode pMachine;
  1024. PCObjectNode pObject;
  1025. PCCounterNode pCounter;
  1026. PCInstanceNode pInstance;
  1027. PCGraphItem pItem;
  1028. // Programming error if either of these two pointers is NULL.
  1029. assert ( NULL != ppSelected );
  1030. assert ( NULL != piSelectType );
  1031. // Adjust coordinates by scroll offset
  1032. pt.x = xPos + GetScrollPos(m_hWnd, SB_HORZ);
  1033. pt.y = yPos + GetScrollPos(m_hWnd, SB_VERT);
  1034. for (pMachine = m_pCtrl->CounterTree()->FirstMachine() ;
  1035. pMachine;
  1036. pMachine = pMachine->Next()) {
  1037. if (PtInName(pt, xColumnMargin, pMachine->m_yPos, pMachine->m_xWidth)) {
  1038. *ppSelected = pMachine;
  1039. *piSelectType = MACHINE_NODE;
  1040. return TRUE;
  1041. }
  1042. for (pObject = pMachine->FirstObject() ;
  1043. pObject ;
  1044. pObject = pObject->Next()) {
  1045. if (PtInName(pt, xObjectMargin, pObject->m_yPos, pObject->m_xWidth)) {
  1046. *ppSelected = pObject;
  1047. *piSelectType = OBJECT_NODE;
  1048. return TRUE;
  1049. }
  1050. for (pCounter = pObject->FirstCounter();
  1051. pCounter ;
  1052. pCounter = pCounter->Next()) {
  1053. if (PtInName(pt, xCounterMargin, pCounter->m_yPos, pCounter->m_xWidth)) {
  1054. *ppSelected = pCounter;
  1055. *piSelectType = COUNTER_NODE;
  1056. return TRUE;
  1057. }
  1058. }
  1059. for (pInstance = pObject->FirstInstance();
  1060. pInstance ;
  1061. pInstance = pInstance->Next()) {
  1062. INT xInstancePos = m_xInstanceMargin + pInstance->m_xPos;
  1063. if (PtInName(pt, xInstancePos - pInstance->m_xWidth, pObject->m_yPos, pInstance->m_xWidth) ||
  1064. (pInstance->HasParent() &&
  1065. PtInName(pt, xInstancePos - pInstance->m_xWidth, pObject->m_yPos - m_yLineHeight, pInstance->m_xWidth))) {
  1066. *ppSelected = pInstance;
  1067. *piSelectType = INSTANCE_NODE;
  1068. return TRUE;
  1069. }
  1070. if (pt.x > xInstancePos || pt.x < xInstancePos - m_xValueWidth)
  1071. continue;
  1072. for (pItem = pInstance->FirstItem();
  1073. pItem;
  1074. pItem = pItem->m_pNextItem) {
  1075. if (pt.y > pItem->m_pCounter->m_yPos && pt.y < pItem->m_pCounter->m_yPos + m_yLineHeight) {
  1076. *ppSelected = pItem;
  1077. *piSelectType = ITEM_NODE;
  1078. return TRUE;
  1079. }
  1080. }
  1081. }
  1082. }
  1083. }
  1084. *ppSelected = NULL;
  1085. return FALSE;
  1086. }
  1087. PCGraphItem
  1088. CReport::GetItem (
  1089. void *pSelected,
  1090. INT nSelectType )
  1091. {
  1092. PCMachineNode pMachine;
  1093. PCObjectNode pObject;
  1094. PCCounterNode pCounter;
  1095. PCInstanceNode pInstance;
  1096. PCGraphItem pItem;
  1097. PCGraphItem pReturn = NULL;
  1098. if ( NULL != pSelected ) {
  1099. switch (nSelectType) {
  1100. case MACHINE_NODE:
  1101. pMachine = (PCMachineNode)pSelected;
  1102. pObject = pMachine->FirstObject();
  1103. if ( NULL != pObject ) {
  1104. pInstance = pObject->FirstInstance();
  1105. if ( NULL != pInstance ) {
  1106. pReturn = pInstance->FirstItem();
  1107. }
  1108. }
  1109. break;
  1110. case OBJECT_NODE:
  1111. pObject = (PCObjectNode)pSelected;
  1112. pInstance = pObject->FirstInstance();
  1113. if ( NULL != pInstance ) {
  1114. pReturn = pInstance->FirstItem();
  1115. }
  1116. break;
  1117. case INSTANCE_NODE:
  1118. pInstance = (PCInstanceNode)pSelected;
  1119. pReturn = pInstance->FirstItem();
  1120. break;
  1121. case COUNTER_NODE:
  1122. pCounter = (PCCounterNode)pSelected;
  1123. pObject = pCounter->m_pObject;
  1124. for (pInstance = pObject->FirstInstance();
  1125. ((NULL != pInstance) && (NULL == pReturn));
  1126. pInstance = pInstance->Next()) {
  1127. for (pItem = pInstance->FirstItem();
  1128. ((NULL != pItem) && (NULL == pReturn));
  1129. pItem = pItem->m_pNextItem) {
  1130. if (pItem && pItem->m_pCounter == pCounter) {
  1131. pReturn = pItem;
  1132. }
  1133. }
  1134. }
  1135. break;
  1136. case ITEM_NODE:
  1137. pReturn = (PCGraphItem)pSelected;
  1138. break;
  1139. default:
  1140. break;
  1141. }
  1142. }
  1143. return pReturn;
  1144. }
  1145. BOOL
  1146. CReport::SelectionDeleted (
  1147. PCGraphItem pDeletedItem )
  1148. {
  1149. BOOL bSelectionDeleted = FALSE;
  1150. INT iItemCount = 0;
  1151. PCMachineNode pMachine;
  1152. PCObjectNode pObject;
  1153. PCCounterNode pCounter;
  1154. PCInstanceNode pInstance;
  1155. PCGraphItem pItem;
  1156. if ( NULL == m_pSelect )
  1157. return FALSE;
  1158. // Delete the selection if this is the last remaining
  1159. // item for the selection object.
  1160. switch (m_nSelectType) {
  1161. case MACHINE_NODE:
  1162. // Check for multiple items for this machine.
  1163. pMachine = (PCMachineNode)m_pSelect;
  1164. for ( pObject = pMachine->FirstObject();
  1165. ( NULL != pObject ) && ( 2 > iItemCount );
  1166. pObject = pObject->Next()) {
  1167. for ( pInstance = pObject->FirstInstance();
  1168. ( NULL != pInstance ) && ( 2 > iItemCount );
  1169. pInstance = pInstance->Next()) {
  1170. for ( pItem = pInstance->FirstItem();
  1171. ( NULL != pItem ) && ( 2 > iItemCount );
  1172. pItem = pItem->m_pNextItem) {
  1173. iItemCount++;
  1174. }
  1175. }
  1176. }
  1177. bSelectionDeleted = ( iItemCount < 2 );
  1178. break;
  1179. case OBJECT_NODE:
  1180. // Check for multiple items for this object.
  1181. pObject = (PCObjectNode)m_pSelect;
  1182. for ( pInstance = pObject->FirstInstance();
  1183. ( NULL != pInstance ) && ( 2 > iItemCount );
  1184. pInstance = pInstance->Next()) {
  1185. for ( pItem = pInstance->FirstItem();
  1186. ( NULL != pItem ) && ( 2 > iItemCount );
  1187. pItem = pItem->m_pNextItem) {
  1188. iItemCount++;
  1189. }
  1190. }
  1191. bSelectionDeleted = ( iItemCount < 2 );
  1192. break;
  1193. case INSTANCE_NODE:
  1194. // Check for multiple items (counters) for this instance.
  1195. pInstance = (PCInstanceNode)m_pSelect;
  1196. iItemCount = 0;
  1197. for ( pItem = pInstance->FirstItem();
  1198. ( NULL != pItem ) && ( 2 > iItemCount );
  1199. pItem = pItem->m_pNextItem) {
  1200. iItemCount++;
  1201. }
  1202. bSelectionDeleted = ( iItemCount < 2 );
  1203. break;
  1204. case COUNTER_NODE:
  1205. // Check for multiple items (instances) for this counter.
  1206. pCounter = (PCCounterNode)m_pSelect;
  1207. pObject = pCounter->m_pObject;
  1208. for ( pInstance = pObject->FirstInstance();
  1209. ( NULL != pInstance ) && ( 2 > iItemCount );
  1210. pInstance = pInstance->Next()) {
  1211. for ( pItem = pInstance->FirstItem();
  1212. ( NULL != pItem ) && ( 2 > iItemCount );
  1213. pItem = pItem->m_pNextItem) {
  1214. if (pItem && pItem->m_pCounter == pCounter) {
  1215. iItemCount++;
  1216. break;
  1217. }
  1218. }
  1219. }
  1220. bSelectionDeleted = ( iItemCount < 2 );
  1221. break;
  1222. case ITEM_NODE:
  1223. // Selection matches the deleted item.
  1224. bSelectionDeleted = ( pDeletedItem == (PCGraphItem)m_pSelect );
  1225. break;
  1226. default:
  1227. break;
  1228. }
  1229. return bSelectionDeleted;
  1230. }
  1231. void
  1232. CReport::OnLButtonDown (
  1233. INT xPos,
  1234. INT yPos )
  1235. {
  1236. PCGraphItem pItem;
  1237. HDC hDC = GetDC(m_hWnd);
  1238. if ( NULL != hDC ) {
  1239. SetWindowOrgEx (
  1240. hDC,
  1241. GetScrollPos (m_hWnd, SB_HORZ),
  1242. GetScrollPos (m_hWnd, SB_VERT),
  1243. NULL) ;
  1244. DrawSelectRect(hDC, FALSE);
  1245. if ( SelectName(xPos, yPos, &m_pSelect, &m_nSelectType) )
  1246. DrawSelectRect(hDC, TRUE);
  1247. ReleaseDC(m_hWnd, hDC);
  1248. pItem = GetItem(m_pSelect, m_nSelectType);
  1249. m_pCtrl->SelectCounter(pItem);
  1250. }
  1251. return;
  1252. }
  1253. void
  1254. CReport:: OnDblClick (
  1255. INT, // xPos,
  1256. INT // yPos
  1257. )
  1258. {
  1259. PCGraphItem pItem;
  1260. pItem = GetItem ( m_pSelect, m_nSelectType );
  1261. m_pCtrl->DblClickCounter ( pItem );
  1262. }
  1263. void
  1264. CReport::OnHScroll (
  1265. INT iScrollCode,
  1266. INT iScrollNewPos )
  1267. {
  1268. INT iScrollAmt, iScrollPos, iScrollRange ;
  1269. INT iScrollLo ;
  1270. RECT rectClient ;
  1271. INT xWidth ;
  1272. GetClientRect (m_hWnd, &rectClient) ;
  1273. xWidth = rectClient.right - rectClient.left ;
  1274. if (m_xReportWidth <= xWidth)
  1275. return ;
  1276. iScrollPos = GetScrollPos (m_hWnd, SB_HORZ) ;
  1277. GetScrollRange (m_hWnd, SB_HORZ, &iScrollLo, &iScrollRange) ;
  1278. switch (iScrollCode)
  1279. {
  1280. case SB_LINEUP:
  1281. iScrollAmt = - m_yLineHeight ;
  1282. break ;
  1283. case SB_LINEDOWN:
  1284. iScrollAmt = m_yLineHeight ;
  1285. break ;
  1286. case SB_PAGEUP:
  1287. iScrollAmt = - (rectClient.right - rectClient.left) / 2 ;
  1288. break ;
  1289. case SB_PAGEDOWN:
  1290. iScrollAmt = (rectClient.right - rectClient.left) / 2 ;
  1291. break ;
  1292. case SB_THUMBPOSITION:
  1293. iScrollAmt = iScrollNewPos - iScrollPos ;
  1294. break ;
  1295. default:
  1296. iScrollAmt = 0 ;
  1297. }
  1298. iScrollAmt = PinInclusive (iScrollAmt,
  1299. -iScrollPos,
  1300. iScrollRange - iScrollPos) ;
  1301. if (iScrollAmt) {
  1302. iScrollPos += iScrollAmt ;
  1303. ScrollWindow (m_hWnd, -iScrollAmt, 0, NULL, NULL) ;
  1304. SetScrollPos (m_hWnd, SB_HORZ, iScrollPos, TRUE) ;
  1305. UpdateWindow (m_hWnd) ;
  1306. }
  1307. }
  1308. void
  1309. CReport::OnVScroll (
  1310. INT iScrollCode,
  1311. INT iScrollNewPos
  1312. )
  1313. {
  1314. INT iScrollAmt, iScrollPos, iScrollRange ;
  1315. INT iScrollLo ;
  1316. RECT rectClient ;
  1317. iScrollPos = GetScrollPos (m_hWnd, SB_VERT) ;
  1318. GetScrollRange (m_hWnd, SB_VERT, &iScrollLo, &iScrollRange) ;
  1319. GetClientRect (m_hWnd, &rectClient) ;
  1320. switch (iScrollCode) {
  1321. case SB_LINEUP:
  1322. iScrollAmt = - m_yLineHeight ;
  1323. break ;
  1324. case SB_LINEDOWN:
  1325. iScrollAmt = m_yLineHeight ;
  1326. break ;
  1327. case SB_PAGEUP:
  1328. iScrollAmt = - (rectClient.bottom - rectClient.top) / 2 ;
  1329. break ;
  1330. case SB_PAGEDOWN:
  1331. iScrollAmt = (rectClient.bottom - rectClient.top) / 2 ;
  1332. break ;
  1333. case SB_THUMBPOSITION:
  1334. iScrollAmt = iScrollNewPos - iScrollPos ;
  1335. break ;
  1336. default:
  1337. iScrollAmt = 0 ;
  1338. }
  1339. iScrollAmt = PinInclusive (iScrollAmt, -iScrollPos, iScrollRange - iScrollPos) ;
  1340. if (iScrollAmt) {
  1341. iScrollPos += iScrollAmt ;
  1342. ScrollWindow (m_hWnd, 0, -iScrollAmt, NULL, NULL) ;
  1343. SetScrollPos (m_hWnd, SB_VERT, iScrollPos, TRUE) ;
  1344. UpdateWindow (m_hWnd) ;
  1345. }
  1346. }
  1347. //
  1348. // Window procedure
  1349. //
  1350. LRESULT APIENTRY
  1351. ReportWndProc (
  1352. HWND hWnd,
  1353. UINT uiMsg,
  1354. WPARAM wParam,
  1355. LPARAM lParam )
  1356. {
  1357. PREPORT pReport = NULL;
  1358. BOOL bCallDefProc = TRUE;
  1359. LRESULT lReturnValue = 0L;
  1360. RECT rect;
  1361. // hWnd is used to dispatch to window procedure, so major error if it is NULL.
  1362. assert ( NULL != hWnd );
  1363. pReport = (PREPORT)GetWindowLongPtr(hWnd,0);
  1364. if ( NULL == pReport ) {
  1365. if ( WM_CREATE == uiMsg && NULL != lParam ) {
  1366. pReport = (PREPORT)((CREATESTRUCT*)lParam)->lpCreateParams;
  1367. SetWindowLongPtr(hWnd,0,(INT_PTR)pReport);
  1368. } else {
  1369. // Programming error
  1370. assert ( FALSE );
  1371. }
  1372. } else {
  1373. bCallDefProc = FALSE ;
  1374. switch (uiMsg) {
  1375. case WM_DESTROY:
  1376. break ;
  1377. case WM_LBUTTONDOWN:
  1378. if (!pReport->m_pCtrl->IsUIDead()) {
  1379. // pReport->m_pCtrl->Activate();
  1380. // pReport->m_pCtrl->AssignFocus();
  1381. pReport->OnLButtonDown(LOWORD (lParam), HIWORD (lParam));
  1382. }
  1383. break;
  1384. case WM_CONTEXTMENU:
  1385. if (!pReport->m_pCtrl->IsUIDead()) {
  1386. // pReport->m_pCtrl->Activate();
  1387. // pReport->m_pCtrl->AssignFocus();
  1388. // *** DefWindowProc is not Smonctrl, so context menu not happening.
  1389. if (LOWORD(lParam)!= 0xffff || HIWORD(lParam) != 0xffff){
  1390. // Always call the default procedure, to handle the case where the
  1391. // context menu is activated from within a select rectangle.
  1392. bCallDefProc = TRUE;
  1393. }else {
  1394. if (!pReport->OnContextMenu(0,0))
  1395. bCallDefProc = TRUE;
  1396. }
  1397. }
  1398. break;
  1399. case WM_LBUTTONDBLCLK:
  1400. if (!pReport->m_pCtrl->IsUIDead()) {
  1401. // pReport->m_pCtrl->Activate();
  1402. // pReport->m_pCtrl->AssignFocus();
  1403. pReport->OnDblClick(LOWORD (lParam), HIWORD (lParam));
  1404. }
  1405. break;
  1406. case WM_ERASEBKGND:
  1407. GetClientRect(hWnd, &rect);
  1408. SetBkColor((HDC)wParam, pReport->m_pCtrl->clrBackPlot());
  1409. ClearRect((HDC)wParam, &rect);
  1410. lReturnValue = TRUE;
  1411. break;
  1412. case WM_PAINT:
  1413. pReport->OnPaint () ;
  1414. break ;
  1415. case WM_HSCROLL:
  1416. pReport->OnHScroll (LOWORD (wParam), HIWORD (wParam)) ;
  1417. break ;
  1418. case WM_VSCROLL:
  1419. pReport->OnVScroll (LOWORD (wParam), HIWORD (wParam)) ;
  1420. break ;
  1421. case WM_COMMAND:
  1422. if (pReport->m_pCtrl->IsUIDead())
  1423. break;
  1424. switch (LOWORD(wParam)) {
  1425. case IDM_REPORT_COPY:
  1426. case IDM_REPORT_COPYALL:
  1427. break;
  1428. case IDM_REPORT_DELETE:
  1429. pReport->DeleteSelection();
  1430. break;
  1431. case IDM_PROPERTIES:
  1432. pReport->m_pCtrl->DisplayProperties();
  1433. break;
  1434. case IDM_ADDCOUNTERS:
  1435. pReport->m_pCtrl->AddCounters();
  1436. break;
  1437. case IDM_SAVEAS:
  1438. pReport->m_pCtrl->SaveAs();
  1439. break;
  1440. default:
  1441. bCallDefProc = TRUE;
  1442. }
  1443. break;
  1444. default:
  1445. bCallDefProc = TRUE ;
  1446. }
  1447. }
  1448. if (bCallDefProc)
  1449. lReturnValue = DefWindowProc (hWnd, uiMsg, wParam, lParam) ;
  1450. return (lReturnValue);
  1451. }