Files
envi-code/SourceCode/Code2026/tg_shs/shs_public/TGSizeDescrWnd.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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;
}
}