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

📄 opcdata.cpp

📁 OPC Client 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	//2. Release the interface references:
	m_pIServer->Release();
	m_pIServer=NULL;
	
	//3. Release the IShutdownSink
	m_pIShutdownSink->Release ();
	m_pIShutdownSink=NULL;
}
//*/

	m_bConnected=FALSE;

	//
	CString strTip;
	strTip.Format (_T("%s:%s(%s) 服务器已经关闭"),m_strRemoteMachine, m_strName,m_strProgID);
	//通知事件视中提示
	LogMsg(HINT_OPCSERVER_SHUTDOWN_EVENT+HINT_EVENT_OFFSET,(CObject *)&strTip);
	//通知相关视做处理
	LogMsg(HINT_OPCSERVER_SHUTDOWN_EVENT,this);
	//HINT_REMPC_SET_STATE
}

// **************************************************************************
// GetValue ()
//
// Description:
//	Returns a string representation of the current value.
//
// Parameters:
//
// Returns:
//  VARIANT
// **************************************************************************
VARIANT COPCItem::GetValue()
{
	return m_vtValue;
}

// **************************************************************************
// GetValue ()
//
// Description:
//	Returns a string representation of the current value.
//
// Parameters:
//	VARIANT vtValue
//
// Returns:
//  CString
// **************************************************************************
void COPCItem::GetValue(CString& strValue)
{
	// Format output string according to data type:
	TCHAR szNum [100];
	switch (m_vtValue.vt)
	{
		case VT_BOOL:
			wsprintf (szNum, _T("%d"), m_vtValue.boolVal ? 1 : 0);
			strValue=szNum;
			break;

		case VT_UI1:
			wsprintf (szNum, _T("%u"), m_vtValue.bVal);
			strValue=szNum;
			break;

		case VT_I1:
			wsprintf (szNum, _T("%d"), m_vtValue.cVal);
			strValue=szNum;
			break;

		case VT_UI2:
			wsprintf (szNum, _T("%u"), m_vtValue.uiVal);
			strValue=szNum;
			break;

		case VT_I2:
			wsprintf (szNum, _T("%d"), m_vtValue.iVal);
			strValue=szNum;
			break;

		case VT_UI4:
			wsprintf (szNum, _T("%u"), m_vtValue.ulVal);
			strValue=szNum;
			break;

		case VT_I4:
			wsprintf (szNum, _T("%d"), m_vtValue.lVal);
			strValue=szNum;
			break;

		case VT_R4:
			_stprintf (szNum, _T("%G"), m_vtValue.fltVal);
			strValue=szNum;
			break;

		case VT_R8:
			_stprintf (szNum, _T("%G"), m_vtValue.dblVal);
			strValue=szNum;
			break;

		case VT_BSTR:
			strValue = m_vtValue.bstrVal;
			break;

		default:
			strValue = "NULL";
			
	}
}

void COPCItem::SetTimeStamp(FILETIME ftTimeStamp)
{
	m_ftTimeStamp=ftTimeStamp;
}

void COPCItem::SetValue(VARIANT &varValue)
{
	m_vtValue=varValue;
	
}

