zoukankan      html  css  js  c++  java
  • MFC--根据串口采集的数据借助GDI绘制曲线

    根据采集到的数据绘制曲线

    在串口编程中会涉及到这样一个问题,就是将采集到的数据以曲线的形式展示出来,大家自然而然会想到采用方便快捷的控件进行编程。编程周期短,完成任务快,但是真实情况来看,控件会实现很多你用不到的功能,实现机制也不可见,这样在功能上会造成浪费,对性能和实现的效果上会有一些不可控,所以在这一类编程中建议自己通过设备上下文自己编写适合自己软件的曲线图。

    我要实现的功能如下图:

     

    这是一个在网上下载的例程运行的效果,我中间采用的编程思想大多来源这里,只是针我要实现的功能进行了修改。因为我的程序现在还没进行设备测试,所以这里借用一下这个效果图。

    将画图实现的功能封装在一个类里面,在需要画图的时候,便可以实例化一个对象。

    下面是详细的实现过程,为防止屏幕闪烁,采用了双缓冲技术。

    实现的过程中主要的两问题是:1、为了绘制速度快,不会因为数据的增加而出现绘制越来越慢,最后卡死的现象,这里采用例程中用的方法,将已经画过的图像保存BitMap 中,来了数据直接在map上绘制,然后再复制在屏幕上。2、我的功能中会根据用户操作改变曲线显示的区域大小,这个时候就需要全部重绘,原来map里的曲线就不能再用了,因为大小已经改变了,这时候在OnPaint函数里面实现的功能就是重新绘制坐标轴框图和根据保存的数据进行曲线的绘制。

    该类的头文件函数:

      1 #pragma once
      2 
      3 
      4 
      5 //用于绘制二维曲线
      6 class CDrawView : public CWnd
      7 {
      8     DECLARE_DYNCREATE(CDrawView)
      9 
     10 public:
     11     CDrawView();        
     12     virtual ~CDrawView();
     13     DECLARE_MESSAGE_MAP()
     14 
     15 public:
     16 #ifdef _DEBUG
     17     virtual void AssertValid() const;
     18 #ifndef _WIN32_WCE
     19     virtual void Dump(CDumpContext& dc) const;
     20 #endif
     21 #endif
     22 
     23 public:
     24 
     25 
     26 
     27     CPoint m_dCurrentPosition;     //current position
     28     CPoint m_dPreviousPosition;     //previous position
     29     double m_updateRate;//数据更新率
     30     void setUpdateRate(double updateRate);
     31 
     32     CList<CPoint,CPoint&> dataList;//用于存储真实数据
     33     CList<CPoint,CPoint&> dataList1;//用于绘图
     34     CList<CPoint,CPoint&> tempDataList;//暂存数据
     35     void InvalidateCtrl();
     36     void SetYRange(double dYLower, double dYUpper, int nYDecimalPlaces);
     37     void SetXRange(int dXLower,int dXUpper,int nXDecimalPlaces);
     38     void SetXUnits(CString string);
     39     void SetYUnits(CString string);
     40     void SetGridColor(COLORREF color);
     41     void SetPlotColor(COLORREF color);
     42     void SetBackgroundColor(COLORREF color);
     43     void SetTitle(CString title);
     44     void AppendPoint(CPoint *newDataList);
     45     void Reset();
     46     void DrawPoint();
     47 
     48     //各个部分的颜色
     49     COLORREF m_crBackColor;     //backGround color
     50     COLORREF m_crGridColor;     //Grid color
     51     COLORREF m_crPlotColor;     //data plot color
     52 
     53     //设备上下文以及与其相关的位图
     54 
     55     CDC m_dcGrid;
     56     CDC m_dcPlot;
     57     CBitmap *m_pBitmapOldGrid;
     58     CBitmap *m_pBitmapOldPlot;
     59     CBitmap m_pBitmapGrid;
     60     CBitmap m_pBitmapPlot;
     61 
     62 
     63     //画图区域相关
     64     int m_nHalfShiftPixels;
     65     int m_nPlotShiftPixels;
     66     int m_nClientHeight;
     67     int m_nClientWidth;
     68     int m_nPlotHeight;
     69     int m_nPlotWidth;
     70 
     71     //坐标轴Y
     72     double m_dYLowerLimit;
     73     double m_dYUpperLimit;
     74     double m_dYRange;
     75     double m_dVerticalFactor;
     76 
     77     //坐标轴X
     78     int m_dXLowerLimit;
     79     int m_dXUpperLimit;
     80     double m_dXRange;
     81     double m_dHorizontalFactor;
     82 
     83     //title
     84     CString m_sTitile;
     85 
     86     CRect m_rectClient;
     87     CRect m_rectPlot;
     88     CPen  m_penPlot;
     89     CBrush m_brushBack;
     90 
     91     int m_nShiftPixels;          //amount  to  shift with each new point 
     92     int m_nYDecimal;
     93     int m_nXDecimal;
     94 
     95     CString m_strXUnitsString;
     96     CString m_strYUnitsString;
     97 
     98 
     99 
    100 
    101     CString str;
    102     CList<int,int>listOfFogX;
    103 
    104     afx_msg void OnPaint();
    105     BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID=NULL);
    106     afx_msg void OnSize(UINT nType, int cx, int cy);
    107 };
    View Code

     

    该类的实现文件内容:

      1 // DrawView.cpp : 实现文件
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "IMU4.h"
      6 #include "DrawView.h"
      7 #include "math.h"
      8 
      9 
     10 // CDrawView
     11 
     12 IMPLEMENT_DYNCREATE(CDrawView, CWnd)
     13 
     14 CDrawView::CDrawView()
     15 {
     16     m_nYDecimal = 3 ;
     17 
     18     m_dPreviousPosition.x = 0;
     19     m_dPreviousPosition.y = 0;
     20 
     21     m_dCurrentPosition.x = 0;
     22     m_dCurrentPosition.y = 0;
     23 
     24     m_dYLowerLimit = -10.0 ;
     25     m_dYUpperLimit =  10.0 ;
     26     m_dYRange =  m_dYUpperLimit - m_dYLowerLimit ;   
     27 
     28     m_dXLowerLimit = 0;
     29     m_dXUpperLimit = 1000;
     30     m_dXRange = m_dXUpperLimit - m_dXLowerLimit;
     31 
     32     m_dVerticalFactor = (double)m_nPlotHeight / m_dYRange ; 
     33     m_dHorizontalFactor = (double)m_nClientWidth / m_dXRange / 100.0;
     34 
     35     m_nShiftPixels     = 4 ;
     36     m_nHalfShiftPixels = m_nShiftPixels/2 ;                     
     37     m_nPlotShiftPixels = m_nShiftPixels + m_nHalfShiftPixels ;  
     38 
     39     m_crBackColor  = RGB(  0,   0,   0) ;  
     40     m_crGridColor  = RGB(  0, 255, 255) ;  
     41     m_crPlotColor  = RGB(255, 255, 255) ;  
     42 
     43     m_penPlot.CreatePen(PS_SOLID, 0, m_crPlotColor) ;
     44     m_brushBack.CreateSolidBrush(m_crBackColor) ;
     45 
     46     m_strXUnitsString.Format(_T("")) ;  
     47     m_strYUnitsString.Format(_T("")) ;  
     48 
     49     m_pBitmapOldGrid = NULL ;
     50 }
     51 
     52 CDrawView::~CDrawView()
     53 {
     54 
     55 }
     56 
     57 
     58 BEGIN_MESSAGE_MAP(CDrawView, CWnd)
     59     ON_WM_MOUSEACTIVATE()
     60     ON_WM_DESTROY()
     61     ON_WM_PAINT()
     62     ON_WM_SIZE()
     63     ON_WM_TIMER()
     64 END_MESSAGE_MAP()
     65 
     66 
     67 
     68 #ifdef _DEBUG
     69 void CDrawView::AssertValid() const
     70 {
     71     CWnd::AssertValid();
     72 }
     73 
     74 #ifndef _WIN32_WCE
     75 void CDrawView::Dump(CDumpContext& dc) const
     76 {
     77     CWnd::Dump(dc);
     78 }
     79 #endif
     80 #endif
     81 void CDrawView::InvalidateCtrl()
     82 {
     83     //用于画坐标轴等信息的函数
     84     int i;
     85     int nCharacters;
     86     int nTopGridPix,nMidGridPix,nBottomGridPix;//分别代表绘图区的三条线(暂定)
     87 
     88     CPen *oldPen;
     89     CPen solidPen(PS_SOLID,0,m_crGridColor);//建立一个画实线的画笔对象
     90     CFont axisFont,yUnitFont,*oldFont;//建立三个字体对象
     91     CString strTemp = _T("0");
     92 
     93     CClientDC dc(this);
     94     if(m_dcGrid.GetSafeHdc() == NULL)
     95     {
     96         m_dcGrid.CreateCompatibleDC(&dc);    
     97         m_pBitmapGrid.CreateCompatibleBitmap(&dc,m_nClientWidth,m_nClientHeight);    
     98         m_pBitmapOldGrid = m_dcGrid.SelectObject(&m_pBitmapGrid);
     99     }
    100     m_dcGrid.SetBkColor(m_crBackColor);
    101     m_dcGrid.FillRect(m_rectClient, &m_brushBack) ;    
    102     nCharacters = max(abs((int)log10(fabs(m_dYUpperLimit))),abs((int)log10(fabs(m_dYLowerLimit))));
    103     nCharacters = nCharacters + 4 + m_nYDecimal;
    104 
    105     m_rectPlot.left = m_rectClient.left + 6 * nCharacters;
    106     m_nPlotWidth = m_rectPlot.Width();
    107 
    108     //draw the plot rectangle
    109     oldPen = m_dcGrid.SelectObject(&solidPen);
    110     m_dcGrid.MoveTo(m_rectPlot.left,m_rectPlot.top);
    111     m_dcGrid.LineTo(m_rectPlot.right + 1,m_rectPlot.top);
    112     m_dcGrid.LineTo(m_rectPlot.right + 1,m_rectPlot.bottom + 1);
    113     m_dcGrid.LineTo(m_rectPlot.left,m_rectPlot.bottom + 1);
    114     m_dcGrid.LineTo(m_rectPlot.left,m_rectPlot.top);
    115 
    116     //draw the dotted lines,
    117     //use setPixel instead of a dotted pen - this allows for a 
    118     //finer  dotted line  and a more "" technical "look
    119     nMidGridPix = (m_rectPlot.top + m_rectPlot.bottom) / 2;
    120     nTopGridPix = nMidGridPix - m_nPlotHeight / 4;
    121     nBottomGridPix = nMidGridPix + m_nPlotHeight / 4;
    122 
    123     for(i = m_rectPlot.left; i < m_rectPlot.right; i+= 4)
    124     {
    125         m_dcGrid.SetPixel(i,nTopGridPix,m_crGridColor);
    126         m_dcGrid.SetPixel(i,nMidGridPix,m_crGridColor);
    127         m_dcGrid.SetPixel(i,nBottomGridPix,m_crGridColor);
    128     }
    129 
    130     //create some fonts (horiaontal  and vertical )
    131     //use a height  of 14 pixels and 300 weight
    132     //(this may need  to be adjusted depending on the display )
    133 
    134     axisFont.CreateFont (14, 0, 0, 0, 300,
    135                        FALSE, FALSE, 0, ANSI_CHARSET,
    136                        OUT_DEFAULT_PRECIS, 
    137                        CLIP_DEFAULT_PRECIS,
    138                        DEFAULT_QUALITY, 
    139                        DEFAULT_PITCH|FF_SWISS, _T("Arial"));
    140     yUnitFont.CreateFont (14, 0, 900, 0, 300,
    141                        FALSE, FALSE, 0, ANSI_CHARSET,
    142                        OUT_DEFAULT_PRECIS, 
    143                        CLIP_DEFAULT_PRECIS,
    144                        DEFAULT_QUALITY, 
    145                        DEFAULT_PITCH|FF_SWISS, _T("Arial")) ;
    146 
    147     //grab the horizontal font
    148     oldFont = m_dcGrid.SelectObject(&axisFont);
    149 
    150     //y max
    151     m_dcGrid.SetTextColor(m_crGridColor);
    152     m_dcGrid.SetTextAlign(TA_RIGHT|TA_TOP);
    153     strTemp.Format (_T("%.*lf"),m_nYDecimal, m_dYUpperLimit) ;//*号会被m_nYDecimals取代,表示保留几位小数
    154     m_dcGrid.TextOutW(m_rectPlot.left - 4,m_rectPlot.top,strTemp);
    155 
    156     m_dcGrid.SetTextAlign (TA_LEFT|TA_TOP) ;
    157     m_dcGrid.TextOut (m_rectPlot.left - 4, m_rectPlot.bottom - (0 - m_dYLowerLimit) * m_dVerticalFactor, _T("0")) ;
    158     //y min 
    159     m_dcGrid.SetTextAlign(TA_RIGHT|TA_BASELINE);
    160     strTemp.Format(_T("%.*lf"),m_nYDecimal,m_dYLowerLimit);
    161     m_dcGrid.TextOutW(m_rectPlot.left - 4,m_rectPlot.bottom,strTemp);
    162 
    163     //x min
    164     m_dcGrid.SetTextAlign (TA_LEFT|TA_TOP) ;
    165     m_dcGrid.TextOut (m_rectPlot.left, m_rectPlot.bottom+4, _T("0")) ;
    166     //横坐标
    167     for(int i = 1;i <= 5;i++)
    168     {
    169         m_dcGrid.SetTextAlign(TA_CENTER|TA_TOP);
    170         strTemp.Format(_T("%d"),m_dXUpperLimit * i / 6);
    171         m_dcGrid.TextOut((m_rectPlot.left + m_nPlotWidth * i / 6),m_rectPlot.bottom + 4, strTemp);
    172     }
    173     // x max
    174      m_dcGrid.SetTextAlign (TA_RIGHT|TA_TOP) ;
    175      strTemp.Format (_T("%d"), m_dXUpperLimit) ; 
    176      m_dcGrid.TextOut (m_rectPlot.right, m_rectPlot.bottom+4, strTemp) ;
    177 
    178      // x units
    179     m_dcGrid.SetTextAlign (TA_CENTER|TA_TOP) ;
    180     m_dcGrid.TextOut (m_rectPlot.right - 70, 
    181                     m_rectPlot.bottom+4, m_strXUnitsString) ;
    182     //title
    183     m_dcGrid.SetTextAlign (TA_CENTER|TA_TOP) ;
    184     m_dcGrid.TextOut ((m_rectPlot.left+m_rectPlot.right)/2, 
    185         m_rectPlot.top-17, m_sTitile) ;
    186 
    187     // restore the font
    188     m_dcGrid.SelectObject(oldFont) ;
    189     // y units
    190     oldFont = m_dcGrid.SelectObject(&yUnitFont) ;
    191     m_dcGrid.SetTextAlign (TA_CENTER|TA_BASELINE) ;
    192     m_dcGrid.TextOut ((m_rectClient.left+m_rectPlot.left)/2, 
    193                     (m_rectPlot.bottom+m_rectPlot.top)/2, m_strYUnitsString) ;
    194     m_dcGrid.SelectObject(oldFont) ;
    195 
    196     //创建画曲线的内存DC和兼容Bitmap
    197     if (m_dcPlot.GetSafeHdc() == NULL)
    198     {
    199         m_dcPlot.CreateCompatibleDC(&dc) ;
    200         m_pBitmapPlot.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ;
    201         m_pBitmapOldPlot = m_dcPlot.SelectObject(&m_pBitmapPlot) ;
    202     }
    203     // make sure the plot bitmap is cleared
    204     m_dcPlot.SetBkColor (m_crBackColor) ;
    205     m_dcPlot.FillRect(m_rectClient, &m_brushBack) ;
    206 }
    207 
    208 //set title
    209 void CDrawView::SetTitle(CString title)
    210 {
    211     m_sTitile = title;
    212     InvalidateCtrl();
    213 }
    214 void CDrawView::SetYRange(double dYLower, double dYUpper, int nYDecimalPlaces)
    215 {
    216   ASSERT(dYUpper > dYLower) ;
    217 
    218   m_dYLowerLimit     = dYLower ;
    219   m_dYUpperLimit     = dYUpper ;
    220   m_nYDecimal      = nYDecimalPlaces ;
    221   m_dYRange          = m_dYUpperLimit - m_dYLowerLimit ;
    222   m_dVerticalFactor = (double)m_nPlotHeight / m_dYRange ; 
    223 
    224   InvalidateCtrl() ;
    225 } // SetYRange
    226 
    227 void CDrawView::SetXRange(int dXLower,int dXUpper,int nXDecimalPlaces)
    228 {
    229     ASSERT(dXUpper > dXLower);
    230 
    231     m_dXLowerLimit = dXLower;
    232     m_dXUpperLimit = dXUpper;
    233     m_nXDecimal = nXDecimalPlaces;
    234     m_dXRange = m_dXUpperLimit - m_dXLowerLimit;
    235     m_dHorizontalFactor = (double)m_nPlotWidth / m_dXRange / 400.0 /** (m_updateRate * 400)*/;
    236 
    237     InvalidateCtrl();
    238 }
    239 
    240 void CDrawView::SetXUnits(CString string)
    241 {
    242     m_strXUnitsString = string ;
    243     InvalidateCtrl() ;
    244 
    245 }  // SetXUnits
    246 
    247 
    248 void CDrawView::SetYUnits(CString string)
    249 {
    250     m_strYUnitsString = string ;
    251     InvalidateCtrl() ;
    252 
    253 }  // SetYUnits
    254 
    255 void CDrawView::SetGridColor(COLORREF color)
    256 {
    257     m_crGridColor = color ;
    258     InvalidateCtrl() ;
    259 
    260 }  // SetGridColor
    261 
    262 void CDrawView::SetPlotColor(COLORREF color)
    263 {
    264     m_crPlotColor = color ;
    265 
    266     m_penPlot.DeleteObject() ;
    267     m_penPlot.CreatePen(PS_SOLID, 0, m_crPlotColor) ;
    268     InvalidateCtrl() ;
    269 
    270 }  // SetPlotColor
    271 
    272 void CDrawView::SetBackgroundColor(COLORREF color)
    273 {
    274     m_crBackColor = color ;
    275 
    276     m_brushBack.DeleteObject() ;
    277     m_brushBack.CreateSolidBrush(m_crBackColor) ;
    278     InvalidateCtrl() ;
    279 
    280 }  // SetBackgroundColor
    281 
    282 void CDrawView::AppendPoint(CPoint *newpPoint)
    283 {
    284     //在plotBitmap上继续画刚接收到的一个数据点,如果一次画本次接收到的所有数据,耗时严重,实时性不强
    285     CPoint dPrevious;
    286     
    287     dPrevious = m_dCurrentPosition;
    288     m_dCurrentPosition = *newpPoint;
    289     //根据新来的数据点更新纵坐标
    290     if(m_dCurrentPosition.y < m_dYLowerLimit)
    291     {
    292         m_dYLowerLimit = m_dCurrentPosition.y;
    293     }
    294     if(m_dCurrentPosition.y > m_dYUpperLimit)
    295     {
    296         m_dYUpperLimit = m_dCurrentPosition.y;
    297     }
    298     //将数据保存在链表里用于重绘以及后面的参数计算
    299     dataList.AddTail(m_dCurrentPosition);
    300     //在plotBitmap上接着画当前数据点
    301     DrawPoint();
    302     //在界面上显示出来
    303     //在这里要注意CClientDC和CPaintDC的区别,一定要避免在OnPaint函数里直接或间接的用CClientDC,这样会使界面一直重绘,造成假死现象
    304     if(IsWindow(this->m_hWnd))
    305     {
    306         CClientDC dc(this) ;  // device context for painting
    307         CDC memDC ;            //定义一个内存设备描述表对象(即后备缓冲区)
    308         CBitmap memBitmap ;    //定义一个位图对象
    309         CBitmap* oldBitmap ; // bitmap originally found in CMemDC
    310 
    311         if(dc.GetSafeHdc() != NULL)
    312         {
    313             memDC.CreateCompatibleDC(&dc) ;//建立与屏幕设备描述表(前端缓冲区)兼容的内存设备描述表句柄(后备缓冲区)
    314             memBitmap.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ;//建立一个与屏幕设备描述表(或者内存设备描述表)兼容的位图
    315             oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap) ;//只有选入了位图的设备描述表才有地方绘图,画到指定的位图上
    316 
    317             if (memDC.GetSafeHdc() != NULL)
    318             {
    319                 // first drop the grid on the memory dc
    320                 memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
    321                          &m_dcGrid, 0, 0, SRCCOPY) ;
    322              // now add the plot on top as a "pattern" via SRCPAINT.
    323              // works well with dark background and a light plot
    324                 memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
    325                            &m_dcPlot, 0, 0, SRCPAINT) ;  //SRCPAINT
    326              // finally send the result to the display
    327                 dc.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
    328                           &memDC, 0, 0, SRCCOPY) ;
    329             }
    330 
    331             memDC.SelectObject(oldBitmap) ;
    332         }
    333     }
    334 }
    335 //将当前数据点绘制到plotBitmap上    
    336 void CDrawView::DrawPoint()
    337 { 
    338     double currX, prevX, currY, prevY ;
    339 
    340     CPen *oldPen ;
    341     CRect rectCleanUp ;
    342 
    343     if (m_dcPlot.GetSafeHdc() != NULL)
    344     {
    345 
    346         oldPen = m_dcPlot.SelectObject(&m_penPlot) ;
    347      // 移到由prevX和prevY指定的前一个位置
    348         prevX = m_rectPlot.left +  m_dPreviousPosition.x * m_dHorizontalFactor;
    349         prevY = m_rectPlot.bottom - 
    350               (long)((m_dPreviousPosition.y - m_dYLowerLimit) * m_dVerticalFactor);
    351         m_dcPlot.MoveTo (prevX, prevY);
    352 
    353      // 画到当前点的位置
    354         currX = m_rectPlot.left + m_dCurrentPosition.x * m_dHorizontalFactor;
    355         currY = m_rectPlot.bottom - 
    356             (long)((m_dCurrentPosition.y - m_dYLowerLimit) * m_dVerticalFactor);
    357         m_dcPlot.LineTo (currX, currY);
    358 
    359     // restore the pen 
    360         m_dcPlot.SelectObject(oldPen) ;
    361     // store the current point for connection to the next point
    362         m_dPreviousPosition.x = m_dCurrentPosition.x ;
    363         m_dPreviousPosition.y = m_dCurrentPosition.y;
    364   }
    365 
    366 } // end DrawPoint
    367 void CDrawView::OnPaint()
    368 {
    369         if(m_dcGrid.GetSafeHdc() != NULL)
    370         {
    371             m_dcGrid.DeleteDC();
    372             m_pBitmapGrid.DeleteObject();
    373         }
    374         if(m_dcPlot.GetSafeHdc() != NULL)
    375         {
    376             m_dcPlot.DeleteDC();
    377             m_pBitmapPlot.DeleteObject();
    378         }
    379             
    380     InvalidateCtrl();
    381 
    382     double pointX,pointY;
    383     CPoint tempPoint;
    384     CPen *oldPen1 ;
    385     //dataList1.RemoveAll();
    386     if(dataList.GetCount() > 1)
    387     {
    388         //绘图区域大小已经改变,需要重绘
    389         if(m_dcPlot.GetSafeHdc() != NULL )
    390         {
    391             oldPen1 = m_dcPlot.SelectObject(&m_penPlot) ;
    392             POSITION pos1 = dataList.GetHeadPosition();
    393             
    394             tempPoint = dataList.GetNext(pos1);
    395             pointX = m_rectPlot.left + tempPoint.x * m_dHorizontalFactor;
    396             pointY = m_rectPlot.bottom - 
    397                 (long)((tempPoint.y - m_dYLowerLimit) * m_dVerticalFactor);
    398             m_dcPlot.MoveTo(pointX,pointY);
    399             CString str;
    400             str.Format(_T("long is %d"),dataList.GetCount());
    401             //TRACE(str);
    402             for(int i = 1; i < dataList.GetCount();i++ )
    403             {
    404                 tempPoint = dataList.GetNext(pos1);
    405                 pointX = m_rectPlot.left + tempPoint.x * m_dHorizontalFactor;
    406                 pointY = m_rectPlot.bottom - 
    407                 (long)((tempPoint.y - m_dYLowerLimit) * m_dVerticalFactor);
    408                 m_dcPlot.LineTo(pointX,pointY);
    409                 m_dcPlot.MoveTo(pointX,pointY);
    410             }
    411             m_dcPlot.SelectObject(oldPen1);
    412         }
    413     }
    414 
    415 
    416     if(m_nClientHeight != 0)
    417     {
    418         CPaintDC dc(this) ;  // device context for painting
    419     
    420         CDC memDC ;            //定义一个内存设备描述表对象(即后备缓冲区)
    421         CBitmap memBitmap ;    //定义一个位图对象
    422         CBitmap* oldBitmap ; // bitmap originally found in CMemDC
    423 
    424         memDC.CreateCompatibleDC(&dc) ;//建立与屏幕设备描述表(前端缓冲区)兼容的内存设备描述表句柄(后备缓冲区)
    425         memBitmap.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ;//建立一个与屏幕设备描述表(或者内存设备描述表)兼容的位图
    426         oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap) ;//只有选入了位图的设备描述表才有地方绘图,画到指定的位图上
    427     
    428         if (memDC.GetSafeHdc() != NULL)
    429         {
    430             
    431              //first drop the grid on the memory dc
    432             memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
    433                  &m_dcGrid, 0, 0, SRCCOPY) ;
    434              // now add the plot on top as a "pattern" via SRCPAINT.
    435          // works well with dark background and a light plot
    436     
    437             memDC.BitBlt(0, 0, m_nPlotWidth, m_nPlotHeight, 
    438                    &m_dcPlot, 0, 0, SRCPAINT) ;  //SRCPAINT
    439           //finally send the result to the display    
    440             dc.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
    441                   &memDC, 0, 0, SRCCOPY) ;
    442             
    443         }
    444 
    445         memDC.SelectObject(oldBitmap) ;
    446         memDC.DeleteDC();
    447         memBitmap.DeleteObject();
    448     }    
    449 }
    450 
    451 
    452 void CDrawView::Reset()
    453 {
    454   InvalidateCtrl() ;
    455 }        
    456 
    457 
    458 BOOL CDrawView::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
    459 {
    460     // TODO: 在此添加专用代码和/或调用基类
    461     BOOL result;
    462     static CString className = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW);//注册窗口类,返回值包含创建的窗口类的信息
    463     result = CWnd::CreateEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, 
    464                           className, NULL, dwStyle, 
    465                           rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
    466                           pParentWnd->GetSafeHwnd(), (HMENU)nID) ;
    467     m_dPreviousPosition.x = 0;
    468     m_dPreviousPosition.y = 0;
    469 
    470     m_dCurrentPosition.x = 0;
    471     m_dCurrentPosition.y = 0;
    472     if (result != 0)
    473         // InvalidateCtrl() ;
    474     
    475     return result ;
    476 }
    477 
    478 
    479 void CDrawView::OnSize(UINT nType, int cx, int cy)
    480 {
    481     CWnd::OnSize(nType, cx, cy);
    482 
    483     GetClientRect(&m_rectClient) ;
    484     // set some member variables to avoid multiple function calls
    485     m_nClientHeight = m_rectClient.Height() ;
    486     m_nClientWidth  = m_rectClient.Width() ;
    487     // the "left" coordinate and "width" will be modified in 
    488     // InvalidateCtrl to be based on the width of the y axis scaling
    489     m_rectPlot.left   = 20 ;  
    490     m_rectPlot.top    = 25;
    491     m_rectPlot.right  = m_rectClient.right-10 ;
    492     m_rectPlot.bottom = m_rectClient.bottom-25 ;
    493 
    494     // set some member variables to avoid multiple function calls
    495     m_nPlotHeight = m_rectPlot.Height() ;
    496     m_nPlotWidth  = m_rectPlot.Width() ;
    497 
    498     // set the scaling factor for now, this can be adjusted 
    499     // in the SetRange functions
    500     m_dVerticalFactor = (double)m_nPlotHeight / m_dYRange ; 
    501     m_dHorizontalFactor = (double)m_nClientWidth / m_dXRange /400.0 /** (m_updateRate * 400)*/;
    502     
    503 }
    504 void CDrawView::setUpdateRate(double updateRate)
    505 {
    506     m_updateRate = updateRate;
    507 }
    View Code
  • 相关阅读:
    多测师讲解jmeter _ 导入本地文本内容参数化方法一__(1)高级讲师肖sir
    深圳_多测师面试 _平安项目总结(2020年10月)_高级讲师肖sir
    多测师讲解jmeter _token提取_高级讲师肖sir
    多测师讲解jmeter _图片详解_(全)高级讲师肖sir
    深圳精英面试总结——华为外包面试,明源云客,有咖面试,招商面试 总结(001)
    多测师讲解接口测试 —jmeter接数据库(004)_高级讲师肖sir
    多测师讲解jmeter _接口请求_(003)高级讲师肖sir
    多测师讲解jmeter _安装和配置环境(00)_高级讲师肖sir
    多测师讲解接口 _需求文档(用户增删改查)_高级讲师肖sir
    jemeter参数化读取文件
  • 原文地址:https://www.cnblogs.com/ling123/p/7029094.html
Copyright © 2011-2022 走看看