工控编程吧
标题:
上位机VC MFC自绘实现圆型按钮
[打印本页]
作者:
qq263946146
时间:
2017-11-16 00:07
标题:
上位机VC MFC自绘实现圆型按钮
上位机VC MFC自绘实现圆型按钮
(, 下载次数: 11)
上传
点击文件名下载附件
(, 下载次数: 0)
上传
点击文件名下载附件
[weixinlianxi]1[/weixinlianxi]
[iqiyi]http://player.video.qiyi.com/546afbb3f2c603dd9ca9d5cda06b732a/0/367/w_19ruy1tyix.swf-albumId=9924459109-tvId=9924459109-isPurchase=0-cnId=12[/iqiyi]
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
}
复制代码
欢迎光临 工控编程吧 (https://www.gkbc8.com/)
Powered by Discuz! X3.4