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.

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