//断开OPC服务器连接
bool COPCServer::Disconnect(BOOL bShutdownRequest/*=FALSE*/ )
{

	UINT unEventID=HINT_REMOVE_SERVER+HINT_EVENT_OFFSET;
	CString strTip;

try{
	//1. Remove the OPC Group:
	POSITION pos=m_cMapGroup.GetStartPosition ();
	COPCGroup* pGroup=NULL;
	CString strGroup;
	while(pos)
	{
		m_cMapGroup.GetNextAssoc (pos,strGroup,(void*&)pGroup);
		
		//1.释放项与OPC的连接
		pGroup->Uninitialize ();

		//2.释放组与OPC的连接
		if(!bShutdownRequest)
			RemoveGroupFromOPC(m_pIServer,pGroup->GetServerHandle (),strGroup);

	}

	//2. Release the interface references:
	m_pIServer->Release();
	m_pIServer=NULL;
	
	//3.Release IShutdownSink
	m_pIShutdownSink->Release ();
	m_pIShutdownSink = NULL;
	//
	strTip.Format (_T("%s:%s(%s) 断开连接"),m_strRemoteMachine, m_strName,m_strProgID);
	
	//
	//释放其他接口
	//1.
	if(m_pICommon)				//N/A		OPC20		OPC30 
	{
		m_pICommon->Release ();
		m_pICommon = NULL;
	}

	//2.
	if(m_pIConnPtContainer)	//N/A		OPC20		OPC30 
	{
		m_pIConnPtContainer->Release ();
		m_pIConnPtContainer = NULL;
	}

	//3.
	if(m_pIItemProps)			//N/A		OPC20		N/A 
	{
		m_pIItemProps->Release ();
		m_pIItemProps = NULL;
	}

	//4.
	if(m_pIBrowseAddressSpace)	//Optional	OPC20		N/A
	{
		m_pIBrowseAddressSpace->Release ();
		m_pIBrowseAddressSpace = NULL;
	}

	//5.
	if(m_pIPublicGroups)		//Optional	Optional	N/A
	{
		m_pIPublicGroups->Release ();
		m_pIPublicGroups = NULL;
	}

	//6.
	if(m_pIBrowse)				//N/A		N/A			OPC30
	{
		m_pIBrowse->Release ();
		m_pIBrowse = NULL;
	}

	//7.
	if(m_pIItemIO)				//N/A		N/A			OPC30
	{
		m_pIItemIO->Release ();
		m_pIItemIO = NULL;
	}

	//8.
	if(m_pIPersistFile)
	{
		m_pIPersistFile->Release ();
		m_pIPersistFile = NULL;
	}

	//9.释放接收器接口
	if(m_pIShutdownSink)
	{
		//得到连接点对象:
		IConnectionPoint *pCP = NULL;
		HRESULT hr = m_pIConnPtContainer->FindConnectionPoint (IID_IOPCShutdown, &pCP);
		//断开接收器与可连接对象的连接
		pCP->Unadvise (m_dwCookieShutdownSink);
		pCP->Release ();

		m_pIShutdownSink->Release ();
		m_pIShutdownSink = NULL;
	}

}
catch(...)
{
	strTip.Format (_T("%s:%s(%s) 断开连接出现异常"),m_strRemoteMachine, m_strName,m_strProgID);
}

	m_bConnected=FALSE;

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

	return 1;
}

void COPCServer::RemoveGroupFromOPC(IOPCServer *pIOPCServer, OPCHANDLE hServerGroup,CString strGroupName)
{
	// 
	UINT unEventID=HINT_GROUP_REMOVE+HINT_EVENT_OFFSET;
	CString strResult=_T("NULL");

try{

//	HRESULT hr = pIOPCServer->RemoveGroup( hServerGroup, FALSE);
	HRESULT hr = pIOPCServer->RemoveGroup( hServerGroup, TRUE);

	switch(hr)
	{
	case S_OK:
		strResult.Format (_T("%s 组删除 成功"),strGroupName);
		break;
	case E_FAIL:
		strResult.Format (_T("%s 组删除 失败"),strGroupName);
		break;
	case E_OUTOFMEMORY:
		strResult.Format (_T("%s 组删除 失败(没有足够内存)"),strGroupName);
		break;
	case E_INVALIDARG:
		strResult.Format (_T("%s 组删除 失败(参数错误)"),strGroupName);
		break;
	case OPC_S_INUSE:
		strResult.Format (_T("%s 组删除 成功(存在参考)"),strGroupName);
		break;
	default:
		{
			strResult.Format (_T("%s 组删除(不知道的错误)"),strGroupName);
		}
	}
	TRACE(_T("RemoveGroup::%s  \n"),strResult);
	//	_ASSERT(!hr);
}catch(...)
{
	strResult.Format (_T("%s 组删除 出现异常"),strGroupName);
}

	//
	LogMsg(unEventID,(CObject *)& strResult);

}

int COPCServer::AddGroupToOPC(COPCGroup* pGroup)
{
	//检查结果
	UINT unEventID=HINT_GROUP_ADD+HINT_EVENT_OFFSET;
	CString strTip;
	//
	DWORD dwUpdateRate = 0;
	OPCHANDLE hClientGroup = 0;

	// If we are connected to OPC Server, issue a request to add this group:
	//判断OPC Server 是否连接到OPC
	if (!m_bConnected)
	{	// No connection:

	// Log message that says we can't add the OPC Group because we are not
	// connected to OPC Server:
		strTip.Format (_T("错误:(OPC Server)%s 没有连接上"),m_strName);
		//事件视中提示
		LogMsg(unEventID,(CObject *)& strTip);
	return 1;
	}

	// Initialize arguments for add group request:
	//初始化组的值
	HRESULT hr				= E_FAIL;
	WCHAR *pszName			= NULL;
	LPCTSTR lpszName		= pGroup->GetName ();
	float fDeadband			= pGroup->GetDeadband ();
	long lTimeBias			= pGroup->GetTimeBias ();
	OPCHANDLE hServer		= NULL;
	IUnknown *pUnknown		= NULL;

	DWORD dwRevUpdateRate	= 0;

	// All strings transmitted by COM must be in wide character (Unicode) format.
	// Declare a buffer to contain name string in wide character format.
	//在COM中,所有的字符串传输必须是宽字符格式
	WCHAR wchBuffer	[DEFBUFFSIZE];

	// Convert the string format:
	if (lpszName != NULL)
	{
#ifdef _UNICODE
		// String is already in Unicode format, so simply copy into buffer:
		lstrcpyn (wchBuffer, lpszName, sizeof (wchBuffer) / sizeof (WCHAR));
#else
		// String is not in Unicode format, so convert and place result into buffer:
		if (!MultiByteToWideChar (CP_ACP, 0, lpszName, -1, wchBuffer, DEFBUFFSIZE))
			{
			ASSERT (FALSE);
			return 0;
			}
#endif

			// Reassign name pointer to buffer:
		pszName = wchBuffer;
	}
	
	// Add an OPC group and get a pointer to the IUnknown I/F:

	ASSERT(m_pIServer);

	hr = m_pIServer->AddGroup (
			pszName,							// [in] group name
			pGroup->IsActive (),				// [in] active state
			pGroup->GetUpdateRate (),			// [in] requested update rate
			(OPCHANDLE) pGroup,					// [in] our handle to this group
			&lTimeBias,							// [in] time bias
			&fDeadband,							// [in] percent deadband
			pGroup->GetLanguageID (),			// [in] requested language ID
			&pGroup->m_hServer,					// [out] server handle to this group
			&dwRevUpdateRate,					// [out] revised update rate 
//			IID_IOPCItemMgt,					// [in] request an IUknown pointer /*riid*/
//			(IUnknown**) &pGroup->m_pIOPCItemMgt//	/*ppUnk*/
			IID_IUnknown,						// [in] request an IUknown pointer
			&pUnknown
		);

//		hr = m_pIServer->AddGroup(
//			/*szName*/ lpszName ,
//			/*bActive*/ FALSE,
//			/*dwRequestedUpdateRate*/ dwUpdateRate,
//			/*hClientGroup*/ hClientGroup,
//			/*pTimeBias*/ 0,
//			/*pPercentDeadband*/ 0,
//			/*dwLCID*/0,
//			/*phServerGroup*/&pGroup->m_hServerGroup,
//			&dwUpdateRate,
//			/*riid*/ IID_IOPCItemMgt,
//			/*ppUnk*/ (IUnknown**) &pGroup->m_pIOPCItemMgt);
	_ASSERT(!FAILED(hr));
	//
	switch(hr)
	{
	case S_OK:
		strTip.Format (_T("%s 组增加 成功"),lpszName);
		
		//使组有效
		pGroup->SetValid (TRUE);

		// We should have gotten a valid pointer to the OPC Groups's IUnknown interface.
		// Set some things that only make sence if we have a vaild IUnknown pointer:
		if (pUnknown)
			{
			// Reset update rate if OPC Server does not support requested rate:
			if (pGroup->GetUpdateRate () != dwRevUpdateRate)
				pGroup->SetUpdateRate (dwRevUpdateRate);

			// Initialize the CGroup object, which will include getting necessary
			// interface pointers from IUnknown:
			//pGroup->m_hServer = hServer;
			pGroup->Initialize (pUnknown);

			// We can release the IUnknown pointer since initialized group
			// should have gotten the interface pointers it needs from it.
			pUnknown->Release ();
			}
			else
			{
			TRACE (_T("OPC: Warning added group %s to OPC server, but IUnknown is invalid.\r\n"),
				pGroup->GetName ());
			}
		break;
	case E_FAIL:
		strTip.Format(_T("%s 组增加函数调用 失败"),lpszName);
		break;
	case E_OUTOFMEMORY:
		strTip.Format (_T("%s 组增加函数调用 失败(无足够内存)"),lpszName);
		break;
	case E_INVALIDARG:
		strTip.Format (_T("%s 组增加函数调用 失败(参数错误)"),lpszName);
		break;
	case OPC_E_DUPLICATENAME:
		strTip.Format (_T("%s 组增加函数调用 失败(重名)"),lpszName);
		break;
	case OPC_S_UNSUPPORTEDRATE:
		strTip.Format (_T("%s 组增加函数调用 失败(更新速率不支持)"),lpszName);
		break;
	case E_NOINTERFACE:
		strTip.Format (_T("%s 组增加函数调用 失败(不支持接口IID_IUnknown)"),lpszName);
		break;
	default:
		strTip.Format (_T("%s 组增加函数调用 失败(不知道的错误)"),lpszName);
	}

	//事件视中提示
	LogMsg(unEventID,(CObject *)& strTip);
		
	return 2;
}

void COPCGroup::SetOPCServer(COPCServer* pOPCServer)
{
	m_pOPCServer=pOPCServer;
}

COPCServer* COPCGroup::GetOPCServer()
{
	return m_pOPCServer;
}

long COPCGroup::GetTimeBias()
{
	return m_lTimeBias;
}

float COPCGroup::GetDeadband()
{
	return m_fDeadband;
}

CString COPCGroup::GetName()
{
	return m_strName;
}

BOOL COPCGroup::IsActive()
{
	return m_bActive;
}

BOOL COPCGroup::IsBeingItem(CString &strItemID)
{
	BOOL bBeing=FALSE;

	COPCItem* pItem;
	if(m_cMapItem.Lookup (strItemID,(CObject *&)pItem))
		bBeing=TRUE;

	return bBeing;
}

BOOL COPCGroup::IsBeingAlias(CString &strAlias)
{
	BOOL bBeing=FALSE;

	COPCItem* pItem;
	if(m_cMapAlias.Lookup (strAlias,(CObject *&)pItem))
		bBeing=TRUE;

	return bBeing;
}

BOOL COPCGroup::IsConnected()
{
	BOOL bConnected=FALSE;
	if(m_pIOPCItemMgt)
		bConnected=TRUE;

	return bConnected;
}

DWORD COPCGroup::GetUpdateRate()
{
	return m_dwUpdateRate;
}

LCID COPCGroup::GetLanguageID()
{
	return m_dwLanguageID;
}

void COPCGroup::ReadItem()
{
	OPCHANDLE hServerItem;
	VARIANT varValue;

⌨️ 快捷键说明

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