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

📄 opcserver.cpp

📁 opc的客户端程序,在csdn上下的,不过我想看看这里下的详细说明
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "opcserver.h"
#include "opcclientdoc.h"

//#define FULL_TEST

extern OPCClientDoc* theDoc;
// The OPC data formats
UINT OPCSTMFORMATDATA = RegisterClipboardFormat(_T("OPCSTMFORMATDATA"));
UINT OPCSTMFORMATDATATIME = RegisterClipboardFormat(_T("OPCSTMFORMATDATATIME"));
UINT OPCSTMFORMATWRITECOMPLETE = RegisterClipboardFormat(_T("OPCSTMFORMATWRITECOMPLETE"));

IMPLEMENT_SERIAL(Item, CObject,0)
IMPLEMENT_SERIAL(COPCGroup, CObject, 0)
IMPLEMENT_SERIAL(COPCServer, CObject, 0)

//************************************************************
//************************************************************
//************************************************************
//class Item

void Item::Serialize(CArchive& ar)
{
	if(ar.IsStoring())
	{
		ar<<name;		//名称
		ar<<access_path;	//访问路径
		ar<<description;
	}
	else
	{
		ar>>name;
		ar>>access_path;
		ar>>description;
	}
}
//************************************************************
//默认构造函数
COPCGroup::COPCGroup(COPCServer* server)
	:group_name(_T("Group1")), 
	update_rate(1000),
	dead_band(0.0),
	time_bias(0),
	active(false),
	local_id(0),
	group_handle(0),
	parent(server)
{
	connection1 = 0;
	connection2 = 0;
	call_back_connection = 0;
	use_cp = false;
	
	tree_item = 0;

	advise_sink = new CAdviseSink;
	ASSERT(advise_sink);
	advise_sink->AddRef();
	
	call_back = new OPCCallbackObject;
	call_back->AddRef();

	current_item = NULL;
	while(!items.IsEmpty())
		delete items.RemoveHead();
}

//拷贝构造函数
COPCGroup::COPCGroup(COPCServer* server, COPCGroup& group)
{
	group_name = group.get_name();
	update_rate = group.get_update_rate();
	dead_band = group.get_dead_band();
	time_bias = group.get_time_bias();
	active = group.get_active();
	local_id = group.get_local_id();
	group_handle = 0;
	
	parent = group.parent;
	tree_item = 0;

	connection1 = 0;
	connection2 = 0;
	call_back_connection = 0;
	use_cp = false;
	
	advise_sink = new CAdviseSink;
	ASSERT(advise_sink);
	advise_sink->AddRef();
	
	call_back = new OPCCallbackObject;
	call_back->AddRef();
	
	current_item = NULL;
	while(!items.IsEmpty())
		delete items.RemoveHead();
	
	ItemList& item_list = group.get_items();
	POSITION item_pos = item_list.GetHeadPosition();
	while(item_pos){
		Item* item = item_list.GetNext(item_pos);
		Item* new_item = new Item;
		
		if(!new_item || !item)
			continue;
		
		CoFileTimeNow(&new_item->timestamp);
		new_item->name = item->name;
		new_item->access_path = item->access_path;
		new_item->description = item->description;
		new_item->hServerHandle = item->hServerHandle;
		new_item->quality = item->quality;
		new_item->access_rights = item->access_rights;
		new_item->active = item->active;
		new_item->native_type = item->native_type;
		new_item->value = item->value;
		new_item->server = parent;
		new_item->group = this;
		
		items.AddTail(new_item);
	}
}

COPCGroup::~COPCGroup(){

	//删除每个点
	HRESULT hr = S_OK;
	if(opc_group.IsOk()){
		if(use_cp)
			hr = AtlUnadvise(opc_group, IID_IOPCDataCallback, call_back_connection);
		else{
			DataObject data_object;
			hr = data_object.Attach(opc_group);
			if(SUCCEEDED(hr)){
				if(connection1)
					hr = data_object.DUnadvise(connection1);
				if(connection2)
					hr = data_object.DUnadvise(connection2);

				data_object.Detach();
			}
		}
		
		int count = items.GetCount();
		if(count > 0){
			OPCItemMgt item_mgt;
			hr = item_mgt.Attach(opc_group);
			if(SUCCEEDED(hr)){
				HRESULT* errors = NULL;
				OPCHANDLE* handles = new OPCHANDLE[count];
				ASSERT(handles);

				POSITION item_pos = items.GetHeadPosition();
				for(int index = 0; item_pos; index++){
					Item* item = items.GetNext(item_pos);
					ASSERT(item);

					handles[index] = item->hServerHandle;
				}
				hr = item_mgt.RemoveItems(count, handles, &errors);
				if(SUCCEEDED(hr))
					CoTaskMemFree(errors);

				delete[] handles;

				item_mgt.Detach();
			}
		}
	}	
	if(parent && parent->is_connected()){
		hr = parent->opc_server.RemoveGroup(group_handle, FALSE);
		if(FAILED(hr))
			theDoc->ReportError(_T("Remove Group Failed: "), hr);
	}
		

	current_item = NULL;
	while(!items.IsEmpty())
		delete items.RemoveHead();

	call_back->Release();
	advise_sink->Release();

	opc_group.Detach();
}

