
// MeterDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Meter.h"
#include "MeterDlg.h"
#include "afxdialogex.h"
#include <share.h>
#include <locale.h>
#include <time.h>
#include "windows.h"
#include "mmsystem.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif




CMeterDlg::CMeterDlg(CWnd* pParent)
	: CDialogEx(CMeterDlg::IDD, pParent)
{
	//m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_bComConnect = FALSE;
	m_lastid=0;
	m_matches=0;
	m_tLastMatch=0;
	m_strWriteFileName=_T("");
	m_bWriteData=FALSE;
}

void CMeterDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STC_LCD, m_stcLCD);
	DDX_Control(pDX, IDC_BTN_V, m_btnV);
	DDX_Control(pDX, IDC_BTN_A, m_btnA);
	DDX_Control(pDX, IDC_BTN_OHM, m_btnOHM);
	DDX_Control(pDX, IDC_BTN_CAP, m_btnC);
	DDX_Control(pDX, IDC_BTN_DIODE, m_btnD);
	DDX_Control(pDX, IDC_BTN_CONTI, m_btnConti);
	DDX_Control(pDX, IDC_BTN_ACDC, m_btnACDC);
	DDX_Control(pDX, IDC_BTN_AUTOMANUAL, m_btnAutoManual);
	DDX_Control(pDX, IDC_BTN_REL, m_btnRel);
	DDX_Control(pDX, IDC_BTN_AMA, m_btnAmA);
	DDX_Control(pDX, IDC_BTN_DIV, m_btnDIV);
	DDX_Control(pDX, IDC_LIST_DATA, m_listData);
	DDX_Control(pDX, IDC_BTN_CLEAR, m_btnClearData);
	DDX_Control(pDX, IDC_BTN_SAVE, m_btnSaveData);
	DDX_Control(pDX, IDC_BTN_RUN, m_btnRunStop);
	DDX_Control(pDX, IDC_CBO_INTERVAL, m_cboInterval);
	DDX_Control(pDX, IDC_RADIO_USB, m_rdoUSB);
	DDX_Control(pDX, IDC_RADIO_COM, m_rdoCOM);
	DDX_Control(pDX, IDC_CBO_COMPORT, m_cboCOMPort);
	DDX_Control(pDX, IDC_STC_COMPORT, m_stcCOMPort);
	DDX_Control(pDX, IDC_BTN_CONNECT, m_btnConnect);
	DDX_Control(pDX, IDC_LIST_DATA, m_listData);
	DDX_Control(pDX, IDC_STATIC7, m_stcFilename);
	DDX_Control(pDX, IDC_CHECKAUTO, m_chkAutoscroll);
	
	DDX_Control(pDX, IDC_EDIT3, m_editWavFile);
	DDX_Control(pDX, IDC_EDIT4, m_editCommand);
	DDX_Control(pDX, IDC_EDIT1, m_from);
	DDX_Control(pDX, IDC_EDIT2, m_to);
	DDX_Control(pDX, IDC_CHECKREP, m_checkRepeat);
	DDX_Control(pDX, IDC_CHECK3, m_checkAlarmEnabled);
	DDX_Control(pDX, IDC_EDITDELAY, m_editDelay);
	DDX_Control(pDX, IDC_STATICN, m_stcMatchCounter);
	DDX_Control(pDX, IDC_CHECKLOG, m_chkShowLog);
}

BEGIN_MESSAGE_MAP(CMeterDlg, CDialogEx)
	ON_WM_PAINT()
	ON_COMMAND(IDOK,&CMeterDlg::OnOk)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BTN_V, &CMeterDlg::OnBnClickedBtnV)
	ON_BN_CLICKED(IDC_BTN_A, &CMeterDlg::OnBnClickedBtnA)
	ON_BN_CLICKED(IDC_BTN_OHM, &CMeterDlg::OnBnClickedBtnOhm)
	ON_BN_CLICKED(IDC_BTN_CAP, &CMeterDlg::OnBnClickedBtnCap)
	ON_BN_CLICKED(IDC_BTN_DIODE, &CMeterDlg::OnBnClickedBtnDiode)
	ON_BN_CLICKED(IDC_BTN_CONTI, &CMeterDlg::OnBnClickedBtnConti)
	ON_BN_CLICKED(IDC_BTN_ACDC, &CMeterDlg::OnBnClickedBtnAcdc)
	ON_BN_CLICKED(IDC_BTN_AUTOMANUAL, &CMeterDlg::OnBnClickedBtnAutomanual)
	ON_BN_CLICKED(IDC_BTN_REL, &CMeterDlg::OnBnClickedBtnRel)
	ON_BN_CLICKED(IDC_BTN_AMA, &CMeterDlg::OnBnClickedBtnAma)
	ON_BN_CLICKED(IDC_BTN_DIV, &CMeterDlg::OnBnClickedBtnDiv)
	ON_BN_CLICKED(IDC_BTN_CLEAR, &CMeterDlg::OnBnClickedBtnClear)
	ON_BN_CLICKED(IDC_BTN_SAVE, &CMeterDlg::OnBnClickedBtnSave)
	ON_BN_CLICKED(IDC_BTN_RUN, &CMeterDlg::OnBnClickedBtnRun)
	ON_CBN_SELCHANGE(IDC_CBO_INTERVAL, &CMeterDlg::OnCbnSelchangeCboInterval)
	ON_BN_CLICKED(IDC_BTN_HELP, &CMeterDlg::OnBnClickedBtnHelp)
	ON_BN_CLICKED(IDC_RADIO_USB, &CMeterDlg::OnBnClickedRadioUsb)
	ON_BN_CLICKED(IDC_RADIO_COM, &CMeterDlg::OnBnClickedRadioCom)
	ON_CBN_SELCHANGE(IDC_CBO_COMPORT, &CMeterDlg::OnCbnSelchangeCboComport)
	ON_BN_CLICKED(IDC_BTN_CONNECT, &CMeterDlg::OnBnClickedBtnConnect)
	ON_BN_CLICKED(IDC_BTN_SAVE3, &CMeterDlg::OnBnClickedBtnSave3)
	ON_BN_CLICKED(IDC_CHECK1, &CMeterDlg::OnBnClickedCheck1)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_DATA, &CMeterDlg::OnLvnItemchangedListData)
	ON_BN_CLICKED(IDC_BUTTON1, &CMeterDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CMeterDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CMeterDlg::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_CHECKREP, &CMeterDlg::OnBnClickedCheckrep)
