extoolbar.cpp

来自「c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++」· C++ 代码 · 共 1,031 行 · 第 1/2 页

CPP
1,031
字号
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
//       http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"

#include "ExToolBar.h"

#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC( CExToolBar, CToolBar )
BEGIN_MESSAGE_MAP( CExToolBar, CToolBar )
	ON_WM_NCCALCSIZE()
	ON_WM_CREATE()
	ON_WM_NCPAINT()
	ON_WM_SYSCOLORCHANGE()
    ON_WM_WINDOWPOSCHANGING()
END_MESSAGE_MAP()

CExToolBar::CExToolBar( void )
{
    m_nShowIconMode = 1;        // Large icon.
    m_bShowIconText = false;     // Text.

    m_SmallIconSize = CSize( 16, 16 );
    m_LargeIconSize = CSize( 52, 40 );

    m_bOldFloating=false; 
}

CExToolBar::~CExToolBar( void )
{
    for ( int i=0; i<NB_POSSIBLE_MODE; i++ )
    {
        if ( m_ImageList[ i ].GetSafeHandle() )
            m_ImageList[ i ].DeleteImageList();
    }
}

void CExToolBar::SetIconMode(UINT _nShowIconMode )
{
    m_nShowIconMode = _nShowIconMode;

    AssignImageList();

    ResizeToolBar();
}

UINT CExToolBar::GetIconMode( void ) const
{
    return m_nShowIconMode;
}

void CExToolBar::SetTextMode( 
     bool _bShowIconText )
{
	_bShowIconText = false;  // Override. Don't want text.
    m_bShowIconText = _bShowIconText;

    ResizeToolBar();
}

bool CExToolBar::GetTextMode( void ) const
{
    return m_bShowIconText;
}

BOOL CExToolBar::LoadToolBar( 
     UINT _ResourceId )
{
    CString lpszResourceName;
    lpszResourceName.Format( "#%d", _ResourceId );
    BOOL bReturn = CToolBar::LoadToolBar( lpszResourceName );

    if ( bReturn == FALSE )
    {
        return bReturn;
    }

    CToolBarCtrl& bar = GetToolBarCtrl();
    int nIndex = 0;
    CRect NoTextRc( 0, 0, 0, 0 );
    bar.GetItemRect( 0, NoTextRc );
  
    TBBUTTON tb;
    for ( nIndex = bar.GetButtonCount(); nIndex >= 0; nIndex-- )
    {
        ZeroMemory(&tb, sizeof(TBBUTTON));
        bar.GetButton(nIndex, &tb);

        if ( ( tb.fsStyle & TBSTYLE_SEP ) ==  TBSTYLE_SEP ) {
            continue;
        }

        if ( tb.idCommand == 0 ) {
            continue;
        }

        CString strText((LPCSTR)tb.idCommand);
        LPCTSTR lpszButtonText = NULL;
        CString	strButtonText(_T(&""));
        _TCHAR	seps[] = _T(&"\n");

        if ( !strText.IsEmpty() ) {
            lpszButtonText = _tcstok( ( LPTSTR ) ( LPCTSTR ) strText, seps );
            while( lpszButtonText )
            {
                strButtonText = lpszButtonText;
                lpszButtonText = _tcstok( NULL, seps );
            } 
        }

        if ( !strButtonText.IsEmpty() ) {
            SetButtonText( nIndex, strButtonText );
        }
    }

	CRect rc( 0, 0, 0, 0 );
	CSize sizeMax( 0, 0 );

	for ( nIndex = bar.GetButtonCount(); nIndex >= 0; nIndex-- )
	{
		bar.GetItemRect( nIndex, rc );

		rc.NormalizeRect();
		sizeMax.cx = __max( rc.Size().cx, sizeMax.cx );
		sizeMax.cy = __max( rc.Size().cy, sizeMax.cy );
	}

    m_nTextWidth = sizeMax.cx;
    m_nTextHeight = sizeMax.cy - ( NoTextRc.Size().cy );
    ResizeToolBar();

    CClientDC dc( this );
    int nNbBits = dc.GetDeviceCaps( BITSPIXEL );
    for ( int i=0; i<NB_POSSIBLE_MODE; i++ )
    {
        UINT nColorMode = ILC_COLOR;
        if ( nNbBits > 8 )
        {
            nColorMode = ILC_COLORDDB;
        }

        CSize Size = m_LargeIconSize;
        if ( i < 3 )
        {
            Size = m_SmallIconSize;
        }
      
        m_ImageList[ i ].Create( Size.cx, Size.cy, nColorMode | ILC_MASK, bar.GetButtonCount(), 10 );
    }

    return bReturn;
}

