//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1999 - 1999 // // File: statbar.cpp // //-------------------------------------------------------------------------- #include "stdafx.h" #include "StatBar.h" #include "amcmsgid.h" // CODEWORK message reflection not working yet // Set the default upper and lower bounds since these are the default values used in CProgressCtrl CAMCProgressCtrl::CAMCProgressCtrl() : CProgressCtrl() { nLower = 0; nUpper = 100; } // Set the default upper and lower bounds before setting the range in the base class void CAMCProgressCtrl::SetRange( int nNewLower, int nNewUpper ) { if ((nLower != nNewLower) || (nUpper != nNewUpper)) { nLower = nNewLower; nUpper = nNewUpper; /* * MFC 4.2 doesn't define SetRange32, so do it the old-fashioned way */ SendMessage (PBM_SETRANGE32, nNewLower, nNewUpper); } } // Retrieve the range void CAMCProgressCtrl::GetRange( int * nGetLower, int * nGetUpper ) { *nGetLower = nLower; *nGetUpper = nUpper; } // Display the progress bar whenever the position is being set int CAMCProgressCtrl::SetPos(int nPos) { /* * Theming: When navigation is concluded, the web browser will set a * 0 position, with a range of (0,0). This would leave the progress * control visible, but not distiguishable from the status bar because * the status bar and the progress bar had the same background. When * themes are enabled, the progress bar is distinguishable because the * themed progress bar has a different background from the status bar. * See bug 366817. * * The fix is to only show the progress bar if there's a non-empty range. */ bool fShow = (nUpper != nLower); ShowWindow (fShow ? SW_SHOW : SW_HIDE); return CProgressCtrl::SetPos(nPos); } IMPLEMENT_DYNAMIC(CAMCStatusBar, CStatBar) BEGIN_MESSAGE_MAP(CAMCStatusBar, CStatBar) //{{AFX_MSG_MAP(CAMCStatusBar) ON_WM_CREATE() ON_WM_SIZE() //}}AFX_MSG_MAP ON_WM_SETTINGCHANGE() ON_MESSAGE (WM_SETTEXT, OnSetText) ON_MESSAGE (SB_SETTEXT, OnSBSetText) END_MESSAGE_MAP() const TCHAR CAMCStatusBar::DELINEATOR[] = TEXT("|"); const TCHAR CAMCStatusBar::PROGRESSBAR[] = TEXT("%"); CAMCStatusBar::CAMCStatusBar() { } CAMCStatusBar::~CAMCStatusBar() { CSingleLock lock( &m_Critsec ); POSITION pos = m_TextList.GetHeadPosition(); while ( NULL != pos ) { delete m_TextList.GetNext( pos ); } m_TextList.RemoveAll(); } void CAMCStatusBar::Parse(LPCTSTR strText) { m_progressControl.ShowWindow(SW_HIDE); CString str[eStatusFields]; int i; if (strText != NULL) { str[0] = strText; str[0].TrimLeft(); str[0].TrimRight(); } // If there is no text to display if (str[0].IsEmpty()) { // Set the variable to designate this m_iNumStatusText = 0; // Wipe the rest of the panes for (i = 0; i < eStatusFields; i++) SetPaneText(i, NULL ); } else { m_iNumStatusText = 0xffff; int iLocationDelin = 0; // Dissect the string into parts to be displayed in appropriate windows for (i = 0; (i < eStatusFields) && ((iLocationDelin = str[i].FindOneOf(DELINEATOR)) > -1); i++) { if (i < eStatusFields - 1) { str[i+1] = str[i].Mid(iLocationDelin + 1); /* * trim leading whitespace (trailing whitespace * should have been trimmed already) */ str[i+1].TrimLeft(); ASSERT (str[i+1].IsEmpty() || !_istspace(str[i+1][str[i+1].GetLength()-1])); } str[i] = str[i].Left( iLocationDelin ); /* * trim trailing whitespace (leading whitespace * should have been trimmed already) */ str[i].TrimRight(); ASSERT (str[i].IsEmpty() || !_istspace(str[i][0])); } // If the progress bar is being displayed if ((str[1].GetLength() > 1) && (str[1].FindOneOf(PROGRESSBAR) == 0)) { if (str[1][0] == str[1][1]) str[1] = str[1].Mid(1); else { int val = _ttoi(str[1].Mid(1)); m_progressControl.SetRange(0, 100); m_progressControl.SetPos(val); m_iNumStatusText &= ~(0x2); } } // Display the text in the panes (which wipes them if necessary) for (i = 0; i < eStatusFields; i++) if (m_iNumStatusText & (1 << i)) SetPaneText(i, str[i]); } } void CAMCStatusBar::Update() { // keep copy of string to avoid WIN32 operations while holding critsec CString str; { CSingleLock lock( &m_Critsec ); if ( !m_TextList.IsEmpty() ) { CString* pstr = m_TextList.GetHead(); ASSERT( pstr != NULL ); str = *pstr; } } if (str.IsEmpty()) GetParentFrame()->SendMessage (WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE); else Parse(str); } int CAMCStatusBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CStatBar::OnCreate(lpCreateStruct) == -1) return -1; // Create the progres bar control as a child of the status bar CRect rect(0,0,0,0); m_progressControl.Create(PBS_SMOOTH|WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE, rect, this, 0x1000); m_staticControl.Create(_T(""), WS_CLIPSIBLINGS|WS_CHILD|WS_VISIBLE|SS_SIMPLE, rect, this, 0x1001); // Remove the static edge, hide the window and display a changes frame m_progressControl.ModifyStyleEx(WS_EX_STATICEDGE, 0, SWP_HIDEWINDOW | SWP_FRAMECHANGED); SetStatusBarFont(); return 0; } void CAMCStatusBar::OnSize(UINT nType, int cx, int cy) { CStatBar::OnSize(nType, cx, cy); // Get the width of the first pane for position and get the width of the pane // to set the width of the progress bar CRect textRect, progressRect, staticRect; GetItemRect(0, &textRect); GetItemRect(1, &progressRect); GetItemRect(2, &staticRect); progressRect.InflateRect(-2, -2); staticRect.InflateRect(-2, -2); int pane1Width = textRect.Width(); // (Text area) add two for the border int pane2Width = progressRect.Width(); // (Progress area) add two for the border const int BORDER = 4; // size the progress bar if (IsWindow (m_progressControl)) m_progressControl.SetWindowPos(NULL, pane1Width + BORDER, BORDER, pane2Width, progressRect.Height(), SWP_FRAMECHANGED | SWP_NOREPOSITION | SWP_NOZORDER); // size the static control if (IsWindow (m_staticControl)) m_staticControl.SetWindowPos(NULL, pane1Width + pane2Width + (2*BORDER), BORDER, staticRect.Width(), staticRect.Height(), SWP_FRAMECHANGED | SWP_NOREPOSITION | SWP_NOZORDER); } /*+-------------------------------------------------------------------------* * CAMCStatusBar::OnSettingChange * * WM_SETTINGCHANGE handler for CAMCStatusBar. *--------------------------------------------------------------------------*/ void CAMCStatusBar::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) { Default(); if (uFlags == SPI_SETNONCLIENTMETRICS) { // the system status bar font may have changed; update it now SetStatusBarFont(); } } /*+-------------------------------------------------------------------------* * CAMCStatusBar::OnSetText * * WM_SETTEXT handler for CAMCStatusBar. *--------------------------------------------------------------------------*/ LRESULT CAMCStatusBar::OnSetText (WPARAM, LPARAM lParam) { Parse (reinterpret_cast(lParam)); return (TRUE); } /*+-------------------------------------------------------------------------* * CAMCStatusBar::OnSBSetText * * SB_SETTEXT handler for CAMCStatusBar. *--------------------------------------------------------------------------*/ LRESULT CAMCStatusBar::OnSBSetText (WPARAM wParam, LPARAM) { return (Default()); } /*+-------------------------------------------------------------------------* * CAMCStatusBar::SetStatusBarFont * * *--------------------------------------------------------------------------*/ void CAMCStatusBar::SetStatusBarFont () { /* * delete the old font */ m_StaticFont.DeleteObject (); /* * query the system for the current status bar font */ NONCLIENTMETRICS ncm; ncm.cbSize = sizeof (ncm); SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); /* * use it here, too; we need to set the font for the embedded static * control, but the status bar window will take care of itself */ m_StaticFont.CreateFontIndirect (&ncm.lfStatusFont); m_staticControl.SetFont (&m_StaticFont, false); }