END_MESSAGE_MAP()


// CMeterDlg message handlers

BOOL CMeterDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 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

	SetWindowText(_T("Hantek365 Ver 1.0.0.0-LINDAR"));
	InitDevice();
	m_stcLCD.InitLCD();
	m_stcLCD.m_pMeter = &m_DMM;
	InitListCtrl();
	m_cboInterval.SetCurSel(m_DMM.m_nInterval);
	m_rdoUSB.SetCheck(m_DMM.m_nCommType == COMM_USB);
	m_rdoCOM.SetCheck(m_DMM.m_nCommType == COMM_COM);
	m_cboCOMPort.SetCurSel(0);
	m_rdoUSB.EnableWindow(FALSE);
	m_rdoCOM.EnableWindow(FALSE);
	if(m_DMM.m_nCommType == COMM_USB)
	{
		m_cboCOMPort.ShowWindow(SW_HIDE);
		m_stcCOMPort.ShowWindow(SW_HIDE);
		m_btnConnect.ShowWindow(SW_HIDE);
	}
	else
	{
		m_cboCOMPort.ShowWindow(SW_SHOW);
		m_stcCOMPort.ShowWindow(SW_SHOW);
		m_btnConnect.ShowWindow(SW_SHOW);
	}
	m_hEvent = CreateEvent(NULL,FALSE,TRUE,NULL);
	m_hThreadProc = CreateThread(NULL,0,DMMProc,this,0,NULL);

	CString str;
	str=AfxGetApp()->GetProfileString(_T("Alarm"),_T("min"),_T(""));
	m_from.SetWindowTextW(str);

	str=AfxGetApp()->GetProfileString(_T("Alarm"),_T("max"),_T(""));
	m_to.SetWindowTextW(str);
	
	str=AfxGetApp()->GetProfileString(_T("Alarm"),_T("sound"),_T(""));
	m_editWavFile.SetWindowTextW(str);
	
	str=AfxGetApp()->GetProfileString(_T("Alarm"),_T("command"),_T(""));
	m_editCommand.SetWindowTextW(str);
	
	str=AfxGetApp()->GetProfileString(_T("Alarm"),_T("delay"),_T("10"));
	m_editDelay.SetWindowTextW(str);
	
	UINT a=AfxGetApp()->GetProfileInt(_T("Alarm"),_T("loop"),0);

	if(a)
	{
		m_checkRepeat.SetCheck(BST_CHECKED);
	}
	else 
	{
		m_checkRepeat.SetCheck(BST_UNCHECKED);
	}
	m_chkShowLog.SetCheck(BST_CHECKED);


	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMeterDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		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;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CMeterDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMeterDlg::InitDevice()
{
	int nDev = m_DMM.SearchDevice();
	if(nDev <= 0)
	{
		AfxMessageBox(_T("No usb device was found!"));
		//	CDialogEx::OnCancel();
	}
	else
	{
		if(nDev > 1)//more than one device
		{
			CDlgDevList dlg;
			dlg.m_pCurSel = &m_DMM.m_nDevIndex;
			if(IDOK != dlg.DoModal(nDev))
			{
				CDialogEx::OnCancel();
			}
		}
	}
}

void CMeterDlg::GetDMMData()
{
	if(1 == m_DMM.HDGetDMMData())
	{
		WriteData();
	}
	SetCtrlsText();
	m_stcLCD.DrawLCD();
	ShowCtrls();
	
	if(m_DMM.m_bRun)
	{
		m_btnRunStop.SetWindowText(_T("Stop"));
	}
	else
	{
		m_btnRunStop.SetWindowText(_T("Run"));
	}
}

void CMeterDlg::InitListCtrl()
{
	CString str;
	m_listData.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
	m_listData.InsertColumn(0,_T("ID"), LVCFMT_RIGHT, 45);
	m_listData.InsertColumn(1,_T("Time"), LVCFMT_RIGHT, 130);
	m_listData.InsertColumn(2,_T("Value"), LVCFMT_RIGHT, 75);
}



