上位机VC MFC自绘实现圆型按钮
上位机VC MFC自绘实现圆型按钮
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
MFC的控件通过自绘的方式可以实现界面上的各种效果,当前实现通过自绘实现圆形按钮功能,效果如图。从Cbutton派生出自己的类,编写好自绘类后就是类的使用,与按钮控件的使用一样 由于是圆形的按钮,所以的拖拽添加按钮控件时,尽量使其保持方形。类中使用有atan2等三角算法,所以要包含其头文件#include "math.h" 1.新建基于对话框的应用程序 2.从Cbutton派生出自己的类classCRoundBtn : public Cbutton。 然后就是编写这个类:添加头文件#include “math.h”,添加成员变量与成员函数 private: CRgn m_rgn; CPointm_ptCentre; int m_nRadius; BOOL m_bDrawDashedFocusCircle;
voidDrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crColour, BOOL bDashed =FALSE); voidDrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crBright, COLORREFcrDark); COLORREFGetColour(double dAngle, COLORREF crBright, COLORREF crDark); 在其构造函数与析构函数中处理成员变量 CRoundBtn::CRoundBtn(){m_bDrawDashedFocusCircle = TRUE;}
CRoundBtn::~CRoundBtn(){ m_rgn.DeleteObject();}
添加虚函数DrawItem,PreSubclassWindow,两个函数代码可查阅项目工程。
最后就是类的使用,和正常控件使用一样,添加几个按钮控件,关联基于自己写的类的变量便可
- void CRoundBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- ASSERT(lpDrawItemStruct != NULL);
-
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rect = lpDrawItemStruct->rcItem;
- UINT state = lpDrawItemStruct->itemState;
- UINT nStyle = GetStyle();
- int nRadius = m_nRadius;
- int nSavedDC = pDC->SaveDC();
- pDC->SelectStockObject(NULL_BRUSH);
- pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE));
- // Draw the focus circle around the button
- if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle)
- DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,0));
- // Draw the raised/sunken edges of the button (unless flat)
- if (nStyle & BS_FLAT) {
- DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,0));
- DrawCircle(pDC, m_ptCentre, nRadius--, ::GetSysColor(COLOR_3DHIGHLIGHT));
- } else {
- if ((state & ODS_SELECTED)) {
- DrawCircle(pDC, m_ptCentre, nRadius--,
- ::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT));
- DrawCircle(pDC, m_ptCentre, nRadius--,
- ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT));
- } else {
- DrawCircle(pDC, m_ptCentre, nRadius--,
- ::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
- DrawCircle(pDC, m_ptCentre, nRadius--,
- ::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));
- }
- }
-
- // draw the text if there is any
- CString strText;
- GetWindowText(strText);
- if (!strText.IsEmpty())
- {
- CRgn rgn;
- rgn.CreateEllipticRgn(m_ptCentre.x-nRadius, m_ptCentre.y-nRadius,
- m_ptCentre.x+nRadius, m_ptCentre.y+nRadius);
- pDC->SelectClipRgn(&rgn);
- CSize Extent = pDC->GetTextExtent(strText);
- CPoint pt = CPoint( m_ptCentre.x - Extent.cx/2, m_ptCentre.x - Extent.cy/2 );
- if (state & ODS_SELECTED) pt.Offset(1,1);
- pDC->SetBkMode(TRANSPARENT);
- if (state & ODS_DISABLED)
- pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
- else
- pDC->TextOut(pt.x, pt.y, strText);
- pDC->SelectClipRgn(NULL);
- rgn.DeleteObject();
- }
- // Draw the focus circle on the inside of the button
- if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle)
- DrawCircle(pDC, m_ptCentre, nRadius-2, RGB(0,0,0), TRUE);
- pDC->RestoreDC(nSavedDC);
- }
- void CRoundBtn::DrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crColour, BOOL bDashed)
- {
- const int nDashLength = 1;
- LONG lError, lXoffset, lYoffset;
- int nDash = 0;
- BOOL bDashOn = TRUE;
- //Check to see that the coordinates are valid
- ASSERT( (p.x + lRadius <= LONG_MAX) && (p.y + lRadius <= LONG_MAX) );
- ASSERT( (p.x - lRadius >= LONG_MIN) && (p.y - lRadius >= LONG_MIN) );
- //Set starting values
- lXoffset = lRadius;
- lYoffset = 0;
- lError = -lRadius;
- do {
- if (bDashOn) {
- pDC->SetPixelV(p.x + lXoffset, p.y + lYoffset, crColour);
- pDC->SetPixelV(p.x + lXoffset, p.y - lYoffset, crColour);
- pDC->SetPixelV(p.x + lYoffset, p.y + lXoffset, crColour);
- pDC->SetPixelV(p.x + lYoffset, p.y - lXoffset, crColour);
- pDC->SetPixelV(p.x - lYoffset, p.y + lXoffset, crColour);
- pDC->SetPixelV(p.x - lYoffset, p.y - lXoffset, crColour);
- pDC->SetPixelV(p.x - lXoffset, p.y + lYoffset, crColour);
- pDC->SetPixelV(p.x - lXoffset, p.y - lYoffset, crColour);
- }
- //Advance the error term and the constant X axis step
- lError += lYoffset++;
- //Check to see if error term has overflowed
- if ((lError += lYoffset) >= 0)
- lError -= --lXoffset * 2;
- if (bDashed && (++nDash == nDashLength)) {
- nDash = 0;
- bDashOn = !bDashOn;
- }
- } while (lYoffset <= lXoffset); //Continue until halfway point
- }
复制代码
|