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

📄 ctrlcoolbar.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// CtrlCoolBar.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "CtrlCoolBar.h"
#include "CoolInterface.h"
#include "Skin.h"

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

IMPLEMENT_DYNAMIC(CCoolBarCtrl, CControlBar)

BEGIN_MESSAGE_MAP(CCoolBarCtrl, CControlBar)
	//{{AFX_MSG_MAP(CCoolBarCtrl)
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_HSCROLL()
	ON_WM_CTLCOLOR()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

#define DEFAULT_HEIGHT		30
#define GRIPPER_WIDTH		4
#define SEPARATOR_WIDTH		7
#define MARGIN_WIDTH		5

#define BUTTON_WIDTH		9
#define IMAGE_WIDTH			16
#define IMAGEBUTTON_WIDTH	25	// ( BUTTON_WIDTH + IMAGE_WIDTH )
#define TEXT_GAP			4
#define CONTROL_HEIGHT		19


/////////////////////////////////////////////////////////////////////////////
// CCoolBar construction

CCoolBarCtrl::CCoolBarCtrl()
{
	m_bStretch		= FALSE;
	m_nHeight		= DEFAULT_HEIGHT;
	m_bGripper		= FALSE;
	m_bBold			= FALSE;
	m_bDragForward	= FALSE;
	m_pSyncObject	= NULL;
	m_bBuffered		= FALSE;
	m_bMenuGray		= FALSE;
	
	m_pDown		= NULL;
	m_pHot		= NULL;
	m_bTimer	= FALSE;
	m_crBack	= 0;
	m_bRecalc	= FALSE;
}

CCoolBarCtrl::~CCoolBarCtrl()
{
	Clear();
}

/////////////////////////////////////////////////////////////////////////////
// CCoolBar system operations

BOOL CCoolBarCtrl::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
{
	CRect rc;
	dwStyle |= WS_CHILD;
	return CWnd::Create( NULL, NULL, dwStyle, rc, pParentWnd, nID, NULL );
}

void CCoolBarCtrl::SetSize(int nHeight, BOOL bStretch)
{
	m_bStretch	= bStretch;
	m_nHeight	= nHeight < 1 ? DEFAULT_HEIGHT : nHeight;

	SetWindowPos( NULL, 0, 0, 0, 0,
		SWP_DRAWFRAME|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER );
}

void CCoolBarCtrl::SetGripper(BOOL bGripper)
{
	m_bGripper = bGripper;
}

void CCoolBarCtrl::SetBold(BOOL bBold)
{
	m_bBold = bBold;
	OnUpdated();
}

void CCoolBarCtrl::SetDragForward(BOOL bForward)
{
	m_bDragForward = bForward;
}

void CCoolBarCtrl::SetWatermark(HBITMAP hBitmap, BOOL bDetach)
{
	if ( m_bmImage.m_hObject )
	{
		if ( bDetach )
		{
			m_bmImage.Detach();
		}
		else
		{
			m_bmImage.DeleteObject();
		}
	}

	if ( hBitmap ) m_bmImage.Attach( hBitmap );
}

void CCoolBarCtrl::SetSyncObject(CSyncObject* pSyncObject)
{
	m_pSyncObject = pSyncObject;
}

/////////////////////////////////////////////////////////////////////////////
// CCoolBar item operations

CCoolBarItem* CCoolBarCtrl::Add(UINT nID, LPCTSTR pszText, int nPosition)
{
	CCoolBarItem* pItem = new CCoolBarItem( this, nID );
	
	if ( nPosition == -1 )
	{
		m_pItems.AddTail( pItem );
	}
	else
	{
		POSITION pos = m_pItems.FindIndex( nPosition );
		if ( pos ) m_pItems.InsertBefore( pos, pItem ); else m_pItems.AddTail( pItem );
	}
	
	pItem->m_nImage = CoolInterface.ImageForID( nID );
	
	if ( pszText ) pItem->SetText( pszText );
	
	return pItem;
}

CCoolBarItem* CCoolBarCtrl::Add(UINT nCtrlID, int nWidth, int nHeight)
{
	CCoolBarItem* pItem = new CCoolBarItem( this, nCtrlID );
	m_pItems.AddTail( pItem );
	
	pItem->m_nCtrlID		= nCtrlID;
	pItem->m_nWidth			= nWidth;
	pItem->m_nCtrlHeight	= nHeight ? nHeight : CONTROL_HEIGHT;
	
	return pItem;
}