void COPCGroup::Serialize(CArchive& ar){
	if(ar.IsStoring()){
		ar << group_name;
		ar << update_rate;
		ar << dead_band;
		ar << time_bias;
		ar << local_id;
		ar << active;

		int item_count = items.GetCount();
		ar << item_count;
		POSITION item_pos = items.GetHeadPosition();
		while(item_pos){
			Item* item = items.GetNext(item_pos);
			if(item)
				item->Serialize(ar);
		}
	}
	else{
		ar >> group_name;
		ar >> update_rate;
		ar >> dead_band;
		ar >> time_bias;
		ar >> local_id;
		ar >> active;
		
		active = TRUE;

		
		if(parent && parent->is_connected())
			parent->add_group(this);
		else{
			delete this;
			return;
		}

		while(!items.IsEmpty())
			delete items.RemoveHead();

		int item_count = 0;
		ar >> item_count;
		while(item_count --){
			Item* item = new Item;
			if(item){
				item->Serialize(ar);
				item->active = TRUE;

				//items.AddTail(item);
				add_item(item);
			}
		}
	}
}

Item* COPCGroup::add_item(Item *item)
{
	USES_CONVERSION;
	CWaitCursor wait;

	if(!(item && parent)){
		delete item;
		return 0;
	}
	
	OPCItemMgt item_mgt;
	HRESULT hr = item_mgt.Attach(opc_group);
	if(FAILED(hr)){
		delete item;
		return 0;
	}
	
	current_item = item;		//当前点

	OPCITEMDEF	item_def;
	item_def.szItemID = T2OLE(item->name.GetBuffer(0));
	item_def.szAccessPath = T2OLE(item->access_path.GetBuffer(0));
	item_def.pBlob = NULL;
	item_def.dwBlobSize = 0;
	item_def.bActive = item->active;
	item_def.hClient = (OPCHANDLE)item;
	item_def.vtRequestedDataType = item->native_type;
	
	//添加点
	OPCITEMRESULT*	results;
	HRESULT*	errors;
	hr = item_mgt.AddItems(1, &item_def, &results, &errors);
	if(FAILED(hr)){
		theDoc->ReportError(_T("Add Items: "), hr);
		delete item;

		return 0;
	}
	item->hServerHandle = results->hServer;
	item->native_type = results->vtCanonicalDataType;
	
	HRESULT item_result = errors[0];
	if(results->pBlob != NULL)
		CoTaskMemFree(results->pBlob);
	
	CoTaskMemFree(results);
	CoTaskMemFree(errors);
	
	if(FAILED(item_result)){
		theDoc->ReportError(_T("Add Items: "), hr);
		delete item;
		return 0;
	}

	items.AddTail(item);		//保存点
	
	//读取初始值
	OPCSyncIO sync_io;
	hr = sync_io.Attach(opc_group);
	if(SUCCEEDED(hr)){
		OPCITEMSTATE* item_state = NULL;
		hr = sync_io.Read(
			OPC_DS_CACHE,
			1,
			&item->hServerHandle,
			&item_state,
			&errors);
		if(SUCCEEDED(hr)){
			ASSERT(item_state->hClient == (OPCHANDLE)item);
			item->quality = item_state->wQuality;
			item->value = item_state->vDataValue;
			
			VariantClear(&item_state->vDataValue);
			CoTaskMemFree(item_state);
			CoTaskMemFree(errors);
		}
		else{
			theDoc->ReportError(_T("SysncIO Read: "), hr);
			return 0;
		}

		sync_io.Detach();
	}
	
	return item;
}