void CMeterDlg::WriteData()
{
	char buffer[2048];
	wchar_t buf[2048];
	CString strTime[MAX_DATA_LEN];
	CString strData[MAX_DATA_LEN];	
	FullData fulldata[MAX_DATA_LEN];	
	int k;
	int nitems;
	FILE*   fileHandle=NULL;
	CString str;

	/* CSV FILE FORMAT
		RECORD_ID;
		YEAR
		MONTH
		DATE
		HOURS
		MINUTES
		SECONDS
		MILLISECONDS
		VALUE
		UNIT
		UNIT_N
		UNIT_TYPE
	*/

	setlocale(LC_ALL, ".OCP");
	nitems=m_DMM.GetDequeFullData(fulldata,m_lastid+1);
	if(m_bWriteData==TRUE && m_strWriteFileName!=L""){
		if ((fileHandle=_wfsopen(m_strWriteFileName,L"at+", SH_DENYNO))==NULL){
			AfxMessageBox(_T("WRITE FAILED! WRITE STOPPED"));
			m_bWriteData=FALSE;
		}
	}

	for(int i = 0; i < nitems; i++){	
		m_lastid=fulldata[i].id;
		if(fileHandle){
			sprintf_s(buffer,"%d;%04d;%02d;%02d;%02d;%02d;%02d;%d;%f;%s;%d;%d\n",
				fulldata[i].id,fulldata[i].year,fulldata[i].month,fulldata[i].day,
				fulldata[i].hour,fulldata[i].minute,fulldata[i].second,fulldata[i].millisecond,
				fulldata[i].value,fulldata[i].unit,fulldata[i].nUnit,fulldata[i].nUnitType);
		
			int strSize = strlen(buffer);
			if (fwrite(buffer, sizeof(char), strSize, fileHandle) != strSize){
				AfxMessageBox(_T("WRITE FAILED! WRITE STOPPED"));
				m_bWriteData=FALSE;
			}
		}
		if(m_chkShowLog.GetCheck())
		{
			str.Format(_T("%ld"),m_lastid);
			k=m_listData.InsertItem(m_listData.GetItemCount(), str);
			m_listData.SetItemText(k,1,fulldata[i].DT);
			m_listData.SetItemText(k,2,fulldata[i].humanValue);
			if(m_chkAutoscroll.GetCheck()){
				m_listData.EnsureVisible(k,FALSE);
			}
			if(m_listData.GetItemCount()>30000)
			{
				m_listData.DeleteItem(0);
			}
		}
		if(m_checkAlarmEnabled.GetCheck()){
			double from;
			double to;
			int delay;
			BOOL match_from=TRUE;
			BOOL match_to=TRUE;
			BOOL is_from=FALSE;
			BOOL is_to=FALSE;
			m_from.GetWindowTextW(buf,20);
			if(wcslen(buf)>0){
				is_from=TRUE;
				from=_wtof(buf);
			}
			m_to.GetWindowTextW(buf,20);
			if(wcslen(buf)>0){
				is_to=TRUE;
				to=_wtof(buf);
			}
			if(is_from && fulldata[i].value<=from){
				match_from=FALSE;
			}
			if(is_to && fulldata[i].value>=to){
				match_to=FALSE;
			}
			m_editDelay.GetWindowTextW(buf,20);
			if(wcslen(buf)>0){
				delay=_wtoi(buf);
			}
			if(match_to && match_from && (is_from || is_to)){
				CString cnt;
				m_matches++;
				cnt.Format(_T("%d"),m_matches);
				m_stcMatchCounter.SetWindowText(cnt);

				if(m_tLastMatch<time(NULL)-delay){
					// sound?
					if(m_editWavFile.GetWindowTextLengthW()>0){
						m_editWavFile.GetWindowTextW(buf,1024);
						if(m_checkRepeat.GetCheck()){
							PlaySound((LPTSTR)buf,NULL,SND_LOOP | SND_ASYNC|SND_FILENAME|SND_NOSTOP);
						}
						else {
							PlaySound((LPTSTR)buf,NULL,SND_ASYNC|SND_FILENAME|SND_NOSTOP);
						}
					}
					m_editCommand.GetWindowTextW(buf,1024);
					if(wcslen(buf)){
						ShellExecute(NULL,TEXT("open"),(LPCWSTR)buf,NULL,TEXT("\\"),SW_SHOWNORMAL);
					}
					m_tLastMatch=time(NULL);
				}
			}
		}
	}
	
	if(fileHandle){
		if (fclose(fileHandle)){
			AfxMessageBox(_T("WRITE FAILED! WRITE STOPPED"));
			m_bWriteData=FALSE;
		}
		else {
			HTMSG msg;
			msg.nType = MSG_SET_WRITEFILE;
			msg.nValue = m_cboCOMPort.GetCurSel();
			PushCmdMsg(msg);			
		}
	}
	
	setlocale(LC_ALL, "C");
}

void CMeterDlg::SetCtrlsText()
{
//AC DC
	if(m_DMM.m_DMMData.nType == DMM_VOLTAGE || m_DMM.m_DMMData.nType == DMM_CURRENT)
	{
		if(m_DMM.m_DMMData.nDCAC == DMM_DC)
		{
			m_btnACDC.SetWindowText(_T("DC"));
		}
		else if(m_DMM.m_DMMData.nDCAC == DMM_AC)
		{
			m_btnACDC.SetWindowText(_T("AC"));
		}
		else
		{
#ifdef _DEBUG
			m_btnACDC.SetWindowText(_T("Error"));
#endif
		}
	}
//Auto Manual
	if(m_DMM.m_DMMData.nType == DMM_OHM || m_DMM.m_DMMData.nType == DMM_VOLTAGE || ((m_DMM.m_DMMData.nType == DMM_CURRENT) && (m_DMM.m_DMMData.bAmA == DMM_MA)))
	{
		if(m_DMM.m_DMMData.nMode == DMM_AUTO)
		{
			m_btnAutoManual.SetWindowText(_T("Auto"));
		}
		else if(m_DMM.m_DMMData.nMode == DMM_MANUAL)
		{
			m_btnAutoManual.SetWindowText(_T("Manual"));
			
			if(m_DMM.m_DMMData.nType == DMM_VOLTAGE && m_DMM.m_DMMData.nDCAC == DMM_DC)
			{
				if(m_DMM.m_DMMData.nRange >= 0 && m_DMM.m_DMMData.nRange < MANUAL_V_DC_DIV_NUM)
					m_btnDIV.SetWindowText(g_strManualVDC[m_DMM.m_DMMData.nRange]);
			}
			else if(m_DMM.m_DMMData.nType == DMM_VOLTAGE && m_DMM.m_DMMData.nDCAC == DMM_AC)
			{
				if(m_DMM.m_DMMData.nRange >= 0 && m_DMM.m_DMMData.nRange < MANUAL_V_AC_DIV_NUM)
					m_btnDIV.SetWindowText(g_strManualVAC[m_DMM.m_DMMData.nRange]);
			}
			else if((m_DMM.m_DMMData.nType == DMM_CURRENT) && (m_DMM.m_DMMData.bAmA == DMM_MA))
			{
				if(m_DMM.m_DMMData.nRange >= 0 && m_DMM.m_DMMData.nRange < MANUAL_A_DIV_NUM)
					m_btnDIV.SetWindowText(g_strManualAMA[m_DMM.m_DMMData.nRange]);
			}
			else if(m_DMM.m_DMMData.nType == DMM_OHM)
			{
				if(m_DMM.m_DMMData.nRange >= 0 && m_DMM.m_DMMData.nRange < MANUAL_OHM_DIV_NUM)
					m_btnDIV.SetWindowText(g_strManualOHM[m_DMM.m_DMMData.nRange]);
			}
		}
	}
//A mA
	if(m_DMM.m_DMMData.nType == DMM_CURRENT)
	{
		if(m_DMM.m_DMMData.bAmA == DMM_A)
		{
			m_btnAmA.SetWindowText(_T("A"));
		}
		else
		{
			m_btnAmA.SetWindowText(_T("mA"));
		}
	}
}

void CMeterDlg::ShowCtrls()
{
//AC DC
	if(m_DMM.m_DMMData.nType == DMM_VOLTAGE || m_DMM.m_DMMData.nType == DMM_CURRENT)
	{
		m_btnACDC.ShowWindow(SW_SHOW);
	}
	else
	{
		m_btnACDC.ShowWindow(SW_HIDE);
	}

//Auto Manual
	if(m_DMM.m_DMMData.nType == DMM_OHM || m_DMM.m_DMMData.nType == DMM_VOLTAGE || ((m_DMM.m_DMMData.nType == DMM_CURRENT) && (m_DMM.m_DMMData.bAmA == DMM_MA)))
	{
		m_btnAutoManual.ShowWindow(SW_SHOW);
		//Manual Range
		if(m_DMM.m_DMMData.nMode == DMM_MANUAL)
		{
			m_btnDIV.ShowWindow(SW_SHOW);
		}
		else
		{
			m_btnDIV.ShowWindow(SW_HIDE);
		}
	}
	else
	{
		m_btnAutoManual.ShowWindow(SW_HIDE);
		//Manual Range
		m_btnDIV.ShowWindow(SW_HIDE);
	}

//Rel
	if(m_DMM.m_DMMData.nType == DMM_DIODE || m_DMM.m_DMMData.nType == DMM_CONTI)
	{
		m_btnRel.ShowWindow(SW_HIDE);
	}
	else
	{
		m_btnRel.ShowWindow(SW_SHOW);
	}
//A mA
	if(m_DMM.m_DMMData.nType == DMM_CURRENT)
	{
		m_btnAmA.ShowWindow(SW_SHOW);
	}
	else
	{
		m_btnAmA.ShowWindow(SW_HIDE);
	}

}

DWORD WINAPI CMeterDlg::DMMProc(LPVOID lParam)//
{
	CMeterDlg* pDlg = (CMeterDlg*)lParam;
	while(1)
	{
		pDlg->Run();
		Sleep(200);
	}
	return 1;
}

void CMeterDlg::Run()
{
	m_DMM.HDDevConnect();
	HTMSG msg = GetCmdMsg();
	while(msg.nType != MSG_NULL)
	{
		CmdMsgProc(msg);
		msg = GetCmdMsg();
	}
	GetDMMData();
}

void CMeterDlg::PushCmdMsg(HTMSG msg)
{
	ULONG i = 0;
	HTMSG msgT;
	deque <HTMSG>::iterator iterDoc;

	WaitForSingleObject(m_hEvent,INFINITE);
	ResetEvent(m_hEvent);

	for(iterDoc = m_msgDeque.begin(); iterDoc != m_msgDeque.end(); iterDoc++)
	{
		msgT = m_msgDeque.at(i);
		if(msgT.nType == msg.nType && msgT.nValue == msg.nValue)
		{
			m_msgDeque.erase(iterDoc);
			break;
		}
		i++;
	}
	m_msgDeque.push_back(msg);

	SetEvent(m_hEvent);
}

HTMSG CMeterDlg::GetCmdMsg()
{
	HTMSG msg;

	WaitForSingleObject(m_hEvent,INFINITE);
	ResetEvent(m_hEvent);
	if(m_msgDeque.empty())
	{
		msg.nType = MSG_NULL;
		msg.nValue = 0;
	}
	else
	{
		msg = m_msgDeque.front();
		m_msgDeque.pop_front();
	}
	SetEvent(m_hEvent);
	return msg;
}

void CMeterDlg::CmdMsgProc(HTMSG msg)
{
	char buf[20];
	if(msg.nType == MSG_SET_DMM_TYPE)
	{
		m_DMM.HDSetDMMType((short)msg.nValue);
		//ClearData();
	}
	else if(msg.nType == MSG_SET_DMM_ACDC)
	{
		if(m_DMM.m_DMMData.nType == DMM_VOLTAGE)
		{
			if(m_DMM.m_DMMData.nDCAC == DMM_DC)
			{
				m_DMM.HDSetVACAUTOV();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_AC)
			{
				m_DMM.HDSetVDCAUTOV();
				//ClearData();
			}
		}
		else if(m_DMM.m_DMMData.nType == DMM_CURRENT)
		{
			if(m_DMM.m_DMMData.nDCAC == DMM_DC)
			{
				if(m_DMM.m_DMMData.bAmA == DMM_MA)
				{
					m_DMM.HDSetAACAUTOMA();
				}
				else
				{
					m_DMM.HDSetAACA();
				}
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_AC)
			{
				if(m_DMM.m_DMMData.bAmA == DMM_MA)
				{
					m_DMM.HDSetADCAUTOMA();
				}
				else
				{
					m_DMM.HDSetADCA();
				}
				//ClearData();
			}
		}
	}
	else if(msg.nType == MSG_SET_DMM_AUTOMANUAL)
	{
		if(m_DMM.m_DMMData.nType == DMM_VOLTAGE)
		{
			if(m_DMM.m_DMMData.nDCAC == DMM_DC && m_DMM.m_DMMData.nMode == DMM_AUTO)
			{
				m_DMM.HDSetVDCManual60mV();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_DC && m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				m_DMM.HDSetVDCAUTOV();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_AC && m_DMM.m_DMMData.nMode == DMM_AUTO)
			{
				m_DMM.HDSetVACManual60mV();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_AC && m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				m_DMM.HDSetVACAUTOV();
				//ClearData();
			}
		}
		else if(m_DMM.m_DMMData.nType == DMM_CURRENT)
		{
			if(m_DMM.m_DMMData.bAmA == DMM_MA && m_DMM.m_DMMData.nDCAC == DMM_DC && m_DMM.m_DMMData.nMode == DMM_AUTO)
			{
				m_DMM.HDSetADCMAManual60mA();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.bAmA == DMM_MA && m_DMM.m_DMMData.nDCAC == DMM_DC && m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				m_DMM.HDSetADCAUTOMA();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.bAmA == DMM_MA && m_DMM.m_DMMData.nDCAC == DMM_AC && m_DMM.m_DMMData.nMode == DMM_AUTO)
			{
				m_DMM.HDSetAACMAManual60mA();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.bAmA == DMM_MA && m_DMM.m_DMMData.nDCAC == DMM_AC && m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				m_DMM.HDSetAACAUTOMA();
				//ClearData();
			}
		}
		else if(m_DMM.m_DMMData.nType == DMM_OHM)
		{
			if(m_DMM.m_DMMData.nMode == DMM_AUTO)
			{
				m_DMM.HDSetOHMManual();
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				m_DMM.HDSetOHMAUTO();
				//ClearData();
			}
		}
	}
	else if(msg.nType == MSG_SET_DMM_REL)
	{
		if(m_DMM.m_DMMData.bRel == 1)
		{
			m_DMM.HDExitRel();
			//ClearData();
		}
		else if(m_DMM.m_DMMData.bRel == 0)
		{
			m_DMM.HDSetRel();
			//ClearData();
		}
	}
	else if(msg.nType == MSG_SET_DMM_DIV)
	{
		short nDIV = m_DMM.m_DMMData.nRange;
		if(m_DMM.m_DMMData.nType == DMM_VOLTAGE)
		{
			if(m_DMM.m_DMMData.nDCAC == DMM_DC && m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				nDIV++;
				if(nDIV > MANUAL_DC_800V)
					nDIV = MANUAL_DC_60MV;
				m_DMM.HDSetVDCManualDIV(nDIV);
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_AC && m_DMM.m_DMMData.nMode == DMM_MANUAL)
			{
				nDIV++;
				if(nDIV > MANUAL_AC_600V)
					nDIV = MANUAL_AC_60MV;
				m_DMM.HDSetVACManualDIV(nDIV);
				//ClearData();
			}			
		}
		else if(m_DMM.m_DMMData.nType == DMM_CURRENT)
		{
			nDIV++;
			if(nDIV > MANUAL_600MA)
				nDIV = MANUAL_60MA;
			if(m_DMM.m_DMMData.nDCAC == DMM_DC && m_DMM.m_DMMData.bAmA == DMM_MA)
			{
				m_DMM.HDSetADCManualDIV(nDIV);
				//ClearData();
			}
			else if(m_DMM.m_DMMData.nDCAC == DMM_AC && m_DMM.m_DMMData.bAmA == DMM_MA)
			{
				m_DMM.HDSetAACManualDIV(nDIV);
				//ClearData();
			}
		}
		else if(m_DMM.m_DMMData.nType == DMM_OHM)
		{
			nDIV++;
			if(nDIV > MANUAL_60M)
				nDIV = MANUAL_600;
			m_DMM.HDSetOHMDIV(nDIV);
			//ClearData();
		}
	}
	else if(msg.nType == MSG_SET_DMM_AMA)
	{
		if(m_DMM.m_DMMData.nType == DMM_CURRENT)
		{
			if(m_DMM.m_DMMData.bAmA == DMM_A)
			{
				if(m_DMM.m_DMMData.nDCAC == DMM_DC)
				{
					m_DMM.HDSetADCAUTOMA();
					//ClearData();
				}
				else if(m_DMM.m_DMMData.nDCAC == DMM_AC)
				{
					m_DMM.HDSetAACAUTOMA();
					//ClearData();
				}
				else
				{
#ifdef _DEBUG
					AfxMessageBox(_T("MSG_SET_DMM_AMA : Error...1"));
#endif
				}
			}
			else if(m_DMM.m_DMMData.bAmA == DMM_MA)
			{
				if(m_DMM.m_DMMData.nDCAC == DMM_DC)
				{
					m_DMM.HDSetADCA();
					//ClearData();
				}
				else if(m_DMM.m_DMMData.nDCAC == DMM_AC)
				{
					m_DMM.HDSetAACA();
					//ClearData();
				}
				else
				{
#ifdef _DEBUG
					AfxMessageBox(_T("MSG_SET_DMM_AMA : Error...2"));
#endif
				}
			}
			else
			{
#ifdef _DEBUG
				AfxMessageBox(_T("MSG_SET_DMM_AMA : Error...3"));
#endif
			}
		}
	}
	else if(msg.nType == MSG_CLEAR_DATA)
	{
		ClearData();
	}
	else if(msg.nType == MSG_SAVE_DATA)
	{
		SaveData();
	}
	else if(msg.nType == MSG_SET_WRITEFILE)
	{
		if(m_bWriteData==TRUE && m_strWriteFileName != L""){
			_itoa_s(m_lastid,buf,10,10);
			m_stcFilename.SetWindowText(L"Saving data to "+m_strWriteFileName+L" "+buf);
		}
		else {
			m_stcFilename.SetWindowText(L"");
		}
	}
	else if(msg.nType == MSG_RUN_STOP)
	{
		m_DMM.m_bRun ^= TRUE;
		if(m_DMM.m_bRun)
		{
			m_rdoUSB.EnableWindow(FALSE);
			m_rdoCOM.EnableWindow(FALSE);
			m_stcCOMPort.EnableWindow(FALSE);
			m_cboCOMPort.EnableWindow(FALSE);
			m_btnConnect.EnableWindow(FALSE);
			//ClearData();
		}
		else
		{
			m_rdoUSB.EnableWindow();
			m_rdoCOM.EnableWindow();
			m_stcCOMPort.EnableWindow();
			m_cboCOMPort.EnableWindow();
			m_btnConnect.EnableWindow();
		}
	}
	else if(msg.nType == MSG_SET_INTERVAL)
	{
		m_DMM.m_nInterval = msg.nValue;
		//ClearData();
	}
	else if(msg.nType == MSG_SET_COMM_TYPE)
	{
		if(m_DMM.m_nCommType == COMM_COM && m_bComConnect)
		{
			m_DMM.HDCloseCOM();
			m_bComConnect = FALSE;
			m_btnConnect.SetWindowText(_T("Open"));
		}
		m_DMM.m_nCommType = msg.nValue;
	}
	else if(msg.nType == MSG_SET_COM_PORT)
	{
		m_DMM.m_nCOMPort = msg.nValue;
	}
	else if(msg.nType == MSG_SET_COM)
	{
		if(m_DMM.m_nCommType == COMM_COM)
		{
			if(!m_bComConnect)
			{
				if(!m_DMM.HDOpenCOM())
				{
					m_bComConnect = FALSE;
					m_btnConnect.SetWindowText(_T("Open"));
					AfxMessageBox(_T("Can not open COM!"));
				}
				else
				{
					m_bComConnect = TRUE;
					m_btnConnect.SetWindowText(_T("Close"));
					if(!m_DMM.m_bRun)
					{
						HTMSG msg;
						msg.nType = MSG_RUN_STOP;
						PushCmdMsg(msg);
					}
				}
			}
			else
			{
				m_DMM.HDCloseCOM();
				m_bComConnect = FALSE;
				m_btnConnect.SetWindowText(_T("Open"));
			}
		}
	}
	else
	{
	}
}


void CMeterDlg::UserExitThread()//
{
	SuspendThread(m_hThreadProc);
	//
	TerminateThread(m_hThreadProc,0);
	//
	CloseHandle(m_hThreadProc);
	//
	CloseHandle(m_hEvent);
}

void CMeterDlg::OnDestroy()
{
	CString str;
	m_from.GetWindowTextW(str);
	AfxGetApp()->WriteProfileString(_T("Alarm"),_T("min"),str);
	m_to.GetWindowTextW(str);
	AfxGetApp()->WriteProfileString(_T("Alarm"),_T("max"),str);
	m_editWavFile.GetWindowTextW(str);
	AfxGetApp()->WriteProfileString(_T("Alarm"),_T("sound"),str);
	m_editCommand.GetWindowTextW(str);
	AfxGetApp()->WriteProfileString(_T("Alarm"),_T("command"),str);
	m_editDelay.GetWindowTextW(str);
	AfxGetApp()->WriteProfileString(_T("Alarm"),_T("delay"),str);
	if(m_checkRepeat.GetCheck())
	{
		AfxGetApp()->WriteProfileInt(_T("Alarm"),_T("loop"),1);
	}
	else 
	{
		AfxGetApp()->WriteProfileInt(_T("Alarm"),_T("loop"),0);
	}
	CDialogEx::OnDestroy();
	UserExitThread();
}

void CMeterDlg::ClearData()
{
	m_DMM.ClearDataDeque();
	m_listData.DeleteAllItems();
}

void CMeterDlg::SaveData()
{
	CStdioFile file;
	CFileException ex;	
	CString str;
	CString strFileName = m_DMM.m_strSaveFileName;

	if(!file.Open(strFileName,CFile::modeWrite | CFile::modeCreate,&ex))
	{
		return;
	}
	for(int i=0;i<m_listData.GetItemCount();i++){
		str.Format(_T("%s	--	%s\n"),m_listData.GetItemText(i,1),m_listData.GetItemText(i,2));
		file.WriteString(str);
	}

	file.Close();
}

void CMeterDlg::SetDMMType(short nType)
{
	HTMSG msg;
	msg.nType = MSG_SET_DMM_TYPE;
	msg.nValue = nType;
	PushCmdMsg(msg);
}

void CMeterDlg::SetDMMACDC()
{
	HTMSG msg;
	msg.nType = MSG_SET_DMM_ACDC;
	PushCmdMsg(msg);
}

void CMeterDlg::SetDMMAutoManual()
{
	HTMSG msg;
	msg.nType = MSG_SET_DMM_AUTOMANUAL;
	PushCmdMsg(msg);
}

void CMeterDlg::SetDMMRel()
{
	HTMSG msg;
	msg.nType = MSG_SET_DMM_REL;
	PushCmdMsg(msg);
}

void CMeterDlg::SetDMMDIV()
{
	HTMSG msg;
	msg.nType = MSG_SET_DMM_DIV;
	PushCmdMsg(msg);
}

void CMeterDlg::SetDMMAmA()
{
	HTMSG msg;
	msg.nType = MSG_SET_DMM_AMA;
	PushCmdMsg(msg);
}


void CMeterDlg::OnBnClickedBtnV()
{
	SetDMMType(DMM_VOLTAGE);
}


void CMeterDlg::OnBnClickedBtnA()
{
	SetDMMType(DMM_CURRENT);
}


void CMeterDlg::OnBnClickedBtnOhm()
{
	SetDMMType(DMM_OHM);
}


void CMeterDlg::OnBnClickedBtnCap()
{
	SetDMMType(DMM_CAP);
}


void CMeterDlg::OnBnClickedBtnDiode()
{
	SetDMMType(DMM_DIODE);
}


void CMeterDlg::OnBnClickedBtnConti()
{
	SetDMMType(DMM_CONTI);
}


void CMeterDlg::OnBnClickedBtnAcdc()
{
	SetDMMACDC();
}


void CMeterDlg::OnBnClickedBtnAutomanual()
{
	SetDMMAutoManual();
}


void CMeterDlg::OnBnClickedBtnRel()
{
	SetDMMRel();
}

void CMeterDlg::OnBnClickedBtnAma()
{
	SetDMMAmA();
}


void CMeterDlg::OnBnClickedBtnDiv()
{
	SetDMMDIV();
}


void CMeterDlg::OnBnClickedBtnClear()
{
	HTMSG msg;
	msg.nType = MSG_CLEAR_DATA;
	PushCmdMsg(msg);
}


void CMeterDlg::OnBnClickedBtnSave()
{
	CFileDialog dlgSave(FALSE,_T(".txt"),NULL,OFN_OVERWRITEPROMPT,_T("Text File(*.txt)|*.txt||"));
	dlgSave.m_ofn.lpstrTitle=_T("Save data to file...");

	if(IDOK==dlgSave.DoModal())
	{
		m_DMM.m_strSaveFileName=dlgSave.GetPathName();
		HTMSG msg;
		msg.nType = MSG_SAVE_DATA;
		PushCmdMsg(msg);
	}
}


void CMeterDlg::OnBnClickedBtnRun()
{
	HTMSG msg;
	msg.nType = MSG_RUN_STOP;
	PlaySound(NULL, NULL, SND_APPLICATION);
	PushCmdMsg(msg);
}


void CMeterDlg::OnCbnSelchangeCboInterval()
{
	HTMSG msg;
	msg.nType = MSG_SET_INTERVAL;
	msg.nValue = m_cboInterval.GetCurSel();
	PushCmdMsg(msg);
}


void CMeterDlg::OnBnClickedBtnHelp()
{
	CString appPath,strPath,strName;
	int at;
	TCHAR tempPath[_MAX_PATH];
	::GetModuleFileName(NULL,tempPath,_MAX_PATH);
	appPath=tempPath;
	at=appPath.ReverseFind('\\');
	appPath=appPath.Left(at);
	strName = _T("English");
	strPath.Format(_T("%s\\Help-%s.chm"), appPath,strName);
	ShellExecute(NULL, _T("open"), strPath, NULL, NULL, SW_SHOWNORMAL);
}



void CMeterDlg::OnBnClickedRadioUsb()
{
	m_cboCOMPort.ShowWindow(SW_HIDE);
	m_stcCOMPort.ShowWindow(SW_HIDE);
	m_btnConnect.ShowWindow(SW_HIDE);
	HTMSG msg;
	msg.nType = MSG_SET_COMM_TYPE;
	msg.nValue = COMM_USB;
	PushCmdMsg(msg);
}


void CMeterDlg::OnBnClickedRadioCom()
{
	m_cboCOMPort.ShowWindow(SW_SHOW);
	m_stcCOMPort.ShowWindow(SW_SHOW);
	m_btnConnect.ShowWindow(SW_SHOW);
	HTMSG msg;
	msg.nType = MSG_SET_COMM_TYPE;
	msg.nValue = COMM_COM;
	PushCmdMsg(msg);
}

void CMeterDlg::OnCbnSelchangeCboComport()
{
	HTMSG msg;
	msg.nType = MSG_SET_COM_PORT;
	msg.nValue = m_cboCOMPort.GetCurSel();
	PushCmdMsg(msg);
	
}


void CMeterDlg::OnBnClickedBtnConnect()
{
	HTMSG msg;
	msg.nType = MSG_SET_COM;
	PushCmdMsg(msg);
}


void CMeterDlg::OnBnClickedBtnSave3()
{
	CFileDialog dlgSave(FALSE,_T(".csv"),NULL,OFN_CREATEPROMPT|OFN_PATHMUSTEXIST,_T("CSV File(*.csv)|*.csv||"));
	dlgSave.m_ofn.lpstrTitle=_T("Continuously write to file...");

	if(IDOK==dlgSave.DoModal())
	{
		m_strWriteFileName=dlgSave.GetPathName();
		HTMSG msg;
		msg.nType = MSG_SET_WRITEFILE;
		msg.nValue = m_cboCOMPort.GetCurSel();
		PushCmdMsg(msg);		
	}
}


void CMeterDlg::OnBnClickedCheck1()
{
	CButton *m_ctlCheck = (CButton*) GetDlgItem(IDC_CHECK1);
	int ChkBox = m_ctlCheck->GetCheck();
	if(ChkBox==BST_CHECKED){
		m_bWriteData=TRUE;
		HTMSG msg;
		msg.nType = MSG_SET_WRITEFILE;
		msg.nValue = m_cboCOMPort.GetCurSel();
		PushCmdMsg(msg);			
	}
	else {
		m_bWriteData=FALSE;
		HTMSG msg;
		msg.nType = MSG_SET_WRITEFILE;
		msg.nValue = m_cboCOMPort.GetCurSel();
		PushCmdMsg(msg);	
	}
}


void CMeterDlg::OnLvnItemchangedListData(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	*pResult = 0;
}



void CMeterDlg::OnBnClickedButton1()
{
	m_matches=0;
	m_tLastMatch=0;
	m_stcMatchCounter.SetWindowText(_T(""));
	PlaySound(NULL, NULL, SND_APPLICATION);
}




void CMeterDlg::OnBnClickedButton2()
{
	CFileDialog dlgLoad(FALSE,_T(".*"),NULL,OFN_PATHMUSTEXIST,_T("File(*.*)|*.*||"));
	dlgLoad.m_ofn.lpstrTitle=_T("Choose file to run on alarm");

	if(IDOK==dlgLoad.DoModal())
	{
		m_editCommand.SetWindowTextW(dlgLoad.GetPathName());
	}
}


void CMeterDlg::OnBnClickedButton3()
{
	CFileDialog dlgLoad(FALSE,_T(".wav"),NULL,OFN_PATHMUSTEXIST,_T("WAV File(*.wav)|*.wav||"));
	dlgLoad.m_ofn.lpstrTitle=_T("Choose wav file to play on alarm");

	if(IDOK==dlgLoad.DoModal())
	{
		m_editWavFile.SetWindowTextW(dlgLoad.GetPathName());
	}
}

void CMeterDlg::OnOk()
{
}

BOOL CMeterDlg::PreTranslateMessage(MSG* pMsg)
{
    if( pMsg->message == WM_KEYDOWN )
    {
        if(pMsg->wParam == VK_ESCAPE)
        {
            return TRUE;                // Do not process further
        }
    }

    return CWnd::PreTranslateMessage(pMsg);
}

void CMeterDlg::OnBnClickedCheckrep()
{
	PlaySound(NULL, NULL, SND_APPLICATION);
}
