Click here to Skip to main content
15,886,609 members
Articles / Desktop Programming / MFC

Analog Meter Class

Rate me:
Please Sign up or sign in to vote.
4.17/5 (8 votes)
18 Jan 2000 114.6K   5.1K   55  
A control that displays a numerical value as an analog meter
// AnalogMeterTestView.cpp : implementation of the CAnalogMeterTestView class
//

#include "stdafx.h"
#include <math.h>
#include "AnalogMeterTest.h"
#include "InputString.h"

#include "AnalogMeterTestDoc.h"
#include "AnalogMeterTestView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAnalogMeterTestView

IMPLEMENT_DYNCREATE(CAnalogMeterTestView, CView)

BEGIN_MESSAGE_MAP(CAnalogMeterTestView, CView)
	//{{AFX_MSG_MAP(CAnalogMeterTestView)
	ON_COMMAND(ID_TIMER_STARTSTOP, OnTimerStartstop)
	ON_WM_TIMER()
	ON_COMMAND(ID_METER_RANGE, OnMeterRange)
	ON_COMMAND(ID_METER_RANGEDECIMALS, OnMeterRangedecimals)
	ON_COMMAND(ID_METER_TITLE, OnMeterTitle)
	ON_COMMAND(ID_METER_VALUEDECIMALS, OnMeterValuedecimals)
	ON_UPDATE_COMMAND_UI(ID_TIMER_STARTSTOP, OnUpdateTimerStartstop)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAnalogMeterTestView construction/destruction

CAnalogMeterTestView::CAnalogMeterTestView()
{
	// TODO: add construction code here
	m_lastAngleDeg = 0.0 ;
	m_bTimerRunning = FALSE ;

	m_meterLeft.SetRange (-5.0, 5.0) ;
	m_meterLeft.SetRangeDecimals(1) ;
	m_meterLeft.SetValueDecimals(3) ;
	m_meterLeft.SetTitle("Channel A") ;

	m_meterRight.SetRange (-10.0, 10.0) ;
	m_meterRight.SetRangeDecimals(1) ;
	m_meterRight.SetValueDecimals(3) ;
	m_meterRight.SetTitle("Channel B") ;

}

CAnalogMeterTestView::~CAnalogMeterTestView()
{
}

BOOL CAnalogMeterTestView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CAnalogMeterTestView drawing

void CAnalogMeterTestView::OnDraw(CDC* pDC)
{
	CAnalogMeterTestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CRect rectClient ;

	GetClientRect (&rectClient);

	// make two side-by-side rectangles 
	m_rectLeftMeter.left = rectClient.left + rectClient.Width()/10 ;
	m_rectLeftMeter.right = rectClient.left + rectClient.Width()/2 - 5 ;
	m_rectLeftMeter.top = rectClient.top + rectClient.Height()/10 ;
	m_rectLeftMeter.bottom = rectClient.bottom - rectClient.Height()/10 ;
	
	m_rectRightMeter.left = rectClient.left + rectClient.Width()/2 + 5 ;
	m_rectRightMeter.top = m_rectLeftMeter.top ;
	m_rectRightMeter.right = rectClient.right - rectClient.Width()/10 ;
	m_rectRightMeter.bottom = m_rectLeftMeter.bottom ;

	// force them to be square
	if (m_rectLeftMeter.Height() > m_rectLeftMeter.Width())
	{
		m_rectLeftMeter.bottom = m_rectLeftMeter.top + m_rectLeftMeter.Width() ;
		m_rectRightMeter.bottom = m_rectLeftMeter.bottom ;
	}
	else
	{
		m_rectLeftMeter.left = m_rectLeftMeter.right-m_rectLeftMeter.Height() ;
		m_rectRightMeter.right = m_rectRightMeter.left+m_rectLeftMeter.Height() ;
	}

	m_meterLeft.ShowMeter (pDC, m_rectLeftMeter) ;
	m_meterRight.ShowMeter (pDC, m_rectRightMeter) ;

}

/////////////////////////////////////////////////////////////////////////////
// CAnalogMeterTestView printing

BOOL CAnalogMeterTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CAnalogMeterTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CAnalogMeterTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CAnalogMeterTestView diagnostics

#ifdef _DEBUG
void CAnalogMeterTestView::AssertValid() const
{
	CView::AssertValid();
}

void CAnalogMeterTestView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CAnalogMeterTestDoc* CAnalogMeterTestView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAnalogMeterTestDoc)));
	return (CAnalogMeterTestDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CAnalogMeterTestView message handlers

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnTimerStartstop() 
{
	// TODO: Add your command handler code here
	if (m_bTimerRunning)
		KillTimer(1) ;
	else
		SetTimer(1, 10, NULL) ;

	m_bTimerRunning ^= TRUE ;
}

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	double mRad, dValue ;
	CClientDC 	dcClient(this) ;

	m_lastAngleDeg += 5.0 ;

	if (m_lastAngleDeg >= 360.0)
		m_lastAngleDeg = 0.0 ;

	mRad = m_lastAngleDeg*3.14159/180.0 ;
	dValue = 5.0*sin(mRad) ;

	m_meterLeft.UpdateNeedle (&dcClient, dValue) ;
	m_meterRight.UpdateNeedle (&dcClient, dValue) ;

	// provided by ClassWizard
	CView::OnTimer(nIDEvent);
}

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnMeterRange() 
{
	// TODO: Add your command handler code here
	CInputString dlg ;
	CString tempString ;
	double tempUpper, tempLower ;

	tempString.Format("%f", m_meterLeft.GetMaxRange()) ;
	if (dlg.Run ("AnalogMeterTest", "Enter the &upper range limit:", &tempString) == IDOK)
	{
		tempUpper = atof(tempString) ;
		tempString.Format("%f", m_meterLeft.GetMinRange()) ;
		if (dlg.Run ("AnalogMeterTest", "Enter the &lower range limit:", &tempString) == IDOK)
		{
			tempLower = atof(tempString) ;
			if (tempLower == tempUpper)
			{
				if (tempUpper == 0.0)  // if both are zero, make them +/- 10
					tempUpper = 10.0 ;
				if (tempUpper < 0)
					tempUpper = -tempUpper ;
				tempLower = -tempUpper ;
			}
			m_meterLeft.SetRange(tempLower, tempUpper) ;
			
			CClientDC dcClient(this) ;
			m_meterLeft.ShowMeter(&dcClient, m_rectLeftMeter) ;
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnMeterRangedecimals() 
{
	// TODO: Add your command handler code here
	CInputString dlg ;
	CString tempString ;

	tempString.Format("%d", m_meterLeft.GetRangeDecimals()) ;
	if (dlg.Run ("AnalogMeterTest", "Enter the range &decimals:", &tempString) == IDOK)
	{
		m_meterLeft.SetRangeDecimals(atoi(tempString)) ;
			
		CClientDC dcClient(this) ;
		m_meterLeft.ShowMeter(&dcClient, m_rectLeftMeter) ;
	}
		
}

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnMeterTitle() 
{
	// TODO: Add your command handler code here
	CInputString dlg ;
	CString tempString ;

	tempString = m_meterLeft.GetTitle() ;
	if (dlg.Run ("AnalogMeterTest", "Enter the &title:", &tempString) == IDOK)
	{
		m_meterLeft.SetTitle(tempString) ;
			
		CClientDC dcClient(this) ;
		m_meterLeft.ShowMeter(&dcClient, m_rectLeftMeter) ;
	}
	
}

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnMeterValuedecimals() 
{
	// TODO: Add your command handler code here
	CInputString dlg ;
	CString tempString ;

	tempString.Format("%d", m_meterLeft.GetValueDecimals()) ;
	if (dlg.Run ("AnalogMeterTest", "Enter the value &decimals:", &tempString) == IDOK)
	{
		m_meterLeft.SetValueDecimals(atoi(tempString)) ;
			
		CClientDC dcClient(this) ;
		m_meterLeft.ShowMeter(&dcClient, m_rectLeftMeter) ;
	}
	
}

/////////////////////////////////////////////////////////////////////////////
void CAnalogMeterTestView::OnUpdateTimerStartstop(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_bTimerRunning)
		pCmdUI->SetCheck(1) ;
	else
		pCmdUI->SetCheck(0) ;
	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) Digital Metrology Solutions, Inc.
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions