// DO16Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "DO16.h"
#include "DO16Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

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

/////////////////////////////////////////////////////////////////////////////
// CDO16Dlg dialog

CDO16Dlg::CDO16Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDO16Dlg::IDD, pParent)
	, m_strCom(_T(""))
	, m_txthelp(_T(""))
	, m_debug(FALSE)
	, m_BaseAddr(0)
{
	//{{AFX_DATA_INIT(CDO16Dlg)
	m_BaudRate = _T("38400");
	m_addr = 254;
	m_BaseAddr = 0;
	m_selectmode = -1;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_LOGO);
}

void CDO16Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDO16Dlg)
	DDX_Control(pDX, IDC_ICO_DI10, m_ICO_DI10);
	DDX_Control(pDX, IDC_ICO_DI9, m_ICO_DI9);
	DDX_Control(pDX, IDC_ICO_DI8, m_ICO_DI8);
	DDX_Control(pDX, IDC_ICO_DI7, m_ICO_DI7);
	DDX_Control(pDX, IDC_ICO_DI6, m_ICO_DI6);
	DDX_Control(pDX, IDC_ICO_DI5, m_ICO_DI5);
	DDX_Control(pDX, IDC_ICO_DI4, m_ICO_DI4);
	DDX_Control(pDX, IDC_ICO_DI3, m_ICO_DI3);
	DDX_Control(pDX, IDC_ICO_DI2, m_ICO_DI2);
	DDX_Control(pDX, IDC_ICO_DI16, m_ICO_DI16);
	DDX_Control(pDX, IDC_ICO_DI15, m_ICO_DI15);
	DDX_Control(pDX, IDC_ICO_DI14, m_ICO_DI14);
	DDX_Control(pDX, IDC_ICO_DI13, m_ICO_DI13);
	DDX_Control(pDX, IDC_ICO_DI12, m_ICO_DI12);
	DDX_Control(pDX, IDC_ICO_DI11, m_ICO_DI11);
	DDX_Control(pDX, IDC_ICO_DI1, m_ICO_DI1);
	DDX_Control(pDX, IDC_ICO_JD9, m_ICO_JD9);
	DDX_Control(pDX, IDC_ICO_JD8, m_ICO_JD8);
	DDX_Control(pDX, IDC_ICO_JD7, m_ICO_JD7);
	DDX_Control(pDX, IDC_ICO_JD6, m_ICO_JD6);
	DDX_Control(pDX, IDC_ICO_JD5, m_ICO_JD5);
	DDX_Control(pDX, IDC_ICO_JD4, m_ICO_JD4);
	DDX_Control(pDX, IDC_ICO_JD3, m_ICO_JD3);
	DDX_Control(pDX, IDC_ICO_JD2, m_ICO_JD2);
	DDX_Control(pDX, IDC_ICO_JD1, m_ICO_JD1);
	DDX_Control(pDX, IDC_ICO_JD16, m_ICO_JD16);
	DDX_Control(pDX, IDC_ICO_JD15, m_ICO_JD15);
	DDX_Control(pDX, IDC_ICO_JD14, m_ICO_JD14);
	DDX_Control(pDX, IDC_ICO_JD13, m_ICO_JD13);
	DDX_Control(pDX, IDC_ICO_JD12, m_ICO_JD12);
	DDX_Control(pDX, IDC_ICO_JD11, m_ICO_JD11);
	DDX_Control(pDX, IDC_ICO_JD10, m_ICO_JD10);
	DDX_Control(pDX, IDC_BMP_STATUS, m_bmpStatus);
	DDX_Control(pDX, IDC_COMBO_COMPORT, m_ctrcomport);
	DDX_CBString(pDX, IDC_COMBO_BAUDRATE, m_BaudRate);
	DDX_Text(pDX, IDC_EDIT_ADDR, m_addr);
	//  DDX_CBString(pDX, IDC_COMBO_EQUIPTYPE, m_EquipType);
	//}}AFX_DATA_MAP
	//  DDX_CBIndex(pDX, IDC_COMBO_BAUDRATE232, m_baud232);
	//  DDX_CBIndex(pDX, IDC_COMBO_BAUDRATE485, m_baud485);
	DDX_Control(pDX, IDC_ICO_DI17, m_ICO_DI17);
	DDX_Control(pDX, IDC_ICO_DI18, m_ICO_DI18);
	DDX_Control(pDX, IDC_ICO_DI19, m_ICO_DI19);
	DDX_Control(pDX, IDC_ICO_DI20, m_ICO_DI20);
	DDX_Control(pDX, IDC_LIST3, m_ctrllist);
	DDX_Control(pDX, IDC_COMBO_EQUIPTYPE, m_CtlEquipType);
	DDX_CBString(pDX, IDC_COMBO_COMPORT, m_strCom);
	DDX_Text(pDX, IDC_STATIC_HELP, m_txthelp);
	DDX_Check(pDX, IDC_CHECK1, m_debug);
	DDX_Control(pDX, IDC_EDIT1, m_ctledit);
	DDX_Text(pDX, IDC_EDIT_BASEAddr, m_BaseAddr);
}