CCoolBarItem* CCoolBarCtrl::GetIndex(int nIndex) const
{
	for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; )
	{
		CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos );
		if ( ! nIndex-- ) return pItem;
	}
	
	return NULL;
}

CCoolBarItem* CCoolBarCtrl::GetID(UINT nID) const
{
	for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; )
	{
		CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos );
		if ( pItem->m_nID == nID ) return pItem;
	}
	
	return NULL;
}

int CCoolBarCtrl::GetIndexForID(UINT nID) const
{
	int nIndex = 0;
	
	for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; nIndex++ )
	{
		CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos );
		if ( pItem->m_nID == nID ) return nIndex;
	}
	
	return -1;
}

int CCoolBarCtrl::GetCount() const
{
	return m_pItems.GetCount();
}

BOOL CCoolBarCtrl::LoadToolBar(UINT nIDToolBar)
{
	CToolBar pToolBar;
	
	if ( ! pToolBar.Create( this ) || ! pToolBar.LoadToolBar( nIDToolBar ) ) return FALSE;
	
	for ( int i = 0 ; i < pToolBar.GetCount(); i++ )
	{
		UINT nID, nStyle;
		int nImage;
		
		pToolBar.GetButtonInfo( i, nID, nStyle, nImage );
		
		Add( nID );
	}
	
	return TRUE;
}

void CCoolBarCtrl::Clear()
{
	for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; )
	{
		delete (CCoolBarItem*)m_pItems.GetNext( pos );
	}
	
	m_pItems.RemoveAll();
}

void CCoolBarCtrl::Copy(CCoolBarCtrl* pOther)
{
	Clear();
	
	for ( POSITION pos = pOther->m_pItems.GetHeadPosition() ; pos ; )
	{
		CCoolBarItem* pItem = (CCoolBarItem*)pOther->m_pItems.GetNext( pos );
		m_pItems.AddTail( new CCoolBarItem( this, pItem ) );
	}
}

UINT CCoolBarCtrl::ThrowMenu(UINT nID, CMenu* pMenu, CWnd* pParent, BOOL bCommand, BOOL bRight)
{
	if ( pMenu == NULL ) return 0;
	if ( pParent == NULL ) pParent = AfxGetMainWnd();
	if ( pParent == NULL ) pParent = this;
	
	m_pDown = GetID( nID );
	if ( m_pDown == NULL ) return 0;
	
	m_bMenuGray = TRUE;
	Invalidate();
	UpdateWindow();
	
	CRect rcButton;
	GetItemRect( m_pDown, &rcButton );
	ClientToScreen( &rcButton );
	rcButton.DeflateRect( 1, 2 );
	
	TPMPARAMS tpm;
	tpm.cbSize = sizeof(tpm);
	tpm.rcExclude = rcButton;
	
	DWORD nFlags = TPM_LEFTBUTTON|TPM_VERTICAL;
	
	if ( bCommand ) nFlags |= TPM_RETURNCMD;
	
#if 1
	CoolMenu.RegisterEdge( rcButton.left, rcButton.bottom, rcButton.Width() );
	bRight = FALSE;
#endif
	
	nFlags |= ( bRight ? TPM_RIGHTALIGN : TPM_LEFTALIGN );
	
	UINT nCmd = TrackPopupMenuEx( pMenu->GetSafeHmenu(), nFlags,
		bRight ? rcButton.right : rcButton.left, rcButton.bottom,
		pParent->GetSafeHwnd(), &tpm );
	
	m_bMenuGray = FALSE;
	m_pDown = NULL;
	Invalidate();
	
	return nCmd;
}

void CCoolBarCtrl::OnUpdated()
{
	if ( ! m_bStretch )
	{
		CSize czLast = m_czLast;
		
		if ( CalcFixedLayout( FALSE, TRUE ) != czLast )
		{
			CMDIFrameWnd* pOwner = (CMDIFrameWnd*)GetOwner();

			if ( pOwner && pOwner->IsKindOf( RUNTIME_CLASS(CMDIFrameWnd) ) )
			{
				if ( pOwner->IsIconic() )
					m_bRecalc = TRUE;
				else
					pOwner->RecalcLayout();
			}
		}
	}
	
	Invalidate();
}

/////////////////////////////////////////////////////////////////////////////
// CCoolBar message handlers

int CCoolBarCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CControlBar::OnCreate( lpCreateStruct ) == -1 ) return -1;
	m_dwStyle |= CBRS_BORDER_3D;
	return 0;
}

CSize CCoolBarCtrl::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
	if ( m_bStretch || bStretch )
	{
		CSize size( 32000, m_nHeight );

		if ( CWnd* pParent = AfxGetMainWnd() )
		{
			CRect rc;
			pParent->GetWindowRect( &rc );
			if ( rc.Width() > 32 ) size.cx = rc.Width() + 2;
		}

		m_czLast = size;

		return size;
	}
	else
	{
		CSize size( MARGIN_WIDTH * 2 + 5, m_nHeight );
		if ( m_bGripper ) size.cx += GRIPPER_WIDTH;

		for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; )
		{
			CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos );
			if ( pItem->m_bVisible ) size.cx += pItem->m_nWidth;
		}

		m_czLast = size;

		return size;
	}
}

void CCoolBarCtrl::PrepareRect(CRect* pRect) const
{
	CRect rcClient;
	GetClientRect( &rcClient );
	CalcInsideRect( rcClient, FALSE );

	rcClient.left -= m_cyTopBorder;
	rcClient.top -= m_cxLeftBorder;
	rcClient.right += m_cyBottomBorder;
	rcClient.bottom += m_cxRightBorder;

	pRect->SetRect( rcClient.left + MARGIN_WIDTH, rcClient.top + 1, rcClient.right - MARGIN_WIDTH, rcClient.bottom - 1 );
	if ( m_bGripper ) pRect->left += GRIPPER_WIDTH;
}

CCoolBarItem* CCoolBarCtrl::HitTest(const CPoint& point, CRect* pItemRect, BOOL bSeparators) const
{
	if ( m_pItems.IsEmpty() ) return NULL;

	BOOL bRight = FALSE;
	CRect rcClient, rcItem;

	PrepareRect( &rcClient );
	rcItem.CopyRect( &rcClient );
	
	for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; )
	{
		CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos );
		if ( ! pItem->m_bVisible ) continue;
		
		if ( pItem->m_nID == ID_RIGHTALIGN && ! bRight )
		{
			int nRight = 0;
			bRight = TRUE;
			
			for ( POSITION pos2 = pos ; pos2 ; )
			{
				CCoolBarItem* pRight = (CCoolBarItem*)m_pItems.GetNext( pos2 );
				if ( pRight->m_bVisible ) nRight += pRight->m_nWidth;
			}
			
			if ( rcClient.right - rcItem.left >= nRight )
			{
				rcItem.left = rcClient.right - nRight;
			}
		}
		else
		{
			rcItem.right = rcItem.left + pItem->m_nWidth;
			
			if ( rcItem.PtInRect( point ) )
			{
				if ( pItemRect ) *pItemRect = rcItem;
				return ( pItem->m_nID != ID_SEPARATOR || bSeparators ) ? pItem : NULL;
			}
			
			rcItem.OffsetRect( rcItem.Width(), 0 );
		}
	}

	return NULL;
}

BOOL CCoolBarCtrl::GetItemRect(CCoolBarItem* pFind, CRect* pRect) const
{
	if ( m_pItems.IsEmpty() ) return FALSE;
	
	BOOL bRight = FALSE;
	CRect rcClient, rcItem;
	
	PrepareRect( &rcClient );
	rcItem.CopyRect( &rcClient );
	
	for ( POSITION pos = m_pItems.GetHeadPosition() ; pos ; )
	{
		CCoolBarItem* pItem = (CCoolBarItem*)m_pItems.GetNext( pos );
		if ( ! pItem->m_bVisible ) continue;

		if ( pItem->m_nID == ID_RIGHTALIGN && ! bRight )
		{
			int nRight = 0;
			bRight = TRUE;
			
			for ( POSITION pos2 = pos ; pos2 ; )
			{
				CCoolBarItem* pRight = (CCoolBarItem*)m_pItems.GetNext( pos2 );
				if ( pRight->m_bVisible ) nRight += pRight->m_nWidth;
			}
			
			if ( rcClient.right - rcItem.left >= nRight )
			{
				rcItem.left = rcClient.right - nRight;
			}
		}
		else
		{
			rcItem.right = rcItem.left + pItem->m_nWidth;
			
			if ( pItem == pFind )
			{
				*pRect = rcItem;
				return TRUE;
			}
			
			rcItem.OffsetRect( rcItem.Width(), 0 );
		}
	}

	return FALSE;
}

int CCoolBarCtrl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
{
	CRect rcItem;
	CCoolBarItem* pItem = HitTest( point, &rcItem );

	if ( pItem == NULL ) return -1;
	if ( ! pTI ) return 1;

	pTI->uFlags		= 0;
	pTI->hwnd		= GetSafeHwnd();
	pTI->uId		= (UINT)pItem->m_nID;
	pTI->rect		= rcItem;
	pTI->lpszText	= LPSTR_TEXTCALLBACK;

	if ( pItem->m_sTip.GetLength() )
	{
		pTI->lpszText = _tcsdup( pItem->m_sTip );
	}
	else
	{
		CString strTip;

		if ( LoadString( strTip, pTI->uId ) )
		{
			if ( LPCTSTR pszBreak = _tcschr( strTip, '\n' ) )
			{
				pTI->lpszText = _tcsdup( pszBreak + 1 );
			}
			else
			{
				strTip = strTip.SpanExcluding( _T(".") );
				pTI->lpszText = _tcsdup( strTip );
			}
		}
	}

	return pTI->uId;
}

void CCoolBarCtrl::DoPaint(CDC* pDC)
{
	ASSERT_VALID( this );
	ASSERT_VALID( pDC );
	
	CRect rc;
	GetClientRect( &rc );
	
	if ( m_bBuffered || m_bmImage.m_hObject != NULL )
	{
		CDC* pBuffer = CoolInterface.GetBuffer( *pDC, rc.Size() );
		
		if ( CoolInterface.DrawWatermark( pBuffer, &rc, &m_bmImage ) )
		{
			CalcInsideRect( rc, FALSE );
			rc.left -= m_cyTopBorder;
			rc.top -= m_cxLeftBorder;
			rc.right += m_cyBottomBorder;
			rc.bottom += m_cxRightBorder;
		}
		else
		{
			DrawBorders( pBuffer, rc );
		}
		
		DoPaint( pBuffer, rc, TRUE );
		
		GetClientRect( &rc );
		pDC->BitBlt( 0, 0, rc.Width(), rc.Height(), pBuffer, 0, 0, SRCCOPY );
		pBuffer->SelectClipRgn( NULL );
	}
	else
	{
		DrawBorders( pDC, rc );
		DoPaint( pDC, rc, FALSE );
		pDC->FillSolidRect( &rc, CoolInterface.m_crMidtone );
	}
}

void CCoolBarCtrl::DoPaint(CDC* pDC, CRect& rcClient, BOOL bTransparent)
{
	CRect rcItem( rcClient.left + MARGIN_WIDTH, rcClient.top + 1, rcClient.right - MARGIN_WIDTH, rcClient.bottom - 1 );
	CRect rcCopy;
	
	if ( m_bGripper )
	{
		if ( bTransparent )
		{
			for ( int nY = rcClient.top + 4 ; nY < rcClient.bottom - 4 ; nY += 2 )
			{
				pDC->Draw3dRect( rcClient.left + 3, nY, GRIPPER_WIDTH, 1,
					CoolInterface.m_crDisabled, CoolInterface.m_crDisabled );
			}
		}
		else
		{
			for ( int nY = rcClient.top + 4 ; nY < rcClient.bottom - 4 ; nY += 2 )
			{
				pDC->Draw3dRect( rcClient.left + 3, nY, GRIPPER_WIDTH, 2,
					CoolInterface.m_crDisabled, CoolInterface.m_crMidtone );
			}
			
			pDC->ExcludeClipRect( rcClient.left + 3, rcClient.top + 4, rcClient.left + GRIPPER_WIDTH + 2, rcClient.bottom - 4 );
		}
		
		rcItem.left += GRIPPER_WIDTH;
	}
	
	if ( m_pItems.GetCount() == 0 ) return;
	
	CFont* pOldFont = (CFont*)pDC->SelectObject( m_bBold ? &CoolInterface.m_fntBold : &CoolInterface.m_fntNormal );

⌨️ 快捷键说明

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