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

📄 opcdata.cpp

📁 OPC Client 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// value of the item:
	OPCITEMSTATE* pValue = NULL;

	//get a pointer to the IOPCSyncIOInterface:
	IOPCSyncIO* pIOPCSyncIO;
	m_pIOPCItemMgt->QueryInterface(__uuidof(pIOPCSyncIO), (void**) &pIOPCSyncIO);

	//从设备中读取项值:
	HRESULT* pErrors = NULL; //存储错误代码

	CString strItem;
	COPCItem Item;
	POSITION pos=m_cMapItem.GetStartPosition ();
	while(pos)
	{
		m_cMapItem.GetNextAssoc (pos,strItem,(CObject *&)Item);
		hServerItem=Item.GetServerHandle () ;

		HRESULT hr = pIOPCSyncIO->Read (OPC_DS_DEVICE, 1, &hServerItem, &pValue, &pErrors);
		_ASSERT(!hr);
		_ASSERT(pValue!=NULL);

		Item.SetValue (pValue[0].vDataValue);		//设定项值
		m_cMapItem.SetAt (strItem,(CObject *)&Item);	//更新项

		varValue = pValue[0].vDataValue;
	}

}

BOOL COPCGroup::WriteItem(CString strItem, VARIANT& varValue)
{
	COPCItem Item;
	if(!m_cMapItem.Lookup (strItem,(CObject *&)Item))
		return FALSE;

	OPCHANDLE hServerItem=Item.GetServerHandle () ;

	//得到IOPCSyncIO接口指针:
	IOPCSyncIO* pIOPCSyncIO;
	m_pIOPCItemMgt->QueryInterface(__uuidof(pIOPCSyncIO), (void**) &pIOPCSyncIO);

	//写项值到OPCServer:
	HRESULT* pErrors = NULL; //存储错误代码

	HRESULT hr = pIOPCSyncIO->Write (1,&hServerItem, &varValue, &pErrors);
	_ASSERT(!hr);

	//Release memeory allocated by the OPC server:
	CoTaskMemFree(pErrors);
	pErrors = NULL;

	//释放IOPCSyncIO接口:
	pIOPCSyncIO->Release();

	if(hr==TRUE)
	{
		//更新项值
		Item.SetValue (varValue);
		m_cMapItem.SetAt (strItem,(CObject *&)Item);

		return TRUE;
	}
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
//COPCGroup: Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL( COPCGroup, CObject, VERSIONABLE_SCHEMA | 2 )

COPCGroup::COPCGroup()
{
	m_hTreeItem=NULL;


	// OPC Group properties:
	m_strName			= GROUP_DEFAULT_NAME;
	m_dwUpdateRate		= GROUP_DEFAULT_UPDATERATE;	
	m_dwLanguageID		= GROUP_DEFAULT_LANGUAGEID;	
	m_lTimeBias			= GROUP_DEFAULT_TIMEBIAS;
	m_fDeadband			= GROUP_DEFAULT_DEADBAND;
	m_bActive			= GROUP_DEFAULT_ACTIVESTATE;
	m_dwUpdateMethod	= GROUP_DEFAULT_UPDATEMETHOD;

	m_hServer			= NULL;
	m_bValid			= FALSE;

	// Interface pointers :
	m_pIOPCGroupStateMgt			= NULL;
	m_pIOPCPublicGroupStateMgt		= NULL;
	m_pIOPCItemMgt				= NULL;
	m_pIOPCSync					= NULL;
	m_pIOPCAsync				= NULL;
	m_pIDataObject			= NULL;
	m_pIOPCAsync2				= NULL;		
	m_pIConnPtContainer			= NULL;

	m_pIDataSink20				= NULL;
	m_dwCookieDataSink20		= 0;

//	m_pIAdviseSink				= NULL;
	m_dwCookieRead				= 0;
	m_dwCookieWrite				= 0;

	//
//	m_bConnected=FALSE;

}

COPCGroup::~COPCGroup()
{
//	ASSERT (m_cdwItems == 0);

	ASSERT (m_pIOPCGroupStateMgt == NULL);
	ASSERT (m_pIOPCPublicGroupStateMgt == NULL);
	ASSERT (m_pIOPCItemMgt == NULL);
	ASSERT (m_pIOPCSync == NULL);
	ASSERT (m_pIOPCAsync == NULL);
	ASSERT (m_pIDataObject == NULL);
	ASSERT (m_pIOPCAsync2 == NULL);
	ASSERT (m_pIConnPtContainer == NULL);
	
	ASSERT (m_pIDataSink20 == NULL);
	ASSERT (m_dwCookieDataSink20 == 0);

//	ASSERT (m_pIAdviseSink == NULL);
//	ASSERT (m_dwCookieRead == 0);
//	ASSERT (m_dwCookieWrite == 0);

	// 删除项数据
	COPCItem* pItem=NULL;
	CString rKey;

	POSITION pos=m_cMapItem.GetStartPosition ();
	while(pos)
	{
		m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);
		TRACE("COPCGroup::~COPCGroup()---%s\n",rKey);
		delete pItem;
		pItem=NULL;
	}
	
}

void COPCGroup::AddItem(COPCItem *pItem)
{
	m_cMapItem.SetAt(pItem->GetItemID(),pItem);
	m_cMapAlias.SetAt(pItem->GetAlias(),pItem);

	m_strItemNames.RemoveAll ();
	m_strItemNames.Add (pItem->GetAlias ());
	//
	OPCHANDLE hOPCHandle;
	AddItemToOPC(1,&pItem->GetOPCITEMDEF (),&hOPCHandle);
	pItem->SetServerHandle (hOPCHandle);

}

void COPCGroup::ConnectItemToOPC()
{
	int nCount=m_cMapItem.GetCount();
	if(nCount<=0)
		return;

	OPCITEMDEF* pOPCItemDef=NULL;
	OPCHANDLE* pOPCHandle=NULL;	
	COPCItem* pItem=NULL;
	CString rKey;
	int nIndex=0;
	try{
	pOPCItemDef=new OPCITEMDEF[nCount];
	pOPCHandle=new OPCHANDLE[nCount];

	}catch(...){
		CString strError;

		if(pOPCItemDef)
			delete[] pOPCItemDef;
		else
			strError.Format (_T("COPCGroup 连接 OPC 错误(OPCITEMDEF 申请内存)!"),m_strName);

		if(pOPCHandle)
			delete[] pOPCHandle;
		else
			strError.Format (_T("COPCGroup 连接 OPC 错误(OPCHANDLE 申请内存)!"),m_strName);
		AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
		return;
	}

	m_strItemNames.RemoveAll ();
	POSITION pos=m_cMapItem.GetStartPosition ();
	nIndex=0;
	try{
	while(pos)
	{
		m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);

		pItem->GetOPCITEMDEF (pOPCItemDef[nIndex++]);
		m_strItemNames.Add (pItem->GetAlias ());
	}
	}catch(...){
		CString strError;
		strError.Format (_T("COPCGroup 连接第%d项OPC Item[%s] GetOPCITEMDEF()错误\nOPC Item 共有%d项!"),nIndex,rKey,nCount);
		AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
		return;
	}
	//
	AddItemToOPC(nCount,pOPCItemDef,pOPCHandle);

	//Set Server Handle
	pos=m_cMapItem.GetStartPosition ();
	nIndex=0;
	try{
	while(pos)
	{
		m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);

		pItem->SetServerHandle (pOPCHandle[nIndex++]);
//		CString strError;
//		strError.Format (_T("COPCGroup 连接第%d项OPC Item[%s] \nOPC Item 共有%d项!"),nIndex,rKey,nCount);
//		AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
	}
	}catch(...){
		CString strError;
		strError.Format (_T("COPCGroup 连接第%d项OPC Item[%s]SetServerHandle() 错误\nOPC Item 共有%d项!"),nIndex,rKey,nCount);

		if(pOPCItemDef)
			delete[] pOPCItemDef;
		else
			strError.Format (_T("COPCGroup 连接 OPC 错误(OPCITEMDEF 申请内存)!"),m_strName);

		if(pOPCHandle)
			delete[] pOPCHandle;
		else
			strError.Format (_T("COPCGroup 连接 OPC 错误(OPCHANDLE 申请内存)!"),m_strName);
		AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
		return;
	}

	delete[] pOPCItemDef;
	delete[] pOPCHandle;
}


void COPCGroup::AddItemToOPC(int nCount,OPCITEMDEF* pOPCItemDef,OPCHANDLE* pOPCHandle)
{
	HRESULT hr;

	
	// Array of items to add:
//	OPCITEMDEF ItemArray[1] =
//	{{
//	/*szAccessPath*/ L"",
//	/*szItemID*/ ITEM_ID,				//项名称
//	/*bActive*/ FALSE,
//	/*hClient*/ 1,
//	/*dwBlobSize*/ 0,
//	/*pBlob*/ NULL,
//	/*vtRequestedDataType*/ VT_R4,		//数据类型
//	/*wReserved*/0
//	}};

	//Add Result:
	OPCITEMRESULT* pAddResult=NULL;
	HRESULT* pErrors = NULL;
	// Add an Item to the previous Group:
//	hr = pIOPCItemMgt->AddItems(1, ItemArray, &pAddResult, &pErrors);
	//
	try{
	if(m_pIOPCItemMgt)
		hr = m_pIOPCItemMgt->AddItems(nCount, pOPCItemDef, &pAddResult, &pErrors);
	else
		AfxMessageBox(_T("COPCGroup 连接 OPC Item AddItemToOPC()错误::m_pIOPCItemMgt=NULL"), MB_OK| MB_ICONQUESTION);

	_ASSERT(!hr);
	}catch(...){
		CString strError;
		strError.Format (_T("COPCGroup 连接 OPC Item AddItemToOPC()错误"));
		AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
		return;
	}


	// Server handle for the added item:
//	Item.SetServerHandle (pAddResult[0].hServer);
	bool bLogMsg=false;
	CString strTip=m_strName;
	CString strItemID;
	UINT    unID=HINT_ITEM_ADD+HINT_EVENT_OFFSET;
	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 S_OK:
	case S_FALSE:
	{
		CString strTemp;
		for(int nIndex=0;nIndex<nCount;nIndex++)
		{
			pOPCHandle[nIndex]=NULL;
			switch(pErrors[nIndex])
			{
			case S_OK:
				{
				pOPCHandle[nIndex]=pAddResult[nIndex].hServer;
				strTemp=_T(" 项增加 成功");
				break;
				}
			case OPC_E_INVALIDITEMID:
				{
				strTemp=_T(" 项的ID结构错误");
				break;
				}
			case OPC_E_UNKNOWNITEMID:
				{
				strTemp=_T(" 项无知的ID(OPCServer中不存在)");
				break;
				}
			case OPC_E_BADTYPE:
				{
				strTemp=_T(" 项数据类型错误");
				break;
				}
			case OPC_E_UNKNOWNPATH:
				{
				strTemp=_T(" 项数据访问路径错误");
				break;
				}
			default:
				;
			}


#ifdef _UNICODE
			DWORD dwLen;
			dwLen = lstrlen (pOPCItemDef[nIndex].szItemID);
			lstrcpyn (strItemID, pOPCItemDef[nIndex].szItemID, dwLen + 1);
#else
			strItemID=pOPCItemDef[nIndex].szItemID ;
#endif
			strTip.Format (_T("%s.%s[%s]"),m_strName,m_strItemNames.GetAt (nIndex),strItemID);
			strTip+=strTemp;

			//事件视中提示
			LogMsg(unID,(CObject *)& strTip);
			bLogMsg=true;
		}
		break;
	}
	default:
		{
			strTip.Format (_T("[%s]组增加项(不知道的错误)"),m_strName);
			TRACE(_T("COPCGroup::AddItemToOPC()---no know error\n"));
		}
	}
	m_strItemNames.RemoveAll ();

	//事件视中提示
	if(!bLogMsg)		//返回值非 S_OK/S_FALSE:
		LogMsg(unID,(CObject *)& strTip);

	// release memory allocated by the server:
	try{
	if(pAddResult)
	{
		if(pAddResult->pBlob)
			CoTaskMemFree(pAddResult->pBlob);
		CoTaskMemFree(pAddResult);
		pAddResult = NULL;
	}

	if(pAddResult)
	{
		CoTaskMemFree(pErrors);
		pErrors = NULL;
	}
	}catch(...){
		CString strError;
		strError.Format (_T("COPCGroup 连接项OPC Item ::AddItemToOPC() Release CoTaskMemFree()错误!"));
		AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
		return;
	}

}

