⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opcdata.cpp

📁 OPC Client 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	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 + -