⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spectrumanalyzer.cpp

📁 一个组太软件中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SpectrumAnalyzer.cpp : implementation file
//

// Written by : Mehdi Ebrahimian (mebrahimian[AT]yahoo.com)
// Version: 10/May/2004

#include "stdafx.h"
#include "SpectrumAnalyzer.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSpectrumAnalyzer


CSpectrumAnalyzer::CSpectrumAnalyzer()
{
	
	// for a description on each variable, goto .h of file
	
	m_pMemDC = NULL;
	m_pList=NULL;
	
	m_crBackGround = RGB(0, 0, 0);
	m_crGrids = RGB(0, 130, 66);
	m_crText = RGB(255, 255, 0);
	m_crDrawPen = RGB(0, 255, 0);
	m_crIndicatorPen = RGB(255, 0, 0);

	m_iDrawPenWidth=1;
	m_DrawPen.DeleteObject();
	m_DrawPen.CreatePen(PS_SOLID, m_iDrawPenWidth, m_crDrawPen);

	m_IndicatorPen.DeleteObject();
	m_IndicatorPen.CreatePen(PS_SOLID, m_iDrawPenWidth, m_crIndicatorPen);
	
	// margins for drawing grid and etc in the control
	m_iTopMargin = 14; 
	m_iBotMargin = 20;
	m_iLeftMargin = 24;
	m_iRightMargin = 8;
		
		
	m_iNumVGridLines = 10;
	m_iNumHGridLines = 6;
	m_iHScrollShift = 10;

	// Spacing between grid lines; this is for best resolution (dippest zoom-in)
	m_iHLabelSpacing = 50000;
	m_iVLabelSpacing = 20; // draw labels each 20 points

	m_iHLabelValueScale = 1000000; // show hor. labels at most each 100000 Hz
	m_iHLabelDistance = 3;

	m_iVHighIndicator = 80; // mark higher than it as HIGH region!
		
}

CSpectrumAnalyzer::~CSpectrumAnalyzer()
{
	if(m_pMemDC)
		delete m_pMemDC;

	if(m_pList)
		delete m_pList;
}


/////////////////////////////////////////////////////////////////////////////
// CSpectrumAnalyzer message handlers



BEGIN_MESSAGE_MAP(CSpectrumAnalyzer, CWnd)
	//{{AFX_MSG_MAP(CSpectrumAnalyzer)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_HSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CSpectrumAnalyzer member functions


BOOL CSpectrumAnalyzer::Create(const RECT &rect, CWnd *pParentWnd, UINT uID, CPoint m_RangeX, CPoint YRange)
{
	//Postcondition:
	//	Creates a window within the "rect" region of the client screen
	//	Returns TRUE if the function creates the control successfully
	//	or FALSE if it fails.

	// for a description on each variable, goto .h of file

	BOOL bRet = CWnd::CreateEx(WS_EX_CLIENTEDGE, 
								AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW),
								NULL,
								WS_VISIBLE | WS_CHILD | WS_HSCROLL,
								rect.left,
								rect.top,
								rect.right - rect.left,
								rect.bottom - rect.top,
								pParentWnd->GetSafeHwnd(),
								(HMENU)uID);
	
	if(!bRet)
		return FALSE;

	m_pMemDC = new CDC;
	if(!m_pMemDC)
		return FALSE;

	// Note No. 13830203-4
	m_pList = new CList<CPoint, CPoint&>;
	if(!m_pList)
		return FALSE;
	
	m_ViewTopLeft = CPoint(0,0);
	
	GetClientRect(m_rcClient);

	m_iClientWidth = m_rcClient.right - m_rcClient.left;	
	m_iClientHeight = m_rcClient.bottom - m_rcClient.top;

	if(!InvalidateCtrl())
		return FALSE;

		
	CFont m_TextFont;
	LOGFONT lf;
	ZeroMemory(&lf, sizeof(LOGFONT));
	lstrcpy(lf.lfFaceName, _T("Arial"));
	
	lf.lfHeight=14;
	
	m_TextFont.CreateFontIndirect(&lf);

	CFont *pOldFont=m_pMemDC->SelectObject(&m_TextFont);
	
	m_pMemDC->SetTextColor(m_crText);

	SetRangeX(m_RangeX);
	SetRangeY(YRange);

	SetVHighIndicator(m_iVHighIndicator);

	UpdateLabels();
	
    // Set the horizontal scrolling parameters.
	// Note No. 13830203-3
    m_iHScrollPos = 0;

    SCROLLINFO si;
    si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
    si.nMin = 0;
    si.nMax = m_iMaxHAxis;
    si.nPos = m_iHScrollPos;
    si.nPage = 200;
    SetScrollInfo (SB_HORZ, &si, TRUE);
	
	return TRUE;
}

BOOL CSpectrumAnalyzer::Destroy()
{
	return (CWnd::DestroyWindow());
}

void CSpectrumAnalyzer::SetRangeX(const CPoint RangeX)
{

	//	Sets the upper and lower (limits) range
	m_RangeX = RangeX;
	
	double a, b, fViewableRange;
	a = m_RangeX.y - m_RangeX.x;
	b = m_iClientWidth;
	fViewableRange = m_iNumVGridLines * m_iHLabelSpacing;

	m_iMaxHAxis =  int (a*b/fViewableRange);

	a = m_iMaxHAxis;
	b = m_RangeX.y-m_RangeX.x;

	m_fHAxisScale = a/b;

	a=(m_iClientWidth - m_iRightMargin)-m_iLeftMargin;
	b= m_iClientWidth;
	
	m_fHViewScale = a/b;

}

void CSpectrumAnalyzer::SetRangeY(const CPoint RangeY)
{
	//	Sets the upper and lower (limits) range
	m_RangeY=RangeY;
	
	m_iMaxVAxis = m_iClientHeight;

	double a = m_iMaxVAxis, b = m_RangeY.y - m_RangeY.x;
	m_fVAxisScale = a/b;
			
	a = m_iTopMargin - (m_iClientHeight - m_iBotMargin);
	b = m_iClientHeight;

	m_fVViewScale = a/b;

}
void CSpectrumAnalyzer::DrawText(CPoint Pos, CString szStr)
{
	if(!m_pMemDC->GetSafeHdc())
		return;

	m_pMemDC->TextOut(Pos.x, Pos.y, szStr);
	
	CRect rcInv(m_rcClient.left, m_rcClient.top, m_rcClient.right, m_rcClient.bottom);
	InvalidateRect(rcInv);
}


BOOL CSpectrumAnalyzer::InvalidateCtrl()
{

	//Postcondition:
	//	Paints the entire client area of the control
	//	Returns TRUE if it's done successfuly or FALSE if it fails

	CClientDC dc(this);

	if(m_pMemDC->GetSafeHdc())
		return FALSE;

	if(!m_pMemDC->CreateCompatibleDC(&dc))
		return FALSE;


	m_pMemDC->SetBkColor(m_crBackGround);
		
	CBitmap bmp;
	if(!bmp.CreateCompatibleBitmap(&dc, m_rcClient.Width(), m_rcClient.Height()))
		return FALSE;

	if(!m_pMemDC->SelectObject(bmp))
		return FALSE;

	//Set the background color of the control
	CBrush bkBrush;
	if(!bkBrush.CreateSolidBrush(m_crBackGround))
		return FALSE;
	
	m_pMemDC->FillRect(m_rcClient, &bkBrush);

	//Select a specified pen to the device context to draw background lines
	CPen bkLinesPen;
	if(!bkLinesPen.CreatePen(PS_SOLID, 1, m_crGrids))
		return FALSE;

	if(!m_pMemDC->SelectObject(bkLinesPen))
		return FALSE;

	InvalidateRect(m_rcClient);
	return TRUE;

}

void CSpectrumAnalyzer::OnPaint() 
{
	CPaintDC dc(this);

	if(m_pMemDC->GetSafeHdc())
		dc.BitBlt(0, 0, m_rcClient.Width(), m_rcClient.Height(), m_pMemDC, 0, 0, SRCCOPY);
}


void CSpectrumAnalyzer::DrawLine()
{
	//Postcondition:
	//	Draws the spectrum within the client area of the control
	
	int j;
	if(!m_pMemDC->GetSafeHdc())
		return;

	
	if (m_pList->GetCount()<=1)
		return;  // nothing to draw!

	m_pMemDC->SelectObject(m_DrawPen);
	
	// go to first point to draw from 
	POSITION pos = m_pList->GetHeadPosition();	
	
	CPoint pt1, pt2;
	for (j = 0; j < m_pList->GetCount(); j++)
	{
		switch (GetPairOfPoints(pt1, pt2, pos))
		{
		case 0:
			
			DrawPieceOfLine(pt1, pt2);
			break;
		case 1:
			{
				// pt2 is out of viewable region, but we must draw a line to it to
				// make the curve seem continous 
				// do not draw in Marginal region, so interpolate!
				CPoint ptInter;
				ptInter.x = m_iClientWidth - m_iRightMargin;
				if (pt1.x != pt2.x)
					ptInter.y = ( (ptInter.x - pt1.x) * (pt1.y - pt2.y) / (pt1.x - pt2.x) ) + pt1.y;
				else
					ptInter.y = (pt1.y + pt2.y) /2;
				
				DrawPieceOfLine(pt1, ptInter);
			}
			break;
		case 2:
			{
				// pt1 is out of viewable region, but we must draw a line to it to
				// make the curve seem continous 
				// do not draw in Marginal region, so interpolate!
				CPoint ptInter;
				ptInter.x = m_iLeftMargin;
				if (pt1.x != pt2.x)
					ptInter.y = ( (ptInter.x - pt1.x) * (pt1.y - pt2.y) / (pt1.x - pt2.x) ) + pt1.y;
				else
					ptInter.y = (pt1.y + pt2.y) /2;
			
				DrawPieceOfLine(ptInter, pt2);
			}
			break;
		case 3:
			break;
		case 4: 
			break;
		default:
			break;
		}
	}


	CRect rcInv(m_rcClient.left, m_rcClient.top, m_rcClient.right, m_rcClient.bottom);
	InvalidateRect(rcInv);

}

BYTE CSpectrumAnalyzer::GetPairOfPoints(CPoint &pt1, CPoint &pt2, POSITION &pos)
{
	// gets two points from List: pt1 is at position "next to" pos and pt2 is the next point
	// return value:
	//     0 : both are in viewable region
	//	   1 : first is in viewable region , but the second one is not 
	//	   2 : first is not in viewable reg, but the second one is 
	//     3 : both are not in viewable reg., or both don't exist
	//     4 : the second one does not exist!

	if (pos==NULL) // both do not exist
		return 3;

	BOOL bViewable1=FALSE, bViewable2=FALSE;
	
	pt1 = m_pList->GetNext(pos);
	pt1 = MapPointToAxis( pt1 );
	
	if (MapAxisToView(pt1))
		bViewable1 = TRUE;

	if (pos == NULL) // second point does not exist
		return 4;

	pt2 = m_pList->GetNext(pos);
	pt2 = MapPointToAxis( pt2 );

	if (MapAxisToView(pt2))
		bViewable2 = TRUE;

	CPoint ptDummy;
	if (pos == NULL)
		pos = m_pList->GetTailPosition();
	else
		ptDummy = m_pList->GetPrev(pos); // so that pos points to pt1 for future call of function
	
	BYTE retByte;
	if (bViewable1)
	{
		if (bViewable2)
			retByte = 0;
		else
			retByte = 1;
	}
	else
	{
		if (bViewable2)
			retByte = 2;
		else
			retByte = 3;
	}
	
	return retByte;
}



void CSpectrumAnalyzer::AddPoint(CPoint CurPos)
{

	//ASSERT(NewPos.x <= m_RangeX.y && NewPos.x >= m_RangeY.x && NewPos.y<=m_RangeY.y && NewPos.y>=m_RangeY.x);
	CPoint NewPos=CurPos;

	if ( NewPos.x<m_RangeX.x)
		NewPos.x=m_RangeX.x;
	if (NewPos.x>m_RangeX.y)
		NewPos.x=m_RangeX.y;

	if ( NewPos.y<m_RangeY.x)
		NewPos.y=m_RangeY.x;
	if (NewPos.y>m_RangeY.y)
		NewPos.y=m_RangeY.y;

	m_pList->AddTail(NewPos);
	
	return;		
}

void CSpectrumAnalyzer::Clear()
{
	// Clear the client area
	
	if(!m_pMemDC->GetSafeHdc())
		return;

	//Set the background color of the control
	CBrush bkBrush;
	if(!bkBrush.CreateSolidBrush(m_crBackGround))
		return;
	
	m_pMemDC->FillRect(m_rcClient, &bkBrush);
	
	InvalidateRect(m_rcClient);
}

void CSpectrumAnalyzer::OnLButtonDown( UINT dwFlags, CPoint pos)
{

	// send a message to parent to set the radio to a newer frequency
	// but only if not scanning!

	// user should hold CTRL key for this option to act!
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -