65.9K
CodeProject 正在变化。 阅读更多。
Home

模拟仪表盘类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.17/5 (8投票s)

2000年1月19日

viewsIcon

115911

downloadIcon

5090

一个将数值显示为模拟仪表盘的控件

  • 下载演示项目 - 40 Kb
  • 下载源代码文件 - 6 Kb
  • Sample Image - analog_meter.gif

    最近,我参与了一个仪器项目,其中使用一个单独的显示(CView)来呈现测量结果以及一些传感器的状态。 希望将所有内容放在一个可以最大化的“窗口”中,并且无需处理重叠的窗口或对话框即可查看所有相关信息。

    作为图形化显示传感器状态的一种方法,开发了一个“模拟仪表”类,该类可用于任何显示上下文中的任何正方形矩形中。 因此,可以在应用程序的 CView 派生类中确定一个正方形区域 (CRect),并且可以在此 CRect 中根据需要显示和更新仪表。

    绘制仪表有些微不足道,但是平滑(且快速)地动画化此类仪表则有所不同。 为此,我回顾了我在 示波器/条形图控件 中使用的“三重缓冲”方法。 在这种方法中,我创建了三个位图:一个用于底层“网格”(饼形楔形,标题和数值限制值),一个用于“指针”,另一个用于在 BitBlt'ing 到目标显示上下文之前临时存储指针和网格组合的“结果”

    为了提高动画的速度,这些位图仅在“需要时”更新。 例如,仅当仪表的矩形已更改时才重绘网格位图,并且仅当指针的位置已更改时才重绘指针位图。 此外,位图的组合在基于内存的结果中执行,然后在显示之前执行,以提供更快的性能。

    可以基于以下步骤使用模拟仪表

    • 将仪表添加到您的类中
    • 根据您的特定需求初始化仪表的属性。
    • 在所需的显示上下文中确定一个正方形矩形。
    • 显示仪表。
    • 根据需要更新仪表。

    以下详细概述了这些步骤

    1. 在仪表的拥有者(例如,您的 CView 派生类)中,添加您的仪表。
    2. 建立 CRect 成员变量来跟踪仪表的位置也可能很有用。

      class CAnalogMeterTestView : public CView
      {
      public:
          CRect m_rectLeftMeter ;
          CRect m_rectRightMeter ;
          CAnalogMeter m_meterLeft ;
          CAnalogMeter m_meterRight ;
      } // end CAnalogMeterTestView
      

    3. 初始化仪表属性。
    4. 最好在仪表所有者的构造函数中进行调整。

      CAnalogMeterTestView::CAnalogMeterTestView()
      {
        // setup the Left meter properties
        m_meterLeft.SetRange (-5.0, 5.0) ;
        m_meterLeft.SetRangeDecimals(1) ;
        m_meterLeft.SetValueDecimals(3) ;
        m_meterLeft.SetTitle("Channel A") ;
      
        // setup the Right meter properties
        m_meterRight.SetRange (-10.0, 10.0) ;
        m_meterRight.SetRangeDecimals(1) ;
        m_meterRight.SetValueDecimals(3) ;
        m_meterRight.SetTitle("Channel B") ;
      
      } // end CAnalogMeterTestView constructor
      

    5. 确定仪表的位置(正方形矩形)并显示它。
    6. 最好在仪表所有者的 OnDraw 函数中进行调整。

      void CAnalogMeterTestView::OnDraw(CDC* pDC)
      {
        // determine the meter rectangle(s) - make sure they are square
        // fill in the member variable CRect's accordingly
      
        // show the meters in their respective rectangles
        m_meterLeft.ShowMeter (pDC, m_rectLeftMeter) ;
        m_meterRight.ShowMeter (pDC, m_rectRightMeter) ;
      } // end OnDraw
      

    7. 根据需要更新指针位置。
    8. 我使用的方法是根据计时器定期更新指针位置。

      void CAnalogMeterTestView::OnTimer(UINT nIDEvent) 
      {
        double dLeftValue,          // the new meter values to be shown
               dRightValue ;
        CClientDC dcClient(this) ;  // get a client dc for the updated meter
       
        // determine the new values // update the meters
        m_meterLeft.UpdateNeedle (&dcClient, dLeftValue) ;
        m_meterRight.UpdateNeedle (&dcClient, dRightValue) ; 
      
        // call the base class, as the Class Wizard says I should
        CView::OnTimer(nIDEvent);
      } // end OnTimer 
      

    9. 其他注意事项
    10. 自定义

      如上面的步骤2所示,可以轻松修改仪表范围、标题和数值上的小数位数。但是,应该注意的是,您必须在进行这些更改后调用 ShowMeter 才能“看到”效果。 可以更改这些属性(通过“Set”函数)或检索这些属性(通过“Get”函数)。 公共属性修改/访问函数是

      • SetRange (GetMaxRange,GetMinRange)
      • SetRangeDecimals (GetRangeDecimals)
      • SetValueDecimals (GetValueDecimals)
      • SetTitle (GetTitle)
      • 提示:您必须调用 ShowMeter 才能在调用“Set”函数后看到效果。

      “仪表内部”的自定义

      CAnalogMeter 构造函数包含一些可能提供一些有趣的自定义项的区域,特别是在颜色方面。 尝试修改成员变量:m_colorGridm_colorNeedlem_colorValue

      此外,仪表的“饼图切片”的宽度基于 CAnalogMeter::DrawGrid() 函数中指定的角度。 该角度通过变量 dLimitAngleDeg 设置。

     

    在您向我发送令人讨厌的电子邮件之前,请阅读此内容...(在发送友好的电子邮件之前,您不必阅读此内容)

    该仪表旨在用于 CView 派生类中,并且已使用我的打印机和剪贴板功能进行了测试。 我没有尝试在其他区域(例如对话框中的控件)中使用它。 我确信可以添加这些功能,或者可以将这种方法应用于这些其他区域,但是我现在没有时间这样做。

    © . All rights reserved.