void CExToolBar::SetImageList( 
     ImageMode_ _Mode,
     CImageList& _rList )
{
    m_ImageList[ _Mode ].Attach( _rList.Detach() );
}

void CExToolBar::AssignImageList( void )
{
    CImageList* pTempHotList;
    CImageList* pTempNormalList;
    CImageList* pTempDisableList;
    if ( m_nShowIconMode == 0 )
    {
        pTempHotList     = &m_ImageList[ SmallHot ];
        pTempNormalList  = &m_ImageList[ SmallStandard ];
        pTempDisableList = &m_ImageList[ SmallDisable ];
    }
    if ( m_nShowIconMode == 1 )
    {
        pTempHotList     = &m_ImageList[ LargeHot ];
        pTempNormalList  = &m_ImageList[ LargeStandard ];
        pTempDisableList = &m_ImageList[ LargeDisable ];
    }

    SetHotImageList( pTempHotList );
    SetStandardImageList( pTempNormalList );
    SetDisableImageList( pTempDisableList );
}

void CExToolBar::InitImageList( void )
{
    AssignImageList();
}

CSize CExToolBar::CalcButtonSize( void )
{
    CSize theButtonSize;
    if ( m_nShowIconMode == 0 )
    {
        theButtonSize = CSize( m_SmallIconSize.cx + 8, m_SmallIconSize.cy + 7 );
    }
    else if ( m_nShowIconMode == 1 )
    {
        theButtonSize = CSize( m_LargeIconSize.cx + 8, m_LargeIconSize.cy + 7 );
    }

    if ( m_bShowIconText )
    {
        if ( theButtonSize.cx < m_nTextWidth ) 
        {
            theButtonSize.cx = m_nTextWidth;
        }

        theButtonSize.cy += m_nTextHeight;
    }

    return theButtonSize;
}

void CExToolBar::SetHotImageList( 
     CImageList* pList )
{
	CWnd* pWnd = &GetToolBarCtrl();
	pWnd->SendMessage( TB_SETHOTIMAGELIST, 0, ( LPARAM ) ( HIMAGELIST ) *pList );
}

void CExToolBar::SetStandardImageList( 
     CImageList* pList )
{
	CWnd* pWnd = &GetToolBarCtrl();
	pWnd->SendMessage( TB_SETIMAGELIST, 0, ( LPARAM ) ( HIMAGELIST ) *pList );
}

void CExToolBar::SetDisableImageList( 
     CImageList* pList )
{
	CWnd* pWnd = &GetToolBarCtrl();
	pWnd->SendMessage( TB_SETDISABLEDIMAGELIST, 0, ( LPARAM ) ( HIMAGELIST ) *pList );
}
void CExToolBar::SetButtonDropDown( 
     int nID )
{
	DWORD dwStyle = GetButtonStyle( CommandToIndex( nID ) );
	dwStyle |= TBSTYLE_DROPDOWN;
	SetButtonStyle( CommandToIndex( nID ), dwStyle );

    CToolBarCtrl& bar = GetToolBarCtrl();
    CSize theStdButtonSize = CalcButtonSize();
    CRect rc( 0, 0, 0, 0 );
    bar.GetItemRect( CommandToIndex( nID ), rc );
    m_nDropButtonSize = rc.Width() - theStdButtonSize.cx;
}

void CExToolBar::ResizeToolBar( void )
{
    CSize theSize = ( m_nShowIconMode == 0 ) ? m_SmallIconSize : m_LargeIconSize;
    CSize theButtonSize = CalcButtonSize();

	SetSizes( theButtonSize, theSize );
    MoveWindow( 0, 0, 450, theButtonSize.cy);
    SendMessage( WM_SIZE, SIZE_RESTORED );
//    CFrameWnd* pFrameWnd = GetDockingFrame();
//	pFrameWnd->DelayRecalcLayout();
}

void CExToolBar::DrawGripper( 
     CDC& dc ) const
{
	if( m_dwStyle & CBRS_FLOATING )
    {
		return;
    }
	
	CRect gripper;
	GetWindowRect( gripper );
	ScreenToClient( gripper );

	/* Draw border */
    COLORREF clrBtnHilight = ::GetSysColor(COLOR_BTNHILIGHT);
    COLORREF clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
	POINT BottomLine[2];
	CPen Dark(PS_SOLID, 1, clrBtnShadow);
	CPen Light(PS_SOLID, 1, clrBtnHilight);
	CPen *Old;

	BottomLine[0].x = gripper.left;
	BottomLine[1].x = gripper.right;
	BottomLine[0].y = gripper.bottom;
	BottomLine[1].y = gripper.bottom;

	Old = dc.SelectObject(&Light);
    dc.Polyline( BottomLine, 2 );
	dc.SelectObject(Old);

	BottomLine[0].y -= 1;
	BottomLine[1].y -= 1;

	Old = dc.SelectObject(&Dark);
    dc.Polyline( BottomLine, 2 );
	dc.SelectObject(Old);

	gripper.OffsetRect( -gripper.left, -gripper.top );

    if( m_dwStyle & CBRS_ORIENT_HORZ ) {
	
		gripper.DeflateRect( 3, 3 );
		gripper.right = gripper.left+3;
        dc.Draw3dRect( gripper, clrBtnHilight, clrBtnShadow );
		
		gripper.OffsetRect(5, 0);
        dc.Draw3dRect( gripper, clrBtnHilight, clrBtnShadow );
	}
	
	else {
		
		gripper.DeflateRect( 3, 3 );
		gripper.bottom = gripper.top+3;
		dc.Draw3dRect( gripper, clrBtnHilight, clrBtnShadow );
		
		gripper.OffsetRect(0, 5);
        dc.Draw3dRect( gripper, clrBtnHilight, clrBtnShadow );
	}
}

void CExToolBar::OnUpdateCmdUI( 
     CFrameWnd* pTarget,
     BOOL bDisableIfNoHndler )
{
	CToolBarCmdUI state;
	state.m_pOther = this;
	
	state.m_nIndexMax = ( UINT ) DefWindowProc( TB_BUTTONCOUNT, 0, 0 );
	for ( state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; state.m_nIndex++ )
	{
		TBBUTTON button;
		VERIFY( DefWindowProc( TB_GETBUTTON, state.m_nIndex, ( LPARAM ) &button ) );
		button.fsState ^= TBSTATE_ENABLED;
		
		state.m_nID = button.idCommand;
		
		if ( !( button.fsStyle & TBSTYLE_SEP ) )
		{
			if ( CWnd::OnCmdMsg( state.m_nID, CN_UPDATE_COMMAND_UI, &state, NULL ) )
				continue;
			
			state.DoUpdate( pTarget, bDisableIfNoHndler );
		}
	}
	
	UpdateDialogControls( pTarget, bDisableIfNoHndler );
}

void CExToolBar::OnNcPaint( void ) 
{
	CControlBar::EraseNonClient();
	CWindowDC dc( this );
	DrawGripper( dc );
	
	CRect pRect;
	GetClientRect( &pRect );
	InvalidateRect( &pRect, TRUE );
	
	CWnd* pWnd = &GetToolBarCtrl();
	pWnd->GetClientRect( &pRect ); 
	pWnd->InvalidateRect( &pRect, TRUE ); 
}

int CExToolBar::OnCreate( 
    LPCREATESTRUCT lpCreateStruct )
{
	if ( CToolBar::OnCreate( lpCreateStruct ) == -1 )
    {
		return -1;
    }
	
	ModifyStyle( 0, TBSTYLE_FLAT );
	SendMessage( TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS );
    
	return 0;
}

void CExToolBar::OnNcCalcSize(
     BOOL bCalcValidRects,
     NCCALCSIZE_PARAMS FAR* lpncsp )
{

	if( !( m_dwStyle & CBRS_FLOATING ) )
    {
	    if( m_dwStyle & CBRS_ORIENT_HORZ ) {
		    lpncsp->rgrc[0].left += 5;
		    lpncsp->rgrc[0].right += 5;
	    }
	    else {
		    lpncsp->rgrc[0].top += 5;
		    lpncsp->rgrc[0].bottom += 5;
	    }
    }
	
	CToolBar::OnNcCalcSize( bCalcValidRects, lpncsp );
}

