// SpectrumAnalyzer.cpp : implementation file
//
#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_iDrawPenWidth=1;
m_DrawPen.DeleteObject();
m_DrawPen.CreatePen(PS_SOLID, m_iDrawPenWidth, RGB(0, 255, 0));
m_IndicatorPen.DeleteObject();
m_IndicatorPen.CreatePen(PS_SOLID, m_iDrawPenWidth, RGB(255, 0, 0));
// 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);
TRACE(_T("InvalidateCtrl()"));
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;
TRACE(_T(" DrawLine()"));
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
BOOL 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
TRACE(_T(" Clear()"));
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!
if ((dwFlags&MK_CONTROL)!=MK_CONTROL)
return;
CPoint *ptCur;
ptCur = new CPoint; // this pointer is deleted in CScanDialog::OnSetToFreq
*ptCur = MapViewToAxis(pos);
*ptCur = MapAxisToPoint(*ptCur);
SendCallback(1, WPARAM(ptCur), 0);
}
CPoint CSpectrumAnalyzer::MapPointToAxis(const CPoint pos)
{
// A Point comes from frequency changer or something else!
// Point.x is in the range: m_RangeX.x and m_RangeX.y
// Point.y is in the range: m_RangeY.x and m_RangeY.y
// a point should be converted to Axis values, that is in screen/control coordinates
// but all points in the control are not viewable, some are in viewable area and the others are not
// Scrolling or Zooming, changes this viewable area
// function MapPointToAxis, maps a point to Axis values
// function MapAxisToView maps a point in Axis scale to View scale (their scales differ in that, Axis also contains the margins)
// a point after mapping to view scale, may not be viewable, so a Bool variable identifies if it is viewable or not
// if that was viewable, the draw it!
CPoint retPos;
retPos.x = int (m_fHAxisScale * (pos.x - m_RangeX.x));
retPos.y = int (m_fVAxisScale * (pos.y - m_RangeY.x));
return retPos;
}
CPoint CSpectrumAnalyzer::MapAxisToPoint(const CPoint pos)
{
// refer to comments in MapPointToAxis function
CPoint retPos;
retPos.x = int (pos.x / m_fHAxisScale) + m_RangeX.x;
retPos.y = int (pos.y / m_fVAxisScale) + m_RangeY.x;
return retPos;
}
BOOL CSpectrumAnalyzer::MapAxisToView(CPoint &pos)
{
// refer to comments in MapPointToAxis function
// if the point is ready to be drawn, return true.
// this is only true if point is within the range of View
BOOL retBool=FALSE;
if ( (pos.x>=m_ViewTopLeft.x) && (pos.x<=m_ViewTopLeft.x+m_iClientWidth) )
{
if ( (pos.y>=m_ViewTopLeft.y) && (pos.y<=m_ViewTopLeft.y+m_iClientHeight))
retBool = TRUE;
}
pos.x-=m_ViewTopLeft.x;
pos.y-=m_ViewTopLeft.y;
pos.x = int ( m_fHViewScale * pos.x + m_iLeftMargin);
pos.y = int ( m_fVViewScale * pos.y + (m_iClientHeight - m_iBotMargin));
return retBool;
}
CPoint CSpectrumAnalyzer::MapViewToAxis(const CPoint pos)
{
// refer to comments in MapPointToAxis function
// if the point is ready to be drawn, return true.
// this is only true if point is within the range of View
CPoint retPos = pos;
retPos.x = int ( (pos.x - m_iLeftMargin) /m_fHViewScale);
retPos.y = int ( (pos.y - (m_iClientHeight - m_iBotMargin)) / m_fVViewScale);
retPos.x+=m_ViewTopLeft.x;
retPos.y+=m_ViewTopLeft.y;
return retPos;
}
void CSpectrumAnalyzer::HorizScroll(BOOL bIfToLeft /* = FALSE */, int iScrollAmount /* = 0 */)
{
// Scroll Horizontally
// Here, I'm clearing all the contents and re-drawing;
// maybe we can use screen memory copy functions to do it faster!
Clear();
int iActualScroll=0;
int iIncDec= int(m_iClientWidth/2);
if (iScrollAmount>0)
iIncDec = iScrollAmount;
if (bIfToLeft){
if (m_ViewTopLeft.x)
{
if (m_ViewTopLeft.x-iIncDec>=0)
{
m_ViewTopLeft.x-=iIncDec;
iActualScroll = -iIncDec;
}
else
{
iActualScroll=-m_ViewTopLeft.x;
m_ViewTopLeft.x =0;
}
}
}
else{
if (m_ViewTopLeft.x<m_iMaxHAxis)
{
if (m_ViewTopLeft.x + iIncDec<= m_iMaxHAxis)
{
m_ViewTopLeft.x += iIncDec;
iActualScroll=iIncDec;
}
else
{
iActualScroll = m_iMaxHAxis-m_ViewTopLeft.x;
m_ViewTopLeft.x=m_iMaxHAxis;
}
}
}
UpdateLabels();
DrawLine();
m_iHScrollPos +=iActualScroll;
SetScrollPos (SB_HORZ, m_iHScrollPos, TRUE);
}
void CSpectrumAnalyzer::UpdateLabels()
{
// Draw Grids and Labels
if(!m_pMemDC->GetSafeHdc())
return;
//Select a specified pen to the device context to draw background lines
CPen bkLinesPen;
if(!bkLinesPen.CreatePen(PS_SOLID, 1, m_crGrids))
return;
if(!m_pMemDC->SelectObject(bkLinesPen))
return;
CPoint LabelLoc;
CString chLabel;
CPoint ptLocPoint;
int iRightExtent; // horizontal lines should be drawn up to last vertical line, not more!
// Vertical Lines, Horizontal Labels
byte iLabelCounter=0;
for (int iHorValue = m_RangeX.x; iHorValue <= m_RangeX.y; iHorValue+=m_iHLabelSpacing )
{
ptLocPoint = CPoint(iHorValue, m_RangeY.x); // y is dummy now
ptLocPoint = MapPointToAxis(ptLocPoint);
ptLocPoint.y = m_ViewTopLeft.y; // y is dummy, but change it so that MapAxisToView function works properly
if (!MapAxisToView(ptLocPoint))
continue;
LabelLoc = CPoint(ptLocPoint.x, m_iClientHeight - m_iBotMargin + 2);
if (!iLabelCounter++)
{
chLabel.Format(_T("% 4.2f"), double(iHorValue) / double(m_iHLabelValueScale) );
DrawText(LabelLoc, chLabel);
m_pMemDC->MoveTo(ptLocPoint.x, m_rcClient.top + m_iTopMargin);
m_pMemDC->LineTo(ptLocPoint.x, m_rcClient.bottom - m_iBotMargin + 4);
}
else
{
m_pMemDC->MoveTo(ptLocPoint.x, m_rcClient.top + m_iTopMargin);
m_pMemDC->LineTo(ptLocPoint.x, m_rcClient.bottom - m_iBotMargin + 2);
}
iRightExtent = ptLocPoint.x;
if (iLabelCounter==m_iHLabelDistance)
iLabelCounter=0;
}
// determining iRightExtent
ptLocPoint = CPoint(m_RangeX.y, m_RangeY.x); // y is dummy now
ptLocPoint = MapPointToAxis(ptLocPoint);
ptLocPoint.y = m_ViewTopLeft.y; // y is dummy, but change it so that MapAxisToView function works properly
if (!MapAxisToView(ptLocPoint)) // last point is out of view
iRightExtent = m_rcClient.right - m_iRightMargin;
// Horizontal Lines, Vertical Labels
for (int iVertValue = 0; iVertValue <= m_RangeY.y; iVertValue+=m_iVLabelSpacing)
{
ptLocPoint = CPoint(m_RangeX.x, iVertValue); // x is dummy now
ptLocPoint = MapPointToAxis(ptLocPoint);
ptLocPoint.x = m_ViewTopLeft.x; // x is dummy, but change it so that MapAxisToView function works properly
MapAxisToView(ptLocPoint);
LabelLoc = CPoint(2, ptLocPoint.y-6);
char chTemp[20];
itoa(iVertValue, chTemp, 10);
chLabel = (LPCSTR) chTemp;
DrawText(LabelLoc, chLabel);
m_pMemDC->MoveTo(m_rcClient.left + m_iLeftMargin-2, ptLocPoint.y);
m_pMemDC->LineTo(iRightExtent, ptLocPoint.y);
}
}
void CSpectrumAnalyzer::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
{
switch (nSBCode)
{
case SB_LINELEFT:
HorizScroll(TRUE, m_iHScrollShift);
break;
case SB_LINERIGHT:
HorizScroll(FALSE, m_iHScrollShift);
break;
case SB_PAGELEFT:
HorizScroll(TRUE, 5*m_iHScrollShift);
break;
case SB_PAGERIGHT:
HorizScroll(FALSE, 5*m_iHScrollShift);
break;
default:
break;
}
}
void CSpectrumAnalyzer::OnMouseMove( UINT nFlags, CPoint point )
{
// send address of the point to message handler of ScanDialog to show it on screen
CPoint *ptCur;
ptCur = new CPoint;
*ptCur = MapViewToAxis(point);
*ptCur = MapAxisToPoint(*ptCur);
if ((ptCur->x > m_RangeX.y) || (ptCur->x < m_RangeX.x) )
return;
SendCallback(2, WPARAM(ptCur), 0);
}
void CSpectrumAnalyzer::ReSetStep(BOOL bDoZoomOut)
{
// re-set the variables and re-draw the chart
// used for Zooming in and out
if (bDoZoomOut)
{
m_iHLabelSpacing *= 2;
if (m_iHLabelSpacing > ( DWORD((m_RangeX.y - m_RangeX.x ) / m_iNumVGridLines ) ))
m_iHLabelSpacing = DWORD((m_RangeX.y - m_RangeX.x ) / m_iNumVGridLines ) ;
}
else
{
m_iHLabelSpacing /= 2;
if (m_iHLabelSpacing < 1000)
m_iHLabelSpacing = 1000;
}
m_ViewTopLeft = CPoint(0,0);
m_iMaxVAxis = m_iClientHeight;
SetRangeX(m_RangeX);
SetRangeY(m_RangeY);
Clear();
UpdateLabels();
DrawLine();
// Set the horizontal scrolling parameters.
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);
}
void CSpectrumAnalyzer::ClearList()
{
m_pList->RemoveAll();
}
CPoint CSpectrumAnalyzer::GetNextPoint(POSITION &NewPos)
{
// gives the next point in the list
// used for saving the list
CPoint retPoint(-1,-1); // determines no point in the list!
if (&NewPos==NULL) // nothing exists in the list
return retPoint;
retPoint = m_pList->GetNext(NewPos);
return retPoint;
}
// This function sets the callback message that will be sent to the
// specified window each time user sets to a new frequency
//
// Parameters:
// [IN] hWnd
// Handle of the window that will receive the callback message.
// Pass NULL to remove any previously specified callback message.
// [IN] nMessage
// Callback message to send to window.
// [IN] wParam
// First 32 bits user specified value that will be passed to the callback function.
// [IN] lParam
// Second 32 bits user specified value that will be passed to the callback function.
//
// Remarks:
// the callback function must be in the form:
// LRESULT On_ChangeCallback(WPARAM wParam, LPARAM lParam)
// Where:
// [IN] wParam
// First 32 bits user specified value.
// [IN] lParam
// Second 32 bits user specified value.
//
// Return value:
// KNOBCONTROLST_OK
// Function executed successfully.
//
void CSpectrumAnalyzer::SetCallbackSetToFreq(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
// Set Callback function's parameters for when WM_USER_SET_TO_FREQ message is invoked by CSpectrumAnalyzer
// Note No. 13830203-5
m_csCallbackSetToFreq.hWnd = hWnd;
m_csCallbackSetToFreq.nMessage = nMessage;
m_csCallbackSetToFreq.wParam = wParam;
m_csCallbackSetToFreq.lParam = lParam;
}
void CSpectrumAnalyzer::SetCallbackShowFreq(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
// Set Callback function's parameters for when WM_USER_SHOW_CURRENT_FREQ message is invoked by CSpectrumAnalyzer
m_csCallbackShowFreq.hWnd = hWnd;
m_csCallbackShowFreq.nMessage = nMessage;
m_csCallbackShowFreq.wParam = wParam;
m_csCallbackShowFreq.lParam = lParam;
}
void CSpectrumAnalyzer::SendCallback(int iCallbackIndex, WPARAM wParam, LPARAM lParam)
{
// Send callback message to parent window
// iCallbackIndex == 1 ---------------> SetToFreq Callback
// iCallbackIndex == 2 ---------------> ShowFreq Callback
// Note No. 13830203-5
if (iCallbackIndex==1)
::PostMessage(m_csCallbackSetToFreq.hWnd, m_csCallbackSetToFreq.nMessage, wParam, lParam);
else
::PostMessage(m_csCallbackShowFreq.hWnd, m_csCallbackShowFreq.nMessage, wParam, lParam);
}
void CSpectrumAnalyzer::DrawPieceOfLine(CPoint ptStart, CPoint ptEnd)
{
if (ptStart.y <= m_iVHighIndicatorView)
{
// start point is in HIGH region
if (ptEnd.y <= m_iVHighIndicatorView)
{
// both points are in HIGH region
m_pMemDC->SelectObject(m_IndicatorPen);
m_pMemDC->MoveTo(ptStart);
m_pMemDC->LineTo(ptEnd);
}
else
{
// Start point is in high region, but not the other
CPoint ptInter;
ptInter.y = m_iVHighIndicatorView;
ptInter.x = (m_iVHighIndicatorView - ptStart.y) * (ptEnd.x - ptStart.x) / (ptEnd.y - ptStart.y) + ptStart.x;
m_pMemDC->SelectObject(m_IndicatorPen);
m_pMemDC->MoveTo(ptStart);
m_pMemDC->LineTo(ptInter);
m_pMemDC->SelectObject(m_DrawPen);
m_pMemDC->MoveTo(ptInter);
m_pMemDC->LineTo(ptEnd);
}
}
else
{
if (ptEnd.y > m_iVHighIndicatorView )
{
// neither points are in HIGH region
m_pMemDC->SelectObject(m_DrawPen);
m_pMemDC->MoveTo(ptStart);
m_pMemDC->LineTo(ptEnd);
}
else
{
// End point is in HIGH region, but not the start point
CPoint ptInter;
ptInter.y = m_iVHighIndicatorView;
ptInter.x = (m_iVHighIndicatorView - ptStart.y) * (ptEnd.x - ptStart.x) / (ptEnd.y - ptStart.y) + ptStart.x;
m_pMemDC->SelectObject(m_DrawPen);
m_pMemDC->MoveTo(ptStart);
m_pMemDC->LineTo(ptInter);
m_pMemDC->SelectObject(m_IndicatorPen);
m_pMemDC->MoveTo(ptInter);
m_pMemDC->LineTo(ptEnd);
}
}
}
void CSpectrumAnalyzer::SetVHighIndicator(int iVHighIndicator)
{
m_iVHighIndicator = iVHighIndicator;
// convert m_iVHighIndicator that is in RangeY scale, to View scale
CPoint ptLocPoint = CPoint(m_RangeX.x, m_iVHighIndicator); // x is dummy now
ptLocPoint = MapPointToAxis(ptLocPoint);
ptLocPoint.x = m_ViewTopLeft.x; // x is dummy, but change it so that MapAxisToView function works properly
MapAxisToView(ptLocPoint);
m_iVHighIndicatorView = ptLocPoint.y;
}