欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>杂项>>文章内容
以曲线或柱状图实时显示数据的控件
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
 

这是一款可以以曲线或柱状图的形式实时动态显示数据的控件。
  主要特点是:支持显示浮点数、负数,显示数据范围大、可以自定义显示范围也可自动选择范围,还可锁定显示范围。
  主要技术来源于网上,我只是对其分离改进了一下。有需要的朋友可以看看或联系我
  Email: wlzqin@{域名已经过期}
           wlzqin@{域名已经过期}
   QQ   :8573980
   MSN :wlzqi@{域名已经过期}

源码下载

使用方法:

1.首先放一个CButton,并对这个按钮生成一个对象。例如 CButton m_btn ;

2.更改按钮的类名 改为 CMulticolorPlotBtn  m_btn

3.初始化: 初始化由自己绝对初始化那些(当然也可省略这步)

4。显示数据。m_btn.SetData( ( float ) rand () ) ;

////////////////////////////////////  MulticolorPlotBtn.h ////////////////////////////////////

/*
模块名称:MulticolorPlotBtn.h
版    本:0.1 Alpha
版    权:Copyright (C) 2005 wlzqin
模块功能:动态图表显示数据
作    者:wlzqi
作者邮箱:mailto:wlzqin@{域名已经过期}
建立时间:22005年6月14日  乙酉 鸡年五月初八
最后修改:by wlzqi
修改历程:
注意事项:
备  注:支持 UNICODE 和 ANSI 编码
  :测试平台 Windows 2000、IE6、Direcx9、 AMD Xp 2000 + CPU
  :不兼容 Windows 98
功能简介:动态实时显示数据,显示方式有BAR和LINE(其它方式以后添加)
    ,可动态实时改变曲线属性。支持任意范围数据,可设定范围,
    也可不设定显示范围(自动寻找最符合的范围),还可任意锁定
    (自由)范围。支持浮点数。
*/

#pragma once
#include "afxwin.h"
#include <math.h>

#define BAR    0
#define LINE   1

class CMulticolorPlotBtn :
 public CButton
{
public:
 CMulticolorPlotBtn(void) ;
 virtual ~CMulticolorPlotBtn(void);

private:    // 公共属性
 int nPlotType ;  // 曲线类型  BAR 或 LINE    // BAR
 bool bfInit ;  // 是否初始化       // false
 // 网格X方向上的间距
 int nGridResolutionX ;          // 10
 // 网格Y方向上的间距
 int nGridResolutionY ;          // 10
 // 网格滚动的速度和方向(正值为从左向右滚动和从上到下,否则反之。0不动)
 int nGridScrollSpeedX ;          // -1
 int nGridScrollSpeedY ;          // 0
 // 数据点分辨率大小(即:一个数据点占据的像素数)
 int nPlotGranulatrity ;          // 2
 // 网格线宽度
 int nGridLineWidth ;          // 1
 // 背景色
 COLORREF m_clrDarkBack ;         // RGB(0,0,75)
 // 前景色
 COLORREF m_clrDarkLine ;         // RGB(32,64,32)
 // 控件矩形
 RECT m_rect ;
 // 控件的尺寸
 CSize m_Size ;
 // 控件可容纳可见的数据点数
 int nPlotData ;            // 0
 // 实际数据
 float * pfData ;           // 0
 // 数据范围
 float fLow , fHigh ;          // 0,0
 // 数据比例
 float fScaleY ;            // 1.0
 // 数据点处的颜色
 COLORREF m_clrCyanData ;         // RGB ( 0,255,255 )
 // 画笔
 CPen m_GridPen ;
 // 数据点位图画刷
 CBrush m_clrBrush ;
 // 网格开始位置
 int nGridStarPosX , nGridStarPosY ;       // 0,0
 // 锁定显示范围
 bool bLock ;            // true---锁定
 // 控件上显示的字体
 CFont m_SmallFont ;
 // Y轴刻度的颜色
 COLORREF m_clrAxisScaleY ;         // RGB ( 0,255,255 )
 // 是否显示Y轴刻度数字
 int nShowFormatDataText ;         // 0---不显示
 // 控件标题
 TCHAR szTitls [MAX_PATH * sizeof ( TCHAR ) + 1] ;   // NULL
 // 曲线单位
 TCHAR szUints [32 * sizeof ( TCHAR ) + 1] ;     // NULL
private:
 // 关键代码
 CRITICAL_SECTION  g_cs ;
public:    // 公共方法
 // 设置画线的类型
 void SetPlotType ( int nType )
 {
  nPlotType = nType ;

  bfInit = false ;
 }
 // 设置网格间距
 void SetGridResolutionX ( int nGridReluX ) { nGridResolutionX = nGridReluX ; }
 void SetGridResolutionY ( int nGridReluY ) { nGridResolutionY = nGridReluY ; }
 // 设置网格滚动速度
 // 正值为从左向右滚动,0不动
 void SetGridScrollSpeedX ( int nSpeedX ) { nGridScrollSpeedX = nSpeedX ; }
 // 正值为从上到下滚动,0不动
 void SetGridScrollSpeedY ( int nSpeedY ) { nGridScrollSpeedY = nSpeedY ; }
 // 数据点面积大小(即:一个数据点占据的像素数)
 bool SetPlotGranulatrity ( int nPlotGrltiy )
 {
  nPlotGranulatrity = nPlotGrltiy ;
  nPlotData = m_Size.cx / nPlotGranulatrity ;
  pfData = new float [ nPlotData ] ;
  if ( pfData )
  {
   // 初始化数据为 0
   ZeroMemory ( pfData , sizeof ( pfData ) * nPlotData ) ;

   return true ;
  }

  return true ;
 }
 // 网格线宽度
 void SetGridLineWidth ( int nWidth ) { nGridLineWidth = nWidth ; }
 // 背景色
 void SetGridBackClr ( COLORREF clr ) { m_clrDarkBack = clr ; }
 // 前景色
 void SetGridLineClr ( COLORREF clr )
 {
  m_clrDarkLine = clr  ;
  m_GridPen.CreatePen ( PS_SOLID , nGridLineWidth , m_clrDarkLine ) ;

  m_clrDarkLine = clr ;
 }
 // 数据范围
 void SetRang ( float fL , float fH )
 {
  fLow = fL ;
  fHigh = fH ;
 }
 // 创建画笔
 void SetLinePen ( int nWidth , COLORREF clr )
 {
  nGridLineWidth = nWidth ;
  m_clrDarkLine = clr  ;
  m_GridPen.CreatePen ( PS_SOLID , nGridLineWidth , m_clrDarkLine ) ;
 }
 // 锁定数据显示范围
 void LockRang ( bool bfLock = true ) ;
 void LockRang ( float fMin = 0.0 , float fMax = 100.0 ) ;
 // Y轴刻度颜色,bfShow==0显示刻度数字,1仅在左上角显示1000(k/sec)/2000样子的数字,2显示最大最小,3显示全部
 void SetAxisScaleClrY ( COLORREF clr = RGB ( 0 , 255 , 255 ) )
 {

  m_clrAxisScaleY = clr ;
 }
 // 标题
 void SetTitle ( PCTSTR pctTitle = NULL )
 {
  _stprintf ( szTitls , _TEXT ( "%s" ) , pctTitle ) ;
 }
 // 数据单位例:SetUnit( _TEXT ( "(k/sec)" ) ) ;
 void SetUnit ( PCTSTR pctUint = NULL )
 {
  _stprintf ( szUints , _TEXT ( "%s" ) , pctUint ) ;
 }
 // 是否显示数据标题、颜色、单位
 /*
 nShow = 0 ; 不显示任何文本
 nShow = 1 ; 仅仅显示标题
 nShow = 2 ; 仅仅显示标题和流量总计
 nShow = 3 ; 显示标题和最小值
 nShow = 4 ; 显示标题、最小值和中值
 */
 void ShowTitle ( int nShow = 1 )
 {
  nShowFormatDataText = nShow ;
 }
private:    // BAR属性
 // BAR颜色
 COLORREF m_clrUp ;
 COLORREF m_clrDown ;
public:     // BAR方法
 // BAR 颜色
 // clrUp  -------- 顶部颜色
 // clrDown  -------- 底部颜色
 // bfRfastness  -------- 红色分量是否固定不变  false ---- 渐变
 // bfGfastness  -------- 红色分量是否固定不变  false ---- 渐变
 // bfBfastness  -------- 红色分量是否固定不变  false ---- 渐变
 void SetBarColor ( COLORREF clrUp , COLORREF clrDown , bool bfRfastness = false , bool bfGfastness = false , bool bfBfastness = false ) ;
 // 设置数据
 void SetData ( float fData ) ;
private:    // LINE属性
 // 曲线颜色
 COLORREF m_clrLinePen ;     // RGB(0,255,0)
 // 曲线宽度
 int nLineWidth ;
public:     // LINE方法
 // 曲线颜色
 void SetLineColorWidth ( COLORREF clrLine = RGB ( 0 , 255 , 0 ) , int nWidth = 1 )
 {
  nLineWidth  = nWidth ;
  m_clrLinePen = clrLine ;
 }
 void SetLineColor ( COLORREF clrLine = RGB ( 0 , 255 , 0 ) ) { m_clrLinePen = clrLine ; }
 void SetLineWidth ( int nWidth = 1 ) { nLineWidth = nWidth ; }
 const COLORREF GetLineColor () { return m_clrLinePen ; }
 const int GetLineWidth () { return nLineWidth ; }
public:
 DECLARE_MESSAGE_MAP()
 afx_msg void OnTimer(UINT nIDEvent);
protected:
 virtual void PreSubclassWindow();
public:
 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};

////////////////////////////////////  end ////////////////////////////////////

////////////////////////////////////  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
  {
  }


  // 绘制Y轴刻度
  TCHAR szAxisScaleYMax [MAX_PATH * sizeof ( TCHAR ) + 1] ;
  TCHAR szAxisScaleYMin [MAX_PATH * sizeof ( TCHAR ) + 1] ;
  TCHAR szAxisScaleY   [MAX_PATH * sizeof ( TCHAR ) + 1] ;

  ZeroMemory ( & szAxisScaleYMax  , sizeof ( szAxisScaleYMax ) ) ;
  ZeroMemory ( & szAxisScaleYMin  , sizeof ( szAxisScaleYMin ) ) ;
  ZeroMemory ( & szAxisScaleY   , sizeof ( szAxisScaleY  ) ) ;

  COLORREF clrText = pMemDC->GetTextColor () ;
  int nBkMode = pMemDC->GetBkMode () ;
  pMemDC->SetTextColor ( m_clrAxisScaleY ) ;
  pMemDC->SetBkMode ( TRANSPARENT ) ;

  pOldFont = pMemDC->SelectObject ( & m_SmallFont ) ;

  // 如果要求现实Y轴刻度数字
  switch ( nShowFormatDataText )
  {
  case 0 :    // 不显示
   {
   } break ;
  case 1 :    // 仅显示标题
   {
    _stprintf ( szAxisScaleYMax , _TEXT ( "%s" ) , szTitls ) ;

    pMemDC->TextOut ( 0 ,     0 , szAxisScaleYMax ) ;
   } break ;
  case 2 :    // 显示标题和流量比例
   {
    _stprintf ( szAxisScaleYMax , _TEXT ( "%s %8.1f %s / %8.1f" ) , szTitls , pfData [ nPlotData - 1 ] , szUints , fHigh ) ;

    pMemDC->TextOut ( 0 ,     0 , szAxisScaleYMax ) ;
   } break ;
  case 3 :    // 显示最大最小值
   {
    // 格式化最大值和标题及单位
    _stprintf ( szAxisScaleYMax , _TEXT ( "%s %8.1f %s / %8.1f" ) , szTitls , pfData [ nPlotData - 1 ] , szUints , fHigh ) ;
    // 格式化最小值
    _stprintf ( szAxisScaleYMin , _TEXT ( "%8.1f" ) , fLow ) ;

    pMemDC->TextOut ( 0 ,     0 , szAxisScaleYMax ) ;
    pMemDC->TextOut ( 0 , m_Size.cy - 10 , szAxisScaleYMin ) ;
   } break ;
  case 4 :    // 显示全部
   {
    // 格式化最大值和标题及单位
    _stprintf ( szAxisScaleYMax , _TEXT ( "%s %8.1f %s / %8.1f" ) , szTitls , pfData [ nPlotData - 1 ] , szUints , fHigh ) ;
    // 格式化最小值
    _stprintf ( szAxisScaleYMin , _TEXT ( "%8.1f" ) , fLow ) ;
    // 格式化中值
    _stprintf ( szAxisScaleY , _TEXT ( "%8.1f" ) , ( ( fHigh - fLow ) / 2.0 + fLow ) ) ;
    

    // 绘制Y轴刻度
    pMemDC->TextOut ( 0 ,     0 , szAxisScaleYMax ) ;
    pMemDC->TextOut ( 0 , m_Size.cy - 10 , szAxisScaleYMin ) ;
    pMemDC->TextOut ( 0 , m_Size.cy /  2 , szAxisScaleY  ) ;
   } break ;
 
  }

  pMemDC->SetTextColor ( clrText ) ;
  pMemDC->SetBkMode ( nBkMode ) ;
  pMemDC->SelectObject ( pOldFont ) ;

  // 离开关键代码
  LeaveCriticalSection ( & g_cs ) ;

  pMemDC->SetBrushOrg ( orgBrushOrigin.x , orgBrushOrigin.y ) ;
 }

 delete pMemDC ;

 ReleaseDC ( pDC ) ;
}


void CMulticolorPlotBtn::OnTimer(UINT nIDEvent)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 switch ( nIDEvent )
 {
 case GRID_TIMER :
  {
  } break ;
 }

 Invalidate ( false ) ;

 CButton::OnTimer(nIDEvent);
}

// BAR 颜色

void CMulticolorPlotBtn::SetBarColor ( COLORREF clrUp , COLORREF clrDown , bool bfRfastness ,
           bool bfGfastness , bool bfBfastness )
{
}

// 设置数据
void CMulticolorPlotBtn::SetData ( float fData )
{
 // 用关键代码同步
 EnterCriticalSection ( & g_cs ) ;

 for ( int n = 0 ; n < nPlotData - 1 ; n ++ )
 {
  pfData [ n ] = pfData [ n + 1 ] ;
 }

 pfData [ nPlotData - 1 ] = fData ;

 if ( bLock )       // 锁定比例范围
 {
 }
 else
 {
  // 保存最小值
  if ( fLow > fData )
  {
   fLow = fData ;
  }
  // 保存最大值
  if ( fHigh < fData )
  {
   fHigh = fData ;
  }
 }

 // 离开关键代码
 LeaveCriticalSection ( & g_cs ) ;
}

// 锁定数据显示范围
void CMulticolorPlotBtn::LockRang ( bool bfLock )
{
 bLock = bfLock ;
}

void CMulticolorPlotBtn::LockRang ( float fMin , float fMax )
{
 fLow = fMin ;
 fHigh = fMax ;

 LockRang ( true ) ;
}

////////////////////////////////////  end ////////////////////////////////////

/////////////////////////////  MemDC.h  ///////////////////////////////////////////////////

#if !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

//////////////////////////////////////////////////
// CMemDC 实现一个内存DC

class CMemDC : public CDC
{
private:
    CBitmap  m_bitmap;      // 实际的bitmap
    CBitmap* m_pOldBitmap;  // 原先在CMemDC中的位图
    CDC*     m_pDC;         // 保存从构造函数中传来的CDC
    CRect    m_rect;        // 画的矩形区域
    BOOL     m_bMemDC;      // 如果CDC是一个内存DC,则为TRUE

public:

    CMemDC(CDC* pDC) : CDC()
    {
        ASSERT(pDC != NULL);

        m_pDC = pDC;
        m_pOldBitmap = NULL;
        m_bMemDC = !pDC->IsPrinting();//判断是否是一个内存DC
             
        if (m_bMemDC)    // 创建一个内存DC
        {
            pDC->GetClipBox(&m_rect);
            CreateCompatibleDC(pDC);
            m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
            m_pOldBitmap = SelectObject(&m_bitmap);
            SetWindowOrg(m_rect.left, m_rect.top);
        }
        else  // 这不是一个内存DC,我们只拷贝相关的DC部分以备打印
        {
            m_bPrinting = pDC->m_bPrinting;
            m_hDC       = pDC->m_hDC;
            m_hAttribDC = pDC->m_hAttribDC;
        }
    }
  
    ~CMemDC()
    {
        if (m_bMemDC)
        {   
            // 拷贝实际的位图到屏幕上
            m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
                          this, m_rect.left, m_rect.top, SRCCOPY);
            //装入原始的位图
            SelectObject(m_pOldBitmap);
        }
  else
  {
            m_hDC = m_hAttribDC = NULL;
        }
    }

    // 允许作为指针
    CMemDC* operator->() {return this;}
    operator CMemDC*() {return this;}

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)

////////////////////////////////////  end ////////////////////////////////////


附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步