123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- #include "Hello.h"
- #define SEGMENTS 500
- #define PI 3.1415926535897932384626433832795
- CMyApp myApp;
- #define CLKSCALE ((INT)8000)
- // 表盘
- typedef struct
- {
- SHORT sin;
- SHORT cos;
- } TRIG;
- TRIG CirTab[] = { // circle sin, cos, table
- { -7999, -0 },
- { -7956, -836 },
- { -7825, -1663 },
- { -7608, -2472 },
- { -7308, -3253 },
- { -6928, -4000 },
- { -6472, -4702 },
- { -5945, -5353 },
- { -5353, -5945 },
- { -4702, -6472 },
- { -3999, -6928 },
- { -3253, -7308 },
- { -2472, -7608 },
- { -1663, -7825 },
- { -836 , -7956 },
- { 0, -7999 },
- { 836, -7956 },
- { 1663, -7825 },
- { 2472, -7608 },
- { 3253, -7308 },
- { 3999, -6928 },
- { 4702, -6472 },
- { 5353, -5945 },
- { 5945, -5353 },
- { 6472, -4702 },
- { 6928, -4000 },
- { 7308, -3253 },
- { 7608, -2472 },
- { 7825, -1663 },
- { 7956, -836 },
- { 8000, 0 },
- { 7956, 836 },
- { 7825, 1663 },
- { 7608, 2472 },
- { 7308, 3253 },
- { 6928, 4000 },
- { 6472, 4702 },
- { 5945, 5353 },
- { 5353, 5945 },
- { 4702, 6472 },
- { 3999, 6928 },
- { 3253, 7308 },
- { 2472, 7608 },
- { 1663, 7825 },
- { 836, 7956 },
- { 0, 7999 },
- { -836, 7956 },
- { -1663, 7825 },
- { -2472, 7608 },
- { -3253, 7308 },
- { -4000, 6928 },
- { -4702, 6472 },
- { -5353, 5945 },
- { -5945, 5353 },
- { -6472, 4702 },
- { -6928, 3999 },
- { -7308, 3253 },
- { -7608, 2472 },
- { -7825, 1663 },
- { -7956, 836 }
- };
- // End
- BOOL CMyApp::InitInstance()
- {
- // Initialize GDI+.
- Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
- m_pMainWnd = new CMainWindow();
- m_pMainWnd->ShowWindow(m_nCmdShow);
- m_pMainWnd->UpdateWindow();
- return CWinApp::InitInstance();
- }
- BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
- ON_WM_PAINT()
- END_MESSAGE_MAP()
- CMainWindow::CMainWindow()
- {
- Create(NULL,_T("The Hello Application"));
- InitCLR();
- }
- void CMainWindow::InitCLR()
- {
- m_nLowwer = 0;
- m_nUpper = 1000;
- m_clrLine = RGB(250,0,0);
- m_nLineWidth = 1;
- m_fCurrentValue = 83.0;
- m_clrCurrentLine = RGB(105,220,200);
- //m_clrCurrentBack = RGB(250,250,225);
- m_clrCurrentBack = RGB(99,99,99);
- m_clrCurrentFore = RGB(80,250,230);
- }
- void CMainWindow::Draw(CDC* pDC)
- {
- CRect rectRgn = m_rctCurrent;
- COLORREF clrPen = m_clrCurrentLine;
- COLORREF clrBrush = m_clrCurrentBack;
- COLORREF clrText = m_clrCurrentFore;
- /*if (!bRuning)
- {
- rectRgn = m_rect;
- clrPen = m_clrLine;
- clrBrush = m_clrBack;
- clrText = m_clrFore;
- }
- if (!m_bVariant)
- m_strCurrentCaption = m_strCaption;*/
- rectRgn.NormalizeRect();
- CBrush brush(clrText);
- CBrush *prebrush = pDC->SelectObject(&brush);
- pDC->FillSolidRect(rectRgn, clrBrush);
- int top = rectRgn.top+10;
- int middle = rectRgn.bottom - 40;
- if ( middle < top ) middle = top;
- CRect rectPie = CRect(rectRgn.left + 10, top, rectRgn.right - 10, top + 2*(middle-top));
- //pDC->Rectangle(rectPie.left,rectPie.top,rectPie.right,rectRgn.bottom-38);;
- CPoint s = CPoint(rectRgn.right - 10, middle);
- CPoint e = CPoint(rectRgn.left + 10, middle);
- INT HorzRes = pDC->GetDeviceCaps(HORZRES);
- INT VertRes = pDC->GetDeviceCaps(VERTRES);
- INT VertSize = pDC->GetDeviceCaps(VERTSIZE);
- INT HorzSize = pDC->GetDeviceCaps(HORZSIZE);
- m_lAspectN = ((LONG)VertRes * 100) / (LONG)VertSize;
- m_lAspectD = ((LONG)HorzRes * 100) / (LONG)HorzSize;
- // 画指针;
- //CPen pen( PS_SOLID, m_nLineWidth, m_clrLine );
- //CPen* pOldPen = pDC->SelectObject(&pen);
- //pDC->MoveTo(rectPie.CenterPoint());
- // 根据外部值,画直线(显示指针位置);
- //rectPie.DeflateRect(5,5,5,5);
- //CRgn rgn;
- //rgn.CreateEllipticRgnIndirect( rectPie );
- //float angle = 180-180*(m_fCurrentValue-m_nLowwer)/(m_nUpper-m_nLowwer);
- //int bLeft = 1;
- //if ( angle < 90 ) bLeft = -1;
- //CPoint lastPoint;
- //int clockRadius = min(m_rect.Width()/2 - 10 , m_rect.Height() - 50) - 10;
- //lastPoint.x = rectPie.CenterPoint().x + clockRadius*cos(angle/180*PI);
- //lastPoint.y = rectPie.CenterPoint().y - clockRadius*sin(angle/180*PI) ; // 差了个精度;
- //lastPoint.y = rectPie.CenterPoint().y - clockRadius*sin(angle/180*PI) + 1;
- // 根据传参,画直线的终点;
- //pDC->LineTo(lastPoint);
- //pDC->SelectObject(pOldPen);
- // 画边框;
- pDC->DrawEdge(&rectRgn,BDR_RAISEDOUTER,BF_RECT);
- rectRgn.DeflateRect(1,1);
- pDC->DrawEdge(rectRgn, BDR_RAISEDOUTER, BF_RECT);
- rectRgn.left = rectRgn.left+5;
- rectRgn.right = rectRgn.right-5;
- rectRgn.top = rectRgn.top+5;
- rectRgn.bottom = rectRgn.bottom-35;
- pDC->DrawEdge(&rectRgn,BDR_SUNKENOUTER,BF_RECT);
- pDC->SelectObject(prebrush);
- //pDC->Rectangle(rectRgn);
- // pDC->SelectObject(pOldPen);
- // 画表盘弧形刻度值;
- //DrawFace(pDC);
- int nRadius[3];
- nRadius[0] = rectRgn.Height()/2 - 10;
- nRadius[1] = nRadius[0] - 60;
- nRadius[2] = nRadius[1] - 80;
- pDC->SetWindowExt(rectRgn.Width(),rectRgn.Height());
- DrawWatch(
- pDC,
- rectRgn,
- 0, // 最小范围值;
- 1000, // 最大范围值;
- m_rect.Width()/10 + m_rect.Height()/10, // 当前范围值;
- "单位:M", // 量程单位;
- 180, // 范围弧度;
- nRadius, // 内弧半径;
- 10, // 大刻度数;
- 10); // 小刻度数;
- //DeleteObject( pen );
- DeleteObject( brush );
- //DeleteObject( rgn );
- }
- void CMainWindow::DrawFace(CDC* pDC)
- {
- INT i;
- RECT tRect;
- tagPOINT clockCenter; // 表盘针形起点;
- m_rect = m_rctCurrent;
- char c[5] = {0};
- int clockRadius = min(m_rect.Width()/2 - 10 , m_rect.Height() - 50);
- clockCenter.y = m_rect.bottom - 20;
- clockCenter.x = m_rect.left + m_rect.Width()/2;
- #if 0
- int nSmall = (m_nUpper - m_nLowwer) / 100;
- int nBig = nSmall / 5;
- POINT ptStart;
- POINT ptEnd;
- pDC->Arc(&m_rect,ptStart,ptEnd);
- #endif
- for (i=0; i < 31; i++)
- {
- tRect.top = (INT)(((LONG)(CirTab[i].cos) * clockRadius) / CLKSCALE + clockCenter.y - 20);
- tRect.left = (INT)(((LONG)(CirTab[i].sin) * clockRadius) / CLKSCALE + clockCenter.x);
- if (i % 5)
- {
- tRect.right = tRect.left + 2;
- tRect.bottom = tRect.top + 2;
- pDC->FillSolidRect(&tRect, RGB(255,0,0));
- }
- else
- {
- tRect.right = tRect.left + 2;
- tRect.bottom = tRect.top + 2;
- if((i / 5) == 0)
- _itoa(m_nLowwer, c , 10);
- else
- _itoa((m_nUpper - m_nLowwer) * i / 30, c , 10);
- pDC->SetTextColor(m_clrFore);
- // 以下TextOut,文本的输出应该放在弧形刻度内侧;而不是放在中间;
- // pDC->TextOut(tRect.left-1,tRect.top-2,c,(int)strlen(c));
- pDC->TextOut(tRect.left-1,tRect.top-2,c,(int)strlen(c));
- }
- }
- }
- void CMainWindow::OnPaint()
- {
- CRect rect;
- GetClientRect(&rect);
- CPaintDC dc(this);
- dc.SetBkMode(TRANSPARENT);
- int nWidth = rect.Width();
- int nHeight = rect.Height();
- #if 1
- m_rect = rect;
- m_rctCurrent = m_rect;
- Draw((CDC*)&dc);
- #endif
- #if 1
- TCHAR szTextOut[256] = {0};
- sprintf_s(szTextOut,"当前窗口大小:%d * %d,倍率 = %lf",nWidth,nHeight,(double)nWidth/nHeight);
- CPen pen(PS_SOLID,1,RGB(105,220,210));
- dc.SelectObject(pen);
- dc.SetTextColor(RGB(105,220,250));
- CRect rtShow(rect.left + 20, rect.top + 40,rect.right ,rect.bottom);
- dc.DrawText(szTextOut, -1, &rtShow, 0);
- #endif
- #if 0
- dc.SetViewportOrg(nWidth/2,nHeight/2);
- int nRadius[]=
- {
- 220,
- 160,
- 90
- };
- DrawWatch(
- (CDC *)&dc,
- rect,
- -500, // 最小范围值;
- 500, // 最大范围值;
- nHeight/10 + nWidth/10, // 当前范围值;
- "单位:M", // 量程单位;
- 320, // 范围弧度;
- nRadius, // 内弧半径;
- 10, // 大刻度数;
- 10); // 小刻度数;
- #endif
- }
- // GDI弧度的起始位置跟数学上的不一样,在GDI中,弧度是从X轴负方向(左边),顺时针开始计算的;
- void CMainWindow::DrawWatch(
- CDC *pDC,
- CRect &Wrect,
- float fMin, // 最小范围值;
- float fMax, // 最大范围值;
- const float &fValue, // 当前值;
- CString strUnit, // 量程单位;
- const float &fRadian, // 范围弧度大小;
- int nRadius[3], // 内弧半径;
- const int &nTable, // 大刻度数;
- const int &nScale // 小刻度数;
- )
- {
- if(fMin>fValue)
- {
- fMin=fValue;
- }
- if(fValue>fMax)
- {
- fMax=fValue;
- }
- int nWidth,nHeight;
- //nWidth = nHeight = 200;
- //nWidth = m_rctCurrent.Width();
- //nHeight = m_rctCurrent.Height();
- CRect rect = Wrect; //(-nWidth,nHeight,nWidth,-nHeight);
- nWidth = Wrect.Width();
- nHeight = Wrect.Height();
- //int nTable = 10; // 大格;
- //int nScale = 5; // 每小段里面的小格;
- COLORREF Green(RGB(0,255,0));
- COLORREF Blue(RGB(0,0,255));
- COLORREF Cyan(RGB(92,92,92));
- COLORREF Yellow(RGB(255,255,0));
- COLORREF Red(RGB(255,0,0));
- COLORREF SkyBlue(RGB(0,128,255));
- COLORREF LineColor(RGB(128,0,0)); // 巧克力色;
-
- // 张开的弧度;
- //float fRadian = 60;
- //// 同心圆半径;
- //int nRadius[]=
- //{
- // 220,
- // 160,
- // 90
- //};
- // 圆心;
- //CPoint ptCenter;
- /*if ( fRadian >180 )
- {
- ptCenter.x = Wrect.left + nWidth/2 ;
- ptCenter.y = Wrect.top + nHeight/2 ;
- nRadius[0] = nHeight/2 - 10;
- nRadius[1] = nRadius[0]*5/6 - 10;
- nRadius[2] = nRadius[1]*2/7 - 10;
- }
- else if( fRadian >= 0 && fRadian <= 180)
- {
- ptCenter.x = Wrect.left + nWidth/2 ;
- ptCenter.y = Wrect.bottom;
- nRadius[0] = nHeight - 10;
- nRadius[1] = nRadius[0]*5/6 - 10;
- nRadius[2] = nRadius[1]*2/7 - 10;
- }*/
- // 圆心;
- CPoint ptCenter;
- if ( fRadian > 180 )
- {
- ptCenter.x = rect.left + nWidth/2 ;
- ptCenter.y = rect.top + nHeight/2 -6 ;
- if ( nHeight < nWidth)
- {
- nRadius[0] = nHeight/2 - 10;
- }else
- nRadius[0] = nWidth/2 - 10;
- nRadius[1] = nRadius[0]*5/6 - 10;
- nRadius[2] = nRadius[1]*2/7 - 10;
- }
- else if( fRadian > 0 && fRadian <= 180)
- {
- ptCenter.x = rect.left + nWidth/2 ;
- ptCenter.y = rect.bottom - 6;
- if ( fRadian == 180 )
- {
- if ( nHeight < nWidth/2)
- nRadius[0] = nHeight - 10;
- else
- nRadius[0] = nWidth/2 - 10;
- }else
- {
- if ( nHeight < nWidth/2)
- nRadius[0] = nHeight - 10;
- else
- nRadius[0] = nWidth/2 - 10;
- }
- nRadius[1] = nRadius[0]*5/6 - 10;
- nRadius[2] = nRadius[1]*2/7 - 10;
- }
-
- //CPoint ptCenter( 0 , 0 );
- // 刻度长度;
- int nLongScal = 16;
- int nShortScal = 6;
-
- CPen LinePen(PS_SOLID,2,LineColor); // 画笔颜色;
- pDC->SelectObject(LinePen);
- // 画3段弧;
- CRect rtArc1(ptCenter.x - nRadius[0], ptCenter.y - nRadius[0], ptCenter.x - nRadius[0] + 2*nRadius[0] + 1, ptCenter.y - nRadius[0] + 2*nRadius[0] + 1);
- CRect rtArc2(ptCenter.x - nRadius[1], ptCenter.y - nRadius[1], ptCenter.x - nRadius[1] + 2*nRadius[1] + 1, ptCenter.y - nRadius[1] + 2*nRadius[1] + 1);
- CRect rtArc3(ptCenter.x - nRadius[2], ptCenter.y - nRadius[2], ptCenter.x - nRadius[2] + 2*nRadius[2] + 1, ptCenter.y - nRadius[2] + 2*nRadius[2] + 1);
- CPoint ptArcStart,ptArcEnd;
- double rad = ((180-fRadian)/2)/180*PI ;
- ptArcEnd.x = ptCenter.x - nRadius[0]*cos(rad);
- ptArcEnd.y = ptCenter.y - nRadius[0]*sin(rad);
- rad = ( (180-fRadian)/2 + fRadian )/180*PI ;
- ptArcStart.x = ptCenter.x - nRadius[0]*cos(rad);
- ptArcStart.y = ptCenter.y - nRadius[0]*sin(rad);
- // 画弧,是从起点逆时针到终点,所以要交换点位置;
- pDC->Arc(rtArc1,ptArcStart,ptArcEnd);
- pDC->Arc(rtArc2,ptArcStart,ptArcEnd);
- CPen LinePen1(PS_SOLID,1,LineColor); // 画笔颜色;
- pDC->SelectObject(LinePen1);
- pDC->Arc(rtArc3,ptArcStart,ptArcEnd);
- // 画 刻度(分段);
- for( int i = 0; i <= nTable*nScale; i++ ) // 总刻度;
- {
- CPoint pt0,pt1;
- double f0 = ( (180-fRadian)/2 + fRadian/(nTable*nScale)*i )/180*PI; // 刻度数对应的弧度;
- pt1.x = ptCenter.x + nRadius[1]*cos(f0);
- pt1.y = ptCenter.y - nRadius[1]*sin(f0);
- if( i%nTable == 0 )
- {
- pt0.x = ptCenter.x + (nRadius[1]+nLongScal)*cos(f0);
- pt0.y = ptCenter.y - (nRadius[1]+nLongScal)*sin(f0);
- CString str;
- str.Format(_T("%.0f"),fMax-(fMax-fMin)/(nTable*nScale)*i);
- // 获取文本所占的大小;
- // 还是不标准位置,应该还有个系数跟弧度有关;
- CRect textrc; // 要使得矩形中心点 在直线 pt0~pt1上;
- CSize ftszie = pDC->GetTextExtent(str);
- // 矩形对角线长度/2;
- double dRtLength = sqrt((pow((float)ftszie.cx,2) + pow((float)ftszie.cy,2)))/2;
- CPoint ptText;
- ptText.x = ptCenter.x + (nRadius[1] + nLongScal + dRtLength)*cos(f0);
- ptText.y = ptCenter.y - (nRadius[1] + nLongScal + dRtLength)*sin(f0);
- textrc.left = ptText.x - ftszie.cx/2;
- textrc.top = ptText.y - ftszie.cy/2;
- textrc.right = ptText.x + ftszie.cx/2;
- textrc.bottom = ptText.y + ftszie.cy/2 ;
- pDC->SetBkColor(Green);
- pDC->SetTextColor(Blue);
- pDC->DrawText(str, &textrc,0);
- CPoint pt2,pt3;
- int nGap = 5;
- pt3.x = ptCenter.x +(nRadius[0]+0)*cos(f0);
- pt3.y = ptCenter.y -(nRadius[0]+0)*sin(f0);
- pt2.x = ptCenter.x +(nRadius[0]-nGap)*cos(f0);
- pt2.y = ptCenter.y -(nRadius[0]-nGap)*sin(f0);
- CPen BigPen(PS_SOLID,2,Yellow); // 画笔颜色;
- pDC->SelectObject(BigPen);
- pDC->MoveTo(pt2);
- pDC->LineTo(pt3);
- pDC->MoveTo(pt0);
- pDC->LineTo(pt1);
- DeleteObject(BigPen);
- }
- else
- {
- pt0.x = ptCenter.x + (nRadius[1]+nShortScal)*cos(f0);
- pt0.y = ptCenter.y - (nRadius[1]+nShortScal)*sin(f0);
- CPen SmallPen(PS_SOLID,1,Blue); // 画笔颜色;
- pDC->SelectObject(SmallPen);
- pDC->MoveTo(pt0);
- pDC->LineTo(pt1);
- DeleteObject(SmallPen);
- }
- }
- CFont font;
- font.CreatePointFont(150,_T("Times New Roman"));
- pDC->SelectObject(font);
- // 输出文本:单位;
- CRect UnitRc;
- CSize ftsize = pDC->GetTextExtent(strUnit);
- UnitRc.left = ptCenter.x - ftsize.cx/2;
- //UnitRc.top = ptCenter.y - (nRadius[0]-nRadius[1]+nRadius[2] + ftsize.cy/2);
- UnitRc.top = ptCenter.y - (nRadius[1]-nRadius[2])/2 - nRadius[2] - ftsize.cy/2; // 使居中;
- UnitRc.right = UnitRc.left + ftsize.cx;
- UnitRc.bottom = UnitRc.top + ftsize.cy;
- pDC->SetTextColor(Red);
- pDC->DrawText(strUnit,&UnitRc,0);
- // 输出文本:当前数据;
- // 要保持在圆心上方;
- CRect DataRc;
- CString strData;
- strData.Format(_T("当前值:%.0f"),fValue);
- ftsize = pDC->GetTextExtent(strData);
- DataRc.left = ptCenter.x - ftsize.cx/2;
- //DataRc.top = ptCenter.y - (nRadius[2]-nLongScal);
- DataRc.top = ptCenter.y - (nRadius[2]/2 - nLongScal); // 使居中;
- DataRc.right = DataRc.left + ftsize.cx;
- DataRc.bottom = DataRc.top + ftsize.cy;
- pDC->DrawText(strData,&DataRc,0);
- // 画指针;
- CPen PointPen(PS_SOLID,2,Green);
- pDC->SelectObject(PointPen);
- CPoint pt0,pt1;
- double f0 = ((180-fRadian)/2+fRadian/(fMax-fMin)*(-fValue+fMax))/180*PI;
- pt0.x = ptCenter.x + (nRadius[2]*cos(f0));
- pt0.y = ptCenter.y - (nRadius[2]*sin(f0));
- pt1.x = ptCenter.x + ((nRadius[1]+nShortScal/2)*cos(f0));
- pt1.y = ptCenter.y - ((nRadius[1]+nShortScal/2)*sin(f0));
- pDC->MoveTo(pt0);
- pDC->LineTo(pt1);
- }
- int CMyApp::ExitInstance()
- {
- // TODO: 在此添加专用代码和/或调用基类
- Gdiplus::GdiplusShutdown(gdiplusToken);
- return CWinApp::ExitInstance();
- }
|