void CExToolBar::OnSysColorChange( void ) 
{
    CToolBar::OnSysColorChange();
}

void CExToolBar::OnWindowPosChanging( LPWINDOWPOS _pWindowPos ) 
{
    if( m_bOldFloating != ( IsFloating()?true:false ) )
    {
        m_bOldFloating = !m_bOldFloating;
        _pWindowPos->flags |= SWP_DRAWFRAME;
    }
    CToolBar::OnWindowPosChanging( _pWindowPos );
}           

void CToolBarCmdUI::Enable( BOOL bOn )
{
	m_bEnableChanged = TRUE;
	CToolBar* pToolBar = ( CToolBar* ) m_pOther;
	ASSERT( pToolBar != NULL );
	ASSERT_KINDOF( CToolBar, pToolBar );
	ASSERT( m_nIndex < m_nIndexMax );
	
	UINT nNewStyle = pToolBar->GetButtonStyle( m_nIndex ) & ~TBBS_DISABLED;
	if ( !bOn )
	{
		nNewStyle |= TBBS_DISABLED;
		nNewStyle &= ~TBBS_PRESSED;
	}
	ASSERT( !( nNewStyle & TBBS_SEPARATOR ) );
	pToolBar->SetButtonStyle( m_nIndex, nNewStyle );
}

void CToolBarCmdUI::SetCheck( int nCheck )
{
	ASSERT( nCheck >= 0 && nCheck <= 2 );
	CToolBar* pToolBar = ( CToolBar* ) m_pOther;
	ASSERT( pToolBar != NULL );
	ASSERT_KINDOF( CToolBar, pToolBar );
	ASSERT( m_nIndex < m_nIndexMax );
	
	UINT nOldStyle = pToolBar->GetButtonStyle( m_nIndex );
	UINT nNewStyle = nOldStyle &
		~( TBBS_PRESSED | TBBS_INDETERMINATE );
	if ( nCheck == 1 )
		nNewStyle |= TBBS_PRESSED;
	else if ( nCheck == 2 )
		nNewStyle |= TBBS_INDETERMINATE;
	
	if ( nNewStyle != nOldStyle ) {
		ASSERT( !( nNewStyle & TBBS_SEPARATOR ) );
		pToolBar->SetButtonStyle( m_nIndex, nNewStyle );
		pToolBar->Invalidate();
	}
}

CSize CExToolBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
	if ((nLength == -1)	&& 
	   !(dwMode & LM_MRUWIDTH) && !(dwMode & LM_COMMIT) &&
	   ((dwMode & LM_HORZDOCK) ||  (dwMode & LM_VERTDOCK)))
	{
		return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZDOCK);
	}

	return CalcLayout(dwMode, nLength);
}

CSize CExToolBar::GetButtonSize(TBBUTTON* pData, int iButton)
{
	CRect rc;
	SendMessage(TB_GETITEMRECT, iButton, (LPARAM)&rc);
	CSize sz = rc.Size();
	
	DWORD dwStyle = pData[iButton].fsStyle;
	if ((pData[iButton].fsState & TBSTATE_WRAP)) {
		if (dwStyle & TBSTYLE_SEP) {
			sz.cy = sz.cx;
			sz.cx = 0;
			
        } else if (dwStyle & TBSTYLE_DROPDOWN ) {//&&
			sz.cx = 0;
		}
	}
	return sz;
}

void CExToolBar::GetButton(int nIndex, TBBUTTON* pButton) const
{
	CToolBar* pBar = (CToolBar*)this;
	VERIFY(pBar->SendMessage(TB_GETBUTTON, nIndex, (LPARAM)pButton));
	pButton->fsState ^= TBSTATE_ENABLED;
}

void CExToolBar::SetButton(int nIndex, TBBUTTON* pButton)
{
	TBBUTTON button;
	VERIFY(SendMessage(TB_GETBUTTON, nIndex, (LPARAM)&button));
	
	button.bReserved[0] = 0;
	button.bReserved[1] = 0;
	pButton->fsState ^= TBSTATE_ENABLED;
	pButton->bReserved[0] = 0;
	pButton->bReserved[1] = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?