windows-nt/Source/XPSP1/NT/admin/activec/conui/statbar.cpp
2020-09-26 16:20:57 +08:00

323 lines
9.1 KiB
C++

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