DWORD COPCGroup::add_items(DWORD item_count, Item *item_arr)
{
	USES_CONVERSION;
	CWaitCursor wait;

	DWORD dwCount = 0;

	for(DWORD i = 0; i < item_count; i++){
		Item* item = item_arr + i;
		
		if(!(item && parent)){
			delete item;
			item = 0;
			continue;
		}
		
		OPCItemMgt item_mgt;
		HRESULT hr = item_mgt.Attach(opc_group);
		if(FAILED(hr)){
			delete item;
			item = 0;
			continue;
		}
		
		current_item = item;		//当前点
		
		OPCITEMDEF	item_def;
		item_def.szItemID = T2OLE(item->name.GetBuffer(0));
		item_def.szAccessPath = T2OLE(item->access_path.GetBuffer(0));
		item_def.pBlob = NULL;
		item_def.dwBlobSize = 0;
		item_def.bActive = item->active;
		item_def.hClient = (OPCHANDLE)item;
		item_def.vtRequestedDataType = item->native_type;
		
		//添加点
		OPCITEMRESULT*	results;
		HRESULT*	errors;
		hr = item_mgt.AddItems(1, &item_def, &results, &errors);
		if(FAILED(hr)){
			theDoc->ReportError(_T("Add Items: "), hr);
			delete item;
			item = 0;
			continue;
		}
		item->hServerHandle = results->hServer;
		item->native_type = results->vtCanonicalDataType;
		
		HRESULT item_result = errors[0];
		if(results->pBlob != NULL)
			CoTaskMemFree(results->pBlob);
		
		CoTaskMemFree(results);
		CoTaskMemFree(errors);
		
		if(FAILED(item_result)){
			theDoc->ReportError(_T("Add Items: "), hr);
			delete item;
			item = 0;
			continue;
		}
		
		items.AddTail(item);		//保存点
		
		//读取初始值
		OPCSyncIO sync_io;
		hr = sync_io.Attach(opc_group);
		if(SUCCEEDED(hr)){
			OPCITEMSTATE* item_state = NULL;
			hr = sync_io.Read(
				OPC_DS_CACHE,
				1,
				&item->hServerHandle,
				&item_state,
				&errors);
			if(SUCCEEDED(hr)){
				ASSERT(item_state->hClient == (OPCHANDLE)item);
				item->quality = item_state->wQuality;
				item->value = item_state->vDataValue;
				
				VariantClear(&item_state->vDataValue);
				CoTaskMemFree(item_state);
				CoTaskMemFree(errors);
			}
			else{
				theDoc->ReportError(_T("SysncIO Read: "), hr);
				continue;
			}
			
			sync_io.Detach();
		}

		dwCount++;
	}

	return dwCount;
}
//****************************************************
COPCServer::COPCServer(){
	current_group = 0;
	server_info = 0;

/*
	shut_down = new OPCShutdownObject;
	shut_down->AddRef();
*/
	shut_down_connection = 0;

	tree_item = 0;
}

COPCServer::~COPCServer(){
	if(is_connected())
		disconnect();
	
	shut_down->Release();

	current_group = NULL;
	while(!groups.IsEmpty())
		delete groups.RemoveHead();

	if(server_info){
		delete server_info;
		server_info = 0;
	}
}


OPCServerInfo* COPCServer::SetServerInfo(OPCServerInfo *info)
{
	if(is_connected()){
		delete info;
		info = 0;
		
		return 0;
	}

	if(info){
		if(server_info)
			delete server_info;

		server_info = info;
	}

	return info;
}

//通用
/*
LPWSTR ConvertMultiByteToWideChar(LPCSTR ttt)
{
	try{
		
		size_t aLen = strlen( ttt ) + 1;
		int wLen = MultiByteToWideChar(
			CP_ACP,
			0,
			ttt,
			aLen,
			NULL,
			0);
		LPOLESTR tempID= new WCHAR [wLen];
		int nreturn=MultiByteToWideChar(CP_ACP,0,ttt,aLen,tempID,wLen);
		return (LPWSTR)tempID;
	}catch(...){
		return L"";
	}
}
*/


extern IOPCServer			*m_pIOPCServer;
extern IOPCItemMgt			*m_pIOPCItemMgt;
extern IOPCGroupStateMgt	*m_pIOPCGroupStateMgt;
extern IOPCAsyncIO2		*m_pIOPCAsyncIO2;
extern OPCITEMRESULT		*m_pItemResult;
extern HRESULT				*m_pErrors;
extern OPCHANDLE			m_GrpSrvHandle;
#include "opctest/callback.h"


//连接OPCServer
bool COPCServer::connect(OPCServerInfo *info)
{
	USES_CONVERSION;

	if(is_connected())
		return true;
	
	CWaitCursor wait_cursor;

	if(info)
		server_info = info;
	else
		info = server_info;
	
	bool use_node = true;
	if(info->m_NodeName.IsEmpty()
		|| _tcsicmp(_T(""), info->m_NodeName) == 0
		|| _tcsicmp(_T("localhost"), info->m_NodeName) == 0
		|| _tcsicmp(_T("127.0.0.1"), info->m_NodeName) ==0 ){
			use_node = false;
		}
	if(use_node){	//是否同为本机
		TCHAR sz_local_host[MAX_COMPUTERNAME_LENGTH + 1];
		DWORD dw_host_size = sizeof(sz_local_host);
		if(GetComputerName(sz_local_host, &dw_host_size)){
			if(_tcsicmp(sz_local_host, info->m_NodeName) == 0)
				use_node = false;
		}
	}
	
	//建立OPC对象
	HRESULT hr = S_OK;
	LPUNKNOWN punknown = NULL;
	
	if(!use_node){	//本地OPCServer
		hr = CoCreateInstance(
			info->m_clsid,

⌨️ 快捷键说明

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