简介
该手册介绍Demo代码阅读和测试,SECS代码的入口、控制、操作、回调响应等
2. C++ EquipViewApp
以下介绍代码阅读和使用
软件目录清单
2.1 初始化函数代码:
BOOL CEquipViewAppDlg::OnInitDialog()
{
CMyDialogEx::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
SetName();
ShowWindow(SW_SHOWNOACTIVATE);
SetNewCreateType(false); // 设置参数:本类非new方式创建的
// 初始化连接 SECS
InitConnect();
InitChildArea();
AddView();
InitTree();
// 初始化子窗口
InitCtrl();
InitChildView();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
讲解:
1. 代码的入口在窗口类CEquipViewAppDlg的OnInitDialog()函数中
2. 首先初始化SECS类的通讯: InitConnect();
2.1 创建通讯对象
try
{
m_pSecs = new CSecsEquip();
}
catch (...)
{
m_pSecs = nullptr;
}
2.2 初始化SECS DLL模块
RcResult rc = m_pSecs->Start();
2.3 设置各项SECS/GEM的参数
rc = m_pSecs->SetIP(g_appdata.m_pAddress);
rc = m_pSecs->SetPort(g_appdata.m_nPort);
rc = m_pSecs->SetPassive(g_appdata.m_bPassive);
rc = m_pSecs->SetDeviceID(g_appdata.m_nDeviceID);
rc = m_pSecs->SetMDLN(g_appdata.m_pInterfaceName);
rc = m_pSecs->SetEnableLog(g_appdata.m_bEnableLog);
rc = m_pSecs->SetT1(g_appdata.m_nTimeout[0]);
rc = m_pSecs->SetT2(g_appdata.m_nTimeout[1]);
rc = m_pSecs->SetT3(g_appdata.m_nTimeout[2]);
rc = m_pSecs->SetT4(g_appdata.m_nTimeout[3]);
rc = m_pSecs->SetT5(g_appdata.m_nTimeout[4]);
rc = m_pSecs->SetT6(g_appdata.m_nTimeout[5]);
rc = m_pSecs->SetT7(g_appdata.m_nTimeout[6]);
// 设置winrar.exe的路径
// 如果recipe是单个文档,无需设置
m_pSecs->SetWinrarPath("C:/Program Files/WinRAR/WinRAR.exe");
// 设置回调
m_pSecs->SetClientData(this);
m_pSecs->m_pTerminalCallback = ::OnTerminalProc;
m_pSecs->m_pStateChangeCallback = ::OnStateChangeProc;
m_pSecs->m_pRemoteCallback = ::OnRemoteProc;
// 示例的回调
m_pSecs->m_pConstantsChangeCallback = ::OnConstantChangeProc;
m_pSecs->m_pVarValueProc = ::OnVarValueProc;
m_pSecs->m_pConstantValueProc = ::OnVarValueProc;
m_pSecs->m_pPPNameListProc = ::OnPPNameListProc;
m_pSecs->m_pPPEventProc = ::OnSecsPPEventProc;
// 特殊
m_pSecs->m_pPPFormatValueProc = OnPPFormatValueProc;
// 通过Csv文件加载配置
rc = m_pSecs->LoadDataByCsvFile();
// 建立通讯
rc = m_pSecs->SetControlMode((CONTROL_MODE)g_appdata.m_nControlMode);
2.4 开始SECS/GEM的通讯
rc = m_pSecs->CommEnable();
2.2 Communication、Control状态获取改变代码:
注册回调函数
m_pSecs->m_pStateChangeCallback = ::OnStateChangeProc;
处理代码
void OnStateChangeProc(CSecsEquip* pSH, const char* varname, int nState)
{
CEquipViewAppDlg* pHV = (CEquipViewAppDlg* )pSH->GetClientData();
if(pHV != nullptr)
{
string pType = varname;
if(pType == "comm_state")
{
pHV->PostMsgToView("Connect", ON_COMM_CHANGE, eCommStateChange, nState);
pHV->PostMsgToView("Event", ON_COMM_CHANGE, eCommStateChange, nState);
pHV->PostMsgToView("Variable", ON_COMM_CHANGE, eCommStateChange, nState);
pHV->SendMessage(ON_COMM_CHANGE, eCommStateChange, nState);
}
else if(pType == "control_state")
{
pHV->PostMsgToView("Connect", ON_CONTROL_CHANGE, eControlStateChange, nState);
pHV->SendMessage(ON_CONTROL_CHANGE, eControlStateChange, nState);
}
}
}
讲解:
1. 何时调用:
当SECS/GEM的通讯状态、控制状态发生改变的时候,SDK将会调用该函数通知最新状态。
2. 关联行:
初始化的时候,把该函数添加到回调中。
m_pSecs->m_pStateChangeCallback = ::OnStateChangeProc;
3. PostMsgToView的作用
上边函数收到状态信息后,将该数据通知到各个窗口里面。
4. 所需工作
显示到主界面中,显示实时的SECS/GEM状态在设备软件上
2.3 远程控制接收代码:
注册回调函数
m_pSecs->m_pRemoteCallback = ::OnRemoteProc;
处理代码
将命令转达到窗口
REMOTE_REPLY OnRemoteProc(CSecsEquip* pSH, REMOTE_DATA rd)
{
CEquipViewAppDlg* pHV = (CEquipViewAppDlg* )pSH->GetClientData();
if(pHV != nullptr)
{
REMOTE_REPLY reply = eCOMMAND_OTHER;
reply = (REMOTE_REPLY)pHV->SendMsgToView("Remote", ON_REMOTE, 0, (LPARAM)&rd);
pHV->SendMsgToView("Auto Simple", ON_REMOTE, 0, (LPARAM)&rd);
return reply;
}
return ::eCOMMAND_REJECTED;
}
实际处理远程命令的代码
LRESULT CAutoSimpleView::OnRemoteProc(WPARAM wp, LPARAM lp)
{
REMOTE_DATA rd = *((REMOTE_DATA*)lp);
if(rd.pRCMD == "PP-SELECT")
{
const char* pRecipeName = rd.GetValue("RecipeName");
if (pRecipeName == nullptr)
{
// 找不到recipe名称参数
return ::eCOMMAND_PARAMETER_IS_INVALID;
}
// 调用切换recipe函数
// ChangeRecipe(pRecipeName)
// 发送切换完成事件
// 发送事件函数一般放在ChangeRecipe里面
m_pSecs->EventPos(ChangeRecipeStartedSimple);
SleepEx();
string pName = "Recipe:";
pName += pRecipeName;
m_staticRecipe.SetWindowText(pName.c_str());
m_pSecs->EventPos(ChangeRecipeCompleteSimple);
//处理成功
return eCOMMAND_PERFORMED;
}
return eCOMMAND_PERFORMED;
}
讲解:
1. 何时调用:
当SECS/GEM收到远程命令时候,SDK将会调用该函数通知设备处理。
2. 关联行:
初始化的时候,把该函数添加到回调中。
m_pSecs->m_pRemoteCallback = ::OnRemoteProc;
3. PostMsgToView的作用
上边函数收到状态信息后,将该数据通知到各个窗口里面。
4. 所需工作
根据处理远程指令,设备做出对应的处理。
2.4 变量更新代码:
注册回调函数
m_pSecs->m_pVarValueProc = ::OnVarValueProc;
处理代码
将命令转达到窗口
// 变量数据
const char* OnVarValueProc(CSecsEquip* pSH, int var)
{
CEquipViewAppDlg* pHV = (CEquipViewAppDlg* )pSH->GetClientData();
if(pHV != nullptr)
{
return pHV->SecsVarValue(var);
}
return "";
}
设备返回变量ID对应的变量值
const char* CEquipViewAppDlg::SecsVarValue(int varID)
{
SYSTEMTIME time;
GetLocalTime(&time);
static CString result;
switch (varID)
{
case 1260: result = ::g_appdata.GetExePath().c_str(); break;
case 1261: result = IntToString(time.wSecond).c_str(); break;
case 4004: result.Format("dynamic constant value %d", time.wMilliseconds); break;
case 1270:
{
// L 类型变量示例
// 极其少情况下使用到
string nMinute = listJoin("A", IntToString(time.wMinute).c_str());
string nSec = listJoin("U4", IntToString(time.wSecond).c_str());
string nMilliseconds = listJoin("I4", IntToString(time.wMilliseconds).c_str());
string pLTypeTmp = listJoin(nMinute.c_str(),
nSec.c_str(),
nMilliseconds.c_str());
result = pLTypeTmp.c_str();
}
break;
default:
{
result = "";
CString pTmp;
pTmp.Format("error variable %d, please contact the engineer", varID);
OutputDebugString(pTmp);
}
break;
}
return (LPCSTR)result;
}
讲解:
1. 何时调用:
当SECS/GEM需要对应变量的时候,SDK将会调用该函数询问设备变量的值。
2. 关联行:
初始化的时候,把该函数添加到回调中。
m_pSecs->m_pVarValueProc = ::OnVarValueProc;
3. 所需工作
判断变量ID,返回变量ID对应的数值
2.5 警报发送1. 找到下边的界面,双击界面的Set或Clear按钮,进入代码
2. 警报发生的时候,只需将“警报ID”和“true状态”发送。
3. 警报清除后,只需将“警报ID”和“false状态”发送。
2.6 事件发送
1. 找到下边的界面,双击界面的“发送事件”按钮,进入代码
2. 事件发生的时候,只需发送对应的事件ID