BEGIN_MESSAGE_MAP(CDO16Dlg, CDialog)
	//{{AFX_MSG_MAP(CDO16Dlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_OPEN, OnBtnOpen)
	ON_BN_CLICKED(IDC_BTN_JD1, OnBtnJd1)
	ON_BN_CLICKED(IDC_BTN_JD2, OnBtnJd2)
	ON_BN_CLICKED(IDC_BTN_JD3, OnBtnJd3)
	ON_BN_CLICKED(IDC_BTN_JD4, OnBtnJd4)
	ON_BN_CLICKED(IDC_BTN_JD5, OnBtnJd5)
	ON_BN_CLICKED(IDC_BTN_JD6, OnBtnJd6)
	ON_BN_CLICKED(IDC_BTN_JD7, OnBtnJd7)
	ON_BN_CLICKED(IDC_BTN_JD8, OnBtnJd8)
	ON_BN_CLICKED(IDC_BTN_JD9, OnBtnJd9)
	ON_BN_CLICKED(IDC_BTN_JD10, OnBtnJd10)
	ON_BN_CLICKED(IDC_BTN_JD11, OnBtnJd11)
	ON_BN_CLICKED(IDC_BTN_JD12, OnBtnJd12)
	ON_BN_CLICKED(IDC_BTN_JD13, OnBtnJd13)
	ON_BN_CLICKED(IDC_BTN_JD14, OnBtnJd14)
	ON_BN_CLICKED(IDC_BTN_JD15, OnBtnJd15)
	ON_BN_CLICKED(IDC_BTN_JD16, OnBtnJd16)
	ON_BN_CLICKED(IDC_BTN_OPENALL, OnBtnOpenall)
	ON_BN_CLICKED(IDC_BTN_CLOSEALL, OnBtnCloseall)
	ON_WM_TIMER()
	ON_EN_CHANGE(IDC_EDIT_ADDR, OnChangeEditAddr)
	ON_CBN_SELCHANGE(IDC_COMBO_EQUIPTYPE, OnSelchangeComboEquiptype)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BTN_SetBaud, &CDO16Dlg::OnBnClickedBtnSetbaud)
	ON_BN_CLICKED(IDC_BTN_ReadBaud, &CDO16Dlg::OnBnClickedBtnReadbaud)
	ON_BN_CLICKED(IDC_BTN_OPENALL2, &CDO16Dlg::OnBnClickedBtnOpenall2)
	ON_BN_CLICKED(IDC_BTN_OPENALL4, &CDO16Dlg::OnBnClickedBtnOpenall4)
	ON_BN_CLICKED(IDC_BTN_OPENALL3, &CDO16Dlg::OnBnClickedBtnOpenall3)
	ON_CBN_SELCHANGE(IDC_COMBO_BAUDRATE232, &CDO16Dlg::OnCbnSelchangeComboBaudrate232)
	ON_CBN_SELCHANGE(IDC_COMBO_BAUDRATE485, &CDO16Dlg::OnCbnSelchangeComboBaudrate485)
	ON_BN_CLICKED(IDC_CHECK1, &CDO16Dlg::OnBnClickedCheck1)
	ON_BN_CLICKED(IDC_BTN_SetBaud2, &CDO16Dlg::OnBnClickedBtnSetbaud2)
	ON_BN_CLICKED(IDC_BTN_ReadBaseAddr, &CDO16Dlg::OnBnClickedBtnReadbaseaddr)
	ON_BN_CLICKED(IDC_BTN_WriteBaseAddr, &CDO16Dlg::OnBnClickedBtnWritebaseaddr)
	ON_BN_CLICKED(IDC_BTN_ReadAddr, &CDO16Dlg::OnBnClickedBtnReadaddr)
	ON_EN_CHANGE(IDC_EDIT_BASEAddr, &CDO16Dlg::OnEnChangeEditBaseaddr)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDO16Dlg message handlers

