以曲线或柱状图实时显示数据的控件(二)

翻译|其它|编辑:郝浩|2005-06-15 12:27:00.000|阅读 1901 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


以曲线或柱状图实时显示数据的控件


//////////////////////////////////// MulticolorPlotBtn.cpp ////////////////////////////////////

#include "StdAfx.h"
#include ".\multicolorplotbtn.h"

#include "MemDC.h"


#define GRID_TIMER 1
//网格刷新速率
#define GRID_UPDATE_SPEED 50

typedef struct
{
float fx ;
float fy ;
} DATA_POINT ;
DATA_POINT * g_DataPoint ;


CMulticolorPlotBtn::CMulticolorPlotBtn()
: nPlotType(BAR)
, bfInit(false)
, nGridResolutionX(10)
, nGridResolutionY(10)
, nGridScrollSpeedX(-1)
, nGridScrollSpeedY(0)
, nPlotGranulatrity(2)
, nGridLineWidth(1)
, m_clrDarkBack(RGB(0,0,75))
, m_clrDarkLine(RGB(32,64,32))
, nPlotData(0)
, pfData(NULL)
, fLow(0.0)
, fHigh(100.0)
, fScaleY(1.0)
, m_clrCyanData(RGB(0,255,255))
, nGridStarPosX(0)
, nGridStarPosY(0)
, bLock(true)
, m_clrAxisScaleY(RGB(0,255,255))
, nShowFormatDataText(0)
, m_clrLinePen(RGB(0,255,0))
, nLineWidth(1)
{
// 关键代码
// 初始化关键代码的 C_S 结构

InitializeCriticalSection ( & g_cs ) ;

// 初始化标题
_stprintf ( szTitls , _TEXT ( "%s" ) , _TEXT ( "" ) ) ;
// 初始化单位
_stprintf ( szUints , _TEXT ( "%s" ) , _TEXT ( "" ) ) ;
}

CMulticolorPlotBtn::~CMulticolorPlotBtn(void)
{
   if ( pfData )
   {
     delete [] pfData ;
    }

   // 释放关键代码
   DeleteCriticalSection ( & g_cs ) ;
}

BEGIN_MESSAGE_MAP(CMulticolorPlotBtn, CButton)
ON_WM_TIMER()
END_MESSAGE_MAP()

void CMulticolorPlotBtn::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类

// 避免把该按钮当成下压式按钮

ModifyStyle( 0 , BS_OWNERDRAW ) ;

GetWindowRect ( & m_rect ) ;
ScreenToClient ( & m_rect ) ;

// 得到该控件的宽和高
m_Size.cx = m_rect.right - m_rect.left ;
m_Size.cy = m_rect.bottom - m_rect.top ;

// 计算控件可容纳可见的数据点数
nPlotData = m_Size.cx / nPlotGranulatrity ;

// 设置控件上显示的文字的字体和大小
m_SmallFont.CreateFont( -11 , 0 , 0 , 0 , FW_THIN , false , false , false , DEFAULT_CHARSET ,
OUT_DEFAULT_PRECIS , CLIP_DEFAULT_PRECIS , DEFAULT_QUALITY , VARIABLE_PITCH , _TEXT( "Times New Roman" ) ) ;

// 给实际数据分配内存
pfData = new float [ nPlotData ] ;
if ( pfData )
{
   // 初始化数据为 0
    ZeroMemory ( pfData , sizeof ( pfData ) * nPlotData ) ;

    m_GridPen.CreatePen ( PS_SOLID , nGridLineWidth , m_clrDarkLine ) ;

    GetWindowRect ( & m_rect ) ;
    ScreenToClient ( & m_rect ) ;

    CRgn m_Rgn ;
    m_Rgn.CreateRoundRectRgn ( 0 , 0 , m_Size.cx , m_Size.cy , 10 , 10 ) ;

    SetWindowRgn ( ( HRGN ) m_Rgn , true ) ;

    SetTimer ( GRID_TIMER , GRID_UPDATE_SPEED , NULL ) ;
   }

 CButton::PreSubclassWindow();
}

void CMulticolorPlotBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

   // TODO: 添加您的代码以绘制指定项

   ASSERT( lpDrawItemStruct != NULL ) ;

   CDC * pDC = CDC::FromHandle( lpDrawItemStruct -> hDC ) ;

   // 创建内存 DC
   CMemDC * pMemDC = new CMemDC ( pDC ) ;

   // 得到控件大小
  RECT clipRect ;
  pMemDC->GetClipBox ( & clipRect ) ;

