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.

416 lines
11 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. statbar.cpp
  5. Abstract:
  6. Implementation of the value bar class.
  7. --*/
  8. #include <stdio.h>
  9. #include "polyline.h"
  10. #include "statbar.h"
  11. #define MAX_STAT_LABEL_LEN 32
  12. static TCHAR aszItemLabel[STAT_ITEM_CNT][MAX_STAT_LABEL_LEN];
  13. static BOOLEAN fInitDone = FALSE;
  14. CStatsBar::CStatsBar(void)
  15. : m_pCtrl ( NULL ),
  16. m_iFontHeight ( 0 ),
  17. m_iValueWidth ( 0 ),
  18. m_pGraphItemToInit ( NULL )
  19. {
  20. memset (&m_Rect, 0, sizeof(m_Rect));
  21. }
  22. CStatsBar::~CStatsBar(void)
  23. {
  24. }
  25. BOOL CStatsBar::Init (PSYSMONCTRL pCtrl, HWND /* hWnd */ )
  26. {
  27. INT i;
  28. // save pointer to primary object
  29. m_pCtrl = pCtrl;
  30. // First time through, load the item labels
  31. if (!fInitDone) {
  32. fInitDone = TRUE;
  33. for (i=0; i<STAT_ITEM_CNT; i++) {
  34. LoadString(g_hInstance, (IDS_STAT_BASE + i), aszItemLabel[i], MAX_STAT_LABEL_LEN);
  35. }
  36. }
  37. // Initialze the stat values
  38. Clear();
  39. return TRUE;
  40. }
  41. void CStatsBar::SizeComponents(LPRECT pRect)
  42. {
  43. // Just save the rectangle
  44. m_Rect = *pRect;
  45. }
  46. void CStatsBar::SetTimeSpan(double dSeconds)
  47. {
  48. m_StatItem[STAT_TIME].dNewValue = dSeconds;
  49. }
  50. void CStatsBar::Update(HDC hDC, PCGraphItem pGraphItem)
  51. {
  52. double dMin, dMax, dAvg, dVal;
  53. PSTAT_ITEM pItem;
  54. INT i;
  55. HRESULT hr;
  56. PDH_STATUS stat;
  57. LONG lCtrStat;
  58. // if no space assigned, return
  59. if (m_Rect.top == m_Rect.bottom) {
  60. m_pGraphItemToInit = pGraphItem;
  61. m_StatItem[0].iInitialized = 0;
  62. return;
  63. }
  64. if (pGraphItem == NULL) {
  65. pItem = &m_StatItem[0];
  66. for (i=0; i<STAT_ITEM_CNT-1; i++, pItem++) {
  67. pItem->dNewValue = 0.0;
  68. pItem->iInitialized = 0;
  69. }
  70. } else {
  71. stat = pGraphItem->GetValue(&dVal, &lCtrStat);
  72. if (stat == 0 && IsSuccessSeverity(lCtrStat))
  73. m_StatItem[STAT_LAST].dNewValue = dVal;
  74. else
  75. m_StatItem[STAT_LAST].dNewValue = 0.0;
  76. hr = pGraphItem->GetStatistics(&dMax, &dMin, &dAvg, &lCtrStat);
  77. if (SUCCEEDED(hr) && IsSuccessSeverity(lCtrStat)) {
  78. m_StatItem[STAT_MIN].dNewValue = dMin;
  79. m_StatItem[STAT_MAX].dNewValue = dMax;
  80. m_StatItem[STAT_AVG].dNewValue = dAvg;
  81. } else {
  82. m_StatItem[STAT_MIN].dNewValue = 0.0;
  83. m_StatItem[STAT_MAX].dNewValue = 0.0;
  84. m_StatItem[STAT_AVG].dNewValue = 0.0;
  85. }
  86. m_StatItem[0].dwCounterType = pGraphItem->m_CounterInfo.dwType;
  87. m_StatItem[0].iInitialized = 1;
  88. }
  89. // hDC is null if updating only values.
  90. if (hDC != NULL) {
  91. SetBkColor(hDC, m_pCtrl->clrBackCtl());
  92. SetTextColor(hDC, m_pCtrl->clrFgnd());
  93. DrawValues(hDC,FALSE);
  94. }
  95. }
  96. void CStatsBar::Clear( void )
  97. {
  98. PSTAT_ITEM pItem;
  99. INT i;
  100. pItem = &m_StatItem[0];
  101. for (i=0; i<STAT_ITEM_CNT-1; i++, pItem++) {
  102. pItem->dValue = pItem->dNewValue = 0.0;
  103. pItem->iInitialized = 0;
  104. }
  105. }
  106. void CStatsBar::Draw (HDC hDC, HDC /* hAttribDC */, PRECT prcUpdate)
  107. {
  108. RECT rectFrame;
  109. PSTAT_ITEM pItem;
  110. HFONT hFontOld;
  111. INT i;
  112. RECT rectPaint;
  113. RECT rectClip;
  114. // if no space assigned, return
  115. if (m_Rect.top == m_Rect.bottom)
  116. return;
  117. // if no painting needed, return
  118. if (!IntersectRect(&rectPaint, &m_Rect, prcUpdate))
  119. return;
  120. SetBkMode(hDC, TRANSPARENT);
  121. SetTextColor(hDC, m_pCtrl->clrFgnd());
  122. SetTextAlign(hDC, TA_LEFT|TA_TOP);
  123. hFontOld = SelectFont(hDC, m_pCtrl->Font());
  124. pItem = &m_StatItem[0];
  125. // If the stat bar was hidden on Update, for example if
  126. // the control was loaded from a property bag, or if a
  127. // counter was selected while the stat bar was hidden,
  128. // initialize it here.
  129. if ( 0 == pItem->iInitialized ) {
  130. Update ( NULL, m_pGraphItemToInit );
  131. }
  132. // Draw Label and 3D box for each item
  133. for (i=0; i<STAT_ITEM_CNT; i++, pItem++) {
  134. rectClip.top = m_Rect.top + pItem->yPos + RECT_BORDER;
  135. rectClip.bottom = rectClip.top + m_iFontHeight;
  136. rectClip.left = m_Rect.left + pItem->xPos;
  137. rectClip.right = rectClip.left + pItem->xLabelWidth;
  138. ExtTextOut(
  139. hDC,
  140. m_Rect.left + pItem->xPos,
  141. m_Rect.top + pItem->yPos + RECT_BORDER,
  142. 0,
  143. &rectClip,
  144. aszItemLabel[i],
  145. lstrlen(aszItemLabel[i]),
  146. NULL );
  147. if ( eAppear3D == m_pCtrl->Appearance() ) {
  148. rectFrame.left = m_Rect.left + pItem->xPos + pItem->xLabelWidth + VALUE_MARGIN;
  149. rectFrame.right = rectFrame.left + m_iValueWidth + 2 * RECT_BORDER;
  150. rectFrame.top = m_Rect.top + pItem->yPos;
  151. rectFrame.bottom = rectFrame.top + m_iFontHeight + 2 * RECT_BORDER;
  152. DrawEdge(hDC, &rectFrame, BDR_SUNKENOUTER, BF_RECT);
  153. }
  154. }
  155. SelectFont(hDC, hFontOld);
  156. SetBkMode(hDC, OPAQUE);
  157. SetBkColor(hDC, m_pCtrl->clrBackCtl());
  158. DrawValues(hDC, TRUE);
  159. }
  160. void CStatsBar::DrawValues(HDC hDC, BOOL bForce)
  161. {
  162. RECT rectValue ;
  163. TCHAR szValue [20] ;
  164. HFONT hFontOld;
  165. PSTAT_ITEM pItem;
  166. INT i;
  167. INT nSecs, nMins, nHours, nDays;
  168. SetTextAlign(hDC, TA_RIGHT | TA_TOP);
  169. hFontOld = SelectFont(hDC, m_pCtrl->Font());
  170. pItem = &m_StatItem[0];
  171. for (i=0; i<STAT_ITEM_CNT; i++,pItem++) {
  172. if ((pItem->dValue == pItem->dNewValue) && !bForce)
  173. continue;
  174. pItem->dValue = pItem->dNewValue;
  175. rectValue.top = m_Rect.top + pItem->yPos + RECT_BORDER;
  176. rectValue.bottom = rectValue.top + m_iFontHeight;
  177. rectValue.left = m_Rect.left + pItem->xPos + pItem->xLabelWidth + VALUE_MARGIN + RECT_BORDER;
  178. rectValue.right = rectValue.left + m_iValueWidth - 1;
  179. if (i == STAT_TIME) {
  180. LPTSTR pszTimeSep = NULL;
  181. pszTimeSep = GetTimeSeparator ( );
  182. nSecs = (INT)pItem->dValue;
  183. nMins = nSecs / 60;
  184. nSecs -= nMins * 60;
  185. nHours = nMins / 60;
  186. nMins -= nHours * 60;
  187. nDays = nHours / 24;
  188. nHours -= nDays * 24;
  189. if (nDays != 0) {
  190. _stprintf(szValue, SZ_DAYTIME_FORMAT, nDays, nHours, pszTimeSep, nMins);
  191. } else {
  192. if (nHours != 0)
  193. _stprintf(szValue, SZ_HRTIME_FORMAT, nHours, pszTimeSep, nMins, pszTimeSep, nSecs);
  194. else
  195. _stprintf(szValue, SZ_MINTIME_FORMAT, nMins, pszTimeSep, nSecs);
  196. }
  197. } else {
  198. if (pItem->dValue > E_MEDIUM_VALUE) {
  199. if (pItem->dValue > E_TOO_LARGE_VALUE) {
  200. lstrcpy (szValue, SZ_VALUE_TOO_HIGH) ;
  201. } else {
  202. if ( pItem->dValue <= E_LARGE_VALUE ) {
  203. FormatNumber (
  204. pItem->dValue,
  205. szValue,
  206. 20,
  207. eMinimumWidth,
  208. eMediumPrecision );
  209. } else {
  210. FormatScientific (
  211. pItem->dValue,
  212. szValue,
  213. 20,
  214. eMinimumWidth,
  215. eLargePrecision );
  216. }
  217. }
  218. } else if (pItem->dValue < -E_MEDIUM_VALUE) {
  219. if (pItem->dValue < -E_TOO_LARGE_VALUE) {
  220. lstrcpy (szValue, SZ_VALUE_TOO_LOW) ;
  221. } else {
  222. if ( pItem->dValue >= -E_LARGE_VALUE ) {
  223. FormatNumber (
  224. pItem->dValue,
  225. szValue,
  226. 20,
  227. eMinimumWidth,
  228. eMediumPrecision );
  229. } else {
  230. FormatScientific (
  231. pItem->dValue,
  232. szValue,
  233. 20,
  234. eMinimumWidth,
  235. eLargePrecision );
  236. }
  237. }
  238. } else {
  239. if ( ( m_StatItem[0].dwCounterType &
  240. ( PERF_TYPE_COUNTER | PERF_TYPE_TEXT ) ) ) {
  241. FormatNumber (
  242. pItem->dValue,
  243. szValue,
  244. 20,
  245. eMinimumWidth,
  246. eSmallPrecision );
  247. } else {
  248. FormatNumber (
  249. pItem->dValue,
  250. szValue,
  251. 20,
  252. eMinimumWidth,
  253. eIntegerPrecision );
  254. }
  255. }
  256. }
  257. // TextOut (hDC, rectValue.right, rectValue.top, szValue, lstrlen (szValue)) ;
  258. ExtTextOut (hDC, rectValue.right, rectValue.top, ETO_OPAQUE, &rectValue,
  259. szValue, lstrlen (szValue), NULL) ;
  260. }
  261. SelectFont(hDC, hFontOld);
  262. }
  263. INT CStatsBar::Height (INT iMaxHeight, INT iMaxWidth)
  264. {
  265. INT iHeight;
  266. INT xPos,yPos;
  267. PSTAT_ITEM pItem;
  268. INT i,j;
  269. INT iItemWidth;
  270. INT iFirst;
  271. INT iRemainder;
  272. iMaxWidth -= 2 * RECT_BORDER;
  273. xPos = 0;
  274. yPos = 0;
  275. iFirst = 0;
  276. pItem = &m_StatItem[0];
  277. for (i=0; i<STAT_ITEM_CNT; i++,pItem++) {
  278. iItemWidth = pItem->xLabelWidth + VALUE_MARGIN + m_iValueWidth;
  279. if (iItemWidth > iMaxWidth)
  280. return 0;
  281. if (xPos + iItemWidth > iMaxWidth) {
  282. iRemainder = iMaxWidth - xPos + LABEL_MARGIN;
  283. xPos = 0;
  284. yPos += m_iFontHeight + LINE_SPACING;
  285. for (j=iFirst; j<i; j++) {
  286. m_StatItem[j].xPos += iRemainder;
  287. }
  288. iFirst = i;
  289. }
  290. pItem->xPos = xPos;
  291. pItem->yPos = yPos;
  292. xPos += (iItemWidth + LABEL_MARGIN);
  293. }
  294. iRemainder = (iMaxWidth - xPos) + LABEL_MARGIN;
  295. for (j=iFirst; j<STAT_ITEM_CNT; j++) {
  296. m_StatItem[j].xPos += iRemainder;
  297. }
  298. // if allowed height is not enough, return zero
  299. iHeight = yPos + m_iFontHeight + 2 * RECT_BORDER;
  300. return (iHeight <= iMaxHeight) ? iHeight : 0;
  301. }
  302. void CStatsBar::ChangeFont(
  303. HDC hDC
  304. )
  305. {
  306. INT xPos,yPos;
  307. TCHAR szValue[20];
  308. HFONT hFontOld;
  309. PSTAT_ITEM pItem;
  310. INT i;
  311. SIZE size;
  312. hFontOld = (HFONT)SelectFont(hDC, m_pCtrl->Font());
  313. // Get width/height of longest value string
  314. FormatNumber (
  315. E_LARGE_VALUE,
  316. szValue,
  317. 20,
  318. eMinimumWidth,
  319. eLargePrecision );
  320. GetTextExtentPoint32(hDC, szValue, lstrlen(szValue), &size);
  321. m_iValueWidth = size.cx;
  322. m_iFontHeight = size.cy;
  323. // Do for all stat items
  324. xPos = 0;
  325. yPos = 0;
  326. pItem = &m_StatItem[0];
  327. for (i=0; i<STAT_ITEM_CNT; i++,pItem++) {
  328. pItem->xLabelWidth = TextWidth(hDC, aszItemLabel[i]);
  329. }
  330. SelectFont(hDC, hFontOld);
  331. }