📄 opcdata.cpp
字号:
pErrors = NULL;
}
void COPCGroup::DelItem()
{
CStringArray cItems;
POSITION pos=m_cMapItem.GetStartPosition ();
CString strKey;
COPCItem* pItem=NULL;
while(pos)
{
m_cMapItem.GetNextAssoc (pos,strKey,(CObject *&)pItem);
cItems.Add (strKey);
}
DelItem(&cItems);
m_cMapAlias.RemoveAll ();
}
void COPCGroup::DelItem(CStringArray *pcItems)
{
ASSERT(pcItems);
CString rKey;
COPCItem* pItem=NULL;
int nUpperBound=pcItems->GetUpperBound ();
OPCHANDLE* phServerArray=new OPCHANDLE[nUpperBound+1];
ASSERT(phServerArray);
int nIndexValid=0;
for(int nIndex=0;nIndex<=nUpperBound;nIndex++)
{
rKey=pcItems->GetAt (nIndex);
if(m_cMapItem.Lookup (rKey,(CObject *&)pItem))
phServerArray[nIndexValid++]=pItem->GetServerHandle ();
}
DelItemToOPC(nIndexValid,phServerArray,pcItems);
delete[] phServerArray;
for(nIndex=0;nIndex<=nUpperBound;nIndex++)
{
rKey=pcItems->GetAt (nIndex);
if(m_cMapItem.Lookup (rKey,(CObject *&)pItem))
{
m_cMapItem.RemoveKey (rKey);
m_cMapAlias.RemoveKey(pItem->GetAlias());
delete pItem;
pItem=NULL;
}
}
}
//------------------------------------------------------------------
//OPC 2.0----OPCGroup
//------------------------------------------------------------------
//------------------------------------------------------------------
//OPC2.0 IOPCAsyncIO2::Read 异步读数据
//------------------------------------------------------------------
void COPCGroup::ReadAsync20 (CObArray &cItems) //异步读数据
{
if (!m_pOPCServer->IsConnected () //连接状态
|| !m_pIOPCAsync2) //IOPCAsyncIO2
return;
DWORD dwItems=cItems.GetUpperBound ()+1;
if(0>=dwItems) //没有OPCItem
return;
ASSERT (m_dwCookieDataSink20 != 0);
DWORD dwIndex = 0;
COPCItem *pItem = NULL;
OPCHANDLE *phServer = NULL;
DWORD dwClientTransID = GetTickCount (); // client provided transaction for notifications (not useful right now)
DWORD dwCancelTransID = 0;
HRESULT *pErrors = NULL;
HRESULT hr = E_FAIL;
DWORD dwSuccess = 0;
// Allocate storage for server item handles:
phServer = (OPCHANDLE *) CoTaskMemAlloc (dwItems * sizeof (OPCHANDLE));
// Return if allocation failed:
if (phServer == NULL)
{
ASSERT (FALSE);
return;
}
// Fill request [in] arguments:
for (dwIndex = 0; dwIndex < dwItems; dwIndex++)
{
// Get pointer to item in input list:
COPCItem *pItem = (COPCItem *) cItems [dwIndex];
ASSERT (pItem != NULL);
// Set server handle:
phServer [dwIndex] = pItem->GetServerHandle ();
}
//检查结果
UINT unEventID=HINT_ITEM_READ;
CString strTip="NULL";
// Wrap request processing in exception hander in case we get
// a bad pointer:
try
{
// Issue read request using IOPCAsyncIO2 interface:
hr = m_pIOPCAsync2->Read(
dwItems, // Number of items requested
phServer, // Item server handles
dwClientTransID, // Client generated transaction id received in callback
&dwCancelTransID, // Server generated transaction id used for canceling this xact
&pErrors);
switch(hr)
{
case E_FAIL:
strTip.Format (_T("[%s]组读数据函数操作 失败"),m_strName);
break;
case E_OUTOFMEMORY:
strTip.Format (_T("[%s]组读数据函数没有足够内存"),m_strName);
break;
case E_INVALIDARG:
strTip.Format (_T("[%s]组读数据函数非法参数"),m_strName);
break;
case CONNECT_E_NOCONNECTION:
strTip.Format (_T("[%s]组读数据函数 失败(没有注册回调函数)"),m_strName);
break;
case S_OK:
case S_FALSE:
{
CString strTemp;
for(DWORD nIndex=0;nIndex<dwItems;nIndex++)
{
switch(pErrors[nIndex])
{
case S_OK:
{
strTemp=_T(" 项读操作调用 成功");
break;
}
case E_FAIL:
{
strTemp=_T(" 项读操作调用 失败");
break;
}
case OPC_E_BADRIGHTS:
{
strTemp=_T(" 项读操作 失败(数据项为只写属性)");
break;
}
case OPC_E_INVALIDHANDLE:
{
strTemp=_T(" 项读操作 失败(无效句柄)");
break;
}
case OPC_E_UNKNOWNITEMID:
{
strTemp=_T(" 读无知的ID(OPCServer中不存在)");
break;
}
default:
;
}
COPCItem *pItem = (COPCItem *) cItems [nIndex];
strTip=pItem->GetItemID ();
strTip+=strTemp;
}
break;
}
default:
{
strTip.Format (_T("[%s]组读数据(不知道的错误)"),m_strName);
TRACE(_T("COPCGroup::WriteAsync20()---no know error\n"));
}
}
}//try
catch (...)
{
// Probably hit a bad pointer. Try to process next item.
TRACE (_T("OPC: ReadAsync20 exception handler invoked\r\n"));
strTip.Format (_T("[%s]组读数据 出现异常错误"),m_strName);
if (m_pOPCServer->IsConnected ())
{
// We not disconnected so why was an exception thrown?
ASSERT (FALSE);
}
}
//事件视中提示
LogMsg(unEventID,(CObject *)& strTip);
// COM requires us to free memory allocated for [out] and [in/out]
// arguments (i.e. phServer, and pErrors):
CoTaskMemFree (phServer);
if (pErrors)
CoTaskMemFree (pErrors);
}
//------------------------------------------------------------------
//OPC2.0 IOPCAsyncIO2::Refresh2 异步刷新数据
//------------------------------------------------------------------
void COPCGroup::ReadAsync20 (CStringArray &cItemNames) //异步读数据
{
CObArray cItems;
GetItem(cItemNames,cItems);
ReadAsync20(cItems);
}
//------------------------------------------------------------------
//OPC2.0 IOPCAsyncIO2::Refresh2 异步刷新数据
//------------------------------------------------------------------
void COPCGroup::RefreshAsync20 (bool bCacheRead/*=true*/) //异步刷新数据
{
// the OPC Server and have a pointer to the IOPCAsyncIO2 interface.
if (!m_pOPCServer->IsConnected () //连接状态
|| m_pIOPCAsync2) //IOPCAsyncIO2
return;
ASSERT (m_dwCookieDataSink20 != 0);
OPCDATASOURCE dwSource = bCacheRead ? OPC_DS_CACHE : OPC_DS_DEVICE ;
DWORD dwCancelTransID = 0;
DWORD dwClientTransID = GetTickCount (); // client provided transaction for notifications (not useful right now)
HRESULT hr = E_FAIL;
// Wrap request processing in exception hander in case we get
// a bad pointer - Not really needed in this case, but this keeps
// same code structure as other operations:
try
{
// Issue refresh request using IOPCAsyncIO2 interface:
hr = m_pIOPCAsync2->Refresh2 (
dwSource, // Data Source CACHE or DEVICE
dwClientTransID, // Client generated transaction id received in callback
&dwCancelTransID); // Server generated transaction id used for canceling this xact
// Log results:
if (SUCCEEDED (hr))
{
// Log request succeeded message. Log different message for device and
// cache refres.
// LogMsg (bDeviceRead ? IDS_ASYNC20_REFRESHDEVICE_SUCCESS : IDS_ASYNC20_REFRESHCACHE_SUCCESS,
// dwClientTransID, GetName ());
}
else
{
// Log request faild messgae. Log different message for device and
// cache refreshes:
// LogMsg (bDeviceRead ? IDS_ASYNC20_REFRESHDEVICE_FAILURE : IDS_ASYNC20_REFRESHCACHE_FAILURE,
// GetName (), hr);
}
}
catch (...)
{
// Probably hit a bad pointer. Try to process next item.
TRACE (_T("OPC: RefreshAsync20 exception handler invoked\r\n"));
if (m_pOPCServer->IsConnected ())
{
// We not disconnected so why was an exception thrown?
ASSERT (FALSE);
}
}//CATCH
}
//------------------------------------------------------------------
//OPC2.0 IOPCAsyncIO2::Write 异步写数据
//------------------------------------------------------------------
void COPCGroup::WriteAsync20 (CStringArray &cItemNames, CStringArray &cstrValues) //异步写数据
{
CObArray cItems;
GetItem(cItemNames,cItems);
WriteAsync20(cItems,cstrValues);
}
//------------------------------------------------------------------
//OPC2.0 IOPCAsyncIO2::Write 异步写数据
//------------------------------------------------------------------
void COPCGroup::WriteAsync20 (CObArray &cItems, CStringArray &cstrValues) //异步写数据
{
// the OPC Server and have a pointer to the IOPCAsyncIO2 interface.
if (!m_pOPCServer->IsConnected () //连接状态
|| !m_pIOPCAsync2) //IOPCAsyncIO2
return;
DWORD dwItems=cItems.GetUpperBound ()+1;
if(0>=dwItems) //没有OPCItem
return;
ASSERT (m_dwCookieDataSink20 != 0);
DWORD dwIndex = 0;
COPCItem *pItem = NULL;
OPCHANDLE *phServer = NULL;
VARIANT *pValues = NULL;
HRESULT *pErrors = NULL;
HRESULT hr = E_FAIL;
DWORD dwCancelTransID = 0;
DWORD dwSuccess = 0;
DWORD dwClientTransID = GetTickCount (); // client provided transaction for notifications (not useful right now)
DWORD dwSentItems = 0;
// Allocate storage for server item handles and write values:
phServer = (OPCHANDLE *) CoTaskMemAlloc (dwItems * sizeof (OPCHANDLE));
pValues = (VARIANT *) CoTaskMemAlloc (dwItems * sizeof (VARIANT));
// Return if allocation failed:
if (phServer == NULL || pValues == NULL)
{
ASSERT (FALSE);
return;
}
// Fill request [in] arguments:
for (dwIndex = 0, dwSentItems = 0; dwIndex < dwItems; dwIndex++)
{
// Get pointer to item in input list:
COPCItem *pItem = (COPCItem *) cItems [dwIndex];
ASSERT (pItem != NULL);
// Load data for array type:
if (pItem->GetDataType () & VT_ARRAY)
{
// Convert array values in string format to variant array. If succeed,
// set server handle:
if (MapStringValToArrayVariant (cstrValues [dwSentItems],&pItem->GetValue (), &pValues[dwSentItems]))
phServer [dwSentItems++] = pItem->GetServerHandle ();
else
{
// Failed to convert array values in string format to variant array:
// Invalidate item:
cItems [dwIndex] = NULL;
}
}
// Load data for non-array type:
else
{
// Convert value in string format to variant. If succeed, set server
// handle:
if (MapStringValToVariant (cstrValues [dwSentItems], pValues [dwSentItems], pItem->GetDataType ()))
phServer [dwSentItems++] = pItem->GetServerHandle ();
else
{
// Failed ot convert value in string format to variant:
// Invalidate item:
cItems [dwIndex] = NULL;
}
}
}
//检查结果
UINT unEventID=HINT_ITEM_WTRITE+HINT_EVENT_OFFSET;
CString strTip="NULL\n";
// Wrap request processing in execption handler in case we get
// a bad pointer:
try
{
// Issue write request using IOPCAsyncIO2 interface:
hr = m_pIOPCAsync2->Write (
dwSentItems, // Number of items to write
phServer, // Server item handles
pValues, // Item data to write
dwClientTransID, // Client generated transaction ID
&dwCancelTransID, // [out] server assigned transaction ID for this request (use if canceling transaction)
&pErrors); // [out] error results
switch(hr)
{
case E_FAIL:
strTip.Format (_T("[%s]组写数据函数操作 失败"),m_strName);
break;
case E_OUTOFMEMORY:
strTip.Format (_T("[%s]组写数据函数没有足够内存"),m_strName);
break;
case E_INVALIDARG:
strTip.Format (_T("[%s]组写数据函数非法参数"),m_strName);
break;
case CONNECT_E_NOCONNECTION:
strTip.Format (_T("[%s]组写数据函数 失败(没有注册回调函数)"),m_strName);
break;
case S_OK:
case S_FALSE:
{
CString strTemp;
for(DWORD nIndex=0;nIndex<dwSentItems;nIndex++)
{
switch(pErrors[nIndex])
{
case S_OK:
{
strTemp=_T(" 项写操作调用 成功");
break;
}
case E_FAIL:
{
strTemp=_T(" 项写操作调用 失败");
break;
}
case OPC_E_BADRIGHTS:
{
strTemp=_T(" 项写操作 失败(数据项只读属性)");
break;
}
case OPC_E_INVALIDHANDLE:
{
strTemp=_T(" 项写操作 失败(无效句柄)");
break;
}
case OPC_E_UNKNOWNITEMID:
{
strTemp=_T(" 项无知的ID(OPCServer中不存在)");
break;
}
default:
;
}
COPCItem *pItem = (COPCItem *) cItems [nIndex];
strTip=pItem->GetItemID ();
strTip+=strTemp;
}
break;
}
default:
{
strTip.Format (_T("[%s]组写数据函数 失败(不知道的错误)"),m_strName);
TRACE(_T("COPCGroup::WriteAsync20()---no know error\n"));
}
}
}//try
catch (...)
{
// Probably hit a bad pointer. Try to process next item.
TRACE (_T("OPC: WriteAsync20 exception handler invoked\r\n"));
if (m_pOPCServer->IsConnected ())
{
// We not disconnected so why was an exception thrown?
ASSERT (FALSE);
}
}
// COM requires us to free memory allocated for [out] and [in/out]
// arguments (i.e. phServer, pValues, and pErrors):
CoTaskMemFree (phServer);
CoTaskMemFree (pValues);
if (pErrors)
CoTaskMemFree (pErrors);
//事件视中提示
LogMsg(unEventID,(CObject *)& strTip);
}
// **************************************************************************
// MapStringValToArrayVariant ()
//
// Description:
// Map a string of array elements to a variant array.
//
// Parameters:
// CString &strValue Input string.
// VARIANT *pvtSrc Source variant. Used to set properties of
// destination variant.
// VARIANT *pvtDst Destination variant
//
// Returns:
// bool - true if successful.
// **************************************************************************
bool COPCGroup::MapStringValToArrayVariant (CString &strValue, VARIANT *pvtSrc, VARIANT *pvtDst)
{
// Source variant must not be empty:
if (pvtSrc->vt == VT_EMPTY)
return (false);
ASSERT (pvtSrc != NULL);
ASSERT (pvtDst != NULL);
ASSERT (pvtSrc->vt & VT_ARRAY);
// Source variant must contain array data:
if (!pvtSrc->parray)
return (false);
int cnRows = 0;
int cnCols = 0;
TCHAR szValue [DEFBUFFSIZE];
// Create a local copy of input string:
lstrcpyn (szValue, strValue, (sizeof (szValue) / sizeof (TCHAR)) - sizeof (TCHAR));
// Set number of rows and columns for this array:
// 1-D array:
if (pvtSrc->parray->cDims == 1)
{
cnRows = 1;
cnCols = pvtSrc->parray->rgsabound [0].cElements;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -