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

📄 group.cpp

📁 此为Insight opc client InfoServerExplorer源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
//  OPC DataAccess VC++ Client:	Group.CPP
//								(Source File)
//
/////////////////////////////////////////////////////////////////////////////
//
//          Author: Raphael Imhof
//    Initial Date: 11/04/98
//       $Workfile: Group.cpp $
//       $Revision: 2 $
//           $Date: 9/09/99 11:01a $
//   Target System: Microsoft Windows NT 4.0
//     Environment: Visual C++ 5.0 / OPC DataAccess 1.0/2.0
//         Remarks: 
//
/////////////////////////////////////////////////////////////////////////////
//
//     Description: implementation of the CGroup class.
//					Encapsulation of group related methods.
//					
//
/////////////////////////////////////////////////////////////////////////////
//
//  History of Changes     (Please remove very old comments and blank lines!)
//            $Log: /IDK/OPCServer/clients/VC++/InfoServerExplorer/Group.cpp $
// 
// 2     9/09/99 11:01a Imhof
// DCS 3227: Set changed flag to true and set the timestamp for read sync
// 
// 1     7/27/99 5:22p Imhof
// 
// 1     7/27/99 5:18p Imhof
// 
// 1     4/26/99 4:07p Imhof
// Readded after SS problems.
// 
// 14    2/24/99 2:02p Imhof
// Added ValidateItem option and support
// 
// 13    1/15/99 6:43p Imhof
// Updated legal notice.
// 
// 12    12/16/98 2:52p Imhof
// 
// 11    12/14/98 4:46p Imhof
// Modifications for OPC 2.0
// 
// 10    12/11/98 5:58p Imhof
// Made modifications for OPC 2.0.
// 
// 9     12/03/98 1:53p Imhof
// Removed read after additems
// 
// 8     11/12/98 2:39p Imhof
// Reenabled the remove item
// 
// 7     11/10/98 2:20p Imhof
// Added file header's.
// 
//  $Nokeywords:$ (To avoid useless search while checking in.)
/////////////////////////////////////////////////////////////////////////////
//  Copyright (C) 1998, Siemens Building Technologies, Inc. Landis Division
//
// SIEMENS BUILDING TECHNOLOGIES, INC. IS PROVIDING THE FOLLOWING
// EXAMPLES OF CODE AS SAMPLE ONLY.
//
// SIEMENS BUILDING TECHNOLOGIES, INC.  MAKES NO REPRESENTATIONS
// OR WARRANTIES OF ANY KIND  WITH RESPECT TO THE VALIDTY OF THE 
// CODES   OR   DESIRED   RESULTS   AND   DISCLAIMS   ALL   SUCH 
// REPRESENTATIONS   AND   WARRANTIES,  INCLUDING  FOR  EXAMPLE, 
// WARRANTIES  OF  MERCHANTABILITY  AND FITNESS FOR A PARTICULAR 
// PURPOSE.    SIEMENS  BUILIDNG  TECHNOLOGIES,  INC.  DOES  NOT 
// REPRESENT  OR  WARRANT  THAT  THE  FOLLOWING CODE SAMPLES ARE 
// ACCURATE, VALID, COMPLETE OR CURRENT.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "infoserverexplorer.h"
#include "Group.h"
#include "IOPCItemMgt.h"
#include "IOPCSyncIO.h"
#include "IOPCAsyncIO.h"
#include "IOPCAsyncIO2.h"
#include "AddItemDlg.h"
#include "IEnumOPCItemAttributes.h"
#include "IDataObject.h"
#include "OpcError.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CGroup,	CObject)

CGroup::CGroup()
{	
	m_dwUpdateRate = 100; 
	m_lTimeBias = 0;
	m_fDeadBand = 1.0f;
	m_dwLCID = 0;

	m_bDataChange = TRUE;

	m_dwOPCSTMFormatWriteCompleteConnection = 0;
	m_dwOPCSTMFormatDataTimeConnection = 0;
	m_dwOPCSTMFormatDataConnection = 0;

	m_dwOPCDataAccessConnectionPoint = 0;

	m_pInfoServer = NULL;

	m_dwCurrentTransactionID = 0;
	m_dwCancelID = 0;
}

CGroup::~CGroup()
{
	//should be already done => size = 0 !
	/*
	int size = m_Items.GetSize();
	CItem* pItem;
	for (int d=0; d < size; d++)
	{
		pItem = m_Items[0];
		RemoveItem(&pItem);
	}
	*/
}

void CGroup::Serialize(CArchive& ar)
{		
	CBase<IOPCGroupStateMgt>::Serialize(ar);

	m_Items.Serialize(ar);
	
	for(int i = 0; i < m_Items.GetSize(); i++)
	{
		if(ar.IsLoading())
		{
			TRACE("we should use ptr array instead !\n");
			m_Items[i] = new CItem;
		}
		m_Items[i]->Serialize(ar);
	}

	if (ar.IsStoring())
	{
		// TODO: add storing code here
		ar << m_dwUpdateRate; 
		ar << m_lTimeBias;
		ar << m_fDeadBand;
		ar << m_dwLCID;
		ar << m_bDataChange;
	}
	else
	{
		// TODO: add loading code here
		ar >> m_dwUpdateRate; 
		ar >> m_lTimeBias;
		ar >> m_fDeadBand;
		ar >> m_dwLCID;	
		ar >> m_bDataChange;
	}
}


BOOL CGroup::AddItem()
{
	CAddItemDlg		dlg(this);

	dlg.DoModal();	

	return TRUE;
}

BOOL CGroup::ReloadItems()
{
	USES_CONVERSION;

	HRESULT							res, res_next;
	CIOPCItemMgt					opcItemMgt(GetInterface());
	CComPtr<IEnumOPCItemAttributes>	pEnum;
	CComPtr<IEnumOPCItemAttributes>	pEnumClone;
	BOOL							bRet = FALSE;
	
	res = opcItemMgt.CreateEnumerator(IID_IEnumOPCItemAttributes, (LPUNKNOWN*)&pEnum);
	if(SUCCEEDED(res))
	{
		CIEnumOPCItemAttributes	opcIEnum(pEnum);

		//integrated test of clone
		res = opcIEnum.Clone(&pEnumClone);
		if(SUCCEEDED(res))
		{
			CIEnumOPCItemAttributes	opcIEnumClone(pEnumClone);
			OPCITEMATTRIBUTES*		pItemArray = NULL;
			ULONG					ulRequested = m_pInfoServer->GetReloadEnumAttributesNextElements();
			ULONG					ulRetrieved = 0;

			res = opcIEnumClone.Reset();
			if(SUCCEEDED(res))
			{
				do
				{
					res_next = opcIEnumClone.Next(ulRequested, &pItemArray, &ulRetrieved);

					//used for read
					OPCHANDLE* phServer = new OPCHANDLE[ulRetrieved];

					for(ULONG e = 0; e < ulRetrieved; e++)
					{
						//we need to save the new client handle !
						CItem*		pNewItem = new CItem;
						HRESULT*	pSetHandleErrors;
						OPCHANDLE	hNewClientHandle = (OPCHANDLE) pNewItem;

						phServer[e] = NULL;

						res = opcItemMgt.SetClientHandles(1, &(pItemArray[e].hServer), &hNewClientHandle, &pSetHandleErrors);
						if(SUCCEEDED(res))
						{
							if(SUCCEEDED(pSetHandleErrors[0]))
							{
								pNewItem->SetName(OLE2A((pItemArray)[e].szItemID));
								TRACE("%s\n", pNewItem->GetName());
								pNewItem->SetHandle((pItemArray)[e].hServer);
								TRACE("---> welchen DatenTyp ist wirklich vom Server momentan supported ?\n");
								pNewItem->SetDataType((pItemArray)[e].vtRequestedDataType);
								pNewItem->SetGroup(this);

								m_Items.Add(pNewItem);
								phServer[e] = pNewItem->GetHandle();

							}
							else
							{
								GetInfoServer()->DisplayError(pSetHandleErrors[e]);
								delete pNewItem;
							}
						}
						else
						{
							GetInfoServer()->DisplayError(res);
							delete pNewItem;
						}
						CoTaskMemFree(pSetHandleErrors);

						CoTaskMemFree(pItemArray[e].szItemID);
						pItemArray[e].szItemID = NULL;
						CoTaskMemFree(pItemArray[e].szAccessPath);
						pItemArray[e].szAccessPath = NULL;
					

					} //end for
					CoTaskMemFree(pItemArray);

					//now read the values (from cache)
					ReadItemsSync(OPC_DS_CACHE, ulRetrieved, phServer);
					
					delete[] phServer;
				}
				while(res_next == S_OK);

				if(FAILED(res_next)) ((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("IEnumUnknown::Next()"), res_next);

				//now we know how many enum items we have
				//lets check now the ::Skip
				res = opcIEnumClone.Reset();
				if(SUCCEEDED(res))
				{
					res = opcIEnumClone.Skip(m_Items.GetSize());
					if(SUCCEEDED(res))
					{
						//no output.
					}
					else
					{
						//skip
						GetInfoServer()->DisplayError(res);
					}
				}
				else
				{
					//reset
					GetInfoServer()->DisplayError(res);
				}

				bRet = TRUE;
			}
			else
			{
				//reset
				GetInfoServer()->DisplayError(res);
			}
		}
		else
		{
			//clone
			GetInfoServer()->DisplayError(res);
		}
		pEnumClone.Release();
	}
	else
	{
		GetInfoServer()->DisplayError(res);
	}

	pEnum.Release();
	return bRet;
}

BOOL CGroup::ReCreateItemOnServer(CItem** item)
{
	USES_CONVERSION;

	HRESULT			res;
	CIOPCItemMgt	opcItemMgt(GetInterface());
	OPCITEMRESULT*	pAddResults = NULL;
	HRESULT*		pErrors = NULL; 
	OPCHANDLE		hItem;


	const unsigned short usItems = 1;
	OPCITEMDEF add_items[usItems];
	add_items[0].szItemID = A2OLE((*item)->GetName());
	add_items[0].szAccessPath = A2OLE("");
	add_items[0].bActive = TRUE;
	add_items[0].hClient = (OPCHANDLE)*item;
	add_items[0].dwBlobSize = 0;
	add_items[0].pBlob = NULL;
	add_items[0].vtRequestedDataType = (*item)->GetDataType();

	if(GetInfoServer()->UseValidateItems()) //only if option is set
	{
		//validate
		if(!ValidateItems(usItems, add_items))
		{
			//cleanup

			return FALSE;
		}
	}

	res = opcItemMgt.AddItems(usItems, add_items, &pAddResults, &pErrors);
	if(SUCCEEDED(res))
	{		
		hItem = pAddResults->hServer;
		(*item)->SetHandle(hItem);
		if(VT_EMPTY == add_items[0].vtRequestedDataType) //native
		{
			if(SUCCEEDED(pErrors[0])) 
				//if asked for native we want the server given type
				(*item)->SetDataType(pAddResults->vtCanonicalDataType);
			else
				((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CIOPCItemMgt::AddItems()"), pErrors[0]);

		}
		else
		{
			if(SUCCEEDED(pErrors[0])) 
				//requested one
				(*item)->SetDataType(add_items[0].vtRequestedDataType);
			else if(pErrors[0] == OPC_E_BADTYPE)
				(*item)->SetDataType(pAddResults->vtCanonicalDataType);
			else
				((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CIOPCItemMgt::AddItems()"), pErrors[0]);

		}

		(*item)->SetGroup(this);
	
		CoTaskMemFree(pAddResults);
		CoTaskMemFree(pErrors);

		//read it !
		/*
		HRESULT*		pReadErrors; 
		OPCITEMSTATE*	pItemValues;

		CIOPCSyncIO	opcSyncIO(GetInterface());

		//read from cache
		OPCHANDLE hServer = (*item)->GetHandle();
		res = opcSyncIO.Read(OPC_DS_CACHE,usItems,&hServer,&pItemValues,&pReadErrors);
		if(SUCCEEDED(res))
		{
			//get the values
			(*item)->SetQuality(pItemValues->wQuality);
			(*item)->SetValue(pItemValues->vDataValue);
			
			TRACE("--->time stamp ??\n");

			VariantClear( &pItemValues->vDataValue );
			CoTaskMemFree(pItemValues);
			CoTaskMemFree(pReadErrors);
		}
		else
		{
			GetInfoServer()->DisplayError(res);
		}
		*/
		return TRUE;
	}
	else
	{
		GetInfoServer()->DisplayError(res);
		return FALSE;
	}
}

BOOL CGroup::RemoveItem(CItem** item)
{
	HRESULT					res;
	HRESULT*				pErrors = NULL; 
	CIOPCItemMgt			opcItemMgt(GetInterface());
	const unsigned short	usItems = 1;
	OPCHANDLE				remove_items[usItems];

	remove_items[0] = (*item)->GetHandle();

	res = opcItemMgt.RemoveItems(usItems, remove_items, &pErrors);
	if(SUCCEEDED(res))
	{	
		CoTaskMemFree(pErrors);

		for(int i = 0; i < m_Items.GetSize() ; i++)
		{
			if( *item == m_Items[i] ) 
			{
				m_Items.RemoveAt(i,1);
				m_Items.FreeExtra();
				delete *item;
			}
		}
		return TRUE;
	}
	else
	{
		GetInfoServer()->DisplayError(res);
		return FALSE;
	}
}

BOOL CGroup::RemoveItems(CArray<CItem*, CItem*>*  remove_items)
{
	HRESULT					res;
	HRESULT*				pErrors = NULL; 
	CIOPCItemMgt			opcItemMgt(GetInterface());
	const unsigned short	usItems = remove_items->GetSize();
	OPCHANDLE*				hServer = new OPCHANDLE[usItems];

	for(int i = 0; i < remove_items->GetSize(); i++)
	{
		hServer[i] = (*remove_items)[i]->GetHandle();
	}

	res = opcItemMgt.RemoveItems(usItems, hServer, &pErrors);
	if(SUCCEEDED(res))
	{	
		CoTaskMemFree(pErrors);

		for(int r = 0; r < remove_items->GetSize() ; r++)
		{
			for(int i = 0; i < m_Items.GetSize() ; i++)
			{
				if( (*remove_items)[r] == m_Items[i] ) 
				{
					m_Items.RemoveAt(i,1);
					m_Items.FreeExtra();
					delete (*remove_items)[r];
					break;
				}
			}
		}
		return TRUE;
	}
	else
	{
		GetInfoServer()->DisplayError(res);
		return FALSE;
	}
}
unsigned int CGroup::GetItems(CArray<CItem*, CItem*>** items)
{
	*items = &m_Items;
	return((*items)->GetSize());
}

void CGroup::SetOPCSTMFormatWriteCompleteConnection(DWORD dwConnection)
{
	m_dwOPCSTMFormatWriteCompleteConnection = dwConnection;
}

void CGroup::SetOPCSTMFormatDataTimeConnection(DWORD dwConnection)
{
	m_dwOPCSTMFormatDataTimeConnection = dwConnection;
}

void CGroup::SetOPCSTMFormatDataConnection(DWORD dwConnection)
{
	m_dwOPCSTMFormatDataConnection = dwConnection;
}

DWORD CGroup::GetOPCSTMFormatWriteCompleteConnection()
{
	return m_dwOPCSTMFormatWriteCompleteConnection;
}

DWORD CGroup::GetOPCSTMFormatDataTimeConnection()
{
	return m_dwOPCSTMFormatDataTimeConnection;
}

DWORD CGroup::GetOPCSTMFormatDataConnection()
{
	return m_dwOPCSTMFormatDataConnection;
}

void CGroup::SetOPCDataAccessConnectionPoint(DWORD dwConnection)
{
	m_dwOPCDataAccessConnectionPoint = dwConnection;
}

DWORD CGroup::GetOPCDataAccessConnectionPoint()
{
	return m_dwOPCDataAccessConnectionPoint;
}

CInfoServer* CGroup::GetInfoServer()
{
	return m_pInfoServer;
}

void CGroup::SetInfoServer(CInfoServer* pInfoServer)
{
	m_pInfoServer = pInfoServer;
}

BOOL CGroup::Refresh(OPCDATASOURCE dwSource)
{
	//value gets returned over the IAdvise sink
	HRESULT		res;

	CheckForOpenTransactions();

	if(GetInfoServer()->GetOPCVersion() >= OPC_VERSION_20)
	{
		CIOPCAsyncIO2	opcAsyncIO2(GetInterface());
		DWORD			dwTransactionID = TRANSACTION_REFRESH;	//in (returned in OnDataChange()) can be any number
		DWORD			dwCancelID;		//out

		res = opcAsyncIO2.Refresh2(dwSource, dwTransactionID, &dwCancelID);

		SetCurrentTransactionID(dwTransactionID);
		SetCurrentCancelID(dwCancelID);
	}
	else
	{
		CIOPCAsyncIO	opcAsyncIO(GetInterface());
		DWORD			dwTransactionID;	//out

		if(GetInfoServer()->GetDataChangeType() > 0) //0 = no timestamp; 1 = with timestamp
			res = opcAsyncIO.Refresh(GetOPCSTMFormatDataTimeConnection(), dwSource, &dwTransactionID);
		else
			res = opcAsyncIO.Refresh(GetOPCSTMFormatDataConnection(), dwSource, &dwTransactionID);

		SetCurrentTransactionID(dwTransactionID);
	}

	if(SUCCEEDED(res))
	{
		return TRUE;
	}

⌨️ 快捷键说明

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