
// Compare2DDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "二维比较.h"
#include "Compare2DDlg.h"
#include "afxdialogex.h"
#include"MC_dll.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CCompare2DDlg 对话框



CCompare2DDlg::CCompare2DDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MY_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	cmpPos0 = 0;
	cmpPos1 = 0;
	ioOutTime = 0;
	cardConnectNo = 0;
}

void CCompare2DDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO1, axis0);
	DDX_Control(pDX, IDC_COMBO2, source0);
	DDX_Control(pDX, IDC_COMBO3, cmpMode0);
	DDX_Text(pDX, IDC_EDIT1, cmpPos0);
	DDX_Control(pDX, IDC_COMBO4, axis1);
	DDX_Control(pDX, IDC_COMBO5, source1);
	DDX_Control(pDX, IDC_COMBO6, cmpMode1);
	DDX_Text(pDX, IDC_EDIT2, cmpPos1);
	DDX_Control(pDX, IDC_COMBO7, triggerMode);
	DDX_Control(pDX, IDC_COMBO8, triggerPrm);
	DDX_Text(pDX, IDC_EDIT3, ioOutTime);
	DDX_Control(pDX, IDC_STATIC_GBAXIS0, groupBoxAxis0);
	DDX_Control(pDX, IDC_STATIC_GBAXIS1, groupBoxAxis1);
	DDX_Control(pDX, IDC_STATIC_OUTPUT0, output0State);
	DDX_Control(pDX, IDC_STATIC_OUTPUT1, output1State);
}

BEGIN_MESSAGE_MAP(CCompare2DDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_CBN_SELCHANGE(IDC_COMBO7, &CCompare2DDlg::OnCbnSelchangeCombo7)
	ON_BN_CLICKED(IDC_BUTTON4, &CCompare2DDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &CCompare2DDlg::OnBnClickedButton5)
	ON_BN_CLICKED(IDC_BUTTON6, &CCompare2DDlg::OnBnClickedButton6)
	ON_BN_CLICKED(IDC_BUTTON1, &CCompare2DDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CCompare2DDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CCompare2DDlg::OnBnClickedButton3)
	ON_WM_DESTROY()
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CCompare2DDlg 消息处理程序

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

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	FormMessageInit();

#pragma region 开卡
	WORD pciNum = 0; //用于接收开卡成功的卡数
	WORD pcieIndex[12];
	DWORD functionReturn = 0; //函数返回值

	functionReturn = MC_Open(0, CONNECTION_PCI, "", &pciNum, pcieIndex);
	if (functionReturn == 0)//函数成功执行
	{
		if (pciNum > 0)//至少一张卡被成功开卡
		{
			cardConnectNo = pcieIndex[0]; //如果有多卡的情况下这里也只用卡1演示

#pragma region 获取卡信息
			//--------------------------获取卡信息------------------------------------------------------------------------
			WORD totalAxisNum = 0; //用于获取卡的轴数
			WORD linerNum = 0;//用于获取卡的插补系个数
			WORD totalInNum = 0;//用于获取卡的输入口数量
			WORD totalOutNum = 0;//用于获取卡的输出口数量
			WORD totalPWMNum = 0;//用于获取卡的PWM通道数量
			functionReturn = MC_GetTotalAxesAndIONum(cardConnectNo, &totalAxisNum, &linerNum, &totalInNum, &totalOutNum, &totalPWMNum);

			//------------------------------------------------------------------------------------------------------------
#pragma endregion

			
			SetTimer(1, 200, NULL);//启动界面监控定时器

		}
		else
		{
			MessageBox(L"未找到卡!");
		}
	}
	else
	{
		MessageBox(L"开卡失败!");
	}
#pragma endregion


	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CCompare2DDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CCompare2DDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		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 CCompare2DDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

/// <summary>
/// 设置界面的控件信息
/// </summary>
void CCompare2DDlg::FormMessageInit()
{
	for (int _axisNo = 0; _axisNo < 12; _axisNo++)
	{
		CString str;
		str.Format(_T("轴%d"), _axisNo);
		axis0.InsertString(_axisNo, str);
		axis1.InsertString(_axisNo, str);
	}
	axis0.SetCurSel(0);
	axis1.SetCurSel(1); //比较轴号

	source0.InsertString(0, L"指令位置");
	source0.InsertString(1, L"反馈位置");
	source0.SetCurSel(0);

	source1.InsertString(0, L"指令位置");
	source1.InsertString(1, L"反馈位置");
	source1.SetCurSel(0);//比较位置源

	cmpMode0.InsertString(0, L"小于");
	cmpMode0.InsertString(1, L"大于等于");
	cmpMode0.SetCurSel(0); 

	cmpMode1.InsertString(0, L"小于");
	cmpMode1.InsertString(1, L"大于等于");
	cmpMode1.SetCurSel(0); //比较模式

	triggerMode.InsertString(0, L"IO输出低");
	triggerMode.InsertString(1, L"IO输出高");
	triggerMode.InsertString(2, L"IO输出反向");
	triggerMode.InsertString(3, L"IO输出脉冲");
	triggerMode.InsertString(4, L"停止轴");
	triggerMode.SetCurSel(0);//触发模式

	for (int _outputNo = 0; _outputNo < 2; _outputNo++)
	{
		CString outputStr;
		outputStr.Format(_T("Output%d"), _outputNo);
		triggerPrm.InsertString(_outputNo, outputStr);
	}
	triggerPrm.SetCurSel(0); //触发参数
}


/// <summary>
/// 触发模式改变，更改触发参数
/// </summary>
void CCompare2DDlg::OnCbnSelchangeCombo7()
{
	// TODO: 在此添加控件通知处理程序代码
	if (triggerMode.GetCurSel() == 4)
	{
		triggerPrm.ResetContent();
		for (int _axisNo = 0; _axisNo < 12; _axisNo++)
		{
			CString str;
			str.Format(_T("轴%d"), _axisNo);
			triggerPrm.InsertString(_axisNo, str);
		}
		triggerPrm.SetCurSel(0);
	}
	else
	{
		triggerPrm.ResetContent();
		for (int _outputNo = 0; _outputNo < 2; _outputNo++)
		{
			CString outputStr;
			outputStr.Format(_T("Output%d"), _outputNo);
			triggerPrm.InsertString(_outputNo, outputStr);
		}
		triggerPrm.SetCurSel(0); //触发参数
	}
}


/// <summary>
/// 启动二维比较按钮点击
/// </summary>
void CCompare2DDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	WORD cmp2DAxis0 = axis0.GetCurSel();
	WORD cmp2DAxis1 = axis1.GetCurSel();

	WORD cmp2DposSrc0 = source0.GetCurSel();
	WORD cmp2DposSrc1 = source1.GetCurSel();

	double pos0 = cmpPos0;
	double pos1 = cmpPos1;

	WORD cmp2DMode0 = cmpMode0.GetCurSel();
	WORD cmp2DMode1 = cmpMode1.GetCurSel();

	WORD trMode = triggerMode.GetCurSel();
	WORD trPrm = triggerPrm.GetCurSel();
	double outTime = ioOutTime;

	WORD cmpAxis[2] = {cmp2DAxis0, cmp2DAxis1};
	WORD posSrc[2] = { cmp2DposSrc0, cmp2DposSrc1 };
	double pos[2] =  { pos0, pos1 };
	WORD cmpMode[2] = { cmp2DMode0, cmp2DMode1 };

	MC_StartSoft2DCmp(cardConnectNo, //启动比较
		0,
		cmpAxis,
		posSrc,
		1,
		pos,
		cmpMode,
		trMode,
		trPrm,
		outTime
	);

	//启动比较之后启动相关轴运动
	MC_Power(cardConnectNo, cmp2DAxis0, 1);
	MC_MoveVelocity(cardConnectNo, cmp2DAxis0, 100, 100, 1000, 0.1, 0.1, 0, 1000000);
	CString str;
	str.Format(L"轴%d", cmp2DAxis0);
	groupBoxAxis0.SetWindowTextW(str);


	MC_Power(cardConnectNo, cmp2DAxis1, 1);
	MC_MoveVelocity(cardConnectNo, cmp2DAxis1, 100, 100, 1000, 0.1, 0.1, 0, 1000000);
	str.Format(L"轴%d", cmp2DAxis1);
	groupBoxAxis1.SetWindowTextW(str);

	UpdateData(false);
}


