|
|
//+-------------------------------------------------------------------------
//
// 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<LPCTSTR>(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); }
|