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