📄 spectrumanalyzer.cpp
字号:
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=0; // 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -