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

📄 macbuttons.cpp

📁 这是我仿照串口助手(龚建伟)作的一个例子并修正了其中的一些bug
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
// MacButtons.cpp : implementation file
//
// Feel free to modifiy and/or distribute this file, but
// do not remove this header.
//
// I would appreciate a notification of any bugs discovered or 
// improvements that could be made.
//
// This file is provided "as is" with no expressed or implied warranty.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MacButtons.h"

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


/////////////////////////////////////////////////////////////////////////////
//
//	CMacButton class, version 2.0
//
//	Copyright (c) 1999 Paul Meidinger (pmmeidinger@yahoo.com)
//
//	History:
//		PMM	12/13/1999		Initial implementation.		
//
//		PMM	12/29/1999		Minor changes made.
//
/////////////////////////////////////////////////////////////////////////////

//-------------------------------------------------------------------
//
CMacButton::CMacButton()
//
// Return Value:	None.
//
// Parameters	:	None.
//
// Remarks		:	Standard constructor.
//
{
	m_nType = TYPE_STANDARD;

	m_nCheck = 0;
	m_bMouseDown = FALSE;

	m_bBold = FALSE;

	m_hIcon = NULL;
	m_hBitmap = NULL;
	m_sizeImage = CSize(0, 0);

	m_nImageEffect = 0;

	GetColors();
	CreatePens();
}	// CMacButton

//-------------------------------------------------------------------
//
CMacButton::~CMacButton()
//
// Return Value:	None.
//
// Parameters	:	None.
//
// Remarks		:	Destructor.
//
{
	DeletePens();
}	// ~CMacButton


BEGIN_MESSAGE_MAP(CMacButton, CButton)
	//{{AFX_MSG_MAP(CMacButton)
	ON_WM_SYSCOLORCHANGE()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMacButton message handlers

//-------------------------------------------------------------------
//
void CMacButton::PreSubclassWindow() 
//
// Return Value:	None.
//
// Parameters	:	None.
//
// Remarks		:	This member function is called by the framework to 
//						allow other necessary subclassing to occur before the 
//						window is subclassed. Adds the BS_OWNERDRAW style.
//
{
	CButton::PreSubclassWindow();
	ModifyStyle(0, BS_OWNERDRAW);
}	// PreSubclassWindow

//-------------------------------------------------------------------
//
void CMacButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) 
//
// Return Value:	None.
//
// Parameters	:	lpDIS - A long pointer to a DRAWITEMSTRUCT structure.
//
// Remarks		:	Called by the framework when a visual aspect of an 
//						owner-drawn button has changed.
//
{
	DrawButton(lpDIS);
}	// DrawItem

//-------------------------------------------------------------------
//
void CMacButton::DrawButton(LPDRAWITEMSTRUCT lpDIS)
//
// Return Value:	None.
//
// Parameters	:	lpDIS - A long pointer to a DRAWITEMSTRUCT structure.
//
// Remarks		:	Draws a Mac button.
//
{
	CDC* pDC = CDC::FromHandle(lpDIS->hDC);
	CRect rectItem(lpDIS->rcItem);

	UINT nState = lpDIS->itemState;
	UINT nStyle = GetStyle();
	BOOL bPushLike = BOOL(nStyle & BS_PUSHLIKE);

	// Create a mem DC for drawing
	CDC dcMem;
	dcMem.CreateCompatibleDC(pDC);
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(pDC, rectItem.Width(), rectItem.Height());
	CBitmap *pOldBmp = dcMem.SelectObject(&bmp);

	int nSaveDC = dcMem.SaveDC();

	CBrush *pOldBrush = (CBrush *)dcMem.SelectStockObject(NULL_BRUSH);
	dcMem.FillSolidRect(rectItem, m_crFace);

	// If the button is standard or pushlike, draw it now.
	// Wait until after drawing the text/image and focus to draw
	//	the radio button or check box. This way, the text or image
	// will not cover the radio or check.
	if (m_nType == TYPE_STANDARD)
		DrawStandardButton(&dcMem, rectItem, nStyle, nState);
	else if (bPushLike)
		DrawPushLikeButton(&dcMem, rectItem, nStyle, nState);

	CRect rectText(rectItem);
	CRect rectImage(rectItem);
	CString sText;
	GetWindowText(sText);

	// Draw an image or the text.
	if (m_hIcon || m_hBitmap)
		DrawImage(&dcMem, rectImage, nStyle, nState);
	else
		DrawButtonText(&dcMem, rectText, sText, nStyle, nState);

	// Draw the focus rect.
	if (nState & ODS_FOCUS)
	{
		if ((m_nType == TYPE_STANDARD) || bPushLike)
		{
			rectText = lpDIS->rcItem;
			rectText.DeflateRect(4, 4, 4, 4);
			dcMem.DrawFocusRect(rectText);
		}
		else if (m_hIcon || m_hBitmap)
		{
			rectImage.InflateRect(1, 1, 1, 1);
			if (rectImage.top < rectItem.top)
				rectImage.top = rectItem.top;
			if (rectImage.bottom > rectItem.bottom)
				rectImage.bottom = rectItem.bottom;
			if (rectImage.left < rectItem.left)
				rectImage.left = rectItem.left;
			if (rectImage.right > rectItem.right)
				rectImage.right = rectItem.right;

			dcMem.DrawFocusRect(rectImage);
		}
		else
		{
			rectText.InflateRect(1, 1, 1, 2);
			if (rectText.top < rectItem.top)
				rectText.top = rectItem.top;
			if (rectText.bottom > rectItem.bottom)
				rectText.bottom = rectItem.bottom;
			if (rectText.left < rectItem.left)
				rectText.left = rectItem.left;
			if (rectText.right > rectItem.right)
				rectText.right = rectItem.right;

			dcMem.DrawFocusRect(rectText); 
		}
	}	// if the button has focus

	// Draw the check box or radio button now.
	if (!bPushLike)
	{
		// Determine the rect for the check mark.
		CRect rectCheck = GetCheckRect(rectItem, nStyle);

		if (m_nType == TYPE_CHECKBOX)
			DrawCheckBox(&dcMem, rectCheck, nStyle, nState);
		else if (m_nType == TYPE_RADIO)
			DrawRadioButton(&dcMem, rectCheck, nStyle, nState);
	}

	pDC->BitBlt(rectItem.left, rectItem.top, rectItem.Width(), rectItem.Height(), &dcMem, rectItem.left, rectItem.top, SRCCOPY);

	// Clean up.
	dcMem.SelectObject(pOldBrush);
	dcMem.SelectObject(pOldBmp);
	dcMem.RestoreDC(nSaveDC);
	dcMem.DeleteDC();
	bmp.DeleteObject();
}	// DrawButton

//-------------------------------------------------------------------
//
void CMacButton::DrawStandardButton(CDC *pDC, const CRect &rect, UINT nStyle, UINT nState)
//
// Return Value:	None.
//
// Parameters	:	pDC - A pointer to the DC to draw on.
//						rect - The button rectangle.
//						nStyle - The button's style.
//						nState - The button's state.
//
// Remarks		:	Draws the button.
//
{
	// Draw a flat button.
	if (nStyle & BS_FLAT)
	{
		COLORREF crFill = ::GetSysColor(COLOR_WINDOW);
		CBrush brFill(nState & ODS_SELECTED ? ~crFill : crFill);
		CBrush *pOldBrush = (CBrush *)pDC->SelectObject(&brFill);
		CPen pen;
		if (nState & ODS_DISABLED)
			pen.CreatePen(PS_SOLID, 1, m_crShadow);
		else if (m_nCheck || m_bMouseDown)
			pen.CreatePen(PS_SOLID, 1, crFill);
		else
			pen.CreatePen(PS_SOLID, 1, ~crFill);
		CPen *pOldPen = (CPen *)pDC->SelectObject(&pen);
		pDC->RoundRect(rect, CPoint(6, 6));
		pDC->SelectObject(pOldBrush);
		pDC->SelectObject(pOldPen);
		pen.DeleteObject();
		return;
	}	// if flat
	
	CBrush brFill(nState & ODS_SELECTED ? m_crLiteShadow : m_crFace);
	CBrush *pOldBrush	= (CBrush *)pDC->SelectObject(&brFill);
	CPen penFrame(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWFRAME));
	CPen *pOldPen = (CPen *)pDC->SelectObject(nState & ODS_DISABLED ? &m_penShadow : &penFrame);

	// Draw a 3D button.
	if (nState & ODS_DISABLED)
		pDC->RoundRect(rect, CPoint(6, 6));
	else if (nState & ODS_SELECTED)
		DrawPressedPushButton(pDC, rect);
	else
		DrawUnpressedPushButton(pDC, rect);

	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);
}	// DrawStandardButton

//-------------------------------------------------------------------
//
void CMacButton::DrawCheckBox(CDC *pDC, CRect rect, UINT nStyle, UINT nState)
//
// Return Value:	None.
//
// Parameters	:	pDC - A pointer to the DC to draw on.
//						rect - The check mark's rectangle.
//						nStyle - The button's style.
//						nState - The button's state.
//
// Remarks		:	Draws the check mark.
//
{
	BOOL bDisabled = nState & ODS_DISABLED;
	
	// Deflate the rect by two on the right (for the check mark's shadow).
	rect.DeflateRect(0, 0, 2, 0);

	CPen *pOldPen = pDC->GetCurrentPen();
	CBrush *pOldBrush = pDC->GetCurrentBrush();

	// Draw a flat checkbox.
	if (nStyle & BS_FLAT)
	{
		COLORREF crFrame = ::GetSysColor(COLOR_WINDOW);
		CPen penFrame(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWFRAME));
		CBrush brFill(crFrame);
		pDC->SelectObject(&penFrame);
		pDC->SelectObject(&brFill);

		pDC->Rectangle(rect);

		if (bDisabled)
		{
			for (int i = rect.left + 1, j = rect.top + 1; i < rect.right; i += 2, j += 2)
			{
				pDC->SetPixel(i, rect.top, crFrame);
				pDC->SetPixel(i - 1, rect.bottom - 1, crFrame);
				pDC->SetPixel(rect.left, j, crFrame);
				pDC->SetPixel(rect.right - 1, j - 1, crFrame);
			}
		}

		rect.DeflateRect(1, 1, 1, 1);

		if (m_bMouseDown)
			pDC->Rectangle(rect);

		// Inflate the rect by two on the right (for the check mark's shadow).
		rect.InflateRect(0, 0, 2, 0);

		int nLeft = rect.left;
		int nTop = rect.top;

		CPen penDkShadow(PS_SOLID, 1, m_crDkShadow);
		pDC->SelectObject(&penDkShadow);

		// Draw the check, cross, or tri-state mark.
		if (m_nCheck == 1)
		{
			if (m_nCheckStyle == CHECK_STYLE_CHECK)
			{
				if (!bDisabled)
				{
					pDC->MoveTo(nLeft + 1, nTop + 4);
					pDC->LineTo(nLeft + 4, nTop + 7);
					pDC->LineTo(nLeft + 12,nTop - 1);
				}
				pDC->MoveTo(nLeft + 2, nTop + 4);
				pDC->LineTo(nLeft + 4, nTop + 6);
				pDC->LineTo(nLeft + 11, nTop -1);
			}
			else if (m_nCheckStyle == CHECK_STYLE_CROSS)
			{
				pDC->MoveTo(nLeft, nTop);
				pDC->LineTo(nLeft + 10, nTop + 10);

				int nAdjust = bDisabled ? 1 : 0;
				pDC->MoveTo(nLeft + nAdjust, nTop + 9 - nAdjust);
				pDC->LineTo(nLeft + 10 - nAdjust, nTop - 1 + nAdjust);
			}
		}
		else if (m_nCheck == 2)
		{
			pDC->SelectObject(&m_penDkShadow);
			pDC->MoveTo(nLeft + 2, nTop + 4);
			pDC->LineTo(nLeft + 8, nTop + 4);
			pDC->MoveTo(nLeft + 2, nTop + 5);
			pDC->LineTo(nLeft + 8, nTop + 5);
		}

	}	// if flat
	// Else draw a 3D checkbox.
	else
	{
		CBrush brFrame(bDisabled ? m_crShadow : ::GetSysColor(COLOR_WINDOWFRAME));
		pDC->FrameRect(rect, &brFrame);
		rect.DeflateRect(1, 1);

		if (m_bMouseDown)
		{								
			CBrush brShadow(m_crLiteShadow);
			pDC->FillRect(rect, &brShadow);
			pDC->Draw3dRect(rect, m_crShadow, m_crLiteFace);
		}
		else
		{
			pDC->FillSolidRect(rect, m_crFace);

			if (!bDisabled)
				pDC->Draw3dRect(rect, m_crHilight, m_crShadow);
		}

		pDC->SetPixel(CPoint(rect.right - 1, rect.top), m_crFace);
		pDC->SetPixel(CPoint(rect.left, rect.bottom - 1), m_crFace);

		// Inflate the rect by two on the right (for the check mark's shadow).
		rect.InflateRect(0, 0, 2, 0);

		int nLeft = rect.left;
		int nTop = rect.top;

		// Draw the check, cross, or tri-state mark.
		if (m_nCheck == 1)
		{
			// Draw the check mark's shadow
			if (m_nCheckStyle == CHECK_STYLE_CHECK)
			{
				// Draw the check mark's shadow
				pDC->SelectObject(bDisabled ? &m_penLiteShadow : &m_penShadow);
				pDC->MoveTo(nLeft + 4, nTop + 8);
				pDC->LineTo(nLeft + 9, nTop + 3);
				pDC->LineTo(nLeft + 9, nTop + 5);

				pDC->SelectObject(&m_penLiteShadow);
				pDC->MoveTo(nLeft + 2, nTop + 6);
				pDC->LineTo(nLeft + 4, nTop + 8);
				pDC->MoveTo(nLeft + 5, nTop + 8);
				pDC->LineTo(nLeft + 9, nTop + 4);

				pDC->SetPixel(nLeft + 11, nTop + 1, bDisabled ? m_crLiteShadow : m_crShadow);
				pDC->SetPixel(nLeft + 12, nTop + 1, m_crLiteShadow);
				pDC->SetPixel(nLeft + 11, nTop + 2, m_crLiteShadow);

				// Draw the check mark.
				pDC->SelectObject(bDisabled ? &m_penShadow : &m_penDkShadow);
				pDC->MoveTo(nLeft + 1, nTop + 4);
				pDC->LineTo(nLeft + 4, nTop + 7);
				pDC->LineTo(nLeft + 12,nTop - 1);
				pDC->MoveTo(nLeft + 2, nTop + 4);
				pDC->LineTo(nLeft + 4, nTop + 6);
				pDC->LineTo(nLeft + 11, nTop -1);
			}

⌨️ 快捷键说明

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