/// <summary>
/// 二维比较停止比较
/// </summary>
void CCompare2DDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	MC_StopSoftCmp(cardConnectNo, Compare_2D, 0);//停止二维比较
	MC_StopEmgImd(cardConnectNo); //停止所有在运动的轴
	
}


/// <summary>
/// 二维比较比较器清零
/// </summary>
void CCompare2DDlg::OnBnClickedButton6()
{
	// TODO: 在此添加控件通知处理程序代码
	MC_ClearSoftCmp(cardConnectNo, Compare_2D, 0);

}

/// <summary>
/// 二维比较位置清除
/// </summary>
void CCompare2DDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	WORD _axis0 = axis0.GetCurSel();
	MC_SetAxisCmdPos(cardConnectNo, _axis0, 0);

	WORD _axis1 = axis1.GetCurSel();
	MC_SetAxisCmdPos(cardConnectNo, _axis1, 0);
}


/// <summary>
/// Output0点击
/// </summary>
void CCompare2DDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	HICON redIcon = AfxGetApp()->LoadIcon(IDI_ICONRED);

	if (((CStatic*)GetDlgItem(IDC_STATIC_OUTPUT0))->GetIcon() == redIcon)
	{
		MC_SetOutIoBit(cardConnectNo, 0, 0);
	}
	else
	{
		MC_SetOutIoBit(cardConnectNo, 0, 1);
	}
}


/// <summary>
/// Output1点击
/// </summary>
void CCompare2DDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	HICON redIcon = AfxGetApp()->LoadIcon(IDI_ICONRED);

	if (((CStatic*)GetDlgItem(IDC_STATIC_OUTPUT1))->GetIcon() == redIcon)
	{
		MC_SetOutIoBit(cardConnectNo, 1, 0);
	}
	else
	{
		MC_SetOutIoBit(cardConnectNo, 1, 1);
	}
}

/// <summary>
/// 窗体销毁时发生
/// </summary>
void CCompare2DDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	KillTimer(1);
	MC_Close(cardConnectNo); //关卡释放资源
	// TODO: 在此处添加消息处理程序代码
}

/// <summary>
/// 更新界面的定时器
/// </summary>
/// <param name="nIDEvent"></param>
void CCompare2DDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	WORD enable = 0;
	double running_pos = 0;
	DWORD completed_points = 0;
	DWORD remained_points = 0;
	MC_GetSoftCmpStatus(cardConnectNo,
		Compare_2D, //比较维数
		0, //比较通道
		&enable, //比较器使能
		&running_pos, //当前比较点位置
		&completed_points, //已完成比较点
		&remained_points); //剩余比较点

	switch (enable)
	{
	case 0:
		GetDlgItem(IDC_EDIT4)->SetWindowTextW(L"未启用");
		break;
	case 1:
		GetDlgItem(IDC_EDIT4)->SetWindowTextW(L"使能");
		break;
	default:
		GetDlgItem(IDC_EDIT4)->SetWindowTextW(L"未定义");
		break;
	}
	CString runningPosStr;
	runningPosStr.Format(_T("%f"), running_pos);//当前比较位置点
	GetDlgItem(IDC_EDIT6)->SetWindowTextW(runningPosStr);

	CString completedPoints;
	completedPoints.Format(_T("%d"), completed_points);//已完成比较点
	GetDlgItem(IDC_EDIT5)->SetWindowTextW(completedPoints);

	CString remainedPoints;
	remainedPoints.Format(_T("%d"), remained_points);
	GetDlgItem(IDC_EDIT7)->SetWindowTextW(remainedPoints);


	WORD _axis0 = axis0.GetCurSel();
	double cmdPos = 0;
	MC_GetAxisCmdPos(cardConnectNo, _axis0, &cmdPos);//获取当前指令位置
	CString cmdPosStr;
	cmdPosStr.Format(_T("%f"), cmdPos);
	GetDlgItem(IDC_EDIT9)->SetWindowTextW(cmdPosStr);

	double cmdSpeed = 0;
	MC_GetAxisCmdSpeed(cardConnectNo, _axis0, &cmdSpeed); //获取当前指令速度
	CString cmdSpeedStr;
	cmdSpeedStr.Format(_T("%f"), cmdSpeed);
	GetDlgItem(IDC_EDIT8)->SetWindowTextW(cmdSpeedStr);

	WORD checkDone = 1;
	MC_GetAxisCheckDone(cardConnectNo, _axis0, &checkDone);//获取轴运动状态
	switch (checkDone)
	{
	case 0:
		GetDlgItem(IDC_EDIT10)->SetWindowTextW(L"运动中");
		break;
	case 1:
		GetDlgItem(IDC_EDIT10)->SetWindowTextW(L"空闲");
		break;
	default:
		CString checkDoneStr;
		checkDoneStr.Format(_T("%d"), checkDone);
		GetDlgItem(IDC_EDIT10)->SetWindowTextW(checkDoneStr);

		break;
	}

	WORD _axis1 = axis1.GetCurSel();
	MC_GetAxisCmdPos(cardConnectNo, _axis1, &cmdPos);//获取当前指令位置
	cmdPosStr.Format(_T("%f"), cmdPos);
	GetDlgItem(IDC_EDIT12)->SetWindowTextW(cmdPosStr);

	MC_GetAxisCmdSpeed(cardConnectNo, _axis1, &cmdSpeed); //获取当前指令速度
	cmdSpeedStr.Format(_T("%f"), cmdSpeed);
	GetDlgItem(IDC_EDIT11)->SetWindowTextW(cmdSpeedStr);

	MC_GetAxisCheckDone(cardConnectNo, _axis1, &checkDone);//获取轴运动状态
	switch (checkDone)
	{
	case 0:
		GetDlgItem(IDC_EDIT13)->SetWindowTextW(L"运动中");
		break;
	case 1:
		GetDlgItem(IDC_EDIT13)->SetWindowTextW(L"空闲");
		break;
	default:
		CString checkDoneStr;
		checkDoneStr.Format(_T("%d"), checkDone);
		GetDlgItem(IDC_EDIT13)->SetWindowTextW(checkDoneStr);
		break;
	}

	byte ioState = 0;
	MC_GetOutIoBit(cardConnectNo, 0, &ioState);
	if (ioState == 0) output0State.SetIcon(AfxGetApp()->LoadIcon(IDI_ICONGREEN));
	else output0State.SetIcon(AfxGetApp()->LoadIcon(IDI_ICONRED));

	MC_GetOutIoBit(cardConnectNo, 1, &ioState);
	if (ioState == 0) output1State.SetIcon(AfxGetApp()->LoadIcon(IDI_ICONGREEN));
	else output1State.SetIcon(AfxGetApp()->LoadIcon(IDI_ICONRED));


	CDialogEx::OnTimer(nIDEvent);
}
