📄 ecgtestdlg.cpp
字号:
// ECGTestDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ECGTest.h"
#include "ECGTestDlg.h"
#include "math.h"
#include "ECGDATADlg.h"
#include "ECGDFTDlg.h"
#include "BIANYIDLG.h"
#include "STARTDLG.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PI 3.1415926
CBIANYIDLG EcgBianyiDlg;
CECGDATADlg EcgDataDlg;
CECGDFTDlg EcgDFTDlg;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CECGTestDlg dialog
CECGTestDlg::CECGTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CECGTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CECGTestDlg)
m_Date = _T("");
m_Time = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CECGTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CECGTestDlg)
DDX_Text(pDX, IDC_DATE, m_Date);
DDX_Text(pDX, IDC_TIME, m_Time);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CECGTestDlg, CDialog)
//{{AFX_MSG_MAP(CECGTestDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDC_FILE_OPEN, OnFileOpen)
ON_COMMAND(IDC_ABORT, OnAbort)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_CHECK6, OnCheck6)
ON_WM_CTLCOLOR()
ON_COMMAND(IDC_EXIT, OnExit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CECGTestDlg message handlers
BOOL CECGTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
startDlg.DoModal();
EcgDataDlg.Create(IDD_FORMVIEW,this);
EcgDataDlg.ShowWindow(SW_SHOW);
EcgDFTDlg.Create(IDD_FORMVIEW1,this);
EcgDFTDlg.ShowWindow(SW_SHOW);
EcgBianyiDlg.Create(IDD_FORMVIEW2,this);
EcgBianyiDlg.ShowWindow(SW_SHOW);
SetTimer(1,100,NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CECGTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CECGTestDlg::OnPaint()
{
/* if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}*/
CPaintDC dc(this); // device context for painting
GetClientRect(rect);
m_bitmap1.Detach();
m_bitmap1.LoadBitmap(IDB_BITMAP11);
CBrush brush(&m_bitmap1);
dc.FillRect(rect,&brush);
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CECGTestDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void ReverseOrder(_complex A[],int N)
{
int NV2=N/2;
int NM1=N-1;
int I,J,K=0;
_complex T;//用于中介的复数变量T
I=J=1;
while(I<=NM1)
{
if(I<J)
{
T=A[J-1];//将A[J-1]的内容和A[I-1]的内容互换,借助于中间变量T
A[J-1]=A[I-1];
A[I-1]=T;
}
K=NV2;
while(K<J)
{
J-=K;
K/=2;
}
J+=K;
I++;
}
}
void four1(double data[1025], int nn, int isign)
{
int n,j,i,m,mmax,istep;
double tempr,tempi,theta,wpr,wpi,wr,wi,wtemp;
n = 2 * nn;
j = 1;
for (i = 1; i<=n ; i=i+2)
{
if( j > i)
{
tempr = data[j];
tempi = data[j + 1];
data[j] = data[i];
data[j + 1] = data[i + 1];
data[i] = tempr;
data[i + 1] = tempi;
}
m = n / 2;
while (m >= 2 && j > m)
{
j = j - m;
m = m / 2;
}
j = j + m;
}
mmax = 2;
while( n > mmax )
{
istep = 2 * mmax;
theta = 6.28318530717959 / (isign * mmax);
wpr = -2.0 * sin(0.5 * theta)*sin(0.5 * theta);
wpi = sin(theta);
wr = 1.0;
wi = 0.0;
for( m = 1; m<=mmax; m=m+2)
{
for (i = m; i<=n; i=i+istep)
{
j = i + mmax;
tempr = double(wr) * data[j] - double(wi) * data[j + 1];
tempi = double(wr) * data[j + 1] + double(wi) * data[j];
data[j] = data[i] - tempr;
data[j + 1] = data[i + 1] - tempi;
data[i] = data[i] + tempr;
data[i + 1] = data[i + 1] + tempi;
}
wtemp = wr;
wr = wr * wpr - wi * wpi + wr;
wi = wi * wpr + wtemp * wpi + wi;
}
mmax = istep;
}
}
void realft(double data[], int &n, int &isign)
{
int n2p3,i,i1,i2,i3,i4;
double theta,c1,c2,wpr,wpi,wr,wi,wrs,wis,h1r,h1i,h2r,h2i,wtemp,wri;
wri=0.0;
theta = 6.28318530717959 / 2.0 / n;
c1 = 0.5;
if (isign == 1)
{
c2 = -0.5;
four1(data, n, 1);
}
else
{
c2 = 0.5;
theta = -theta;
}
wpr = -2.0 * sin(0.5 * theta)*sin(0.5 * theta);
wpi = sin(theta);
wr = 1.0 + wpr;
wi = wpi;
n2p3 = 2 * n + 3;
for (i = 2; i<=n / 2 + 1; i++)
{
i1 = 2 * i - 1;
i2 = i1 + 1;
i3 = n2p3 - i2;
i4 = i3 + 1;
wrs = float(wr);
wis = float(wi);
h1r = c1 * (data[i1] + data[i3]);
h1i = c1 * (data[i2] - data[i4]);
h2r = -c2 * (data[i2] + data[i4]);
h2i = c2 * (data[i1] - data[i3]);
data[i1] = h1r + wrs * h2r - wis * h2i;
data[i2] = h1i + wrs * h2i + wis * h2r;
data[i3] = h1r - wrs * h2r + wis * h2i;
data[i4] = -h1i + wrs * h2i + wis * h2r;
wtemp = wr;
wr = wr * wpr - wi * wri + wr;
wi = wi * wpr + wtemp * wpi + wi;
}
if( isign == 1 )
{
h1r = data[1];
data[1] = h1r + data[2];
data[2] = h1r - data[2];
}
else
{
h1r = data[1];
data[1] = c1 * (h1r + data[2]);
data[2] = c1 * (h1r - data[2]);
four1(data, n, -1);
}
}
void Fourier(_complex A[],int M)
{
_complex U,W,T;
int LE,LE1,I,J,IP;
int N=(int)pow(2,M);
//在此采用的是时间抽选奇偶分解方式,所以在参加运算前首先要对时间序列进行倒序
ReverseOrder(A,N);
int L=1;
while(L<=M)
{
LE=(int)pow(2,L);
LE1=LE/2;
U.x=1.0f;
U.y=0.0f;
W.x=(float)cos(PI/(1.0*LE1));//计算W算子的值
W.y=(float)-1.0*sin(PI/(1.0*LE1));
if(abs(W.x)<1.0e-12)
W.x=0.0f;
if(abs(W.y)<1.0e-12)
W.y=0.0f;
J=1;
while(J<=LE1)
{
I=J;
while(I<=N)
{
IP=I+LE1;
T.x=(float)A[IP-1].x*U.x-A[IP-1].x*U.y;//计算复数运算A*U
T.y=(float)A[IP-1].y*U.y+A[IP-1].y*U.x;
A[IP-1].x=(float)A[I-1].x-T.x;//计算复数运算A-T
A[IP-1].y=(float)A[I-1].y-T.y;
A[I-1].x+=T.x;//计算复数运算A+T
A[I-1].y+=T.y;
I+=LE;
}
float temp=U.x;
U.x=(float)U.x*W.x-U.y*W.y;//计算复数运算U*W
U.y=(float)temp*W.y+U.y*W.x;
J++;
}
L++;
}
}
BOOL m_control=FALSE,m_DFTflag=TRUE,m_filer=FALSE;
CString m_pathName;
int ECGData[166];//心电数据缓冲
double ECGDFTData[1025],ECGDataTemp[1025];//构造复数,以进行傅立叶变换
UINT mThreadTest(LPVOID pParam)//心电数据动态显示线程
{
CStdioFile hFile;
CString fileContent,strtemp;
int pos;
hFile.Open(m_pathName,CFile::modeRead | CFile::typeText);
char str1[10],str2[10];
if(hFile.GetLength()!=0)
{
hFile.ReadString(fileContent);
while(!fileContent.IsEmpty()&& m_control)
{
pos=fileContent.Find('-');
if(pos!=-1)
fileContent=fileContent.Left(pos);
ECGData[0]=atoi(fileContent);
for(int j=165;j>0;j--)
{
ECGData[j]=ECGData[j-1];
}
for(int i=0;i<165;i++)
{
_itoa(ECGData[i],str1,10);
EcgDataDlg.DrawWave(str1);
}
ECGDFTData[0]=atoi(fileContent);//傅立叶变换
for(int m=1024;m>0;m--)
{
ECGDFTData[m]=ECGDFTData[m-1];
}
for(int p=1024;p>0;p--)
{
ECGDataTemp[p]=ECGDFTData[p];
}
/* Fourier(ECGDFTData,10);
for(int n=0;n<1024;n++)
{
_itoa(ECGDFTData[n].x,str2,10);
EcgDFTDlg.DrawDFTWave(str2);
}*/
int h=512,temp=1;
realft(ECGDataTemp, h, temp);
char str[10];
for(int n=1;n<1025;n++)
{
//float ftemp = _cabs(ECGDataTemp[n]);
//_itoa(ftemp,str,10);
_itoa(labs(ECGDataTemp[n]),str,10);
EcgDFTDlg.DrawDFTWave(str);
}
// m_DFTflag=TRUE;
hFile.ReadString(fileContent);
}
}
//Sleep(100);
AfxMessageBox("数据读取完毕!");
return 0;
}
UINT mThreadAnaly(LPVOID pParam)//心电数据动态分析线程
{
char str[10];
while(m_DFTflag)
{
// Fourier(ECGDataTemp,10);
int h=512,temp=1;
realft(ECGDataTemp, h, temp);
for(int n=1;n<1025;n++)
{
//float ftemp = _cabs(ECGDataTemp[n]);
//_itoa(ftemp,str,10);
_itoa(ECGDataTemp[n],str,10);
EcgDFTDlg.DrawDFTWave(str);
}
m_DFTflag = FALSE;
}
return 0;
}
void CECGTestDlg::OnFileOpen()
{
// TODO: Add your command handler code here
CFileDialog opendlg(TRUE,_T("BMP"),_T("*.txt"),OFN_HIDEREADONLY,_T("心电数据文件(*.txt)|*.txt|"));
opendlg.m_ofn.lpstrTitle="打开心电数据文件";
if(opendlg.DoModal()==IDOK)
{
m_pathName=opendlg.GetPathName();
m_control=TRUE;
// AfxBeginThread(mThreadAnaly,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
AfxBeginThread(mThreadTest,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
}
}
void CECGTestDlg::OnAbort()
{
// TODO: Add your command handler code here
CAboutDlg abortDlg;
abortDlg.DoModal();
}
void CECGTestDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CString timestr;
CTime time = CTime::GetCurrentTime();
timestr = time.Format("%Y-%m-%d");
m_Date = timestr;
m_Time = time.Format("%H:%M:%S");
UpdateData(FALSE);
CDialog::OnTimer(nIDEvent);
}
void CECGTestDlg::OnCheck6()
{
// TODO: Add your control notification handler code here
/*if(m_filter=FALSE)
m_filter = TRUE;
else
m_filter = FALSE;*/
}
HBRUSH CECGTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
if(nCtlColor==CTLCOLOR_BTN)
{
pDC->SetTextColor(RGB(100,0,200));
}
if(nCtlColor==CTLCOLOR_STATIC)
{
pDC->SetTextColor(RGB(200,0,200));
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
void CECGTestDlg::OnExit()
{
// TODO: Add your command handler code here
OnOK();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -