QQ登录

只需一步,快速开始

上位机VC MFC自绘实现圆型按钮

[ 复制链接 ]
上位机VC MFC自绘实现圆型按钮

上位机VC MFC自绘实现圆型按钮

上位机VC MFC自绘实现圆型按钮

请点击此处下载

请先注册会员后在进行下载

已注册会员,请先登录后下载

文件名称:上位机VC MFC自绘实现圆型按钮.rar 
文件大小:225.92 KB  售价:10金币
下载权限: 不限 以上或 VIP会员   [购买捐助会员]   [充值积分]   有问题联系我


  

如果您认可,可联系功能定制!

  

如果您着急,充值会员可直接联系发您资料!

  

QQ联系我

微信扫扫联系我

  




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,两个函数代码可查阅项目工程。

最后就是类的使用,和正常控件使用一样,添加几个按钮控件,关联基于自己写的类的变量便可

  1. void CRoundBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  2. {
  3.         ASSERT(lpDrawItemStruct != NULL);
  4.         
  5.         CDC* pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
  6.         CRect rect = lpDrawItemStruct->rcItem;
  7.         UINT state = lpDrawItemStruct->itemState;
  8.         UINT nStyle = GetStyle();
  9.         int nRadius = m_nRadius;

  10.         int nSavedDC = pDC->SaveDC();

  11.         pDC->SelectStockObject(NULL_BRUSH);
  12.         pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE));

  13.         // Draw the focus circle around the button
  14.         if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle)
  15.                 DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,0));

  16.         // Draw the raised/sunken edges of the button (unless flat)
  17.         if (nStyle & BS_FLAT) {
  18.                 DrawCircle(pDC, m_ptCentre, nRadius--, RGB(0,0,0));
  19.                 DrawCircle(pDC, m_ptCentre, nRadius--, ::GetSysColor(COLOR_3DHIGHLIGHT));
  20.         } else {
  21.                 if ((state & ODS_SELECTED))        {
  22.                         DrawCircle(pDC, m_ptCentre, nRadius--,
  23.                                            ::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT));
  24.                         DrawCircle(pDC, m_ptCentre, nRadius--,
  25.                                            ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT));
  26.                 } else {
  27.                         DrawCircle(pDC, m_ptCentre, nRadius--,
  28.                                            ::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
  29.                         DrawCircle(pDC, m_ptCentre, nRadius--,
  30.                                            ::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));
  31.                 }
  32.         }
  33.         
  34.         // draw the text if there is any
  35.         CString strText;
  36.         GetWindowText(strText);

  37.         if (!strText.IsEmpty())
  38.         {
  39.                 CRgn rgn;
  40.                 rgn.CreateEllipticRgn(m_ptCentre.x-nRadius, m_ptCentre.y-nRadius,
  41.                                                           m_ptCentre.x+nRadius, m_ptCentre.y+nRadius);
  42.                 pDC->SelectClipRgn(&rgn);

  43.                 CSize Extent = pDC->GetTextExtent(strText);
  44.                 CPoint pt = CPoint( m_ptCentre.x - Extent.cx/2, m_ptCentre.x - Extent.cy/2 );

  45.                 if (state & ODS_SELECTED) pt.Offset(1,1);

  46.                 pDC->SetBkMode(TRANSPARENT);

  47.                 if (state & ODS_DISABLED)
  48.                         pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
  49.                 else
  50.                         pDC->TextOut(pt.x, pt.y, strText);

  51.                 pDC->SelectClipRgn(NULL);
  52.                 rgn.DeleteObject();
  53.         }

  54.         // Draw the focus circle on the inside of the button
  55.         if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle)
  56.                 DrawCircle(pDC, m_ptCentre, nRadius-2, RGB(0,0,0), TRUE);

  57.         pDC->RestoreDC(nSavedDC);        
  58. }
  59. void CRoundBtn::DrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crColour, BOOL bDashed)
  60. {
  61.         const int nDashLength = 1;
  62.         LONG lError, lXoffset, lYoffset;
  63.         int  nDash = 0;
  64.         BOOL bDashOn = TRUE;

  65.         //Check to see that the coordinates are valid
  66.         ASSERT( (p.x + lRadius <= LONG_MAX) && (p.y + lRadius <= LONG_MAX) );
  67.         ASSERT( (p.x - lRadius >= LONG_MIN) && (p.y - lRadius >= LONG_MIN) );

  68.         //Set starting values
  69.         lXoffset = lRadius;
  70.         lYoffset = 0;
  71.         lError   = -lRadius;

  72.         do {
  73.                 if (bDashOn) {
  74.                         pDC->SetPixelV(p.x + lXoffset, p.y + lYoffset, crColour);
  75.                         pDC->SetPixelV(p.x + lXoffset, p.y - lYoffset, crColour);
  76.                         pDC->SetPixelV(p.x + lYoffset, p.y + lXoffset, crColour);
  77.                         pDC->SetPixelV(p.x + lYoffset, p.y - lXoffset, crColour);
  78.                         pDC->SetPixelV(p.x - lYoffset, p.y + lXoffset, crColour);
  79.                         pDC->SetPixelV(p.x - lYoffset, p.y - lXoffset, crColour);
  80.                         pDC->SetPixelV(p.x - lXoffset, p.y + lYoffset, crColour);
  81.                         pDC->SetPixelV(p.x - lXoffset, p.y - lYoffset, crColour);
  82.                 }

  83.                 //Advance the error term and the constant X axis step
  84.                 lError += lYoffset++;

  85.                 //Check to see if error term has overflowed
  86.                 if ((lError += lYoffset) >= 0)
  87.                         lError -= --lXoffset * 2;

  88.                 if (bDashed && (++nDash == nDashLength)) {
  89.                         nDash = 0;
  90.                         bDashOn = !bDashOn;
  91.                 }

  92.         } while (lYoffset <= lXoffset);        //Continue until halfway point
  93. }
复制代码


回复

使用道具 举报

大神点评(1)

点击查看
快速回复 返回列表 客服中心 搜索