📄 ctrlcoolbar.cpp
字号:
//
// 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 + -