BOOL CDO16Dlg::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

	//------xml 配置
	try
	{
		CXMLApp::init();
		if (CXMLApp::ReadXmlFile() == false)
			CXMLApp::CreateXmlFile();
		if (CXMLApp::ReadXmlFile2() == false)
			CXMLApp::CreateXmlFile2();
		if (CXMLApp::ReadXmlFile3() == false)
			CXMLApp::CreateXmlFile3();
	}
	catch (char*)
	{
	}
	//---初始化参数


	//------添加列表框
	DWORD dwStyle = m_ctrllist.GetExtendedStyle();                    //添加列表框的网格线！！！

	dwStyle |= LVS_EX_FULLROWSELECT;
	dwStyle |= LVS_EX_GRIDLINES;
	m_ctrllist.SetExtendedStyle(dwStyle);

	m_ctrllist.InsertColumn(0, _T("通道"), LVCFMT_LEFT, 20);
	m_ctrllist.InsertColumn(1, _T("模拟量"), LVCFMT_LEFT, 50);              //添加列标题！！！！  这里的80,40,90用以设置列的宽度。！！！LVCFMT_LEFT用来设置对齐方式！！！
	m_ctrllist.InsertColumn(2, _T("数值"), LVCFMT_LEFT, 80);
	m_ctrllist.InsertColumn(3, _T("单位"), LVCFMT_LEFT, 80);

	CString temp;
	m_ctrllist.DeleteAllItems();
	for (int i = 0; i < EQUIP_AI_NUM; i++)
	{
		if (cai[i].IsValid)
		{
			temp.Format(_T("%d"), i + 1);
			int nRow = m_ctrllist.InsertItem(i, temp);
			m_ctrllist.SetItemText(i, 1, cai[i].name);
			temp.Format(_T("%f"), Comm_.InputStatus[i] * cai[i].a + cai[i].b);
			m_ctrllist.SetItemText(i, 2, temp);
			m_ctrllist.SetItemText(i, 3, cai[i].unit);
		}
	}
	//-------------载入图标--------------------
	hIcons[0] = AfxGetApp()->LoadIcon(IDI_ICON_CLOSED);//串口关   
	hIcons[1] = AfxGetApp()->LoadIcon(IDI_ICON_OPENED);//串口开   
	hIcons[2] = AfxGetApp()->LoadIcon(IDI_ICON_JDOFF);//继电器断开  
	hIcons[3] = AfxGetApp()->LoadIcon(IDI_ICON_JDON);//继电器闭合
	hIcons[4] = AfxGetApp()->LoadIcon(IDI_ICON_BTNOFF);//继电器闭合
	hIcons[5] = AfxGetApp()->LoadIcon(IDI_ICON_BTNON);//继电器闭合




	SetTimer(1, 100, NULL);  //设置定时器	
	//------------初始化串口-----

	initCommPort();

	//--------------------初始化设备列表
	m_CtlEquipType.Clear();
	for (int i = 0; i < EQUIP_MAX_NUM; i++)
	{
		if (equip[i].IsValid == 1)
		{
			m_CtlEquipType.AddString(equip[i].name);
		}
	}
	//m_CtlEquipType.SetWindowTextW(cset.EquipName);

	m_BaudRate = cset.baud;
	m_addr = _ttoi(cset.addr);
	m_strCom = cset.comname;


	for (int i = 0; i < EQUIP_MAX_NUM; i++)
	{
		if (cset.EquipName == equip[i].name)
		{

			Comm_.DO_CNT = equip[i].donum;
			Comm_.DI_CNT = equip[i].dinum;
			Comm_.AI_CNT = equip[i].ainum;
			m_txthelp.Format(_T("【%s】:【继电器  %d】【光耦 %d】【模拟量 %d】"), cset.EquipName, Comm_.DO_CNT, Comm_.DI_CNT, Comm_.AI_CNT);
		}
	}
	int n = m_CtlEquipType.FindString(0, cset.EquipName);
	m_CtlEquipType.SetCurSel(n);

	//------------修改继电器信息
	ShowDO();
	ShowDI();
	ShowAI();


	//----------------帮助信息

	ShowDebugText(_T("\r\n          modbus采集控制卡测试软件          \r\n\r\n "));
	ShowDebugText(_T("\r\n【增加设备型号】 修改  设备表.xml.xml\r\n"));
	ShowDebugText(_T("\r\n【模拟量 单位、线性转换、名称】 修改 参数单位.xml\r\n"));
	ShowDebugText(_T("\r\n【继电器 名称】 修改  设备表.xml.xml\r\n"));
	ShowDebugText(_T("\r\n【光耦 名称】 修改  设备表.xml.xml\r\n"));

	UpdateData(FALSE);

	//-------------初始化状态栏-------------------------	

	CRect Rect;
	this->GetClientRect(&Rect);                  //获取客户区域

	int strPartDim[3];
	strPartDim[0] = (int)(Rect.Width()*0.50);
	strPartDim[1] = (int)(Rect.Width()*0.85);
	strPartDim[2] = (int)(Rect.Width());

	m_StatusBar.Create(WS_CHILD | WS_VISIBLE | SBT_OWNERDRAW, CRect(0, 0, 0, 0), this, 0);
	m_StatusBar.SetParts(3, strPartDim);

	//设置状态栏文本内容
	m_StatusBar.SetText(CommpanyName, 1, 0);

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

void CDO16Dlg::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 CDO16Dlg::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();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDO16Dlg::OnQueryDragIcon()
{
	return (HCURSOR)m_hIcon;
}


bool CDO16Dlg::OpenComm(u8 mbaddr)
{
	UpdateData();
	CString strbaud[] = { m_BaudRate, "9600", "2400", "4800", "9600", "19200", "38400", "115200" };

	if (Comm_.IsOpen())
	{
		Comm_.CloseCom();
		//更新设备地址
		GetDlgItem(IDC_COMBO_COMPORT)->EnableWindow(TRUE);
		GetDlgItem(IDC_COMBO_BAUDRATE)->EnableWindow(TRUE);
		SendDlgItemMessage(IDC_BTN_OPEN, WM_SETTEXT, 0, (LPARAM)_T("打开串口"));//
		m_bmpStatus.SetIcon(hIcons[0]);//修改图标为关闭串口图标

		KillTimer(2);
		UpdateData(FALSE);
		Invalidate();
		return true;
	}
	if (m_ctrcomport.GetCurSel() == -1)
	{
		MessageBox(_T("没有选择串口"), _T("提示"), MB_ICONWARNING | MB_OK);
		m_StatusBar.SetText(_T("没有选择串口"), 0, 0);
		return true;
	}
	CString strText;
	m_ctrcomport.GetLBText(m_ctrcomport.GetCurSel(), strText);
	int comportid = _ttoi(strText.Right(strText.GetLength() - 3));

	if (!Comm_.Open(comportid))
	{
		TCHAR szBuf[1024];
		wsprintf(szBuf, _T("打开 COM%d 失败, 错误代码:%d"), comportid, GetLastError());
		m_StatusBar.SetText(szBuf, 0, 0);
		MessageBox(szBuf);
		return true;
	}
	else
	{
		strbaud[0] = m_BaudRate;

		for (int i = 0; i < 8; i++)
		{
			CString straddr;
			straddr.Format(_T("%d"), mbaddr);
			m_StatusBar.SetText(_T("【测试波特率】：") + strbaud[i] + _T("  【测试地址】") + straddr, 0, 0);
			Comm_.comport = comportid;

			char baud[120];
#ifdef UNICODE
			baud[wcstombs(baud, (LPCTSTR)strbaud[i], m_BaudRate.GetLength())] = 0;
#else
			strcpy(baud, (LPCTSTR)strbaud[i]);
#endif

			Comm_.comsetinfo[0] = atoi(baud);

			Comm_.SetComState(1);
					

			Comm_.RstThread = 1;
			Comm_.equipaddr = mbaddr;

			if (Comm_.OpertorRAddr())
			{
				m_BaudRate = strbaud[i];
				m_addr = (Comm_.InputStatus[0] == 0) ? 254 : Comm_.InputStatus[0];

				TCHAR szBuf[1024];
				wsprintf(szBuf, _T("联机成功，当前波特率:%s,当前地址:%d"), strbaud[i], m_addr);
				m_StatusBar.SetText(szBuf, 0, 0);

				CString   EditText;
				GetDlgItemText(IDC_COMBO_EQUIPTYPE, EditText);

				GetDlgItem(IDC_COMBO_COMPORT)->EnableWindow(FALSE);
				GetDlgItem(IDC_COMBO_BAUDRATE)->EnableWindow(FALSE);
				SendDlgItemMessage(IDC_BTN_OPEN, WM_SETTEXT, 0, (LPARAM)_T("关闭串口"));
				m_bmpStatus.SetIcon(hIcons[1]);//修改图标为打开串口图标

				cset.EquipName = EditText;
				cset.baud = m_BaudRate;
				cset.addr.Format(_T("%d"), m_addr);
				cset.comname = m_strCom;
				CXMLApp::CreateXmlFile3();

				UpdateData(FALSE);
				Invalidate();
				return true;
			}
		}
		Comm_.CloseCom();
		m_StatusBar.SetText(_T("联机失败"), 0, 0);
		return false;
	}
	return false;
}
void CDO16Dlg::OnBtnOpen()
{
	// TODO: Add your control notification handler code here
	UpdateData();
	if (OpenComm(m_addr) == true){}
	else if (OpenComm(0xfe) == true)
	{

	}
	else
	{
		MessageBox(_T("联机失败，检查硬件电路"));
	}
}


void CDO16Dlg::initCommPort()
{
	CString serial[256];
	int Comnum = methord::FindCommPort(serial);
	//将用注册表搜索到的串口设备依次加入
	for (int i = 0; i<Comnum; i++)
	{
		m_ctrcomport.InsertString(i, serial[i]);
	}
	if (Comnum)
	{
		m_ctrcomport.SetCurSel(0);
	}
}

void CDO16Dlg::ShowINfo(CString info)
{
	//m_StatusBar.SetText(info, 0, 0);
}

void CDO16Dlg::OnBtnJd1()
{
	// TODO: Add your control notification handler code here
	DealButton(1);
}

void CDO16Dlg::OnBtnJd2()
{
	// TODO: Add your control notification handler code here
	DealButton(2);
}

void CDO16Dlg::OnBtnJd3()
{
	// TODO: Add your control notification handler code here
	DealButton(3);
}

void CDO16Dlg::OnBtnJd4()
{
	// TODO: Add your control notification handler code here
	DealButton(4);
}

void CDO16Dlg::OnBtnJd5()
{
	// TODO: Add your control notification handler code here
	DealButton(5);
}

void CDO16Dlg::OnBtnJd6()
{
	// TODO: Add your control notification handler code here
	DealButton(6);
}

void CDO16Dlg::OnBtnJd7()
{
	// TODO: Add your control notification handler code here
	DealButton(7);
}

void CDO16Dlg::OnBtnJd8()
{
	// TODO: Add your control notification handler code here
	DealButton(8);
}

void CDO16Dlg::OnBtnJd9()
{
	// TODO: Add your control notification handler code here
	DealButton(9);
}

void CDO16Dlg::OnBtnJd10()
{
	// TODO: Add your control notification handler code here
	DealButton(10);
}

void CDO16Dlg::OnBtnJd11()
{
	// TODO: Add your control notification handler code here
	DealButton(11);
}

void CDO16Dlg::OnBtnJd12()
{
	// TODO: Add your control notification handler code here
	DealButton(12);
}

void CDO16Dlg::OnBtnJd13()
{
	// TODO: Add your control notification handler code here
	DealButton(13);
}

void CDO16Dlg::OnBtnJd14()
{
	// TODO: Add your control notification handler code here
	DealButton(14);
}

void CDO16Dlg::OnBtnJd15()
{
	// TODO: Add your control notification handler code here
	DealButton(15);
}

void CDO16Dlg::OnBtnJd16()
{
	// TODO: Add your control notification handler code here
	DealButton(16);
}


void CDO16Dlg::DealButton(int btnindex)
{
	UpdateData();
	int mode = m_selectmode;
	bool onoff;


	if ((btnindex >= 1) && (btnindex <= 16))
	{
		btnindex = btnindex - 1;
		onoff = (Comm_.DOStatus[btnindex] & 0x01) ? FALSE : TRUE;
		if (Comm_.OpertorDO(btnindex, onoff))
		{
			//处理操作单灯
			CStatic *JDStatic[16] = {
				&m_ICO_JD1, &m_ICO_JD2, &m_ICO_JD3, &m_ICO_JD4,
				&m_ICO_JD5, &m_ICO_JD6, &m_ICO_JD7, &m_ICO_JD8,
				&m_ICO_JD9, &m_ICO_JD10, &m_ICO_JD11, &m_ICO_JD12,
				&m_ICO_JD13, &m_ICO_JD14, &m_ICO_JD15, &m_ICO_JD16
			};

			Comm_.DOStatus[btnindex] ^= 0x01;
			(*JDStatic[btnindex]).SetIcon(onoff ? hIcons[3] : hIcons[2]);//处理继电器装填

			m_StatusBar.SetText(_T("控制成功"), 0, 0);
		}
		else  m_StatusBar.SetText(_T("控制失败"), 0, 0);
	}
	else m_StatusBar.SetText(_T("控制失败"), 0, 0);

	UpdateData(FALSE);
}

void CDO16Dlg::OnBtnOpenall()
{
	// TODO: Add your control notification handler code here
	UpdateData();

	if (Comm_.OpertorDO(TRUE))
	{
		//处理操作所有灯
		CStatic *JDStatic[16] = {
			&m_ICO_JD1, &m_ICO_JD2, &m_ICO_JD3, &m_ICO_JD4,
			&m_ICO_JD5, &m_ICO_JD6, &m_ICO_JD7, &m_ICO_JD8,
			&m_ICO_JD9, &m_ICO_JD10, &m_ICO_JD11, &m_ICO_JD12,
			&m_ICO_JD13, &m_ICO_JD14, &m_ICO_JD15, &m_ICO_JD16
		};
		for (int i = 0; i<Comm_.DO_CNT; i++)
		{
			Comm_.DOStatus[i] = 0x01;
			(*JDStatic[i]).SetIcon(hIcons[3]);//处理继电器装填
		}
		m_StatusBar.SetText(_T("控制成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("控制失败"), 0, 0);

	UpdateData(FALSE);
}

void CDO16Dlg::OnBtnCloseall()
{
	// TODO: Add your control notification handler code here
	UpdateData();

	if (Comm_.OpertorDO(FALSE))
	{
		//处理操作所有灯
		CStatic *JDStatic[16] = {
			&m_ICO_JD1, &m_ICO_JD2, &m_ICO_JD3, &m_ICO_JD4,
			&m_ICO_JD5, &m_ICO_JD6, &m_ICO_JD7, &m_ICO_JD8,
			&m_ICO_JD9, &m_ICO_JD10, &m_ICO_JD11, &m_ICO_JD12,
			&m_ICO_JD13, &m_ICO_JD14, &m_ICO_JD15, &m_ICO_JD16
		};
		for (int i = 0; i<Comm_.DO_CNT; i++)
		{
			Comm_.DOStatus[i] = 0x00;
			(*JDStatic[i]).SetIcon(hIcons[2]);//处理继电器装填
		}
		m_StatusBar.SetText(_T("控制成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("控制失败"), 0, 0);

	UpdateData(FALSE);
}

void CDO16Dlg::OnTimer(UINT nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	static u8 cnt;
	int i;
	//UpdateData();

	if (nIDEvent == 1)
	{
		if (Comm_.IsOpen())
		{
			CTime time = CTime::GetCurrentTime();             //获取当前时间
			CString str = time.Format("%H:%M:%S");             //时间格式化为字符串	
			m_StatusBar.SetText(str, 2, 0);

			CStatic *JDStatic[16] = {
				&m_ICO_JD1, &m_ICO_JD2, &m_ICO_JD3, &m_ICO_JD4,
				&m_ICO_JD5, &m_ICO_JD6, &m_ICO_JD7, &m_ICO_JD8,
				&m_ICO_JD9, &m_ICO_JD10, &m_ICO_JD11, &m_ICO_JD12,
				&m_ICO_JD13, &m_ICO_JD14, &m_ICO_JD15, &m_ICO_JD16
			};
			for (i = 0; i < Comm_.DO_CNT; i++)
				(*JDStatic[i]).SetIcon(Comm_.DOStatus[i] ? hIcons[3] : hIcons[2]);//处理继电器装填


			CStatic *DIStatic[20] = {
				&m_ICO_DI1, &m_ICO_DI2, &m_ICO_DI3, &m_ICO_DI4,
				&m_ICO_DI5, &m_ICO_DI6, &m_ICO_DI7, &m_ICO_DI8,
				&m_ICO_DI9, &m_ICO_DI10, &m_ICO_DI11, &m_ICO_DI12,
				&m_ICO_DI13, &m_ICO_DI14, &m_ICO_DI15, &m_ICO_DI16,
				&m_ICO_DI17, &m_ICO_DI18, &m_ICO_DI19, &m_ICO_DI20

			};
			for (i = 0; i < Comm_.DI_CNT; i++)
				(*DIStatic[i]).SetIcon(Comm_.DIStatus[i] ? hIcons[3] : hIcons[2]);//处理继电器装填


			if (Comm_.AI_CNT)
			{
				CString temp;
				double ftemp;
				m_ctrllist.DeleteAllItems();
				for (int i = 0; i < Comm_.AI_CNT; i++)
				{
					if (cai[i].IsValid)
					{
						temp.Format(_T("%d"), i + 1);
						int nRow = m_ctrllist.InsertItem(i, temp);
						m_ctrllist.SetItemText(i, 1, cai[i].name);
						ftemp = Comm_.InputStatus[i];
						ftemp *= cai[i].a;
						ftemp += cai[i].b;
						temp.Format(_T("%f"), ftemp);//* cai[i].a + cai[i].b
						m_ctrllist.SetItemText(i, 2, temp);
						m_ctrllist.SetItemText(i, 3, cai[i].unit);
					}
				}
			}

			if (Comm_.info != _T(""))
			{
				ShowDebugText(Comm_.info);
				Comm_.info = _T("");
			}
			UpdateData(FALSE);
		}
	}

	CDialog::OnTimer(nIDEvent);
}

void CDO16Dlg::OnChangeEditAddr()
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO: Add your control notification handler code here
	UpdateData();
	Comm_.equipaddr = m_addr;

}

void CDO16Dlg::OnSelchangeComboEquiptype()
{
	// TODO: Add your control notification handler code here
	UpdateData();
	Comm_.DI_CNT = 0;
	Comm_.DO_CNT = 0;

	CString   EditText;
	GetDlgItemText(IDC_COMBO_EQUIPTYPE, EditText);
	for (int i = 0; i < EQUIP_MAX_NUM; i++)
	{
		if (EditText == equip[i].name)
		{
			Comm_.DO_CNT = equip[i].donum;
			Comm_.DI_CNT = equip[i].dinum;
			Comm_.AI_CNT = equip[i].ainum;
			m_txthelp.Format(_T("【%s】:【继电器  %d】【光耦 %d】【模拟量 %d】"), EditText, Comm_.DO_CNT, Comm_.DI_CNT, Comm_.AI_CNT);

			ShowDO();
			ShowDI();
			ShowAI();
		}
	}
	Comm_.RstThread = 1;
	UpdateData(FALSE);
}




void CDO16Dlg::OnBnClickedBtnSetbaud()
{
	// TODO: 在此添加控件通知处理程序代码
	// TODO: Add your control notification handler code here
	UpdateData();

	int m_baud232 = ((CComboBox*)GetDlgItem(IDC_COMBO_BAUDRATE232))->GetCurSel();

	if (Comm_.OpertorWBaud(m_baud232, m_baud232))
	{
		m_StatusBar.SetText(_T("控制成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("控制失败"), 0, 0);

	UpdateData(FALSE);
}


void CDO16Dlg::OnBnClickedBtnReadbaud()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData();

	if (Comm_.OpertorRBaud())
	{
		((CComboBox*)GetDlgItem(IDC_COMBO_BAUDRATE232))->SetCurSel(Comm_.HoldStatus[0] % 7);
		((CComboBox*)GetDlgItem(IDC_COMBO_BAUDRATE485))->SetCurSel(Comm_.HoldStatus[1] % 7);
		m_StatusBar.SetText(_T("读取成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("读取失败"), 0, 0);

	UpdateData(FALSE);
}
void CDO16Dlg::OnOK(){


	//这里的代码怎么写，？？？？

}

void CDO16Dlg::OnEnChangeRichedit21()
{
	// TODO:  如果该控件是 RICHEDIT 控件，它将不
	// 发送此通知，除非重写 CDialog::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask()，
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

}
// TODO:  在此添加控件通知处理程序代码


void CDO16Dlg::OnBnClickedBtnOpenall2()
{
	// TODO:  在此添加控件通知处理程序代码
	Comm_.AskDO();
}


void CDO16Dlg::OnBnClickedBtnOpenall4()
{
	// TODO:  在此添加控件通知处理程序代码
	Comm_.AskDI();
}


void CDO16Dlg::OnBnClickedBtnOpenall3()
{
	// TODO:  在此添加控件通知处理程序代码
	Comm_.AskAI();
}

void CDO16Dlg::ShowDebugText(CString str)
{
	if (str == _T(""))return;
	if (m_txtDebug.GetLength() > 10000)
		m_txtDebug = _T("");
	m_txtDebug += str;

	m_ctledit.SetWindowTextW(m_txtDebug);
	m_ctledit.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
}



void CDO16Dlg::OnCbnSelchangeComboBaudrate232()
{
	// TODO:  在此添加控件通知处理程序代码
	UpdateData();
}


void CDO16Dlg::OnCbnSelchangeComboBaudrate485()
{
	// TODO:  在此添加控件通知处理程序代码
	UpdateData();
}


void CDO16Dlg::OnBnClickedCheck1()
{
	// TODO:  在此添加控件通知处理程序代码
	UpdateData();
	Comm_.IsDebug = m_debug;
}


void CDO16Dlg::OnBnClickedBtnSetbaud2()
{
	// TODO:  在此添加控件通知处理程序代码
	m_txtDebug = _T("");

	m_ctledit.SetWindowTextW(m_txtDebug);
}



void  CDO16Dlg::ShowDO()
{
	u32 IDC_BTN_JD[] = {
		IDC_BTN_JD1, IDC_BTN_JD2, IDC_BTN_JD3, IDC_BTN_JD4, IDC_BTN_JD5, IDC_BTN_JD6, IDC_BTN_JD7, IDC_BTN_JD8,
		IDC_BTN_JD9, IDC_BTN_JD10, IDC_BTN_JD11, IDC_BTN_JD12, IDC_BTN_JD13, IDC_BTN_JD14, IDC_BTN_JD15, IDC_BTN_JD16
	};

	for (int i = 0; i < EQUIP_DO_NUM; i++)
	{
		if (cdo[i].IsValid)
			GetDlgItem(IDC_BTN_JD[i])->ShowWindow(SW_SHOW);
		else
			GetDlgItem(IDC_BTN_JD[i])->ShowWindow(SW_HIDE);

		if (i < Comm_.DO_CNT)
		{
			GetDlgItem(IDC_BTN_JD[i])->EnableWindow(true);
		}
		else
			GetDlgItem(IDC_BTN_JD[i])->EnableWindow(false);

		SetDlgItemText(IDC_BTN_JD[i], cdo[i].name);
	}
}

void  CDO16Dlg::ShowDI()
{
	/*
	Comm_.DO_CNT = equip[i].donum;
	Comm_.DI_CNT = equip[i].dinum;
	Comm_.AI_CNT = equip[i].ainum;*/
	u32 IDC_BTN_DI[] = {
		IDC_STATIC_DI1, IDC_STATIC_DI2, IDC_STATIC_DI3, IDC_STATIC_DI4, IDC_STATIC_DI5, IDC_STATIC_DI6, IDC_STATIC_DI7, IDC_STATIC_DI8,
		IDC_STATIC_DI9, IDC_STATIC_DI10, IDC_STATIC_DI11, IDC_STATIC_DI12, IDC_STATIC_DI13, IDC_STATIC_DI14, IDC_STATIC_DI15, IDC_STATIC_DI16,
		IDC_STATIC_DI17, IDC_STATIC_DI18, IDC_STATIC_DI19, IDC_STATIC_DI20
	};

	for (int i = 0; i < EQUIP_DI_NUM; i++)
	{
		if (cdi[i].IsValid)
			GetDlgItem(IDC_BTN_DI[i])->ShowWindow(SW_SHOW);
		else
			GetDlgItem(IDC_BTN_DI[i])->ShowWindow(SW_HIDE);

		if (i < Comm_.DI_CNT)
		{
			GetDlgItem(IDC_BTN_DI[i])->EnableWindow(true);
		}
		else
			GetDlgItem(IDC_BTN_DI[i])->EnableWindow(false);

		SetDlgItemText(IDC_BTN_DI[i], cdi[i].name);
	}
}
void  CDO16Dlg::ShowAI()
{

}


void CDO16Dlg::OnBnClickedBtnReadbaseaddr()
{
	// TODO:  在此添加控件通知处理程序代码
	// TODO: 在此添加控件通知处理程序代码
	UpdateData();

	if (Comm_.OpertorRBaseAddr())
	{
		m_BaseAddr = Comm_.HoldStatus[0];
		m_StatusBar.SetText(_T("读取成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("读取失败"), 0, 0);

	UpdateData(FALSE);
}


void CDO16Dlg::OnBnClickedBtnWritebaseaddr()
{
	// TODO:  在此添加控件通知处理程序代码
	// TODO: 在此添加控件通知处理程序代码

	if (Comm_.OpertorWBaseAddr(m_BaseAddr))
	{
		m_StatusBar.SetText(_T("写入成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("写入失败"), 0, 0);

	UpdateData(FALSE);
}


void CDO16Dlg::OnBnClickedBtnReadaddr()
{
	// TODO:  在此添加控件通知处理程序代码
	// TODO:  在此添加控件通知处理程序代码
	// TODO: 在此添加控件通知处理程序代码
	UpdateData();

	if (Comm_.OpertorRAddr())
	{
		m_addr = (Comm_.InputStatus[0] == 0) ? 254 : Comm_.InputStatus[0];
		m_StatusBar.SetText(_T("读取成功"), 0, 0);
	}
	else m_StatusBar.SetText(_T("读取失败"), 0, 0);

	UpdateData(FALSE);
}


void CDO16Dlg::OnEnChangeEditBaseaddr()
{
	// TODO:  如果该控件是 RICHEDIT 控件，它将不
	// 发送此通知，除非重写 CDialog::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask()，
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
	UpdateData();

}
