C++ MFC在子对话框中操作三菱PLC

喜夏-厌秋 提交于 2019-12-30 19:09:43

前面有一篇文章讲过C++和三菱plc的通讯:https://blog.csdn.net/V_Gogol/article/details/103389983,本文是其拓展。

背景

前面讲过在工程中添加Activex控件,并使用控件创建变量,此对象包含了PLC的多个操作函数。但是在实际项目中遇到了一个问题,就是只能在主对话框放入activex控件,相当于这个对象的作用域仅限于主对话框对应的头文件和源文件,如果要在其他类中对PLC进行操作(例如设置或读取指定端口的值)就会显得比较麻烦。本文讲的是编写一个专门的PLC操作类包含回调函数来实现其他类里也可以方便的对plc进行操作。

实现

直接贴代码:

这个类是为了方便复用和全局范围操作plc编写的,声明了几个回调函数,下面主要讲设置端口值和读取端口值的封装操作。

下面是回调函数,在主对话框初始化函数中注册,就能够实现plc类里进行设置和读取操作时自动执行主对话框中实际的plc操作相关代码

这个是设置和读取端口值函数

以上是声明,下面才是函数实现:

设置和读取差不多,下面以设置值为例对代码进行详细讲解

这个函数在主对话框调用,注册回调函数,相当于通知主对话框,只要调用CFXPlc这个类中的设置端口值函数,就会自动执行主对话框的的对应函数。

////回调--设置指定端口值
BOOL	CFXPlc::C_SetPortValue(BOOL(CALLBACK*lpSetPortValue)(CString PortName, long PortValue))
{
	m_pSPlcV = lpSetPortValue;
	return	PLC_NO_ERROR;
}

下面这个是CFXPlc类里的函数,用于判定回调是否有注册,没有注册报警返回

//回调中间函数--设置指定端口值
BOOL	CFXPlc::Mid_SetPortValue(CString PortName, long PortValue)
{
	if (NULL == m_pSPlcV)
	{
		AfxMessageBox(L"fx-setportvalue未编写回调函数!");
		return	PLC_ERROR;
	}
	else
		return(*m_pSPlcV)(PortName, PortValue);
}

最后就是实际的设置端口值函数,包括两个参数,端口名称和想要设定的值,代码如下

//设置指定端口值
int	CFXPlc::SetPortValue(CString PortName, long PortValue)
{
	if (PLC_ERROR == Mid_SetPortValue(PortName, PortValue))
	{
		AfxMessageBox(PortName + L"值设置失败!");
		return	PLC_ERROR;
	}
	else
		return	PLC_NO_ERROR;
}

它会调用那个回调中间函数,回调中间函数返回的就是主对话框的注册的回调函数地址,也就是直接执行主对话框的中对应的plc操作函数。

后续任何要使用plc操作的地方,只要包含CFXPlc类,创建对象就可以直接操作plc。

下面将主对话框中要编写的代码:

//回调函数--设置指定端口值
BOOL	CALLBACK	CB_SetPortValue(CString PortName, long Value)
{
	try
	{
		if (PLC_NO_ERROR != SetPlcPortValue(0, PortName, Value))
			return	PLC_ERROR;
		else
			return	PLC_NO_ERROR;
	}
	catch (...)
	{
		AfxMessageBox(L"设置"+PortName+L"出错!");
		return PLC_ERROR;
	}
}

上面是主对话框中的回调函数,其中SetPlcPortValue这个函数的具体实现我上篇文章里有源代码。

最后一步,只需要在程序初始化时将CB_SetPortValue的函数地址传给fxplc类中的对应回调函数即可,也就是回调注册,它起的作用是只要调用了fxplc类中SetPortValue这个函数,就会自动主对话框的CB_SetPortValue函数,这样,就可以实现拖入activex控件后整个程序都可操作plc了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!