⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toolbarex.cpp

📁 一个多窗口的浏览器的程序benbrowse
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////
// ToolBarEx.cpp: implementation of the CToolBarEx class.
//
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001 by Nikolay Denisov. All rights reserved.
//
// This code is free for personal and commercial use, providing this 
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Please email bug reports, bug fixes, enhancements, requests and
// comments to: nick@actor.ru
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CommonRes.h"
#include "../resource.h"
#include "CustomizeDialog.h"
#include "SizableReBar.h"
#include "ToolBarEx.h"
#include "WinAppEx.h"

#include <afxpriv.h>    // ON_MESSAGE_VOID()
#include "../generaldata.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

/////////////////////////////////////////////////////////////////////////////
// CToolBarEx

LPCTSTR             CToolBarEx::m_lpszStateInfoEntry = _T("ToolbarStateInfo (v1.01)");
CToolBarEx*         CToolBarEx::m_pToolBar           = 0;
CCustomizeDialog*   CToolBarEx::m_pCustomizeDlg      = 0;
HHOOK               CToolBarEx::m_hCBTHook           = 0;

IMPLEMENT_DYNAMIC( CToolBarEx, CToolBar )

CToolBarEx::CToolBarEx()
{
    m_eTextOptions = toNone;    // no options selected yet
    m_eIconOptions = ioNone;
	m_customize    = TRUE;
}

CToolBarEx::~CToolBarEx()
{
}

BOOL CToolBarEx::Create( CWnd* pParentWnd, DWORD dwStyle, UINT nID /*=AFX_IDW_TOOLBAR*/ )
{
    if ( !CreateEx( pParentWnd,
            TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_TOOLTIPS,
            dwStyle & ~CBRS_TOOLTIPS, CRect( 0, 0, 0, 0 ), nID ) )
    {
        return false;
    }

    GetToolBarCtrl().SetExtendedStyle(
        TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_HIDECLIPPEDBUTTONS );

    return true;
}

/////////////////////////////////////////////////////////////////////////////
// Attributes

void CToolBarEx::SetTextOptions( ETextOptions eTextOptions, bool bUpdate /*=true*/ )
{
    ASSERT( ::IsWindow( m_hWnd ) );
    ASSERT( GetStyle() & TBSTYLE_TOOLTIPS );
    ASSERT( !( GetBarStyle() & CBRS_TOOLTIPS ) );
    ASSERT( IsTextOptionAvailable( eTextOptions ) );

    m_eTextOptions = eTextOptions;

    // Modify toolbar style according to new text options
    ModifyStyle(
        ( eTextOptions == toTextOnRight ) ? 0 : TBSTYLE_LIST,
        ( eTextOptions == toTextOnRight ) ? TBSTYLE_LIST : 0 );

    CToolBarCtrl& tbCtrl = GetToolBarCtrl();
    DWORD dwStyleEx = tbCtrl.GetExtendedStyle();
    tbCtrl.SetExtendedStyle(
        ( eTextOptions == toTextOnRight ) ?
            ( dwStyleEx |  TBSTYLE_EX_MIXEDBUTTONS ) :
            ( dwStyleEx & ~TBSTYLE_EX_MIXEDBUTTONS ) );
    VERIFY( tbCtrl.SetMaxTextRows(
        ( eTextOptions == toNoTextLabels ) ? 0 : 1 ) );

    // Modify all (even currently hidden ones) buttons in internal cache
    int nIndex;
    for ( nIndex = 0; nIndex <= m_aButtons.GetUpperBound(); nIndex++ )
    {
        TBBUTTON& tbinfo = m_aButtons[ nIndex ].tbinfo;
        if ( !( tbinfo.fsStyle & TBSTYLE_SEP ) )
        {
            CString strButtonText;
	
			GetButtonText( tbinfo.idCommand,strButtonText);
			//strButtonText  =  m_aButtons[ nIndex ].btntext;
            CString strToAdd( strButtonText, strButtonText.GetLength() + 1 );
            tbinfo.iString = tbCtrl.AddStrings( strToAdd );

            switch ( eTextOptions )
            {
                case toTextLabels:
                    tbinfo.fsStyle &= ~( TBSTYLE_AUTOSIZE | BTNS_SHOWTEXT );
                    break;

                case toTextOnRight:
                    tbinfo.fsStyle |= ( TBSTYLE_AUTOSIZE |
                        ( HasButtonText( tbinfo.idCommand ) ? BTNS_SHOWTEXT : 0 ) );
                    break;

                case toNoTextLabels:
                    tbinfo.fsStyle &= ~BTNS_SHOWTEXT;
                    tbinfo.fsStyle |= TBSTYLE_AUTOSIZE;
                    break;
            }
        }
    }

    // If requested, reflect changes immediately
    if ( bUpdate )
    {
        ReloadButtons();
        UpdateParentBandInfo();
    }
}

ETextOptions CToolBarEx::GetTextOptions() const
{
    return m_eTextOptions;
}

void CToolBarEx::SetIconOptions( EIconOptions eIconOptions, bool bUpdate /*=true*/ )
{
    ASSERT( ::IsWindow( m_hWnd ) );
    ASSERT( IsIconOptionAvailable( eIconOptions ) );

    m_eIconOptions = eIconOptions;

    // Set image list(s) and icon size for selected icon options
    CToolBarCtrl& tbCtrl = GetToolBarCtrl();
    tbCtrl.SetImageList( 0 );
    tbCtrl.SetHotImageList( 0 );

    CSize szIcon = ( eIconOptions == ioSmallIcons ) ? szImageSmall : szImageLarge;
    VERIFY( tbCtrl.SetBitmapSize( szIcon ) );

    UINT nIDCold = ( eIconOptions == ioSmallIcons ) ? m_nIDSmallCold : m_nIDLargeCold;
    UINT nIDHot  = ( eIconOptions == ioSmallIcons ) ? m_nIDSmallHot  : m_nIDLargeHot;
    ASSERT( nIDCold != ( UINT )-1 );    // at least there must be "cold" imagelist

    m_imageListCold.DeleteImageList();
    VERIFY( m_imageListCold.Attach( ImageList_LoadImage( AfxGetResourceHandle(),
      MAKEINTRESOURCE( nIDCold ), szIcon.cx, 0, RGB(255,0,255),
        IMAGE_BITMAP, LR_CREATEDIBSECTION ) ) );
    tbCtrl.SetImageList( &m_imageListCold );
/////////////

/////////////
    if ( nIDHot != ( UINT )-1 ) // "hot" imagelist is optional
    {
        m_imageListHot.DeleteImageList();
		//m_imageListHot.Create(16, 16, ILC_COLORDDB|ILC_MASK, 40, 1);
        VERIFY( m_imageListHot.Attach( ImageList_LoadImage( AfxGetResourceHandle(),
            MAKEINTRESOURCE( nIDHot ), szIcon.cx, 0, m_clrMask,
            IMAGE_BITMAP, LR_CREATEDIBSECTION ) ) );
        tbCtrl.SetHotImageList( &m_imageListHot );
    }
	else
	{
		int nCount = m_imageListCold.GetImageCount();
		if(nCount>0)
		{
			m_imageListHot.DeleteImageList();
			m_imageListDisabled.DeleteImageList();
			m_imageListDisabled.Create(szIcon.cx,szIcon.cy,ILC_COLORDDB|ILC_MASK,0,10);
			m_imageListHot.Create(szIcon.cx,szIcon.cy,ILC_COLORDDB|ILC_MASK,0,10);
			for(int nIndex=0;nIndex<nCount;nIndex++)
			{
				HICON hIcon = m_imageListCold.ExtractIcon(nIndex);
			//	m_imageListHot.Add(hIcon);
				AddGloomIcon(&m_imageListHot,hIcon);
				AddGrayIcon(&m_imageListDisabled,hIcon);	
				DestroyIcon(hIcon);
			}
			tbCtrl.SetHotImageList(&m_imageListHot);
			tbCtrl.SetDisabledImageList(&m_imageListDisabled);
		}
	}
    // If requested, reflect changes immediately
    if ( bUpdate )
    {
        ReloadButtons();
        UpdateParentBandInfo();
    }
}

EIconOptions CToolBarEx::GetIconOptions() const
{
    return m_eIconOptions;
}

/////////////////////////////////////////////////////////////////////////////
// Operations

void CToolBarEx::SetBitmaps( UINT nIDSmallCold, UINT nIDSmallHot,
                             UINT nIDLargeCold, UINT nIDLargeHot,
                             EIconOptions eIconOptionsDefault,
                             COLORREF clrMask /*=RGB(255,0,255)*/ )
{
    m_nIDSmallCold = nIDSmallCold;
    m_nIDSmallHot  = nIDSmallHot;
    m_nIDLargeCold = nIDLargeCold;
    m_nIDLargeHot  = nIDLargeHot;
    m_clrMask      = clrMask;

    m_eIconOptionsDefault = eIconOptionsDefault;    // to be used on reset
    SetIconOptions( m_eIconOptionsDefault );        // apply new options
}

void CToolBarEx::SetButtons( int nNumButtons, TBBUTTONEX* lpButtons,
                             ETextOptions eTextOptionsDefault )
{
    // Delete old buttons
    CToolBarCtrl& tbCtrl = GetToolBarCtrl();
    while ( tbCtrl.DeleteButton( 0 ) );

    // Load buttons from provided array
    m_aButtons.RemoveAll();
    for ( int nIndex = 0; nIndex < nNumButtons; nIndex++ )
    {
        if ( lpButtons[ nIndex ].bInitiallyVisible )
        {
            VERIFY( tbCtrl.AddButtons( 1, &lpButtons[ nIndex ].tbinfo ) );
        }

        m_aButtons.Add( lpButtons[ nIndex ] );
    }

    m_eTextOptionsDefault = eTextOptionsDefault;    // to be used on reset
    SetTextOptions( m_eTextOptionsDefault );        // apply new options
}

void CToolBarEx::LoadState( LPCTSTR lpszProfileName )
{
    CString strSubKey;
    strSubKey.Format( _T("Software\\%s\\%s\\%s"),
        AfxGetApp()->m_pszRegistryKey,
        AfxGetApp()->m_pszProfileName,
        lpszProfileName );
    GetToolBarCtrl().RestoreState( HKEY_CURRENT_USER,
        strSubKey, m_lpszStateInfoEntry );

// It was found out that TB_SAVERESTORE causes TBN_BEGINADJUST
// and TBN_ENDADJUST to be sent correspondingly at the beggining
// and the end of save/restore process.  So, the following
// call is redundant and therefore was commented out.

//    UpdateParentBandInfo();
}

void CToolBarEx::SaveState( LPCTSTR lpszProfileName )
{
    CString strSubKey;
    strSubKey.Format( _T("Software\\%s\\%s\\%s"),
        AfxGetApp()->m_pszRegistryKey,
        AfxGetApp()->m_pszProfileName,
        lpszProfileName );
    GetToolBarCtrl().SaveState( HKEY_CURRENT_USER,
        strSubKey, m_lpszStateInfoEntry );
}

/////////////////////////////////////////////////////////////////////////////
// Overrides

BOOL CToolBarEx::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult )
{
    NMHDR* pNMHDR = ( NMHDR* )lParam;
    if ( ( pNMHDR->code == TTN_NEEDTEXTA ) ||
         ( pNMHDR->code == TTN_NEEDTEXTW ) )
    {
        // If button doesn't have a tip, ignore notification
        *pResult = HasButtonTip( pNMHDR->idFrom ) ? Default() : 0;
        return TRUE;
    }

    return CToolBar::OnNotify( wParam, lParam, pResult );
}

LRESULT CToolBarEx::DoCustomDraw( NMHDR* pNMHDR, CWnd* pToolBar )
{
    LPNMTBCUSTOMDRAW lpNMCustomDraw = ( LPNMTBCUSTOMDRAW )pNMHDR;

    switch ( lpNMCustomDraw->nmcd.dwDrawStage )
    {
        case CDDS_PREPAINT:
            return CDRF_NOTIFYITEMDRAW;

        case CDDS_ITEMPREPAINT:
        {
            UINT nID = lpNMCustomDraw->nmcd.dwItemSpec;
            bool bHot = ( lpNMCustomDraw->nmcd.uItemState & CDIS_HOT ) != 0;
            if ( pToolBar->SendMessage( TB_ISBUTTONCHECKED, nID ) &&
                 pToolBar->SendMessage( TB_ISBUTTONENABLED, nID ) && bHot )
            {
                // I personally don't like when background of checked item
                // which is currently hot is drawn using dither brush
                lpNMCustomDraw->hbrMonoDither = 0;
            }
            // fall through...
        }
        default:
            return CDRF_DODEFAULT;
    }
}

bool CToolBarEx::HasButtonText( UINT /*nID*/ )
{
    return true;
}

bool CToolBarEx::HasButtonTip( UINT nID )
{
    switch ( m_eTextOptions )
    {
        case toTextLabels:
            return false;
        case toTextOnRight:
            return !HasButtonText( nID );
        case toNoTextLabels:
            return true;
        default:
            ASSERT( false );
            return false;
    }
}

void CToolBarEx::GetButtonText( UINT nID, CString& strText )
{
	CString strFull,strNew;
    if(strFull.LoadString( nID ) )
	{
		GetText(strFull,strNew,menuhint_item_text);
		( AfxExtractSubString( strText, strNew, 1, _T('|') ) );	
	}
	else
		{

		int index=CommandToIndex(nID);
		if(index>=0&&index<m_itemName.GetCount())
			strText=m_itemName.GetAt(m_itemName.FindIndex(index));
	}
		
}

void CToolBarEx::GetButtonTip( UINT nID, CString& strTip)
{
    GetButtonText( nID, strTip);
}

void CToolBarEx::Init()
{
    ASSERT( false );    // must be overridden
}

bool CToolBarEx::IsTextOptionAvailable( ETextOptions /*eTextOptions*/ ) const
{
    return true;
}

bool CToolBarEx::IsIconOptionAvailable( EIconOptions /*eIconOptions*/ ) const
{
    return true;
}

/////////////////////////////////////////////////////////////////////////////
// Implementation

CReBarCtrl& CToolBarEx::GetParentReBarCtrl() const
{
    return STATIC_DOWNCAST( CReBar, GetParent() )->GetReBarCtrl();
}

int CToolBarEx::GetParentBandIndex() const
{
    int nBand = GetParentReBarCtrl().IDToIndex( ( UINT )GetDlgCtrlID() );
    ASSERT( nBand != -1 );
    return nBand;
}

void CToolBarEx::ReloadButtons()
{
    // Reload buttons from internal cache
    CToolBarCtrl& tbCtrl = GetToolBarCtrl();
    for ( int nIndex = 0, nButtons = tbCtrl.GetButtonCount(); nIndex < nButtons; nIndex++ )
    {
        TBBUTTON tbinfo;
        VERIFY( tbCtrl.GetButton( 0, &tbinfo ) );
        VERIFY( GetButtonInfo( tbinfo.idCommand, tbinfo ) );
        VERIFY( tbCtrl.DeleteButton( 0 ) );
        VERIFY( tbCtrl.AddButtons( 1, &tbinfo ) );
    }
}

void CToolBarEx::UpdateParentBandInfo()
{
    CToolBarCtrl& tbCtrl = GetToolBarCtrl();
    tbCtrl.AutoSize();

    // Calculate desired height and ideal width of the bar
    CRect rcItem;
    int cyChild = 0;
    int cxIdeal = 0;
    for ( int nIndex = 0, nButtons = tbCtrl.GetButtonCount(); nIndex < nButtons; nIndex++ )
    {
        if ( tbCtrl.GetItemRect( nIndex, rcItem ) )
        {
            cxIdeal += rcItem.Width();
            cyChild = max( cyChild, rcItem.Height() );
        }
    }

    // Modify parent band info accordingly
    REBARBANDINFO rbbi;
    rbbi.cbSize     = sizeof( rbbi );
    rbbi.fMask      = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
    rbbi.cxIdeal    = cxIdeal;
    rbbi.cxMinChild = 0;
    rbbi.cyMinChild = cyChild;
    VERIFY( GetParentReBarCtrl().SetBandInfo( GetParentBandIndex(), &rbbi ) );

    Invalidate();   // visual feedback
	
}

bool CToolBarEx::GetButtonInfo( UINT nID, TBBUTTON& tbinfo )
{
    if ( tbinfo.fsStyle & TBSTYLE_SEP )
    {
        return true;
    }

    for ( int nIndex = 0; nIndex <= m_aButtons.GetUpperBound(); nIndex++ )
    {
        if ( ( UINT )m_aButtons[ nIndex ].tbinfo.idCommand == nID )
        {
            tbinfo = m_aButtons[ nIndex ].tbinfo;
            return true;
        }
    }

    return false;
}

/////////////////////////////////////////////////////////////////////////
// CToolBarEx message handlers

BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
    //{{AFX_MSG_MAP(CToolBarEx)
    ON_COMMAND(ID_CUSTOMIZE, OnCustomize)
    //}}AFX_MSG_MAP

    ON_MESSAGE( WM_REBAR_CONTEXTMENU, OnReBarContextMenu )
    ON_MESSAGE( WM_REBAR_CHEVRONPUSHED, OnReBarChevronPushed )

⌨️ 快捷键说明

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