if ( bfInit == false )
{
   // 如果没有初始化,则初始化画刷
   CBitmap m_Bmp ;

   // 如果控件大小有效
   if ( clipRect.right - clipRect.left > 1 )
    {
      // 根据数据点分辨率创建内存位图
      m_Bmp.CreateCompatibleBitmap( pMemDC ,nPlotGranulatrity , m_Size.cy ) ;

     CBitmap * pOldBmp = pMemDC->SelectObject( & m_Bmp ) ;

     CSize m_BmpSize = m_Bmp.GetBitmapDimension () ;

    // 根据不同的曲线分别绘制
     
if ( nPlotType == BAR )
       {
          double factor = 255.0 / ( float ) m_Size.cy ;

           BYTE r , g , b ;

          for ( int x = 0 ; x < m_Size.cy ; x ++ )
           {
             g = ( BYTE ) ( 255 - factor * x ) ;
             r = ( BYTE ) ( factor * x ) ;
             b = ( BYTE ) 64 ;

             pMemDC->SetPixelV ( 0 , x , RGB ( r , g , b ) ) ;
             pMemDC->SetPixelV ( 1 , x , RGB ( r , g , b ) ) ;
           }
        }
    else if ( nPlotType == LINE )
       {
         }
     else
     {
     }

   pMemDC->SelectObject ( pOldBmp ) ;

   // 生成位图画刷
   m_clrBrush.CreatePatternBrush ( & m_Bmp ) ;


   bfInit = true ;
  }
}

if ( bfInit )
{
   // 填充背景色
   pMemDC->FillSolidRect ( & clipRect , m_clrDarkBack ) ;

   CFont * pOldFont ;

  //
   CPoint orgBrushOrigin = pMemDC->GetBrushOrg () ;

  // 画网格
    int nGridLinesX = m_Size.cx / nGridResolutionX ;
    int nGridLinesY = m_Size.cy / nGridResolutionY ;

   // 选择画笔
     CPen * pOldPen = pMemDC->SelectObject ( & m_GridPen ) ;

   // 创建垂直线
for ( int x = 0 ; x <= nGridLinesX ; x ++ )
{
   pMemDC->MoveTo ( x * nGridResolutionX + nGridStarPosX , 0 );
   pMemDC->LineTo ( x * nGridResolutionX + nGridStarPosX , m_Size.cy );
}
// 添加水平线
for ( int y = 0 ; y <= nGridLinesY ; y ++ )
{
   pMemDC->MoveTo ( 0 , nGridStarPosY + m_Size.cy - y * nGridResolutionY - 2 ) ;
   pMemDC->LineTo ( m_Size.cx , nGridStarPosY + m_Size.cy - y * nGridResolutionY - 2 ) ;
}
// 控制网格正确移动
   nGridStarPosX += nGridScrollSpeedX ;
   nGridStarPosY += nGridScrollSpeedY ;

   if ( nGridStarPosX < 0 ) nGridStarPosX = nGridResolutionX ;
   if ( nGridStarPosX > nGridResolutionX ) nGridStarPosX = 0 ;
   if ( nGridStarPosY < 0 ) nGridStarPosY = nGridResolutionY ;
   if ( nGridStarPosY > nGridResolutionY ) nGridStarPosY = 0 ;

// 还原网格画笔

pMemDC->SelectObject ( pOldPen ) ;

// 用关键代码同步和SetData
EnterCriticalSection ( & g_cs ) ;

// 画数据

float fx , fy ;
if ( nPlotType == BAR )
{
   RECT rFill ;

   for ( int nData = 0 ; nData < nPlotData ; nData ++ )
    {
       fx = ( float ) ( m_rect.left + nData * nPlotGranulatrity ) ;
       fy = fabs ( ( float ) ( m_rect.bottom - ( ( ( ( pfData[nData] - fLow ) / ( fHigh - fLow )  ) * m_Size.cy ) ) ) ) ;

       rFill.bottom = ( LONG ) m_rect.bottom ;
       rFill.top = ( LONG ) fy ;
       rFill.left = ( LONG ) fx ;
       rFill.right = ( LONG ) ( fx + nPlotGranulatrity ) ;

       pMemDC->SetBrushOrg ( ( int ) fx , m_rect.bottom ) ;

       // 用初始化画刷时生成的渐变位图画刷填充矩形
       pMemDC->FillRect ( & rFill , & m_clrBrush ) ;
       // 画数据点处的颜色
       pMemDC->SetPixelV ( ( int ) fx , ( int ) fy , m_clrCyanData ) ;

     }
 }
else if ( nPlotType == LINE )
     {
       CPoint * g_DataPoint = new CPoint [nPlotData] ;

       // 创建曲线画笔
       CPen m_Pen ;
       m_Pen.CreatePen ( PS_SOLID , nLineWidth , m_clrLinePen ) ;
       CPen * m_pOldPen = pMemDC->SelectObject ( & m_Pen ) ;

      for ( int nData = 0 ; nData < nPlotData ; nData ++ )
      {
        g_DataPoint[nData].x = ( LONG ) ( m_rect.left + nData * nPlotGranulatrity ) ;
        g_DataPoint[nData].y = ( LONG ) fabs ( ( float ) ( m_rect.bottom - ( ( ( ( pfData[nData] - fLow ) / ( fHigh - fLow ) ) * m_Size.cy ) ) ) ) ;
}

    pMemDC->Polyline ( g_DataPoint , nPlotData ) ;

    pMemDC->SelectObject ( m_pOldPen ) ;

    delete [] g_DataPoint ;


    }
  else
 {
 }


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP