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

📄 myroundsliderctrl2.cpp

📁 VCsuishu fudai de yixie chengxuyuanma
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// MyRoundSliderCtrl2.cpp : implementation file
//

#include "stdafx.h"
#include "MyRoundSliderCtrl2.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//包含头文件
#include <math.h>
//#include "MyRoundSliderCtrl2.h"
//

//////////引用别人的函数*********
static const double pi = 2*asin(1);

// The following 3 functions were taken from 'CRoundButton.cpp', written and
// copyright (c) 1997,1998 by Chris Maunder.

// To be honest, I never had a look at their implementation, I just use them.
// This is cut-and-paste-programming at its best... if it works... :)   (Daniel)

// prototypes
COLORREF GetColour(double dAngle, COLORREF crBright, COLORREF crDark);
void DrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crColour, BOOL bDashed = FALSE);
void DrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crBright, COLORREF crDark);


// Calculate colour for a point at the given angle by performing a linear
// interpolation between the colours crBright and crDark based on the cosine
// of the angle between the light source and the point.
//
// Angles are measured from the +ve x-axis (i.e. (1,0) = 0 degrees, (0,1) = 90 degrees )
// But remember: +y points down!

COLORREF GetColour(double dAngle, COLORREF crBright, COLORREF crDark)
{
#define Rad2Deg	180.0/3.1415 
#define LIGHT_SOURCE_ANGLE	-2.356		// -2.356 radians = -135 degrees, i.e. From top left

	ASSERT(dAngle > -3.1416 && dAngle < 3.1416);
	double dAngleDifference = LIGHT_SOURCE_ANGLE - dAngle;

	if (dAngleDifference < -3.1415) dAngleDifference = 6.293 + dAngleDifference;
	else if (dAngleDifference > 3.1415) dAngleDifference = 6.293 - dAngleDifference;

	double Weight = 0.5*(cos(dAngleDifference)+1.0);

	BYTE Red   = (BYTE) (Weight*GetRValue(crBright) + (1.0-Weight)*GetRValue(crDark));
	BYTE Green = (BYTE) (Weight*GetGValue(crBright) + (1.0-Weight)*GetGValue(crDark));
	BYTE Blue  = (BYTE) (Weight*GetBValue(crBright) + (1.0-Weight)*GetBValue(crDark));

	//TRACE("LightAngle = %0.0f, Angle = %3.0f, Diff = %3.0f, Weight = %0.2f, RGB %3d,%3d,%3d\n", 
	//	  LIGHT_SOURCE_ANGLE*Rad2Deg, dAngle*Rad2Deg, dAngleDifference*Rad2Deg, Weight,Red,Green,Blue);

	return RGB(Red, Green, Blue);
}
//画圆,实线圆或虚线圆,没有阴影效果的
void 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
} 
//画圆型阴影效果边框
void DrawCircle(CDC* pDC, CPoint p, LONG lRadius, COLORREF crBright, COLORREF crDark)
{
	LONG lError, lXoffset, lYoffset;

	//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 {
		const double Pi = 3.141592654, 
					 Pi_on_2 = Pi * 0.5;
		//			 Three_Pi_on_2 = Pi * 1.5;
		COLORREF crColour;
		double   dAngle = atan2(lYoffset, lXoffset);

		//Draw the current pixel, reflected across all eight arcs
		crColour = GetColour(dAngle, crBright, crDark);
		pDC->SetPixelV(p.x + lXoffset, p.y + lYoffset, crColour);

		crColour = GetColour(Pi_on_2 - dAngle, crBright, crDark);
		pDC->SetPixelV(p.x + lYoffset, p.y + lXoffset, crColour);

		crColour = GetColour(Pi_on_2 + dAngle, crBright, crDark);
		pDC->SetPixelV(p.x - lYoffset, p.y + lXoffset, crColour);

		crColour = GetColour(Pi - dAngle, crBright, crDark);
		pDC->SetPixelV(p.x - lXoffset, p.y + lYoffset, crColour);

		crColour = GetColour(-Pi + dAngle, crBright, crDark);
		pDC->SetPixelV(p.x - lXoffset, p.y - lYoffset, crColour);

		crColour = GetColour(-Pi_on_2 - dAngle, crBright, crDark);
		pDC->SetPixelV(p.x - lYoffset, p.y - lXoffset, crColour);

		crColour = GetColour(-Pi_on_2 + dAngle, crBright, crDark);
		pDC->SetPixelV(p.x + lYoffset, p.y - lXoffset, crColour);

		crColour = GetColour(-dAngle, crBright, crDark);
		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;

	} while (lYoffset <= lXoffset);	//Continue until halfway point
} 
//////////end 引用别人的函数 **************

/////////////////////////////////////////////////////////////////////////////
// CMyRoundSliderCtrl2

CMyRoundSliderCtrl2::CMyRoundSliderCtrl2()
{
	//初始化变量****
	//针对客户**
	m_dMaxValue = 1.0;//客户指定最大值
	m_dMinValue = 0.0;//客户指定最小值
	m_dPlusValue = 0.02;//增益
	//对程序设计者**
	m_nMaxAngle = 215;//终止角度(最大角度)---对应最小值
	m_nMinAngle = -35;//起始角度(最小角度)---对应最大值
	//绘图变量	
	m_bkClr = RGB(0,255,0);//按钮颜色
	m_scaleClr = RGB(250,100,0);//刻度颜色
	m_pointerClr = RGB(255,0,0);//指针颜色
	m_scaleTextClr = RGB(0,0,255);//刻度上指示值颜色
	m_textClr = RGB(0,255,0);//输出值的颜色
	//
	m_bLButtonDown = FALSE;
	m_bMouseMove = FALSE;
	//初始化m_dCurrentValue,m_nDivNum,m_nAngleDiv,m_nCurrentAngle
	Init();
	//end 初始化变量****
}
//初始化m_dCurrentValue,m_nDivNum,m_nAngleDiv,m_nCurrentAngle
void CMyRoundSliderCtrl2::Init()
{
	m_dCurrentValue = m_dMinValue;//当前值
	m_nDivNum = (int)((m_dMaxValue - m_dMinValue)/m_dPlusValue);  //总格数
	m_nAngleDiv = (m_nMaxAngle - m_nMinAngle)/m_nDivNum;//每小格度数
	m_nCurrentAngle = m_nMaxAngle;//当前位置---对应当前值的最小值
}


CMyRoundSliderCtrl2::~CMyRoundSliderCtrl2()
{
	//释放资源,清理内存
	m_rgn.DeleteObject();

	if(m_memDC.GetSafeHdc())
	{
		m_memDC.SelectObject(m_pOldBitmap);	
		m_memBitmap.DeleteObject();
		m_memDC.DeleteDC();
		//delete m_pOldBitmap;//不能有
	}
}


BEGIN_MESSAGE_MAP(CMyRoundSliderCtrl2, CSliderCtrl)
	//{{AFX_MSG_MAP(CMyRoundSliderCtrl2)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyRoundSliderCtrl2 message handlers

void CMyRoundSliderCtrl2::PreSubclassWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CSliderCtrl::PreSubclassWindow();

		//resize the window to make it square
	GetClientRect(&m_clientRect);
	//
	ChangeSize();

}

void CMyRoundSliderCtrl2::ChangeSize()
{
	m_clientRect.right = m_clientRect.bottom  ;
	//改变窗口形状
	m_rgn.DeleteObject();
	m_rgn.CreateEllipticRgnIndirect(&m_clientRect);
	SetWindowRgn(m_rgn, TRUE);
	//先确定各半径大小--可更改
	m_nBigRadius = m_clientRect.Height()/2;
	m_nSmallRadius = m_nBigRadius*1/2;
	m_nPointerRadius = 3;//指针半径
	//
	m_centerPoint = CPoint(m_clientRect.right/2-1,m_clientRect.bottom/2-1);

	//准备内存DC
	CClientDC dc(this);
	if(m_memDC.m_hDC){
		m_memDC.DeleteDC();	
		m_memBitmap.DeleteObject();
	}
	m_memDC.CreateCompatibleDC(&dc);
	m_memBitmap.CreateCompatibleBitmap(&dc,
		m_clientRect.Width(), m_clientRect.Height());
	m_pOldBitmap = m_memDC.SelectObject(&m_memBitmap);
}

void CMyRoundSliderCtrl2::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	//用双缓存 m_memDC
	// TODO: Add your message handler code here
	CBrush bkBrush(m_bkClr);
	//注意此处一定要重新创建m_rgn,因为很奇怪,似乎m_rgn不能保存自己
	m_rgn.DeleteObject();
	m_rgn.CreateEllipticRgnIndirect(&m_clientRect);
	m_memDC.FillRgn(&m_rgn, &bkBrush);
	//画大边界框****	
	//法2---多画几层是为了是轮廓及阴影看起来更厚重(若仍觉不够,可以再多画几层)
	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-1, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-1,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));
	
	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-2, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-2,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-3, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-2,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-3, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nBigRadius-3,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	//中间突起部分圆****
	/*//画表面颜色
	m_rgn.DeleteObject();
	CRect rect(m_clientRect.right/2-20,m_clientRect.bottom/2-20,
		m_clientRect.right/2+20,m_clientRect.bottom/2+20);
	m_rgn.CreateEllipticRgnIndirect(&rect);
	CBrush brush(RGB(100,0,0));
	dc.FillRgn(&m_rgn, &brush);
	*///
	//画阴影圆框
	//法1
	//DrawCircle(&dc, m_centerPoint, 20, 
	//				RGB(255,0,0),RGB(0,0,0));
	//法2---多画几层是为了是轮廓及阴影看起来更厚重
	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-1, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-1,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-2, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-2,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-3, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-3,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-4, 
		::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW));
//	DrawCircle(&m_memDC, m_centerPoint, m_nSmallRadius-4,
//		::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW));

	//画刻度****
	CPen* pOldPen;
	CPen scalePen(PS_SOLID,1,m_scaleClr);
	pOldPen = m_memDC.SelectObject(&scalePen);
	//刻度圈
	m_memDC.MoveTo(m_centerPoint.x+(int)(m_nSmallRadius*cos(m_nMinAngle*pi/180.0)),
		m_centerPoint.y-(int)(m_nSmallRadius*sin(m_nMinAngle*pi/180.0)));	
	m_memDC.AngleArc( m_centerPoint.x, m_centerPoint.y, 
		m_nSmallRadius, m_nMinAngle, m_nMaxAngle - m_nMinAngle );
	//从根部往上画每格小刻度-----从右边开始画
	//处理长刻度指示值字***
	CString strValue;//
	double d = 0.02;
	strValue.Format("%.2f",d);
	CFont font, *pOldFont;
	//选择字体
	font.CreateFont(10,0,0,0,0,FALSE,FALSE,0,ANSI_CHARSET,
		OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
		DEFAULT_PITCH|FF_SWISS,"Arial");
	pOldFont = m_memDC.SelectObject(&font);
	//颜色和排列方式
	m_memDC.SetBkMode(TRANSPARENT );
	m_memDC.SetTextColor(m_scaleTextClr);			
	m_memDC.SetTextAlign(TA_LEFT);//可有可无,因为是默认方式
	CSize pointerTextSize ;
	CPoint pointerTextPoint;//字的左上角坐标
	


	if(m_nDivNum < 50){
		for(int i=0; i<=m_nDivNum; i++){//m_nDivNum格,m_nDivNum+1根线
			//全画为长刻度
			m_memDC.MoveTo(m_centerPoint.x+(int)(m_nSmallRadius*cos((m_nMinAngle+m_nAngleDiv*i)*pi/180.0)),
				m_centerPoint.y-(int)(m_nSmallRadius*sin((m_nMinAngle+m_nAngleDiv*i)*pi/180.0)));
			m_memDC.LineTo(m_centerPoint.x+(int)((m_nSmallRadius+6)*cos((m_nMinAngle+m_nAngleDiv*i)*pi/180.0)),
				m_centerPoint.y-(int)((m_nSmallRadius+6)*sin((m_nMinAngle+m_nAngleDiv*i)*pi/180.0)));	
			//处理字

⌨️ 快捷键说明

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