📄 buttonslist.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This source code is a part of BCGControlBar library.
// You may use, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
//
// Stas Levin <stas@iet.co.il>
//*******************************************************************************
// ButtonsList.cpp : implementation file
//
#include "stdafx.h"
#include "afxadv.h"
#include <afxpriv.h>
#include "bcgbarres.h"
#include "ButtonsList.h"
#include "BCGToolbarButton.h"
#include "BCGToolBarImages.h"
#include "globals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static const int iXOffset = 4;
static const int iYOffset = 5;
/////////////////////////////////////////////////////////////////////////////
// CButtonsList
CButtonsList::CButtonsList()
{
m_pSelButton = NULL;
m_pImages = NULL;
m_iScrollOffset = 0;
m_iScrollTotal = 0;
m_iScrollPage = 0;
m_bEnableDragFromList = FALSE;
m_bInited = FALSE;
}
//**************************************************************************************
CButtonsList::~CButtonsList()
{
}
BEGIN_MESSAGE_MAP(CButtonsList, CButton)
//{{AFX_MSG_MAP(CButtonsList)
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_VSCROLL()
ON_WM_ENABLE()
ON_WM_SYSCOLORCHANGE()
ON_WM_SIZE()
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CButtonsList message handlers
BOOL CButtonsList::OnEraseBkgnd(CDC* pDC)
{
CRect rectClient; // Client area rectangle
GetClientRect (&rectClient);
pDC->FillSolidRect (&rectClient, ::GetSysColor (COLOR_3DFACE));
return TRUE;
}
//*********************************************************************************************
void CButtonsList::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
if (!m_bInited)
{
RebuildLocations ();
}
CDC* pDC = CDC::FromHandle (lpDIS->hDC);
CRect rectClient = lpDIS->rcItem;
if (m_pImages != NULL)
{
CBCGDrawState ds;
if (!m_pImages->PrepareDrawImage (ds))
{
return;
}
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
CRect rect = pButton->Rect ();
rect.OffsetRect (0, -m_iScrollOffset);
if (rect.top >= rectClient.bottom)
{
break;
}
if (rect.bottom > rectClient.top)
{
int nSaveStyle = pButton->m_nStyle;
if (!IsWindowEnabled ())
{
pButton->m_nStyle |= TBBS_DISABLED;
}
pButton->OnDraw (pDC, rect, m_pImages);
pButton->m_nStyle = nSaveStyle;
if (pButton == m_pSelButton && IsWindowEnabled ())
{
//--------------------
// Draw selection bar:
//--------------------
HWND hwndButton = pButton->GetHwnd ();
if (hwndButton != NULL)
{
rect.InflateRect (0, 2);
}
for (int i = 0; i < 2; i ++)
{
pDC->DrawFocusRect (&rect);
rect.InflateRect (-1, -1);
}
}
}
}
m_pImages->EndDrawImage (ds);
}
pDC->Draw3dRect (rectClient,
::GetSysColor (COLOR_3DSHADOW),
::GetSysColor (COLOR_3DHILIGHT));
}
//*********************************************************************************************
void CButtonsList::OnLButtonDown(UINT /*nFlags*/, CPoint point)
{
CBCGToolbarButton* pButton = HitTest (point);
if (pButton == NULL)
{
return;
}
SelectButton (pButton);
if (m_bEnableDragFromList)
{
COleDataSource srcItem;
pButton->m_bDragFromCollection = TRUE;
pButton->PrepareDrag (srcItem);
pButton->m_bDragFromCollection = TRUE;
srcItem.DoDragDrop ();
}
}
//*********************************************************************************************
void CButtonsList::SetImages (CBCGToolBarImages* pImages)
{
ASSERT_VALID (pImages);
m_pImages = pImages;
m_sizeButton.cx = m_pImages->GetImageSize ().cx + 6;
m_sizeButton.cy = m_pImages->GetImageSize ().cy + 7;
RemoveButtons ();
}
//*********************************************************************************************
void CButtonsList::AddButton (CBCGToolbarButton* pButton)
{
ASSERT_VALID (pButton);
ASSERT (m_pImages != NULL);
m_Buttons.AddTail (pButton);
pButton->OnChangeParentWnd (this);
RebuildLocations ();
HWND hwnd = pButton->GetHwnd ();
if (hwnd != NULL)
{
::EnableWindow (hwnd, FALSE);
}
}
//*********************************************************************************************
void CButtonsList::RemoveButtons ()
{
SelectButton ((CBCGToolbarButton*) NULL);
while (!m_Buttons.IsEmpty ())
{
CBCGToolbarButton* pButton =
(CBCGToolbarButton*) m_Buttons.RemoveHead ();
ASSERT_VALID (pButton);
pButton->OnChangeParentWnd (NULL);
}
m_iScrollOffset = 0;
m_iScrollTotal = 0;
m_iScrollPage = 0;
EnableScrollBarCtrl (SB_VERT, FALSE);
SetScrollRange (SB_VERT, 0, 0);
}
//*********************************************************************************************
CBCGToolbarButton* CButtonsList::HitTest (POINT point) const
{
CRect rectClient;
GetClientRect (&rectClient);
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
CRect rect = pButton->Rect ();
rect.OffsetRect (0, -m_iScrollOffset);
if (rect.PtInRect (point))
{
return pButton;
}
}
return NULL;
}
//*********************************************************************************************
void CButtonsList::SelectButton (CBCGToolbarButton* pButton)
{
if (m_pSelButton == pButton)
{
return;
}
CBCGToolbarButton* pOldSel = m_pSelButton;
m_pSelButton = pButton;
CRect rectClient;
GetClientRect (&rectClient);
CRect rectSelected;
rectSelected.SetRectEmpty ();
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pListButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pListButton != NULL);
CRect rect = pListButton->Rect ();
rect.OffsetRect (0, -m_iScrollOffset);
if (pListButton == m_pSelButton)
{
rectSelected = rect;
}
if (pListButton == m_pSelButton ||
pListButton == pOldSel)
{
rect.InflateRect (2, 2);
CRect rectInter;
if (rectInter.IntersectRect (rectClient, rect))
{
InvalidateRect (&rectInter);
}
}
}
if (!rectSelected.IsRectEmpty ())
{
if (rectSelected.top >= rectClient.bottom ||
rectSelected.bottom <= rectClient.top)
{
int iNewOffset =
max (0,
min (rectSelected.bottom - m_iScrollOffset - rectClient.Height (),
m_iScrollTotal));
SetScrollPos (SB_VERT, iNewOffset);
m_iScrollOffset = iNewOffset;
Invalidate ();
}
}
UpdateWindow ();
//-------------------------------------------------------
// Trigger mouse up event (to button click notification):
//-------------------------------------------------------
CWnd* pParent = GetParent ();
if (pParent != NULL)
{
pParent->SendMessage ( WM_COMMAND,
MAKEWPARAM (GetDlgCtrlID (), BN_CLICKED),
(LPARAM) m_hWnd);
}
}
//*********************************************************************************************
BOOL CButtonsList::SelectButton (int iImage)
{
if (iImage < 0)
{
SelectButton ((CBCGToolbarButton*) NULL);
return TRUE;
}
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pListButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pListButton != NULL);
if (pListButton->GetImage () == iImage)
{
SelectButton (pListButton);
return TRUE;
}
}
return FALSE;
}
//********************************************************************************
void CButtonsList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
int iScrollOffset = m_iScrollOffset;
switch (nSBCode)
{
case SB_TOP:
iScrollOffset = 0;
break;
case SB_BOTTOM:
iScrollOffset = m_iScrollTotal;
break;
case SB_LINEUP:
iScrollOffset -= m_sizeButton.cy + iYOffset;
break;
case SB_LINEDOWN:
iScrollOffset += m_sizeButton.cy + iYOffset;
break;
case SB_PAGEUP:
iScrollOffset -= m_iScrollPage * (m_sizeButton.cy + iYOffset);
break;
case SB_PAGEDOWN:
iScrollOffset += m_iScrollPage * (m_sizeButton.cy + iYOffset);
break;
case SB_THUMBPOSITION:
iScrollOffset = ((m_sizeButton.cy + iYOffset) / 2 + nPos) /
(m_sizeButton.cy + iYOffset) * (m_sizeButton.cy + iYOffset);
break;
default:
return;
}
iScrollOffset = min (m_iScrollTotal, max (iScrollOffset, 0));
if (iScrollOffset != m_iScrollOffset)
{
m_iScrollOffset = iScrollOffset;
SetScrollPos (SB_VERT, m_iScrollOffset);
CRect rectClient; // Client area rectangle
GetClientRect (&rectClient);
rectClient.right -= ::GetSystemMetrics (SM_CXVSCROLL) + 2;
rectClient.InflateRect (-1, -1);
InvalidateRect (rectClient);
}
}
//********************************************************************************
CScrollBar* CButtonsList::GetScrollBarCtrl(int nBar) const
{
if (nBar == SB_HORZ || m_wndScrollBar.GetSafeHwnd () == NULL)
{
return NULL;
}
return (CScrollBar* ) &m_wndScrollBar;
}
//********************************************************************************
void CButtonsList::OnEnable(BOOL bEnable)
{
CButton::OnEnable(bEnable);
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pListButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pListButton != NULL);
}
Invalidate ();
UpdateWindow ();
}
//********************************************************************************
void CButtonsList::OnSysColorChange()
{
if (m_pImages == NULL)
{
return;
}
m_pImages->OnSysColorChange ();
Invalidate ();
UpdateWindow ();
}
//*********************************************************************************
void CButtonsList::RebuildLocations ()
{
if (GetSafeHwnd () == NULL || m_Buttons.IsEmpty ())
{
return;
}
CRect rectClient;
GetClientRect (&rectClient);
CRect rectButtons = rectClient;
rectButtons.right -= ::GetSystemMetrics (SM_CXVSCROLL) + 1;
rectButtons.InflateRect (-iXOffset, -iYOffset);
int x = rectButtons.left;
int y = rectButtons.top - m_iScrollOffset;
CClientDC dc (this);
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT (pButton != NULL);
CSize sizeButton = pButton->OnCalculateSize (&dc, m_sizeButton, TRUE);
if (x + sizeButton.cx > rectButtons.right)
{
if (x == rectButtons.left)
{
sizeButton.cx = rectButtons.right - rectButtons.left;
}
else
{
x = rectButtons.left;
y += sizeButton.cy + iYOffset;
}
}
pButton->SetRect (CRect (CPoint (x, y),
CSize (sizeButton.cx, m_sizeButton.cy)));
x += sizeButton.cx + iXOffset;
}
CBCGToolbarButton* pLastButton = (CBCGToolbarButton*) m_Buttons.GetTail ();
ASSERT (pLastButton != NULL);
int iVisibleRows = rectButtons.Height () / (m_sizeButton.cy + iYOffset);
int iTotalRows = pLastButton->Rect ().bottom / (m_sizeButton.cy + iYOffset);
int iNonVisibleRows = iTotalRows - iVisibleRows;
if (iNonVisibleRows > 0) // Not enouth space.
{
if (m_wndScrollBar.GetSafeHwnd () == NULL)
{
CRect rectSB;
GetClientRect (&rectSB);
rectSB.InflateRect (-1, -1);
rectSB.left = rectSB.right - ::GetSystemMetrics (SM_CXVSCROLL) - 1;
m_wndScrollBar.Create (WS_CHILD | WS_VISIBLE | SBS_VERT,
rectSB, this, 1);
}
m_iScrollTotal = iNonVisibleRows * (m_sizeButton.cy + iYOffset);
m_iScrollPage = iVisibleRows;
SetScrollRange (SB_VERT, 0, m_iScrollTotal);
}
m_bInited = TRUE;
}
//*********************************************************************************
void CButtonsList::OnSize(UINT nType, int cx, int cy)
{
CButton::OnSize(nType, cx, cy);
RebuildLocations ();
}
//*********************************************************************************
HBRUSH CButtonsList::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CWnd::OnCtlColor (pDC, pWnd, nCtlColor);
for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;)
{
CBCGToolbarButton* pButton = (CBCGToolbarButton*) m_Buttons.GetNext (pos);
ASSERT_VALID (pButton);
HWND hwdList = pButton->GetHwnd ();
if (hwdList == NULL) // No control
{
continue;
}
if (hwdList == pWnd->GetSafeHwnd () ||
::IsChild (hwdList, pWnd->GetSafeHwnd ()))
{
HBRUSH hbrButton = pButton->OnCtlColor (pDC, nCtlColor);
return (hbrButton == NULL) ? hbr : hbrButton;
}
}
return hbr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -