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

📄 macbuttons.cpp

📁 这是我仿照串口助手(龚建伟)作的一个例子并修正了其中的一些bug
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				rect.left = (rect.Width() - m_sizeImage.cx) >> 1;
		}
	}
	rect.right = rect.left + m_sizeImage.cx;

	// Calculate the top and bottom of the rect.
	if (nStyle & BS_TOP)
		rect.top += ((m_nType == TYPE_STANDARD) || (nStyle & BS_PUSHLIKE) ? 4 : 1);
	else if (nStyle & BS_BOTTOM)
		rect.top = rect.bottom - m_sizeImage.cy - ((m_nType == TYPE_STANDARD) || (nStyle & BS_PUSHLIKE) ? 4 : 1);
	else
		rect.top = (rect.Height() - m_sizeImage.cy) >> 1;
	rect.bottom = rect.top + m_sizeImage.cy;

	// Adjust the image's rectangle depending on the effect
	if (m_nImageEffect == IMAGE_EFFECT_RAISED || m_nImageEffect == IMAGE_EFFECT_SUNKEN)
	{
		if ((m_nType == TYPE_STANDARD) || (nStyle & BS_PUSHLIKE))
		{
			if (nStyle & BS_LEFT)
			{
				rect.left++;
				rect.right++;
			}
			else if (nStyle & BS_RIGHT)
			{
				rect.left--;
				rect.right--;
			}
		}
		
		if (nStyle & BS_TOP)
		{
			rect.top++;
			rect.bottom++;
		}
		else if (nStyle & BS_BOTTOM)
		{
			rect.top--;
			rect.bottom--;
		}
	}

	// Draw the image.
	if (m_hIcon)
		pDC->DrawState(rect.TopLeft(), m_sizeImage, 
						m_hIcon, nState & ODS_DISABLED ? DSS_DISABLED : DSS_NORMAL, (HBRUSH)NULL);
	else if (m_hBitmap)
		pDC->DrawState(rect.TopLeft(), m_sizeImage, 
						m_hBitmap, nState & ODS_DISABLED ? DSS_DISABLED : DSS_NORMAL, (HBRUSH)NULL);

	if (m_nImageEffect)
	{
		rect.InflateRect(1, 1, 1, 1);
		if (m_nImageEffect == IMAGE_EFFECT_RAISED)
			pDC->Draw3dRect(rect, m_crHilight, m_crShadow);
		if (m_nImageEffect == IMAGE_EFFECT_SUNKEN)
			pDC->Draw3dRect(rect, m_crShadow, m_crHilight);
	}
}	// DrawImage

//-------------------------------------------------------------------
//
HICON CMacButton::SetIcon(HICON hIcon)
//
// Return Value:	The handle of an icon previously associated with the button.
//
// Parameters	:	hIcon - The handle of an icon.
//
// Remarks		:	Call this member function to associate a new icon with the button.
//
{
	m_hIcon = hIcon;
	m_hBitmap = 0;

	if (hIcon)
	{
		// Get icon dimensions.
		ICONINFO iconInfo;
		::ZeroMemory(&iconInfo, sizeof(ICONINFO));
		::GetIconInfo(m_hIcon, &iconInfo);

		m_sizeImage.cx = iconInfo.xHotspot << 1;
		m_sizeImage.cy = iconInfo.yHotspot << 1;
	}

	RedrawWindow();

	return CButton::SetIcon(hIcon);
}	// SetIcon

//-------------------------------------------------------------------
//
HBITMAP CMacButton::SetBitmap(HBITMAP hBitmap)
//
// Return Value:	The handle of a bitmap previously associated with the button.
//
// Parameters	:	hBitmap - The handle of a bitmap.
//
// Remarks		:	Call this member function to associate a new bitmap with the button.
//
{
	m_hBitmap = hBitmap;
	m_hIcon = 0;

	if (hBitmap)
	{
		// Get bitmap dimensions.
		CBitmap *pBmp = CBitmap::FromHandle(hBitmap);
		ASSERT(pBmp);
		BITMAP bmp;
		::ZeroMemory(&bmp, sizeof(BITMAP));
		pBmp->GetBitmap(&bmp);

		m_sizeImage.cx = bmp.bmWidth;
		m_sizeImage.cy = bmp.bmHeight;
	}

	RedrawWindow();

	return CButton::SetBitmap(hBitmap);
}	// SetBitmap

//-------------------------------------------------------------------
//
CRect CMacButton::GetCheckRect(const CRect &rect, UINT nStyle)
//
// Return Value:	A CRect containing the dimensions of the radio/check box.
//
// Parameters	:	rect - The rectangle of the entire button.
//						nStyle - The button's style.
//
// Remarks		:	Returns a rectangle containing the dimensions of the 
//						radio/check box. Only used with radio buttons or check boxes.
//
{
	CRect rectCheck(rect);

	// Calculate the left and right sides of the rect.
	if (nStyle & BS_LEFTTEXT)
	{
		rectCheck.left = rect.right - CHECKBOX_HEIGHT - (m_nType == TYPE_RADIO ? 0 : 2);
	}
	else
	{
		rectCheck.left += (m_nType == TYPE_RADIO ? 1 : 0);
		rectCheck.right = rect.left + CHECKBOX_HEIGHT + (m_nType == TYPE_RADIO ? 1 : 2);
	}

	// Calculate the top and bottom sides of the rect.
	if (nStyle & BS_TOP)
		rectCheck.top += 1;
	else if (nStyle & BS_BOTTOM)
		rectCheck.top = rect.bottom - CHECKBOX_HEIGHT - 3;
	else
		rectCheck.top = ((rect.Height() - CHECKBOX_HEIGHT) >> 1) - 1;
	rectCheck.bottom = rectCheck.top + CHECKBOX_HEIGHT;

	return rectCheck;
}	// GetCheckRect

//-------------------------------------------------------------------
//
void CMacButton::DrawUnpressedPushButton(CDC *pDC, const CRect &rect)
//
// Return Value:	None.
//
// Parameters	:	pDC - A pointer to the DC to draw on.
//						rect - The button's rectangle.
//
// Remarks		:	Draws an unpressed push button.
//
{
	pDC->RoundRect(rect, CPoint(6, 6));

	// Save myself some typing.
	int nLeft = rect.left;
	int nTop = rect.top;
	int nRight = rect.right;
	int nBottom = rect.bottom;

	pDC->SelectObject(&m_penHilight);
	pDC->MoveTo(nLeft + 2, nBottom - 4);
	pDC->LineTo(nLeft + 2, nTop + 2);
	pDC->LineTo(nRight - 3, nTop + 2);
	pDC->SetPixel(nLeft + 3, nTop + 3, m_crHilight);

	pDC->SelectObject(&m_penLiteShadow);
	pDC->MoveTo(nLeft + 3, nBottom - 3);
	pDC->LineTo(nRight - 4, nBottom - 3);
	pDC->LineTo(nRight - 4, nBottom - 4);
	pDC->LineTo(nRight - 3, nBottom - 4);
	pDC->LineTo(nRight - 3, nTop + 2);

	pDC->SelectObject(&m_penShadow);
	pDC->MoveTo(nLeft + 3, nBottom - 2);
	pDC->LineTo(nRight - 3, nBottom - 2);
	pDC->LineTo(nRight - 3, nBottom - 3);
	pDC->LineTo(nRight - 2, nBottom - 3);
	pDC->LineTo(nRight - 2, nTop + 2);

	pDC->SetPixel(nLeft, nTop + 2, m_crDarkDkShadow);
	pDC->SetPixel(nLeft + 2, nTop, m_crDarkDkShadow);
	pDC->SetPixel(nRight - 3, nTop, m_crDarkDkShadow);
	pDC->SetPixel(nRight - 1, nTop + 2, m_crDarkDkShadow);
	pDC->SetPixel(nRight - 1, nBottom - 3, m_crDarkDkShadow);
	pDC->SetPixel(nRight - 3, nBottom - 1, m_crDarkDkShadow);
	pDC->SetPixel(nLeft + 2, nBottom - 1, m_crDarkDkShadow);
	pDC->SetPixel(nLeft, nBottom - 3, m_crDarkDkShadow);

	pDC->SetPixel(nLeft + 1, nTop + 2, m_crLiteShadow);
	pDC->SetPixel(nLeft + 2, nTop + 1, m_crLiteShadow);
	pDC->SetPixel(nRight - 3, nTop + 1, m_crLiteShadow);
	pDC->SetPixel(nRight - 2, nTop + 2, m_crLiteShadow);
	pDC->SetPixel(nLeft + 2, nBottom - 2, m_crLiteShadow);
	pDC->SetPixel(nLeft + 1, nBottom - 3, m_crLiteShadow);

	DrawCornerShadows(pDC, rect);
}	// DrawUnpressedPushButton

//-------------------------------------------------------------------
//
void CMacButton::DrawPressedPushButton(CDC *pDC, const CRect &rect)
//
// Return Value:	None.
//
// Parameters	:	pDC - A pointer to the DC to draw on.
//						rect - The button's rectangle.
//
// Remarks		:	Draws a pressed push button.
//
{
	pDC->RoundRect(rect, CPoint(6, 6));

	// Save myself some typing.
	int nLeft = rect.left;
	int nTop = rect.top;
	int nRight = rect.right;
	int nBottom = rect.bottom;

	pDC->SelectObject((m_nType == TYPE_STANDARD) || m_bMouseDown ? &m_penDarkDkShadow : &m_penShadow);
	pDC->MoveTo(nLeft + 1, nBottom - 4);
	pDC->LineTo(nLeft + 1, nTop + 2);
	pDC->LineTo(nLeft + 2, nTop + 2);
	pDC->LineTo(nLeft + 2, nTop + 1);
	pDC->LineTo(nRight - 3, nTop + 1);

	pDC->SelectObject((m_nType == TYPE_STANDARD) || m_bMouseDown ? &m_penShadow : &m_penLiteShadow);
	pDC->MoveTo(nLeft + 2, nBottom - 4);
	pDC->LineTo(nLeft + 2, nTop + 3);
	pDC->LineTo(nLeft + 3, nTop + 3);
	pDC->LineTo(nLeft + 3, nTop + 2);
	pDC->LineTo(nRight - 3, nTop + 2);

	pDC->SelectObject((m_nType == TYPE_STANDARD) || !(m_nCheck && !m_bMouseDown) ? &m_penLiteFace : &m_penHilight);
	pDC->MoveTo(nLeft + 3, nBottom - 2);
	pDC->LineTo(nRight - 4, nBottom - 2);
	pDC->LineTo(nRight - 2, nBottom - 4);
	pDC->LineTo(nRight - 2, nTop + 2);

	pDC->SelectObject((m_nType == TYPE_STANDARD) || !(m_nCheck && !m_bMouseDown) ? &m_penFace : &m_penLiteFace);
	pDC->MoveTo(nLeft + 3, nBottom - 3);
	pDC->LineTo(nRight - 4, nBottom - 3);
	pDC->LineTo(nRight - 4, nBottom - 4);
	pDC->LineTo(nRight - 3, nBottom - 4);
	pDC->LineTo(nRight - 3, nTop + 2);

	pDC->SetPixel(nRight - 2, nTop + 2, ((m_nType == TYPE_STANDARD) || m_bMouseDown ? m_crFace : m_crLiteFace));
	pDC->SetPixel(nLeft + 2, nBottom - 2, ((m_nType == TYPE_STANDARD) || m_bMouseDown ? m_crFace : m_crLiteFace));
	pDC->SetPixel(nRight - 3, nTop + 1, m_crShadow);
	pDC->SetPixel(nLeft + 1, nBottom - 3, m_crShadow);

	DrawCornerShadows(pDC, rect);
}	// DrawPressedPushButton

//-------------------------------------------------------------------
//
void CMacButton::DrawCornerShadows(CDC *pDC, const CRect &rect)
//
// Return Value:	None.
//
// Parameters	:	pDC - A pointer to the DC to draw on.
//						rect - The button's rectangle.
//
// Remarks		:	Draws the little "shadows" on the corners of push buttons.
//
{
	pDC->SetPixel(rect.left, rect.top + 2, m_crDarkDkShadow);
	pDC->SetPixel(rect.left + 2, rect.top, m_crDarkDkShadow);
	pDC->SetPixel(rect.right - 3, rect.top, m_crDarkDkShadow);
	pDC->SetPixel(rect.right - 1, rect.top + 2, m_crDarkDkShadow);
	pDC->SetPixel(rect.right - 1, rect.bottom - 3, m_crDarkDkShadow);
	pDC->SetPixel(rect.right - 3, rect.bottom - 1, m_crDarkDkShadow);
	pDC->SetPixel(rect.left + 2, rect.bottom - 1, m_crDarkDkShadow);
	pDC->SetPixel(rect.left, rect.bottom - 3, m_crDarkDkShadow);
}	// DrawCornerShadows

//-------------------------------------------------------------------
//
void CMacButton::DrawPushLikeButton(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's rectangle.
//						nStyle - The button's style.
//						nState - The button's state.
//
// Remarks		:	Draws a push-like check box. This function is only used
//						to draw radio buttons and check boxes that have the 
//						BS_PUSHLIKE style.
//
{
	CBrush brFill;

	// Draw a flat button.
	if (nStyle & BS_FLAT)
	{
		COLORREF crFill = ::GetSysColor(COLOR_WINDOW);

		HBITMAP hBmp = GetDitherBitmap(pDC, crFill, ~crFill);
		CBitmap *pBmp = (hBmp ? CBitmap::FromHandle(hBmp) : NULL);
		ASSERT(pBmp);

		// If the mouse is down, use a pattern brush to fill with. 
		// If the button is checked, use the inverted window color.
		if (m_bMouseDown)
			brFill.CreatePatternBrush(pBmp);
		else if (m_nCheck)
			brFill.CreateSolidBrush(~crFill);
		else
			brFill.CreateSolidBrush(crFill);

		CBrush *pOldBrush = (CBrush *)pDC->SelectObject(&brFill);
		CPen pen;
		if (nState & ODS_DISABLED)
			pen.CreatePen(PS_SOLID, 1, m_crDarkDkShadow);
		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();
		brFill.DeleteObject();
		return;
	}	// if flat

	HBITMAP hBmp = GetDitherBitmap(pDC, m_crHilight, m_crFace);
	CBitmap *pBmp = (hBmp ? CBitmap::FromHandle(hBmp) : NULL);
	ASSERT(pBmp);

	// Create the brush to fill with.
	if (m_bMouseDown)
		brFill.CreateSolidBrush(m_crLiteShadow);
	else if (m_nCheck)
		brFill.CreatePatternBrush(pBmp);
	else
		brFill.CreateSolidBrush(m_crFace);

	::DeleteObject(hBmp);

	CBrush *pOldBrush	= (CBrush *)pDC->SelectObject(&brFill);
	CPen penBorder(PS_SOLID, 1, nState & ODS_DISABLED ? m_crShadow : ::GetSysColor(COLOR_WINDOWFRAME));
	CPen *pOldPen = (CPen *)pDC->SelectObject(&penBorder);

	// Draw the pressed or unpressed button
	if (nState & ODS_DISABLED)
		pDC->RoundRect(rect, CPoint(6, 6));
	else if (m_bMouseDown || m_nCheck)
		DrawPressedPushButton(pDC, rect);
	else
		DrawUnpressedPushButton(pDC, rect);

	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);
	brFill.DeleteObject();
}	// DrawPushLikeButton

//-------------------------------------------------------------------
//
HBITMAP CMacButton::GetDitherBitmap(CDC *pDC, COLORREF crColor1, COLORREF crColor2)
//
// Return Value:	An HBITMAP.
//
// Parameters	:	pDC - A pointer to the DC being drawn on.
//						crColor1, crColor2 - Specify the colors used to create a 
//							dither bitmap
//
// Remarks		:	Returns a dithered HBITMAP that is used to create
//						a patter brush for filling a push-like radio button or
//						check box when it is checked.
//
{
	struct  // BITMAPINFO with 16 colors
	{
		BITMAPINFOHEADER    bmiHeader;
		RGBQUAD             bmiColors[16];
	}	bmi;

	DWORD patGray[8];

	bmi.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth        = 2;
	bmi.bmiHeader.biHeight       = 2;
	bmi.bmiHeader.biPlanes       = 1;
	bmi.bmiHeader.biBitCount     = 1;
	bmi.bmiHeader.biCompression  = BI_RGB;
	bmi.bmiHeader.biSizeImage    = 0;
	bmi.bmiHeader.biXPelsPerMeter= 0;
	bmi.bmiHeader.biYPelsPerMeter= 0;
	bmi.bmiHeader.biClrUsed      = 0;
	bmi.bmiHeader.biClrImportant = 0;

	bmi.bmiColors[0].rgbRed      = GetRValue(crColor1);
	bmi.bmiColors[0].rgbGreen    = GetGValue(crColor1);
	bmi.bmiColors[0].rgbBlue     = GetBValue(crColor1);
	bmi.bmiColors[0].rgbReserved = 0;

	bmi.bmiColors[1].rgbRed      = GetRValue(crColor2);
	bmi.bmiColors[1].rgbGreen    = GetGValue(crColor2);
	bmi.bmiColors[1].rgbBlue     = GetBValue(crColor2);
	bmi.bmiColors[1].rgbReserved = 0;

   // Create the byte array for CreateDIBitmap.
   patGray[6] = patGray[4] = patGray[2] = patGray[0] = 0x5555AAAAL;
   patGray[7] = patGray[5] = patGray[3] = patGray[1] = 0xAAAA5555L;

	return CreateDIBitmap(pDC->m_hDC, &bmi.bmiHeader, CBM_INIT, patGray, 
									(LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
}	// GetDitherBitmap

//-------------------------------------------------------------------
//
void CMacButton::RedrawCheck()
//

⌨️ 快捷键说明

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