BOOL COPCGroup::DelItem(const CString strItem)
{
	COPCItem* pItem;
	if(!m_cMapItem.Lookup (strItem,(CObject *&)pItem))
		return FALSE;

	OPCHANDLE hServerArray[1];
	hServerArray[0] = pItem->GetServerHandle () ;
	CStringArray cItems;
	cItems.Add (strItem);
	DelItemToOPC(1,hServerArray,&cItems);

	m_cMapAlias.RemoveKey (pItem->GetAlias());
	delete pItem;
	pItem=NULL;
	return m_cMapItem.RemoveKey (strItem);
}

BOOL COPCGroup::RemoveAllItemFromOPC()
{
	//释放数据
	int nItemCount=m_cMapItem.GetCount ();
	if(0==nItemCount)	//无数据
		return TRUE;
	//
	OPCHANDLE *phServer=new OPCHANDLE[nItemCount];
	int nIndex=0;
	HRESULT* pErrors = NULL;

	COPCItem* pItem=NULL;
	CString rKey;

	POSITION pos=m_cMapItem.GetStartPosition ();
	while(pos)
	{
		m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);

		//从服务器中释放
		phServer[nIndex++]=pItem->GetServerHandle ();

		//初始化数据
		pItem->InitializeOPCData ();
	}
	m_pIOPCItemMgt->RemoveItems (nItemCount,phServer,&pErrors);
	delete[] phServer;
	CoTaskMemFree(pErrors);	//释放内存
	pErrors = NULL;


	return TRUE;
}

void COPCGroup::DelItemToOPC(int nCount,OPCHANDLE* phServerArray,CStringArray *pcItems)
{
	if(pcItems==NULL
		||m_pIOPCItemMgt==NULL
		)
		return;
	if(nCount<=0)
		return;

	//从服务器中移除项
//	OPCHANDLE hServerArray[1];
//	hServerArray[0] = Item.GetServerHandle () ;
	
	HRESULT* pErrors; //存储错误代码
	HRESULT hr = m_pIOPCItemMgt->RemoveItems(nCount, phServerArray, &pErrors);
	_ASSERT(!hr);

	CString strTip=m_strName;
	UINT    unID=HINT_ITEM_ADD+HINT_EVENT_OFFSET;
	switch(hr)
	{
	case E_FAIL:
		strTip.Format (_T("[%s]组删除项---操作 失败"),m_strName);

		break;
	case E_INVALIDARG:
		strTip.Format (_T("[%s]组删除项---内部参数错误"),m_strName);

		break;
	case S_OK:
	case S_FALSE:
	{
		CString strTemp;
		for(int nIndex=0;nIndex<nCount;nIndex++)
		{
			if(S_OK==pErrors[nIndex])
			{
				strTemp=_T(" 项删除 成功");
			}
			else
			{
				strTemp=_T(" 项删除 失败(非法的句柄)");
			}
#ifdef _UNICODE
			DWORD dwLen;
			dwLen = lstrlen (pcItems->GetAt (nIndex));
			lstrcpyn (strTip, pOPCItemDef[nIndex].szItemID, dwLen + 1);
#else
			strTip=pcItems->GetAt (nIndex);
#endif
			strTip+=strTemp;

		}
		break;
	}
	default:
		{
			strTip.Format (_T("[%s]组删除项(不知道的错误)"),m_strName);

			TRACE(_T("COPCGroup::DelItemToOPC()---no know error\n"));
		}
	}

	//事件视中提示
	LogMsg(unID,(CObject *)& strTip);


	//释放内存
	CoTaskMemFree(pErrors);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -