|
|
/******************************************************************************/ /* Bar.CPP: IMPLEMENTATION OF THE CStatBar (Status Bar) CLASS */ /* */ /******************************************************************************/ /* */ /* Methods in this file */ /* */ /* CStatBar::CStatBar */ /* CStatBar::~CStatBar */ /* CStatBar::Create */ /* CStatBar::OnSetFont */ /* CStatBar::DoPaint */ /* CStatBar::DrawStatusText */ /* CStatBar::SetText */ /* CStatBar::SetPosition */ /* CStatBar::SetSize */ /* CStatBar::ClearPosition */ /* CStatBar::ClearSize */ /* CStatBar::Reset */ /* CStatBar::OnPaletteChanged */ /* */ /* */ /* Functions in this file */ /* */ /* ClearStatusBarSize */ /* ClearStatusBarPosition */ /* SetPrompt */ /* SetPrompt */ /* ShowStatusBar */ /* IsStatusBarVisible */ /* GetStatusBarHeight */ /* InvalidateStatusBar */ /* ClearStatusBarPositionAndSize */ /* ResetStatusBar */ /* SetStatusBarPosition */ /* SetStatusBarSize */ /* SetStatusBarPositionAndSize */ /* */ /******************************************************************************/
#include "stdafx.h"
#include "global.h"
#include "pbrush.h"
#include "pbrusfrm.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__; #endif
IMPLEMENT_DYNAMIC( CStatBar, CStatusBar )
#include "memtrace.h"
CStatBar *g_pStatBarWnd = NULL;
static UINT BASED_CODE indicators[] = { ID_SEPARATOR, // status line indicator
IDB_SBPOS, IDB_SBSIZE };
BEGIN_MESSAGE_MAP( CStatBar, CStatusBar ) ON_WM_SYSCOLORCHANGE() ON_MESSAGE(WM_SETFONT, OnSetFont) ON_MESSAGE(WM_SIZEPARENT, OnSizeParent) ON_WM_NCDESTROY() END_MESSAGE_MAP()
static int miSlackSpace;
/******************************************************************************/
CStatBar::CStatBar() { m_iBitmapWidth = 0; m_iBitmapHeight = 0; miSlackSpace = 0; m_iSizeY = 0; }
CStatBar::~CStatBar() { // Ensure that the CControlBar doesn't assert trying access our parent
// object (CPBFrame) during the destruction of our parent object.
m_pDockSite = NULL; }
/******************************************************************************/
BOOL CStatBar::Create( CWnd* pParentWnd ) { BOOL bRC = TRUE; int cxStatBar; // width of a char in the status bar
// Create the status Bar Window.
bRC = CStatusBar::Create(pParentWnd);
ASSERT (bRC != FALSE);
if (bRC != FALSE) { // Set the Pane Indicators.
bRC = SetIndicators( indicators, sizeof( indicators ) / sizeof( UINT ) );
ASSERT( bRC != FALSE );
if (bRC != FALSE) { TRY { // Load the Separator Strings
VERIFY(m_cstringSizeSeparator.LoadString(IDS_SIZE_SEPARATOR)); VERIFY(m_cstringPosSeparator.LoadString(IDS_POS_SEPARATOR)); } CATCH(CMemoryException,e) { m_cstringSizeSeparator.Empty(); m_cstringPosSeparator.Empty(); } END_CATCH
// Load the Position and Size Bitmaps
VERIFY(m_posBitmap.LoadBitmap(IDB_SBPOS)); VERIFY(m_sizeBitmap.LoadBitmap(IDB_SBSIZE));
if ( (m_posBitmap.GetSafeHandle() != NULL) && (m_sizeBitmap.GetSafeHandle() != NULL) ) { //Calculate the size of the pane and set them
CClientDC dc(this);
/*DK* What font to select? */ /*DK* What to do if in foreign Language, Size "0"? */
cxStatBar = (dc.GetTextExtent(TEXT("0"), 1)).cx; BITMAP bmp;
m_posBitmap.GetObject(sizeof (BITMAP), &bmp);
m_iBitmapWidth = bmp.bmWidth; m_iBitmapHeight = bmp.bmHeight;
int iPaneWidth; UINT uiID, uiStyle;
GetPaneInfo( 0, uiID, uiStyle, iPaneWidth) ; SetPaneInfo( 0, uiID, SBPS_NORMAL | SBPS_STRETCH, iPaneWidth );
GetPaneInfo(1, uiID, uiStyle, iPaneWidth);
if (iPaneWidth < bmp.bmWidth + (SIZE_POS_PANE_WIDTH * cxStatBar)) { iPaneWidth = bmp.bmWidth + (SIZE_POS_PANE_WIDTH * cxStatBar); SetPaneInfo(1, uiID, uiStyle, iPaneWidth); }
GetPaneInfo(2, uiID, uiStyle, iPaneWidth);
if (iPaneWidth < bmp.bmWidth + (SIZE_POS_PANE_WIDTH * cxStatBar)) { iPaneWidth = bmp.bmWidth + (SIZE_POS_PANE_WIDTH * cxStatBar); SetPaneInfo(2, uiID, uiStyle, iPaneWidth); }
// force a height change
CFont *pcFontTemp = GetFont();
// initialize font height etc
OnSetFont( (WPARAM)(HFONT)pcFontTemp->GetSafeHandle(), 0 ); } else { bRC = FALSE; } } } return bRC; }
/******************************************************************************/
void CStatBar::OnNcDestroy( void ) { m_posBitmap.DeleteObject(); m_sizeBitmap.DeleteObject();
m_posBitmap.m_hObject = NULL; m_sizeBitmap.m_hObject = NULL;
m_cstringSizeSeparator.Empty(); m_cstringPosSeparator.Empty();
CStatusBar::OnNcDestroy(); }
/******************************************************************************/
CSize CStatBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz) { CSize size = CStatusBar::CalcFixedLayout( bStretch, bHorz );
size.cy = m_iSizeY;
return size; }
/******************************************************************************/ /* Change the height of the status bar to allow the bitmaps to be painted */ /* in the panes. The height is set in the OnSetFont OnSetFont method. Save */ /* the current border values, change then call OnSetFont and then reset the */ /* border values */ /* */ /* This will increase the height of the whole status bar until the next */ /* OnSetFont (font change) for the status bar. */ /* */ /* In Barcore.cpp, the Height of the status bar is set in the OnSetFont */ /* method as follows: */ /* */ /* Height = = (tm.tmHeight - tm.tmInternalLeading) + */ /* CY_BORDER*4 (which is 2 extra on top, 2 */ /* on bottom) - rectSize.Height(); */ /* */ /* This is really */ /* Height = Height of Font + Border between Font and */ /* Pane edges + Border between Pane edges and */ /* Status bar window. */ /* */ /* tm.tmHeight - tm.tmInternalLeading is Font Height CY_BORDER*4 is border */ /* between font and pane edges rectSize.Height is Neg of Border between Pane */ /* and SBar rectSize is set to 0, then the deflated by the border size. */ /* Deflating from 0 => negative, and - negative gives us a positive amount. */ /* */ /* by default m_cyBottomBorder = m_cyTopBorder = 1 */ /******************************************************************************/ /* We only change the border sizes temporarily for the calculation of the */ /* status bar height. We really don't want to change the border sizes, but */ /* are just using them as a way to affect the size of the whole bar. */ /******************************************************************************/
LRESULT CStatBar::OnSetFont(WPARAM wParam, LPARAM lParam) {
CRect rect;
int iTmpcyTopBorder = m_cyTopBorder; int iTmpcyBottomBorder = m_cyBottomBorder;
m_cyTopBorder = m_cyBottomBorder = 2; miSlackSpace = 0;
// Can't do this in MFC 4
// lResult = CStatusBar::OnSetFont(wParam, lParam); //initialize font height etc
rect.SetRectEmpty(); CalcInsideRect( rect, TRUE ); // will be negative size
int iBorder = CY_BORDER * 4 - rect.Height(); int iSize = m_iSizeY - iBorder; int cyTallest = m_iBitmapHeight; CDC dc;
if( dc.CreateIC( TEXT("DISPLAY"), NULL, NULL, NULL ) ) { TEXTMETRIC tm; tm.tmHeight=0; CFont *font = CFont::FromHandle( (HFONT)wParam ); if ( font ) { CFont *oldFont = dc.SelectObject(font);
if( dc.GetTextMetrics( &tm ) && tm.tmHeight > cyTallest ) cyTallest = tm.tmHeight;
if (oldFont) dc.SelectObject(oldFont); } dc.DeleteDC(); }
if (cyTallest > iSize) m_iSizeY = cyTallest + iBorder;
if (m_iBitmapHeight > iSize) miSlackSpace = m_iBitmapHeight - iSize;
m_cyTopBorder = iTmpcyTopBorder; m_cyBottomBorder = iTmpcyBottomBorder;
return 1L; }
/******************************************************************************/ /* This routine is overloaded to allow us to paint the bitmaps in the panes. */ /* If this routine was not here, it would work fine, but no bitmaps would */ /* appear in the status indicator panes. */ /******************************************************************************/
void CStatBar::DoPaint( CDC* pDC ) { BOOL bRC; CString cstringText_Pane1; CString cstringText_Pane2; CRect rect_Pane1; CRect rect_Pane2; CRgn cRgn_Pane1; CRgn cRgn_Pane2; CBitmap* pOldBitmap; UINT uiStyle_Pane1; UINT uiStyle_Pane2; UINT uiID; int iPaneWidth; HDC hdc = pDC->GetSafeHdc();
GetItemRect( 1, &rect_Pane1 ); // get pane rect
GetItemRect( 2, &rect_Pane2 ); // get pane rect
pDC->ExcludeClipRect( &rect_Pane1 ); // exclude pane rect from paint
pDC->ExcludeClipRect( &rect_Pane2 ); // exclude pane rect from paint
CStatusBar::DoPaint( pDC ); // Let Parent Class paint remainder of status bar
CFont* pfntOld = pDC->SelectObject( GetFont() );
GetPaneText( 1, cstringText_Pane1 ); // Get the Text for the Pane
GetPaneText( 2, cstringText_Pane2 ); // The status bar holds the text for us.
GetPaneInfo( 1, uiID, uiStyle_Pane1, iPaneWidth ); GetPaneInfo( 2, uiID, uiStyle_Pane2, iPaneWidth );
uiStyle_Pane1 = SBPS_NORMAL; uiStyle_Pane2 = SBPS_NORMAL;
CDC srcDC; // select current bitmap into a compatible CDC
bRC = srcDC.CreateCompatibleDC( pDC );
ASSERT( bRC != FALSE );
if (bRC != FALSE) { // Set the Text and Background Colors for a Mono to Color Bitmap
// Conversion. These are also set in DrawStatusText, so should not
// have to reset them for the other bitmap/pane
COLORREF crTextColor = pDC->SetTextColor( GetSysColor( COLOR_BTNTEXT ) ); COLORREF crBkColor = pDC->SetBkColor ( GetSysColor( COLOR_BTNFACE ) );
bRC = cRgn_Pane1.CreateRectRgnIndirect( rect_Pane1 );
ASSERT( bRC != FALSE );
if (bRC != FALSE) { pDC->SelectClipRgn( &cRgn_Pane1 ); // set clip region to pane rect
pOldBitmap = srcDC.SelectObject( &m_posBitmap );
rect_Pane1.InflateRect( -CX_BORDER, -CY_BORDER ); // deflate => don't paint on the borders
pDC->BitBlt( rect_Pane1.left, rect_Pane1.top, rect_Pane1.Width(), rect_Pane1.Height(), &srcDC, 0, 0, SRCCOPY ); // BitBlt to pane rect
srcDC.SelectObject( pOldBitmap );
rect_Pane1.InflateRect( CX_BORDER, CY_BORDER ); // Inflate back for drawstatustext
// paint the borders and the text.
DrawStatusText( hdc, rect_Pane1, cstringText_Pane1, uiStyle_Pane1, m_iBitmapWidth + 1 ); }
cRgn_Pane2.CreateRectRgnIndirect(rect_Pane2);
ASSERT( bRC != FALSE );
if (bRC != FALSE) { pDC->SelectClipRgn(&cRgn_Pane2); // set clip region to pane rect
pOldBitmap = srcDC.SelectObject(&m_sizeBitmap); rect_Pane2.InflateRect(-CX_BORDER, -CY_BORDER); // deflate => don't paint on the borders
pDC->BitBlt(rect_Pane2.left, rect_Pane2.top, rect_Pane2.Width(), rect_Pane2.Height(), &srcDC, 0, 0, SRCCOPY); // BitBlt to pane rect
srcDC.SelectObject(pOldBitmap); rect_Pane2.InflateRect(CX_BORDER, CY_BORDER); // Inflate back for drawstatustext
// DrawStatusText will paint the borders and the text.
DrawStatusText(hdc, rect_Pane2, cstringText_Pane2, uiStyle_Pane2, m_iBitmapWidth+1); } pDC->SetTextColor( crTextColor ); pDC->SetBkColor ( crBkColor ); } if (pfntOld != NULL) pDC->SelectObject( pfntOld ); }
/******************************************************************************/ /* Partially taken from BARCORE.CPP DrawStatusText method of CStatusBar. */ /* Last parameter was added */ /* */ /* This will allow us to output the text indented the space amount for our */ /* bitmap. Normally, this routine puts the text left alligned to the pane. */ /******************************************************************************/
void PASCAL CStatBar::DrawStatusText( HDC hDC, CRect const& rect, LPCTSTR lpszText, UINT nStyle, int iIndentText ) { ASSERT(hDC != NULL);
CBrush* cpBrushHilite; CBrush* cpBrushShadow; HBRUSH hbrHilite = NULL; HBRUSH hbrShadow = NULL;
if (! (nStyle & SBPS_NOBORDERS)) { if (nStyle & SBPS_POPOUT) { // reverse colors
cpBrushHilite = GetSysBrush( COLOR_BTNSHADOW ); cpBrushShadow = GetSysBrush( COLOR_BTNHIGHLIGHT ); } else { // normal colors
cpBrushHilite = GetSysBrush( COLOR_BTNHIGHLIGHT ); cpBrushShadow = GetSysBrush( COLOR_BTNSHADOW ); }
hbrHilite = (HBRUSH)cpBrushHilite->GetSafeHandle(); hbrShadow = (HBRUSH)cpBrushShadow->GetSafeHandle(); }
// background is already grey
UINT nOpts = ETO_CLIPPED; int nOldMode = SetBkMode ( hDC, OPAQUE ); COLORREF crTextColor = SetTextColor( hDC, GetSysColor( COLOR_BTNTEXT ) ); COLORREF crBkColor = SetBkColor ( hDC, GetSysColor( COLOR_BTNFACE ) );
// Draw the hilites
if (hbrHilite) { HGDIOBJ hOldBrush = SelectObject( hDC, hbrHilite );
if (hOldBrush) { PatBlt( hDC, rect.right, rect.bottom, -(rect.Width() - CX_BORDER), -CY_BORDER, PATCOPY ); PatBlt( hDC, rect.right, rect.bottom, -CX_BORDER, -(rect.Height() - CY_BORDER), PATCOPY ); SelectObject( hDC, hOldBrush ); } }
if (hbrShadow) { HGDIOBJ hOldBrush = SelectObject( hDC, hbrShadow );
if (hOldBrush) { PatBlt( hDC, rect.left, rect.top, rect.Width(), CY_BORDER, PATCOPY ); PatBlt( hDC, rect.left, rect.top, CX_BORDER, rect.Height(), PATCOPY ); SelectObject( hDC, hOldBrush ); } }
// We need to adjust the rect for the ExtTextOut, and then adjust it back
// just support left justified text
if (lpszText != NULL && !(nStyle & SBPS_DISABLED)) { CRect rectText( rect );
rectText.InflateRect( -2 * CX_BORDER, -CY_BORDER );
// adjust left edge for indented Text
rectText.left += iIndentText;
// align on bottom (since descent is more important than ascent)
SetTextAlign( hDC, TA_LEFT | TA_BOTTOM );
if (miSlackSpace > 0) rectText.InflateRect( 0, -(miSlackSpace / 2) );
ExtTextOut( hDC, rectText.left, rectText.bottom, nOpts, &rectText, lpszText, lstrlen( lpszText ), NULL ); }
SetTextColor( hDC, crTextColor ); SetBkColor ( hDC, crBkColor ); }
/******************************************************************************/
BOOL CStatBar::SetText(LPCTSTR szText) { BOOL bRC = TRUE;
if (theApp.InEmergencyState()) { bRC = FALSE; } else { bRC = SetPaneText(0, szText); }
return bRC; }
/******************************************************************************/
BOOL CStatBar::SetPosition(const CPoint& pos) { BOOL bRC = TRUE; int cch; TCHAR szBuf [20];
cch = wsprintf(szBuf, TEXT("%d~%d"), pos.x, pos.y);
for (int i = 0; i < cch; i++) if (szBuf[i] == TEXT('~')) { szBuf[i] = m_cstringPosSeparator[0]; break; }
ASSERT (cch != 0);
if (cch != 0) { bRC = SetPaneText(1, szBuf); } else { bRC = FALSE; }
return bRC; }
/******************************************************************************/
BOOL CStatBar::SetSize(const CSize& size) { BOOL bRC = TRUE; int cch; TCHAR szBuf [20];
cch = wsprintf( szBuf, TEXT("%d~%d"), size.cx, size.cy );
for (int i = 0; i < cch; i++) if (szBuf[i] == TEXT('~')) { szBuf[i] = m_cstringSizeSeparator[0]; break; }
ASSERT (cch != 0);
if (cch != 0) bRC = SetPaneText(2, szBuf); else bRC = FALSE;
return bRC; }
/******************************************************************************/
BOOL CStatBar::ClearPosition() { BOOL bRC = TRUE; bRC = SetPaneText(1, TEXT("")); // clear the position
return bRC; }
/******************************************************************************/
BOOL CStatBar::ClearSize() { BOOL bRC = TRUE; bRC = SetPaneText(2, TEXT("")); // clear the size
return bRC; }
/******************************************************************************/
BOOL CStatBar::Reset() { return ClearPosition() && ClearSize(); }
/******************************************************************************/
void CStatBar::OnSysColorChange() { CStatusBar::OnSysColorChange(); InvalidateRect(NULL,FALSE); }
/******************************************************************************/
void ClearStatusBarSize() { ASSERT(g_pStatBarWnd); g_pStatBarWnd->ClearSize(); }
/******************************************************************************/
void ClearStatusBarPosition() { ASSERT(g_pStatBarWnd); g_pStatBarWnd->ClearPosition(); }
/******************************************************************************/
void SetPrompt(LPCTSTR szPrompt, BOOL bRedrawNow) { ASSERT(g_pStatBarWnd); g_pStatBarWnd->SetText(szPrompt); if (bRedrawNow) g_pStatBarWnd->UpdateWindow(); }
/******************************************************************************/
void SetPrompt(UINT nStringID, BOOL bRedrawNow) { ASSERT(g_pStatBarWnd); CString str; VERIFY(str.LoadString(nStringID));
g_pStatBarWnd->SetText(str);
if (bRedrawNow) g_pStatBarWnd->UpdateWindow(); }
/******************************************************************************/
void ShowStatusBar(BOOL bShow /* = TRUE */) { ASSERT(g_pStatBarWnd); g_pStatBarWnd->ShowWindow(bShow ? SW_SHOWNOACTIVATE : SW_HIDE); }
/******************************************************************************/
BOOL IsStatusBarVisible() { ASSERT(g_pStatBarWnd); return (g_pStatBarWnd->GetStyle() & WS_VISIBLE) != 0; }
/******************************************************************************/
int GetStatusBarHeight() { ASSERT(g_pStatBarWnd); CRect rect; g_pStatBarWnd->GetWindowRect(rect); return rect.Height(); }
/******************************************************************************/
void InvalidateStatusBar(BOOL bErase /* = FALSE */) { ASSERT(g_pStatBarWnd); g_pStatBarWnd->Invalidate(bErase); }
/******************************************************************************/
void ClearStatusBarPositionAndSize() { ASSERT(g_pStatBarWnd); g_pStatBarWnd->ClearSize(); g_pStatBarWnd->ClearPosition(); }
/******************************************************************************/
void ResetStatusBar() { ASSERT(g_pStatBarWnd); g_pStatBarWnd->Reset(); }
/******************************************************************************/
void SetStatusBarPosition(const CPoint& pos) { ASSERT(g_pStatBarWnd); if ( ::IsWindow(g_pStatBarWnd->m_hWnd) ) g_pStatBarWnd->SetPosition(pos); }
/******************************************************************************/
void SetStatusBarSize(const CSize& size) { ASSERT(g_pStatBarWnd); if ( ::IsWindow( g_pStatBarWnd->m_hWnd) ) g_pStatBarWnd->SetSize(size); }
/******************************************************************************/
void SetStatusBarPositionAndSize(const CRect& rect) { ASSERT(g_pStatBarWnd); g_pStatBarWnd->SetPosition(((CRect&)rect).TopLeft()); g_pStatBarWnd->SetSize(rect.Size()); }
/******************************************************************************/
LRESULT CStatBar::OnSizeParent(WPARAM wParam, LPARAM lParam) { LRESULT lRes = CStatusBar::OnSizeParent(wParam, lParam);
return(lRes); }
|