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

📄 buttonslist.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 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 + -