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

#include "pch.h"
#include "framework.h"
#include "高速锁存.h"
#include "HSLatchDlg.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()


// CHSLatchDlg 对话框



CHSLatchDlg::CHSLatchDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MY_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	IoIndex = 0;
}

void CHSLatchDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO1, HSChan);
	DDX_Control(pDX, IDC_COMBO2, GeneralIO);
	DDX_Control(pDX, IDC_COMBO3, LatchAxis);
	DDX_Text(pDX, IDC_EDIT4, IoIndex);
	DDX_Control(pDX, IDC_EDIT5, LatchResult);
	DDX_Control(pDX, IDC_STATIC_INPUTSTATE, InputState);
	DDX_Control(pDX, IDC_STATIC_AXISGB, AxisGroupBox);
}

BEGIN_MESSAGE_MAP(CHSLatchDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON2, &CHSLatchDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CHSLatchDlg::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &CHSLatchDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON1, &CHSLatchDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON5, &CHSLatchDlg::OnBnClickedButton5)
END_MESSAGE_MAP()


// CHSLatchDlg 消息处理程序

BOOL CHSLatchDlg::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: 在此添加额外的初始化代码
	FormInit();

#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
}

/// <summary>
/// 界面初始化
/// </summary>
void CHSLatchDlg::FormInit()
{
	HSChan.InsertString(0, L"Cap0");
	HSChan.InsertString(1, L"Cap1");
	HSChan.SetCurSel(0); //高速通道

	for (int i = 0; i < 16; i++)
	{
		CString InputStr;
		InputStr.Format(_T("Input%d"), i);
		GeneralIO.InsertString(i, InputStr);
	}
	GeneralIO.SetCurSel(0); //默认选择Input0

	for (int _axis = 0; _axis < 12; _axis++)
	{
		CString axisStr;
		axisStr.Format(_T("轴%d"), _axis);
		LatchAxis.InsertString(_axis, axisStr);
	}
	LatchAxis.SetCurSel(0); //默认选择Input0

	((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);//原点信号默认选上

	((CButton*)GetDlgItem(IDC_RADIO5))->SetCheck(TRUE);//单次锁存默认选上

	((CButton*)GetDlgItem(IDC_RADIO7))->SetCheck(TRUE);//下降沿捕获默认选上

	((CButton*)GetDlgItem(IDC_RADIO10))->SetCheck(TRUE);//位置源默认选上

}

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

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

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


/// <summary>
/// 窗体销毁时发生
/// </summary>
void CHSLatchDlg::OnDestroy()
{
	CDialogEx::OnDestroy();
	KillTimer(1);
	MC_Close(cardConnectNo); //关卡释放资源
	// TODO: 在此处添加消息处理程序代码
}


void CHSLatchDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	UpdateData(true);

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

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

	WORD checkDone = 1;
	MC_GetAxisCheckDone(cardConnectNo, _axis0, &checkDone);//获取轴运动状态
	switch (checkDone)
	{
	case 0:
		GetDlgItem(IDC_EDIT3)->SetWindowTextW(L"运动中");
		break;
	case 1:
		GetDlgItem(IDC_EDIT3)->SetWindowTextW(L"空闲");
		break;
	default:
		CString checkDoneStr;
		checkDoneStr.Format(_T("%d"), checkDone);
		GetDlgItem(IDC_EDIT3)->SetWindowTextW(checkDoneStr);
		break;
	}
	
	byte ioState = 0;
	DWORD inputINdex = IoIndex;
	MC_GetOutIoBit(cardConnectNo, inputINdex, &ioState);
	if (ioState == 0) InputState.SetIcon(AfxGetApp()->LoadIcon(IDI_ICONGREEN));
	else InputState.SetIcon(AfxGetApp()->LoadIcon(IDI_ICONRED));

	CDialogEx::OnTimer(nIDEvent);
}

/// <summary>
/// 高速锁存启动
/// </summary>
void CHSLatchDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	WORD cmpObject = 0; //锁存信号源
	WORD cmpChan = 0; //锁存通道(锁存信号源为高速输入口时为0，2)
	WORD cmpAxis = 0;//锁存轴
	WORD cmpMode = 0;//锁存模式
	WORD cmpLogic = 0;//锁存逻辑
	WORD cmpPosSource = 0;//锁存位置源

	if (((CButton*)GetDlgItem(IDC_RADIO1))->GetCheck() == 1) cmpObject = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO2))->GetCheck() == 1) cmpObject = 1;
	else if (((CButton*)GetDlgItem(IDC_RADIO3))->GetCheck() == 1)
	{
		cmpObject = 2;
		cmpChan = HSChan.GetCurSel();
	}
	else if (((CButton*)GetDlgItem(IDC_RADIO4))->GetCheck() == 1)
	{
		cmpObject = 3;
		cmpChan = GeneralIO.GetCurSel();
	}
	cmpAxis = LatchAxis.GetCurSel();

	if (((CButton*)GetDlgItem(IDC_RADIO5))->GetCheck() == 1) cmpMode = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO6))->GetCheck() == 1) cmpMode = 1;

	if (((CButton*)GetDlgItem(IDC_RADIO7))->GetCheck() == 1) cmpLogic = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO8))->GetCheck() == 1) cmpLogic = 1;
	else if (((CButton*)GetDlgItem(IDC_RADIO9))->GetCheck() == 1) cmpLogic = 2;

	if (((CButton*)GetDlgItem(IDC_RADIO10))->GetCheck() == 1) cmpPosSource = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO11))->GetCheck() == 1) cmpPosSource = 1;

	CString str;
	str.Format(L"轴%d", cmpAxis);
	AxisGroupBox.SetWindowTextW(str);

	MC_StartCapture(cardConnectNo,
		cmpObject,
		cmpAxis,
		cmpChan,
		cmpChan,
		cmpMode,
		cmpLogic,
		cmpPosSource);

	//启动锁存之后启动相关轴的连续运动
	MC_Power(cardConnectNo, cmpAxis, 1); //任何运动都需要轴使能

	MC_MoveVelocity(cardConnectNo, cmpAxis, 100, 100, 1000, 0.1, 0.1, 0, 1000000);//启动速度运动
}


/// <summary>
/// 高速锁存停止
/// </summary>
void CHSLatchDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	WORD cmpObject = 0;
	WORD cmpChan = 0;
	WORD cmpAxis = 0;

	if (((CButton*)GetDlgItem(IDC_RADIO1))->GetCheck() == 1) cmpObject = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO2))->GetCheck() == 1) cmpObject = 1;
	else if (((CButton*)GetDlgItem(IDC_RADIO3))->GetCheck() == 1)
	{
		cmpObject = 2;
		cmpChan = HSChan.GetCurSel();
	}
	else if (((CButton*)GetDlgItem(IDC_RADIO4))->GetCheck() == 1)
	{
		cmpObject = 3;
		cmpChan = GeneralIO.GetCurSel();
	}
	cmpAxis = LatchAxis.GetCurSel();

	MC_StopCapture(cardConnectNo, //停止锁存器
		cmpObject,
		cmpAxis,
		cmpChan);

	MC_StopEmgImd(cardConnectNo);//如果有轴在运动中就停止
}

/// <summary>
/// 高速锁存重启锁存器
/// </summary>
void CHSLatchDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	WORD cmpObject = 0;
	WORD cmpChan = 0;
	WORD cmpAxis = 0;

	if (((CButton*)GetDlgItem(IDC_RADIO1))->GetCheck() == 1) cmpObject = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO2))->GetCheck() == 1) cmpObject = 1;
	else if (((CButton*)GetDlgItem(IDC_RADIO3))->GetCheck() == 1)
	{
		cmpObject = 2;
		cmpChan = HSChan.GetCurSel();
	}
	else if (((CButton*)GetDlgItem(IDC_RADIO4))->GetCheck() == 1)
	{
		cmpObject = 3;
		cmpChan = GeneralIO.GetCurSel();
	}
	cmpAxis = LatchAxis.GetCurSel();

	MC_ReStartCapture(cardConnectNo, //重启锁存器
		cmpObject,
		cmpAxis,
		cmpChan);
}

/// <summary>
/// 锁存结果显示清除
/// </summary>
void CHSLatchDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码

	LatchResult.SetWindowTextW(L"");
	
}

/// <summary>
/// 高速锁存获取锁存结果按钮点击
/// </summary>
void CHSLatchDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	WORD cmpObject = 0;
	WORD cmpChan = 0;
	WORD cmpAxis = 0;

	if (((CButton*)GetDlgItem(IDC_RADIO1))->GetCheck() == 1) cmpObject = 0;
	else if (((CButton*)GetDlgItem(IDC_RADIO2))->GetCheck() == 1) cmpObject = 1;
	else if (((CButton*)GetDlgItem(IDC_RADIO3))->GetCheck() == 1)
	{
		cmpObject = 2;
		cmpChan = HSChan.GetCurSel();
	}
	else if (((CButton*)GetDlgItem(IDC_RADIO4))->GetCheck() == 1)
	{
		cmpObject = 3;
		cmpChan = GeneralIO.GetCurSel();
	}
	cmpAxis = LatchAxis.GetCurSel();

	DWORD cmpCount = 0;
	MC_GetCaptureCount(cardConnectNo, //获取锁存到的位置个数
		cmpObject,
		cmpAxis,
		cmpChan,
		&cmpCount);

	WORD realCount = 0;
	double posArr[255];;
	MC_GetCapturePos(cardConnectNo,
		cmpObject,
		cmpAxis,
		cmpChan,
		cmpCount,
		&realCount,
		posArr);


	CString cmpObjectStr;
	CString cmpChanStr;
	CString cmpAxisStr;
	if (((CButton*)GetDlgItem(IDC_RADIO1))->GetCheck() == 1) { ((CButton*)GetDlgItem(IDC_RADIO1))->GetWindowTextW(cmpObjectStr); }
	else if (((CButton*)GetDlgItem(IDC_RADIO2))->GetCheck() == 1) { ((CButton*)GetDlgItem(IDC_RADIO2))->GetWindowTextW(cmpObjectStr); }
	else if (((CButton*)GetDlgItem(IDC_RADIO3))->GetCheck() == 1)
	{
		((CButton*)GetDlgItem(IDC_RADIO3))->GetWindowTextW(cmpObjectStr);
		HSChan.GetWindowTextW(cmpChanStr);

	}
	else if (((CButton*)GetDlgItem(IDC_RADIO4))->GetCheck() == 1)
	{
		((CButton*)GetDlgItem(IDC_RADIO4))->GetWindowTextW(cmpObjectStr);
		GeneralIO.GetWindowTextW(cmpChanStr);

	}
	LatchAxis.GetWindowTextW(cmpAxisStr);
	for (int i = 0; i < realCount; i++)
	{
		CString posStr;
		posStr.Format(L"%f", posArr[i]);
		CString useStr = cmpObjectStr + cmpAxisStr + cmpChanStr+ posStr+"\r\n";
	
		int nLen = LatchResult.GetWindowTextLengthW();
		LatchResult.SetSel(nLen, nLen);
		LatchResult.ReplaceSel(useStr);
	}
}
