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.

322 lines
9.1 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: statbar.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "StatBar.h"
  12. #include "amcmsgid.h"
  13. // CODEWORK message reflection not working yet
  14. // Set the default upper and lower bounds since these are the default values used in CProgressCtrl
  15. CAMCProgressCtrl::CAMCProgressCtrl() : CProgressCtrl()
  16. {
  17. nLower = 0;
  18. nUpper = 100;
  19. }
  20. // Set the default upper and lower bounds before setting the range in the base class
  21. void
  22. CAMCProgressCtrl::SetRange( int nNewLower, int nNewUpper )
  23. {
  24. if ((nLower != nNewLower) || (nUpper != nNewUpper))
  25. {
  26. nLower = nNewLower;
  27. nUpper = nNewUpper;
  28. /*
  29. * MFC 4.2 doesn't define SetRange32, so do it the old-fashioned way
  30. */
  31. SendMessage (PBM_SETRANGE32, nNewLower, nNewUpper);
  32. }
  33. }
  34. // Retrieve the range
  35. void
  36. CAMCProgressCtrl::GetRange( int * nGetLower, int * nGetUpper )
  37. {
  38. *nGetLower = nLower;
  39. *nGetUpper = nUpper;
  40. }
  41. // Display the progress bar whenever the position is being set
  42. int
  43. CAMCProgressCtrl::SetPos(int nPos)
  44. {
  45. /*
  46. * Theming: When navigation is concluded, the web browser will set a
  47. * 0 position, with a range of (0,0). This would leave the progress
  48. * control visible, but not distiguishable from the status bar because
  49. * the status bar and the progress bar had the same background. When
  50. * themes are enabled, the progress bar is distinguishable because the
  51. * themed progress bar has a different background from the status bar.
  52. * See bug 366817.
  53. *
  54. * The fix is to only show the progress bar if there's a non-empty range.
  55. */
  56. bool fShow = (nUpper != nLower);
  57. ShowWindow (fShow ? SW_SHOW : SW_HIDE);
  58. return CProgressCtrl::SetPos(nPos);
  59. }
  60. IMPLEMENT_DYNAMIC(CAMCStatusBar, CStatBar)
  61. BEGIN_MESSAGE_MAP(CAMCStatusBar, CStatBar)
  62. //{{AFX_MSG_MAP(CAMCStatusBar)
  63. ON_WM_CREATE()
  64. ON_WM_SIZE()
  65. //}}AFX_MSG_MAP
  66. ON_WM_SETTINGCHANGE()
  67. ON_MESSAGE (WM_SETTEXT, OnSetText)
  68. ON_MESSAGE (SB_SETTEXT, OnSBSetText)
  69. END_MESSAGE_MAP()
  70. const TCHAR CAMCStatusBar::DELINEATOR[] = TEXT("|");
  71. const TCHAR CAMCStatusBar::PROGRESSBAR[] = TEXT("%");
  72. CAMCStatusBar::CAMCStatusBar()
  73. {
  74. }
  75. CAMCStatusBar::~CAMCStatusBar()
  76. {
  77. CSingleLock lock( &m_Critsec );
  78. POSITION pos = m_TextList.GetHeadPosition();
  79. while ( NULL != pos )
  80. {
  81. delete m_TextList.GetNext( pos );
  82. }
  83. m_TextList.RemoveAll();
  84. }
  85. void CAMCStatusBar::Parse(LPCTSTR strText)
  86. {
  87. m_progressControl.ShowWindow(SW_HIDE);
  88. CString str[eStatusFields];
  89. int i;
  90. if (strText != NULL)
  91. {
  92. str[0] = strText;
  93. str[0].TrimLeft();
  94. str[0].TrimRight();
  95. }
  96. // If there is no text to display
  97. if (str[0].IsEmpty())
  98. {
  99. // Set the variable to designate this
  100. m_iNumStatusText = 0;
  101. // Wipe the rest of the panes
  102. for (i = 0; i < eStatusFields; i++)
  103. SetPaneText(i, NULL );
  104. }
  105. else
  106. {
  107. m_iNumStatusText = 0xffff;
  108. int iLocationDelin = 0;
  109. // Dissect the string into parts to be displayed in appropriate windows
  110. for (i = 0; (i < eStatusFields) &&
  111. ((iLocationDelin = str[i].FindOneOf(DELINEATOR)) > -1);
  112. i++)
  113. {
  114. if (i < eStatusFields - 1)
  115. {
  116. str[i+1] = str[i].Mid(iLocationDelin + 1);
  117. /*
  118. * trim leading whitespace (trailing whitespace
  119. * should have been trimmed already)
  120. */
  121. str[i+1].TrimLeft();
  122. ASSERT (str[i+1].IsEmpty() || !_istspace(str[i+1][str[i+1].GetLength()-1]));
  123. }
  124. str[i] = str[i].Left( iLocationDelin );
  125. /*
  126. * trim trailing whitespace (leading whitespace
  127. * should have been trimmed already)
  128. */
  129. str[i].TrimRight();
  130. ASSERT (str[i].IsEmpty() || !_istspace(str[i][0]));
  131. }
  132. // If the progress bar is being displayed
  133. if ((str[1].GetLength() > 1) && (str[1].FindOneOf(PROGRESSBAR) == 0))
  134. {
  135. if (str[1][0] == str[1][1])
  136. str[1] = str[1].Mid(1);
  137. else
  138. {
  139. int val = _ttoi(str[1].Mid(1));
  140. m_progressControl.SetRange(0, 100);
  141. m_progressControl.SetPos(val);
  142. m_iNumStatusText &= ~(0x2);
  143. }
  144. }
  145. // Display the text in the panes (which wipes them if necessary)
  146. for (i = 0; i < eStatusFields; i++)
  147. if (m_iNumStatusText & (1 << i))
  148. SetPaneText(i, str[i]);
  149. }
  150. }
  151. void CAMCStatusBar::Update()
  152. {
  153. // keep copy of string to avoid WIN32 operations while holding critsec
  154. CString str;
  155. {
  156. CSingleLock lock( &m_Critsec );
  157. if ( !m_TextList.IsEmpty() )
  158. {
  159. CString* pstr = m_TextList.GetHead();
  160. ASSERT( pstr != NULL );
  161. str = *pstr;
  162. }
  163. }
  164. if (str.IsEmpty())
  165. GetParentFrame()->SendMessage (WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
  166. else
  167. Parse(str);
  168. }
  169. int CAMCStatusBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
  170. {
  171. if (CStatBar::OnCreate(lpCreateStruct) == -1)
  172. return -1;
  173. // Create the progres bar control as a child of the status bar
  174. CRect rect(0,0,0,0);
  175. m_progressControl.Create(PBS_SMOOTH|WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE, rect, this, 0x1000);
  176. m_staticControl.Create(_T(""), WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE|SS_SIMPLE, rect, this, 0x1001);
  177. // Remove the static edge, hide the window and display a changes frame
  178. m_progressControl.ModifyStyleEx(WS_EX_STATICEDGE, 0, SWP_HIDEWINDOW | SWP_FRAMECHANGED);
  179. SetStatusBarFont();
  180. return 0;
  181. }
  182. void CAMCStatusBar::OnSize(UINT nType, int cx, int cy)
  183. {
  184. CStatBar::OnSize(nType, cx, cy);
  185. // Get the width of the first pane for position and get the width of the pane
  186. // to set the width of the progress bar
  187. CRect textRect, progressRect, staticRect;
  188. GetItemRect(0, &textRect);
  189. GetItemRect(1, &progressRect);
  190. GetItemRect(2, &staticRect);
  191. progressRect.InflateRect(-2, -2);
  192. staticRect.InflateRect(-2, -2);
  193. int pane1Width = textRect.Width(); // (Text area) add two for the border
  194. int pane2Width = progressRect.Width(); // (Progress area) add two for the border
  195. const int BORDER = 4;
  196. // size the progress bar
  197. if (IsWindow (m_progressControl))
  198. m_progressControl.SetWindowPos(NULL, pane1Width + BORDER, BORDER, pane2Width,
  199. progressRect.Height(),
  200. SWP_FRAMECHANGED |
  201. SWP_NOREPOSITION |
  202. SWP_NOZORDER);
  203. // size the static control
  204. if (IsWindow (m_staticControl))
  205. m_staticControl.SetWindowPos(NULL, pane1Width + pane2Width + (2*BORDER), BORDER, staticRect.Width(),
  206. staticRect.Height(),
  207. SWP_FRAMECHANGED |
  208. SWP_NOREPOSITION |
  209. SWP_NOZORDER);
  210. }
  211. /*+-------------------------------------------------------------------------*
  212. * CAMCStatusBar::OnSettingChange
  213. *
  214. * WM_SETTINGCHANGE handler for CAMCStatusBar.
  215. *--------------------------------------------------------------------------*/
  216. void CAMCStatusBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
  217. {
  218. Default();
  219. if (uFlags == SPI_SETNONCLIENTMETRICS)
  220. {
  221. // the system status bar font may have changed; update it now
  222. SetStatusBarFont();
  223. }
  224. }
  225. /*+-------------------------------------------------------------------------*
  226. * CAMCStatusBar::OnSetText
  227. *
  228. * WM_SETTEXT handler for CAMCStatusBar.
  229. *--------------------------------------------------------------------------*/
  230. LRESULT CAMCStatusBar::OnSetText (WPARAM, LPARAM lParam)
  231. {
  232. Parse (reinterpret_cast<LPCTSTR>(lParam));
  233. return (TRUE);
  234. }
  235. /*+-------------------------------------------------------------------------*
  236. * CAMCStatusBar::OnSBSetText
  237. *
  238. * SB_SETTEXT handler for CAMCStatusBar.
  239. *--------------------------------------------------------------------------*/
  240. LRESULT CAMCStatusBar::OnSBSetText (WPARAM wParam, LPARAM)
  241. {
  242. return (Default());
  243. }
  244. /*+-------------------------------------------------------------------------*
  245. * CAMCStatusBar::SetStatusBarFont
  246. *
  247. *
  248. *--------------------------------------------------------------------------*/
  249. void CAMCStatusBar::SetStatusBarFont ()
  250. {
  251. /*
  252. * delete the old font
  253. */
  254. m_StaticFont.DeleteObject ();
  255. /*
  256. * query the system for the current status bar font
  257. */
  258. NONCLIENTMETRICS ncm;
  259. ncm.cbSize = sizeof (ncm);
  260. SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  261. /*
  262. * use it here, too; we need to set the font for the embedded static
  263. * control, but the status bar window will take care of itself
  264. */
  265. m_StaticFont.CreateFontIndirect (&ncm.lfStatusFont);
  266. m_staticControl.SetFont (&m_StaticFont, false);
  267. }