MFC-Simulator/TestSimulator/OscDlg.cpp

434 lines
10 KiB
C++
Raw Normal View History

2023-02-03 03:07:52 +01:00
// OscDlg.cpp : <20><><EFBFBD>@<40><>
//
#include "stdafx.h"
#include "TestSimulator.h"
#include "OscDlg.h"
#include "afxdialogex.h"
#include "TestSimulatorDlg.h"
#include <cstdlib>
#include <ctime>
//#include <iostream>
//using namespace std;
//<2F>u<EFBFBD>@<40>ϰ<EFBFBD><CFB0>Ѽ<EFBFBD>
#define WORK_LEFT 0
#define WORK_TOP 0
#define WORK_RIGHT 500
#define WORK_BOTTOM 500
#define BLACK RGB (0, 0, 0) //<2F>I<EFBFBD><49><EFBFBD>C<EFBFBD><43>
#define BLUE RGB (0, 0, 255) //<2F><><EFBFBD><EFBFBD><EFBFBD>C<EFBFBD><43>
#define WHITE RGB (255, 255, 255) //y = 0<><30><EFBFBD>u<EFBFBD>C<EFBFBD><43>
#define YELLOW RGB (255, 255, 0) //<2F>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD>u<EFBFBD>@<40>ӳ<EFBFBD><D3B3><EFBFBD>u<EFBFBD><75><EFBFBD>C<EFBFBD><43>
#define RED RGB (255, 0, 0) //<2F>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD>u<EFBFBD><75><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD>u<EFBFBD><75><EFBFBD>C<EFBFBD><43>
#define GOLD RGB (255, 215, 0) //<2F><><EFBFBD><EFBFBD>output<75>i<EFBFBD><69><EFBFBD>C<EFBFBD><43>
#define GRID 10
#define UNITY 100
#define MAX_PLOT_NUM 501 //<2F>̤jø<6A>sdata<74><61>
#define OFFSET_Y 250 //<2F><><EFBFBD>ܲ<EFBFBD><DCB2>y<EFBFBD>Х<EFBFBD><D0A5>W<EFBFBD><57><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD>A<EFBFBD><41><EFBFBD>F<EFBFBD><46>ø<EFBFBD><C3B8>ø<EFBFBD>s<EFBFBD><73><EFBFBD>ܪi<DCAA><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><47>ϮɻݼW<DDBC>[<5B>@<40>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD>q<EFBFBD><71>(0, 0)<29><><EFBFBD><EFBFBD><EFBFBD>ܪi<DCAA>ϥ<EFBFBD><CFA5><EFBFBD><EFBFBD>I
// COscDlg <20><><EFBFBD>ܤ<EFBFBD><DCA4><EFBFBD>
COscDlg::COscDlg (CWnd* pParent /*=NULL*/)
: CDialogEx(COscDlg::IDD, pParent)
{
m_hIcon = AfxGetApp ()->LoadIcon (IDR_MAINFRAME);
m_pSimulatorDlg = (CTestSimulatorDlg*) pParent;
m_rcWork.SetRect (WORK_LEFT, WORK_TOP, WORK_RIGHT, WORK_BOTTOM);
m_dTime = 0.;
m_dSlctOutputValue = 0.;
m_dMaxDataValue = 0.;
m_dFreq = 0.;
m_iOutputSize = 0;
m_iSlctOutputNum = 0;
m_dYInterval = 0;
m_iXInterval = 0;
m_iYPos = 0;
m_iXPos = 0;
m_bSim = FALSE;
m_bModify = TRUE;
m_bFFT = TRUE;
}
COscDlg::~COscDlg ()
{
if (!m_deqPenPtr.empty ())
{
int iSize = (int) m_deqPenPtr.size ();
for (int i = 0; i < iSize; i++)
delete m_deqPenPtr[i];
}
}
void COscDlg::DoDataExchange (CDataExchange* pDX)
{
CDialogEx::DoDataExchange (pDX);
DDX_Text (pDX, IDC_EDIT_TIME, m_dTime);
DDX_Text (pDX, IDC_EDIT_VALUE, m_dSlctOutputValue);
DDX_Control (pDX, IDC_COMBO_OUTPUT, m_ctrlComboOutput);
DDX_Control (pDX, IDC_COMBO_VALUE_INTERVAL, m_ctrlComboYInterval);
DDX_Control (pDX, IDC_COMBO_TIME_INTERVAL, m_ctrlComboXInterval);
DDX_Text (pDX, IDC_EDIT_FREQUENCY, m_dFreq);
}
BEGIN_MESSAGE_MAP (COscDlg, CDialogEx)
ON_WM_CLOSE()
ON_WM_PAINT()
ON_BN_CLICKED(IDC_BUTTON_START, &COscDlg::OnBnClickedButtonStart)
ON_BN_CLICKED(IDC_BUTTON_STOP, &COscDlg::OnBnClickedButtonStop)
ON_CBN_SELCHANGE(IDC_COMBO_OUTPUT, &COscDlg::OnCbnSelchangeComboOutput)
ON_CBN_SELCHANGE(IDC_COMBO_VALUE_INTERVAL, &COscDlg::OnCbnSelchangeComboValueInterval)
ON_CBN_SELCHANGE(IDC_COMBO_TIME_INTERVAL, &COscDlg::OnCbnSelchangeComboTimeInterval)
END_MESSAGE_MAP ()
// COscDlg <20>T<EFBFBD><54><EFBFBD>B<EFBFBD>z<EFBFBD>`<60><>
BOOL COscDlg::OnInitDialog ()
{
CDialogEx::OnInitDialog();
//<2F>]<5D>w<EFBFBD>üƺؤl
srand ((unsigned int) time (NULL));
//<2F>]<5D>wY<77>b<EFBFBD><62><EFBFBD>jCombo box<6F><78><EFBFBD>e
for (int i = 0; i < 4; i++)
{
CString strYInterval;
double dInterval = 0.5;
for (int j = 0 ; j < i; j++)
dInterval *= 2;
strYInterval.Format (_T ("%g"), dInterval);
m_ctrlComboYInterval.AddString (strYInterval);
}
//<2F><><EFBFBD>l<EFBFBD><6C>Y<EFBFBD>b<EFBFBD><62><EFBFBD>j
m_ctrlComboYInterval.SetCurSel (0);
m_dYInterval = 0.5;
m_iYPos = 0;
m_dMaxDataValue = m_dYInterval * 2.5;
//<2F>]<5D>wX<77>b<EFBFBD><62><EFBFBD>jCombo box<6F><78><EFBFBD>e
m_ctrlComboXInterval.AddString (_T ("5"));
m_ctrlComboXInterval.AddString (_T ("10"));
m_ctrlComboXInterval.AddString (_T ("50"));
m_ctrlComboXInterval.AddString (_T ("100"));
m_ctrlComboXInterval.AddString (_T ("500"));
//<2F><><EFBFBD>l<EFBFBD><6C>X<EFBFBD>b<EFBFBD><62><EFBFBD>j
m_ctrlComboXInterval.SetCurSel (0);
m_iXInterval = 5;
m_iXPos = 0;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX <20>ݩʭ<DDA9><CAAD><EFBFBD><EFBFBD>Ǧ^ FALSE
}
void COscDlg::OnPaint ()
{
//<2F><><EFBFBD>w<EFBFBD>īإ<C4AB>
CPaintDC dcOsc (this); //<2F>ܪi<DCAA><69><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD>dc
CDC dcMem; //<2F><><EFBFBD>sdc
CBitmap bitmapMem;
CBitmap* pOldBitmap;
dcMem.CreateCompatibleDC (&dcOsc); //<2F>إ߻P<DFBB>ܪi<DCAA><69><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><DCB2>ۮe<DBAE><65>dc
bitmapMem.CreateCompatibleBitmap (&dcOsc, WORK_RIGHT, WORK_BOTTOM);
pOldBitmap = dcMem.SelectObject (&bitmapMem);
//ø<>s<EFBFBD>I<EFBFBD><49>
dcMem.SetBkMode (TRANSPARENT);
dcMem.FillSolidRect (m_rcWork, BLACK);
//<2F>Ŧ<EFBFBD><C5A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 10 pixels
CPen penBlue (PS_SOLID, 1, BLUE);
CPen* pOldPen = dcMem.SelectObject (&penBlue);
for (int i = 0; i < m_rcWork.Width (); i += GRID)
{
dcMem.MoveTo (i, 0); //<2F><><EFBFBD><EFBFBD><EFBFBD>u
dcMem.LineTo (i, m_rcWork.Height ());
dcMem.MoveTo (0, i); //<2F><><EFBFBD><EFBFBD><EFBFBD>u
dcMem.LineTo (m_rcWork.Width (), i);
}
//ø<>s<EFBFBD>ܪi<DCAA><69><EFBFBD><EFBFBD><EFBFBD>u(X<>b)
CPen penWhite (PS_SOLID, 2, WHITE);
CString strValueZero ("Value = 0");
dcMem.SelectObject (&penWhite);
SetTextColor (dcMem, WHITE);
dcMem.MoveTo (0, m_rcWork.Height () / 2);
dcMem.LineTo (m_rcWork.Width (), m_rcWork.Height () / 2); //<2F>e<EFBFBD>u
dcMem.TextOutA (0, m_rcWork.Height () / 2, strValueZero, strValueZero.GetLength ()); //<2F>аO<D0B0><4F><EFBFBD>r
//<2F>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD>u<EFBFBD>@<40><>UNITY (<28>@<40><>UNITY<54><59> 100 piexls)
CPen penYellow (PS_SOLID, 1, YELLOW);
CString strValueNOne;
strValueNOne.Format (_T ("Value = %g"), -m_dYInterval);
CString strValuePOne;
strValuePOne.Format (_T ("Value = %g"), m_dYInterval);
dcMem.SelectObject (&penYellow);
SetTextColor (dcMem, YELLOW);
dcMem.MoveTo (0, m_rcWork.Height () / 2 + UNITY);
dcMem.LineTo (m_rcWork.Width (), m_rcWork.Height () / 2 + UNITY);
dcMem.TextOutA (0, m_rcWork.Height () / 2 + UNITY, strValueNOne, strValueNOne.GetLength ());
dcMem.MoveTo (0, m_rcWork.Height () / 2 - UNITY);
dcMem.LineTo (m_rcWork.Width (), m_rcWork.Height () / 2 - UNITY);
dcMem.TextOutA (0, m_rcWork.Height () / 2 - UNITY, strValuePOne, strValuePOne.GetLength ());
//<2F>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD>u<EFBFBD><75><EFBFBD><EFBFBD>UNITY (<28>@<40><>UNITY<54><59> 100 piexls)
CPen penRed (PS_SOLID, 2, RED);
CString strValueNTwo;
strValueNTwo.Format (_T ("Value = %g"), -2 * m_dYInterval);
CString strValuePTwo;
strValuePTwo.Format (_T ("Value = %g"), 2 * m_dYInterval);
dcMem.SelectObject (&penRed);
SetTextColor (dcMem, RED);
dcMem.MoveTo (0, m_rcWork.Height () / 2 + (2 * UNITY));
dcMem.LineTo (m_rcWork.Width (), m_rcWork.Height () / 2 + (2 * UNITY));
dcMem.TextOutA (0, m_rcWork.Height () / 2 + (2 * UNITY), strValueNTwo, strValueNTwo.GetLength ());
dcMem.MoveTo (0, m_rcWork.Height () / 2 - (2 * UNITY));
dcMem.LineTo (m_rcWork.Width (), m_rcWork.Height () / 2 - (2 * UNITY));
dcMem.TextOutA (0, m_rcWork.Height () / 2 - (2 * UNITY), strValuePTwo, strValuePTwo.GetLength ());
//<2F><><EFBFBD><EFBFBD><EFBFBD>}<7D>l
if (m_bSim)
{
CPen penGold (PS_SOLID, 6, GOLD);
int iDataSize = (int) m_pSimulatorDlg->m_deq2DOutputValue.size (); //<2F><><EFBFBD>odata<74>ƥ<EFBFBD>
//<2F><>data<74>Ƥj<C6A4><6A>1<EFBFBD>A<EFBFBD>}<7D><6C>soutput<75>i<EFBFBD><69>
if (iDataSize > 1)
{
int iPlotStart = 0; //ø<>sdata<74>_<EFBFBD>I
if (iDataSize > MAX_PLOT_NUM)
iPlotStart = iDataSize - MAX_PLOT_NUM;
for (int i = 0; i < m_iOutputSize; i++)
{
//<2F>]<5D>w<EFBFBD><77><EFBFBD><EFBFBD>output<75><74><EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʪ<EFBFBD><CAAA>e<EFBFBD><65>
if (m_iSlctOutputNum >= 0 && i == m_iSlctOutputNum)
dcMem.SelectObject (&penGold);
else
dcMem.SelectObject (m_deqPenPtr[i]);
for (int j = 1; j < iDataSize; j++)
{
//<2F>W<EFBFBD>X<EFBFBD><69>sdata<74>ơA<C6A1>h<EFBFBD>ߧY<DFA7><59><EFBFBD>X<EFBFBD>j<EFBFBD><6A>
if (j >= MAX_PLOT_NUM)
break;
double dForwardValue = m_pSimulatorDlg->m_deq2DOutputValue[j - 1 + iPlotStart][i];
double dPostValue = m_pSimulatorDlg->m_deq2DOutputValue[j + iPlotStart][i];
//<2F>P<EFBFBD>_data<74>ȬO<C8AC>_<EFBFBD>W<EFBFBD>X<EFBFBD>ܪi<DCAA><69><EFBFBD>i<EFBFBD><69><EFBFBD>ܤ<EFBFBD><DCA4>̤j<CCA4><6A>
if (dForwardValue > m_dMaxDataValue)
dForwardValue = m_dMaxDataValue;
else if (dForwardValue < -m_dMaxDataValue)
dForwardValue = -m_dMaxDataValue;
if (dPostValue > m_dMaxDataValue)
dPostValue = m_dMaxDataValue;
else if (dPostValue < -m_dMaxDataValue)
dPostValue = -m_dMaxDataValue;
dcMem.MoveTo (j - 1, -(int) (dForwardValue / m_dYInterval * UNITY) + OFFSET_Y);
dcMem.LineTo (j, -(int) (dPostValue / m_dYInterval * UNITY) + OFFSET_Y);
}
}
}
}
//<2F>Ѥ<EFBFBD><D1A4>sdc<64><63><EFBFBD><EFBFBD><EFBFBD>ܥܪi<DCAA><69><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD>dc
dcOsc.BitBlt (WORK_LEFT, WORK_TOP, m_rcWork.Width (), m_rcWork.Height (), &dcMem, WORK_LEFT, WORK_TOP, SRCCOPY);
//<2F>M<EFBFBD>z
dcMem.SelectObject (pOldPen);
dcMem.SelectObject (pOldBitmap);
bitmapMem.DeleteObject ();
dcMem.DeleteDC ();
}
//<2F>ѥD<D1A5><44><EFBFBD>ܲ<EFBFBD><DCB2>ǭ<EFBFBD>(<28><><EFBFBD>e<EFBFBD>ɶ<EFBFBD>, <20><><EFBFBD><EFBFBD>output value, <20>W<EFBFBD>v)
void COscDlg::SetData (double dTime, double dValue, double dFreq)
{
m_dTime = dTime;
m_dSlctOutputValue = dValue;
m_dFreq = dFreq;
}
// <20>ѥD<D1A5><44><EFBFBD>ܲ<EFBFBD><DCB2>ǭ<EFBFBD>(<28><><EFBFBD>e<EFBFBD>ɶ<EFBFBD>, <20><><EFBFBD><EFBFBD>output value)
void COscDlg::SetData (double dTime, double dValue)
{
m_dTime = dTime;
m_dSlctOutputValue = dValue;
}
//<2F><><EFBFBD>UStart<72><74>
void COscDlg::OnBnClickedButtonStart ()
{
if (!m_bSim)
{
m_bModify = FALSE; //<2F>}<7D>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD>X<EFBFBD>b<EFBFBD><62><EFBFBD>jCombo box
m_bSim = TRUE;
m_pSimulatorDlg->SetTimer (0, 10, NULL);
}
}
//<2F><><EFBFBD>UStop<6F><70>
void COscDlg::OnBnClickedButtonStop ()
{
if (m_bSim)
{
m_bSim = FALSE;
m_pSimulatorDlg->KillTimer (0);
}
}
//<2F><><EFBFBD><EFBFBD>output combo box
void COscDlg::OnCbnSelchangeComboOutput ()
{
m_iSlctOutputNum = m_ctrlComboOutput.GetCurSel ();
m_bFFT = TRUE;
}
//<2F><><EFBFBD><EFBFBD>Y<EFBFBD>b<EFBFBD><62><EFBFBD>j combo box
void COscDlg::OnCbnSelchangeComboValueInterval ()
{
m_iYPos = m_ctrlComboYInterval.GetCurSel ();
double dIni = 0.5;
for (int i = 0; i < m_iYPos; i++)
dIni *= 2;
m_dYInterval = dIni;
m_dMaxDataValue = 2.5 * m_dYInterval;
InvalidateRect (m_rcWork, FALSE);
UpdateWindow ();
}
//<2F><><EFBFBD><EFBFBD>X<EFBFBD>b<EFBFBD><62><EFBFBD>j combo box
void COscDlg::OnCbnSelchangeComboTimeInterval ()
{
if (m_bModify && (!m_bSim))
{
m_iXPos = m_ctrlComboXInterval.GetCurSel ();
switch (m_iXPos)
{
case 0:
m_iXInterval = 5;
break;
case 1:
m_iXInterval = 10;
break;
case 2:
m_iXInterval = 50;
break;
case 3:
m_iXInterval = 100;
break;
case 4:
m_iXInterval = 500;
break;
default:
break;
}
}
else
m_ctrlComboXInterval.SetCurSel (m_iXPos);
}
BOOL COscDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
return TRUE;
}
return CDialogEx::PreTranslateMessage(pMsg);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void COscDlg::OnClose ()
{
//<2F>M<EFBFBD><4D><EFBFBD>H<EFBFBD><48><EFBFBD>e<EFBFBD><65>deque
if (!m_deqPenPtr.empty ())
{
for (int i = 0; i < m_iOutputSize; i++)
delete m_deqPenPtr[i];
}
m_pSimulatorDlg->m_bSimulate = FALSE; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_deqPenPtr.clear ();
m_ctrlComboOutput.ResetContent (); //<2F>M<EFBFBD><4D>output combo box<6F><78><EFBFBD>e
m_bSim = FALSE; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_bModify = TRUE; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD>combo box
m_bFFT = TRUE;
m_iSlctOutputNum = 0;
m_dTime = 0.;
m_dSlctOutputValue = 0.;
m_dFreq = 0.;
m_pSimulatorDlg->m_iStep = 0;
m_pSimulatorDlg->KillTimer (0);
CDialogEx::OnClose ();
}
//<2F>]<5D>wchannel<65>ƥ<EFBFBD>
void COscDlg::SetOutputSize (int iOutSize)
{
m_iOutputSize = iOutSize;
}
//<2F><><EFBFBD>l<EFBFBD>ƥܪi<DCAA><69><EFBFBD><EFBFBD><EFBFBD>ܲ<EFBFBD><DCB2><EFBFBD><EFBFBD><EFBFBD>(channel<65>ƥ<EFBFBD>, <20>H<EFBFBD><48><EFBFBD>e<EFBFBD><65>)
void COscDlg::InitialData ()
{
//<2F>]<5D>woutput combo box<6F><78><EFBFBD>e
for (int i = 0; i < m_iOutputSize; i++)
{
CString strOutput;
strOutput.Format (_T ("Output %d"), i + 1);
m_ctrlComboOutput.AddString (strOutput);
}
//<2F>إ<EFBFBD><D8A5>H<EFBFBD><48><EFBFBD>e<EFBFBD><65>
for (int i = 0; i < m_iOutputSize; i++)
{
CPen* pRandPen = new CPen (PS_SOLID, 3, RGB (rand () % 256, rand () % 256, rand () % 256));
m_deqPenPtr.push_back (pRandPen);
}
m_ctrlComboOutput.SetCurSel (0);
}
//<2F><><EFBFBD>o<EFBFBD>ɶ<EFBFBD><C9B6><EFBFBD><EFBFBD>j
int COscDlg::GetTimeInterval () const
{
return m_iXInterval;
}