443 lines
11 KiB
C++
443 lines
11 KiB
C++
#include "stdafx.h"
|
|
#include "TGSizeDescrWnd.h"
|
|
#include "math.h"
|
|
|
|
//#define PI 3.1415926535
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
CTGSizeDescrWnd::CTGSizeDescrWnd()
|
|
{
|
|
m_dPer = 0.00;
|
|
m_eStyle = kProcess/*kPie*/;
|
|
}
|
|
|
|
CTGSizeDescrWnd::~CTGSizeDescrWnd()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTGSizeDescrWnd, CStatic)
|
|
//{{AFX_MSG_MAP(CTGSizeDescrWnd)
|
|
ON_WM_PAINT()
|
|
ON_WM_ERASEBKGND()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
void CTGSizeDescrWnd::SetPer(double dVal)
|
|
{
|
|
m_dPer = dVal;
|
|
}
|
|
|
|
double CTGSizeDescrWnd::GetPer()
|
|
{
|
|
return m_dPer;
|
|
}
|
|
|
|
void CTGSizeDescrWnd::SetStyle(Style eStyle)
|
|
{
|
|
m_eStyle = eStyle;
|
|
}
|
|
|
|
int CTGSizeDescrWnd::GetStyle()
|
|
{
|
|
return m_eStyle;
|
|
}
|
|
|
|
void CTGSizeDescrWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
switch(m_eStyle)
|
|
{
|
|
case kPie:
|
|
{
|
|
DrawPie(&dc);
|
|
break;
|
|
}
|
|
case kProcess:
|
|
{
|
|
DrawProcess(&dc);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
BOOL CTGSizeDescrWnd::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
CPoint CTGSizeDescrWnd::GetPerPoint(double dPer, int nWidthRadius, int nHeightRadius, const CPoint& ptCenter)
|
|
{
|
|
CPoint ptRslt(0,0);
|
|
int i10XPer = (int)dPer*10;
|
|
switch(i10XPer)
|
|
{
|
|
case 0:
|
|
ptRslt.x = 2 * nWidthRadius;
|
|
ptRslt.y = nHeightRadius-1;
|
|
return ptRslt;
|
|
case 1000:
|
|
ptRslt.x = 2 * nWidthRadius;
|
|
ptRslt.y = nHeightRadius;
|
|
return ptRslt;
|
|
case 125:
|
|
ptRslt.x = 2 * nWidthRadius;
|
|
ptRslt.y = 0;
|
|
return ptRslt;
|
|
case 250:
|
|
ptRslt.x = nWidthRadius;
|
|
ptRslt.y = 0;
|
|
return ptRslt;
|
|
case 375:
|
|
ptRslt.x = 0;
|
|
ptRslt.y = 0;
|
|
return ptRslt;
|
|
case 500:
|
|
ptRslt.x = 0;
|
|
ptRslt.y = nHeightRadius;
|
|
return ptRslt;
|
|
case 625:
|
|
ptRslt.x = 0;
|
|
ptRslt.y = 2 * nHeightRadius;
|
|
return ptRslt;
|
|
case 750:
|
|
ptRslt.x = nWidthRadius;
|
|
ptRslt.y = 2 * nHeightRadius;
|
|
return ptRslt;
|
|
case 875:
|
|
ptRslt.x = 2 * nWidthRadius;
|
|
ptRslt.y = 2 * nHeightRadius;
|
|
return ptRslt;
|
|
default:
|
|
break;
|
|
}
|
|
int XOffSet = 0; ///x值偏移中心值
|
|
int YOffSet = 0; ///y值偏移中心值
|
|
/// 如果dPer在0 - 12.5区间,
|
|
if( i10XPer < 125 && i10XPer > 0 )
|
|
{
|
|
YOffSet = (int)(0.008 * nHeightRadius * i10XPer);
|
|
ptRslt.x = 2 * nWidthRadius;
|
|
ptRslt.y = nHeightRadius - YOffSet;
|
|
}
|
|
else if( i10XPer < 375 && i10XPer > 125 )
|
|
{
|
|
XOffSet = (int)(0.008 * nWidthRadius * fabs((double)(i10XPer - 250)));
|
|
if (i10XPer < 250)
|
|
{
|
|
ptRslt.x = nWidthRadius + XOffSet;
|
|
}
|
|
else
|
|
{
|
|
ptRslt.x = nWidthRadius - XOffSet;
|
|
}
|
|
ptRslt.y = 0;
|
|
}
|
|
else if( i10XPer < 625 && i10XPer > 375 )
|
|
{
|
|
YOffSet = (int)(0.008 * nHeightRadius * fabs((double)(i10XPer - 500)));
|
|
if (i10XPer < 500)
|
|
{
|
|
ptRslt.y = nHeightRadius - YOffSet;
|
|
ptRslt.x = 0;
|
|
}
|
|
else
|
|
{
|
|
double dPer2Rad = PI * dPer / 50.0;
|
|
///pie终点与椭圆圆心连线在椭圆上的交点的纵坐标值与XOffSet的差值
|
|
int iPieLineXElps2Offet_Y = (int)fabs(YOffSet + (sin(dPer2Rad) * nHeightRadius));
|
|
///pie终点与椭圆圆心连线在椭圆上的交点的横坐标值与矩形左边的差值
|
|
int iPieLineXElps2Right_X = (int)fabs((cos(dPer2Rad) * nWidthRadius) + nWidthRadius);
|
|
ptRslt.x = iPieLineXElps2Right_X;
|
|
ptRslt.y = nHeightRadius + YOffSet - iPieLineXElps2Offet_Y;
|
|
}
|
|
|
|
}
|
|
else if( i10XPer < 875 && i10XPer > 625 )
|
|
{
|
|
XOffSet = (int)(0.008 * nWidthRadius * fabs((double)(i10XPer - 750)));
|
|
double dPer2Rad = PI * dPer / 50.0;
|
|
///pie终点与椭圆圆心连线在椭圆上的交点的横坐标值与XOffSet的差值
|
|
|
|
///pie终点与椭圆圆心连线在椭圆上的交点的纵坐标值与矩形底边的差值
|
|
int iPieLineXElps2Bottom_Y = (int)fabs(nHeightRadius + (sin(dPer2Rad) * nHeightRadius));
|
|
|
|
if (i10XPer < 750)
|
|
{
|
|
int iPieLineXElps2Offet_X = (int)fabs(XOffSet + (cos(dPer2Rad) * nWidthRadius));
|
|
ptRslt.x = nWidthRadius - XOffSet + iPieLineXElps2Offet_X;
|
|
}
|
|
else
|
|
{
|
|
int iPieLineXElps2Offet_X = (int)fabs(XOffSet - (cos(dPer2Rad) * nWidthRadius));
|
|
ptRslt.x = nWidthRadius + XOffSet - iPieLineXElps2Offet_X;
|
|
}
|
|
ptRslt.y = 2 * nHeightRadius - iPieLineXElps2Bottom_Y;
|
|
}
|
|
else if( i10XPer < 1000 && i10XPer > 875 )
|
|
{
|
|
YOffSet = (int)(0.008 * nHeightRadius * (1000 -i10XPer));
|
|
double dPer2Rad = PI * dPer / 50.0;
|
|
///pie终点与椭圆圆心连线在椭圆上的交点的纵坐标值与XOffSet的差值
|
|
int iPieLineXElps2Offet_Y = (int)fabs(YOffSet + (sin(dPer2Rad) * nHeightRadius));
|
|
///pie终点与椭圆圆心连线在椭圆上的交点的横坐标值与矩形右边的差值
|
|
int iPieLineXElps2Right_X = (int)fabs(nWidthRadius - (cos(dPer2Rad) * nWidthRadius));
|
|
ptRslt.x = 2 * nWidthRadius - iPieLineXElps2Right_X;
|
|
ptRslt.y = nHeightRadius + YOffSet - iPieLineXElps2Offet_Y;
|
|
}
|
|
|
|
return ptRslt;
|
|
}
|
|
|
|
void CTGSizeDescrWnd::DrawPie(CDC *pDC)
|
|
{
|
|
ASSERT(pDC != NULL);
|
|
|
|
if ( GetPer() < -1.e-10 || GetPer() - 100 > 1.e-10)
|
|
{
|
|
::MessageBox(AfxGetMainWnd()->m_hWnd, _T("使用的空间范围有误!"),_T("TPM"), MB_OK);
|
|
return;
|
|
}
|
|
|
|
CRect rc; //上面的粉色pie
|
|
CRect rc2;//下面的紫色pie
|
|
GetClientRect(&rc);//控件的矩形区大小
|
|
rc2 = rc;
|
|
rc2.OffsetRect(0,15); //将紫色pie矩形区向下偏移15像素
|
|
|
|
CBrush brBkgnd,brFrgnd,brDrawClr;
|
|
CBrush* pBrushOld = NULL;
|
|
|
|
brBkgnd.CreateSolidBrush( RGB(128,0,128) );//RGB(128,0,128) 紫色
|
|
brFrgnd.CreateSolidBrush( RGB(255,0,255) );//RGB(255,0,255) 粉色
|
|
brDrawClr.CreateSolidBrush( RGB(0,0,255) );//RGB(0,0,255) 蓝色
|
|
|
|
//画紫色pie
|
|
pBrushOld = pDC->SelectObject(&brBkgnd);
|
|
pDC->Ellipse(rc2);
|
|
pDC->SelectObject(pBrushOld);
|
|
brBkgnd.DeleteObject();
|
|
|
|
//ptStart 画饼的起始点
|
|
//ptEnd 粉色饼的结束点
|
|
//ptBkgndPieEnd 紫色饼的结束点
|
|
CPoint ptStart,ptEnd,ptBkgndPieEnd;
|
|
|
|
//起始位置
|
|
ptStart.x = rc2.right;
|
|
ptStart.y = rc2.CenterPoint().y;
|
|
//取得粉色pie终点的位置
|
|
ptEnd = GetPerPoint( m_dPer, rc.Width() / 2, rc.Height() / 2, rc.CenterPoint() );
|
|
//对于紫色pie,终点位置相对于粉色pie向下偏移15个像素
|
|
ptBkgndPieEnd.x = ptEnd.x;
|
|
ptBkgndPieEnd.y = ptEnd.y + 15;
|
|
|
|
//画紫色pie中使用的蓝色部分,当m_dPer为0时,不画,只使用紫色的背景
|
|
if( (m_dPer > 1.e-10) && (m_dPer - 100.0 < 1.e-10))
|
|
{
|
|
pBrushOld =pDC->SelectObject(&brDrawClr);
|
|
pDC->Pie( rc2, ptStart, ptBkgndPieEnd);
|
|
}
|
|
|
|
if (100.0 - m_dPer < 1.e-10)
|
|
{
|
|
pBrushOld =pDC->SelectObject(&brDrawClr);
|
|
pDC->Ellipse(rc2);
|
|
}
|
|
|
|
//修正立体效果,用rc2矩形中点和紫色pie的终点建立修正矩形
|
|
if ( (m_dPer - 50.0 > 1.e-10) && (m_dPer - 75.0 < 1.e-10) )
|
|
{
|
|
CRect rc2Fix;
|
|
|
|
rc2Fix.top = rc2.CenterPoint().y;
|
|
rc2Fix.left = ptBkgndPieEnd.x;
|
|
rc2Fix.right = rc2.CenterPoint().x;
|
|
rc2Fix.bottom = ptBkgndPieEnd.y;
|
|
|
|
CPen penNew;
|
|
CPen* pPenOld = NULL;
|
|
penNew.CreatePen(PS_SOLID,0,RGB(128,0,128));
|
|
pPenOld = pDC->SelectObject(&penNew);
|
|
|
|
brBkgnd.CreateSolidBrush( RGB(128,0,128) );//RGB(128,0,128)紫色
|
|
pBrushOld = pDC->SelectObject(&brBkgnd);
|
|
pDC->Rectangle(rc2Fix);
|
|
pDC->SelectObject(pBrushOld);
|
|
pDC->SelectObject(pPenOld);
|
|
brBkgnd.DeleteObject();
|
|
penNew.DeleteObject();
|
|
|
|
//画连接上下两个终点的饼的边线
|
|
pDC->MoveTo(ptBkgndPieEnd);
|
|
pDC->LineTo(ptBkgndPieEnd.x,ptBkgndPieEnd.y - 15);
|
|
}
|
|
else if ( (m_dPer - 75.0 > 1.e-10) && (m_dPer - 100.0 < 1.e-10) )
|
|
{
|
|
CRect rc2Fix;
|
|
|
|
rc2Fix.top = rc2.CenterPoint().y;
|
|
rc2Fix.left = rc2.CenterPoint().x;
|
|
rc2Fix.bottom = ptBkgndPieEnd.y;
|
|
rc2Fix.right = ptBkgndPieEnd.x;
|
|
|
|
CPen penNew;
|
|
CPen* pPenOld = NULL;
|
|
penNew.CreatePen(PS_SOLID, 0, RGB(0,0,255));
|
|
pPenOld = pDC->SelectObject(&penNew);
|
|
|
|
brBkgnd.CreateSolidBrush( RGB(0,0,255) );//RGB(0,0,255)蓝色
|
|
pBrushOld = pDC->SelectObject(&brBkgnd);
|
|
pDC->Rectangle(rc2Fix);
|
|
pDC->SelectObject(pBrushOld);
|
|
pDC->SelectObject(pPenOld);
|
|
brBkgnd.DeleteObject();
|
|
penNew.DeleteObject();
|
|
|
|
//画连接上下两个终点的饼的边线
|
|
pDC->MoveTo(ptBkgndPieEnd);
|
|
pDC->LineTo(ptBkgndPieEnd.x,ptBkgndPieEnd.y - 15);
|
|
}
|
|
|
|
pDC->SelectObject(pBrushOld);
|
|
|
|
//连接上下椭圆两边的侧线,看起来比较立体一些
|
|
pDC->MoveTo(rc2.left, rc2.CenterPoint().y);
|
|
pDC->LineTo(rc.left, rc.CenterPoint().y);
|
|
pDC->MoveTo(rc2.right, rc2.CenterPoint().y);
|
|
pDC->LineTo(rc.right, rc.CenterPoint().y);
|
|
|
|
//画粉色的pie
|
|
pBrushOld = pDC->SelectObject( &brFrgnd );
|
|
pDC->Ellipse(rc);
|
|
pDC->SelectObject(pBrushOld);
|
|
brFrgnd.DeleteObject();
|
|
|
|
//画粉色pie中使用的蓝色部分
|
|
ptStart.x = rc.right;
|
|
ptStart.y = rc.CenterPoint().y;
|
|
pBrushOld =pDC->SelectObject(&brDrawClr);
|
|
|
|
if ( m_dPer > 1.e-10 && m_dPer - 100.0 < 1.e-10)
|
|
{
|
|
pDC->Pie(rc, ptStart, ptEnd);
|
|
}
|
|
//如果是100%,直接画椭圆,m_dPer == 100
|
|
if (fabs(100.0 - m_dPer) < 1.e-10)
|
|
{
|
|
pDC->Ellipse(rc);
|
|
}
|
|
pDC->SelectObject(pBrushOld);
|
|
|
|
//加使用率文字
|
|
CFont ftPerTxt;
|
|
ftPerTxt.CreateFont( 15, 0, 0, 0, FW_BLACK, 0, 0, 0,
|
|
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
|
DEFAULT_QUALITY , DEFAULT_PITCH, NULL );
|
|
CFont* pOldFont=(CFont*)pDC->SelectObject(&ftPerTxt);
|
|
pDC->SetTextColor(RGB(255,255,0));
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
CString str;
|
|
str.Format(_T("%d"), int(m_dPer));
|
|
str += _T("%");
|
|
const double fXScale = rc.CenterPoint().x/112.5; //112.5为制作控件时的长轴
|
|
const double fYScale = rc.CenterPoint().y/69.0; //69.0为制作控件时的短轴
|
|
//1<m_dPer<25
|
|
if (int(m_dPer) > 3 && int(m_dPer) <= 25)
|
|
{
|
|
if (int(m_dPer) < 7)
|
|
{
|
|
pDC->TextOut( ((rc.CenterPoint().x * 3) / 2 + (int)(2.0 * fXScale)), ((rc.CenterPoint().y + ptEnd.y) / 2 ), str);
|
|
}
|
|
else
|
|
{
|
|
pDC->TextOut( ((rc.CenterPoint().x * 3) / 2 ), ((rc.CenterPoint().y + ptEnd.y) / 2 + (int)(5.0 * fXScale)), str);
|
|
}
|
|
}
|
|
else if (int(m_dPer) > 25 && int(m_dPer) <= 50)
|
|
{
|
|
if (int(m_dPer) < 37)
|
|
{
|
|
pDC->TextOut( ((rc.right + ptEnd.x) / 2 - (int)(12.0 * fXScale)), ((rc.CenterPoint().y + ptEnd.y) / 2 - (int)(1.0 * fYScale) - 1), str);
|
|
}
|
|
else
|
|
{
|
|
pDC->TextOut( ((rc.right + ptEnd.x) / 2 - (int)(8.0 * fXScale)), ((rc.CenterPoint().y) / 2 - (int)(3.0 * fYScale)), str);
|
|
}
|
|
}
|
|
else if (int(m_dPer) > 50 && int(m_dPer) <= 75)
|
|
{
|
|
if (int(m_dPer) < 67)
|
|
{
|
|
pDC->TextOut( (rc.CenterPoint().x - (int)((m_dPer - 48) * 2 * fXScale)), ((rc.CenterPoint().y) / 2 - (int)(5.0 * fYScale)) , str);
|
|
}
|
|
else
|
|
{
|
|
pDC->TextOut( (rc.CenterPoint().x / 2 - (int)((69 - m_dPer) * 2 * fXScale)), ((rc.CenterPoint().y) - 20), str);
|
|
}
|
|
}
|
|
else if (int(m_dPer) > 75 && int(m_dPer) <= 100)
|
|
{
|
|
if (int(m_dPer) < 87)
|
|
{
|
|
pDC->TextOut( rc.CenterPoint().x / 2 , ((rc.CenterPoint().y) - 20), str);
|
|
}
|
|
else
|
|
{
|
|
pDC->TextOut( (rc.CenterPoint().x / 2 - (int)((79 - m_dPer) * 2 * fXScale)), ((rc.CenterPoint().y) - 20), str);
|
|
}
|
|
}
|
|
ftPerTxt.DeleteObject();
|
|
// str.Format("h:%d w:%d",rc.Height(),rc.Width());
|
|
// MessageBox(str);
|
|
return;
|
|
}
|
|
|
|
void CTGSizeDescrWnd::DrawProcess(CDC *pDC)
|
|
{
|
|
ASSERT(pDC != NULL);
|
|
|
|
|
|
//m_dPer >= 0 && m_dPer <= 100
|
|
if ((m_dPer > -1.e-10) && (m_dPer - 100.0 < 1.e-10))
|
|
{
|
|
|
|
//画背景条
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
|
|
CBrush brBkgnd;
|
|
CBrush* pBrushOld = NULL;
|
|
brBkgnd.CreateSolidBrush( RGB(128,0,128) );//RGB(128,0,128)紫色
|
|
pBrushOld = pDC->SelectObject(&brBkgnd);
|
|
pDC->Rectangle(rc);
|
|
pDC->SelectObject(pBrushOld);
|
|
brBkgnd.DeleteObject();
|
|
|
|
//画使用百分率条
|
|
CBrush brDrawClr;
|
|
brDrawClr.CreateSolidBrush( RGB(0,0,255) );//RGB(0,0,255)蓝色
|
|
pBrushOld = pDC->SelectObject(&brDrawClr);
|
|
pDC->Rectangle(rc.left, rc.top, (int)(rc.right * m_dPer / 100), rc.bottom);
|
|
pDC->SelectObject(pBrushOld);
|
|
brDrawClr.DeleteObject();
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
MessageBox(_T("使用的空间范围有误!"),_T("错误"));
|
|
return;
|
|
}
|
|
}
|
|
|