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

📄 opcserver.cpp

📁 opc的客户端程序,在csdn上下的,不过我想看看这里下的详细说明
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			NULL,
			CLSCTX_ALL,
			IID_IUnknown,
			(LPVOID*)&punknown);
		
		if(FAILED(hr) || punknown == NULL){	//创建失败
			CString msg;
			msg.Format(_T("CoCreateInstance %s failed:"), info->m_ProgID.GetBuffer(0));
			theDoc->ReportError(msg, hr);

			return false;
		}
	}
	else{		//远程对象
		COSERVERINFO	si;
		MULTI_QI	qi;

		si.dwReserved1 = 0;
		si.pAuthInfo = NULL;
		si.pwszName = T2OLE(info->m_NodeName.GetBuffer(0));
		si.dwReserved2 = 0;

		qi.pIID = &IID_IOPCServer;
		qi.pItf = NULL;
		qi.hr = 0;
		
		hr = CoCreateInstanceEx(
			info->m_clsid,
			NULL,
			CLSCTX_REMOTE_SERVER,
			&si,
			1,
			&qi);
		if(FAILED(hr)){
			CString msg(_T("CoCreateInstanceEx failed: "));
			theDoc->ReportError(msg, hr);

			return false;
		}
		if(FAILED(qi.hr) || (qi.pItf == NULL)){
			CString msg(_T("MULTI_QI failed: "));
			theDoc->ReportError(msg, qi.hr);

			return false;
		}

		punknown = qi.pItf;
	}

	hr = opc_server.Attach(punknown);
	punknown->Release();	//释放IUnknown接口
	punknown = NULL;

	if(FAILED(hr)){
		CString msg(_T("OPC Server Attach failed:"));
		if(theDoc)
			theDoc->ReportError(msg, hr);
	}

	//是否实现了IShutdown接口
	hr = AtlAdvise(
		opc_server,
		shut_down->GetUnknown(),
		IID_IOPCShutdown,
		&shut_down_connection
		);
	if(FAILED(hr)){
		CString msg;
		msg.Format(_T("%s: %s can't support IOPCShutdown interface."),
			info->m_NodeName,
			info->m_ProgID);
		if(theDoc)
			theDoc->ReportError(msg.GetBuffer(0));
	}
	
	//添加所有组
	/*
	POSITION group_pos = groups.GetHeadPosition();
	while(group_pos){
		COPCGroup* group = groups.GetNext(group_pos);
		if(!group)
			continue;

		group = add_group(group);
		if(group){		//添加所有点
			POSITION item_pos = group->items.GetHeadPosition();
			while(item_pos){
				Item* item = group->items.GetNext(item_pos);
				if(!item)
					continue;

				item = group->add_item(item);
			}
		}
	}
/*


	HRESULT		r1;
	CLSID		clsid;
	COSERVERINFO sin, *sinptr;
	MULTI_QI	mqi;
	LPWSTR LszNodeName;
	DWORD		clsctx;
	LONG		TimeBias = 0;
	FLOAT		PercentDeadband = 0.0;
	DWORD		RevisedUpdateRate;
//	LPWSTR		ErrorStr1,ErrorStr2;
	CString		szErrorText;
	DWORD		m_dwAdvise;
//	r1 = CoInitialize(NULL);
	LPWSTR Lopcservername;
	Lopcservername=ConvertMultiByteToWideChar("KEPware.KEPServerEx.V4");
	
	r1 = CLSIDFromProgID(Lopcservername, &clsid);
	sinptr = &sin;
	sin.dwReserved1 = sin.dwReserved2 = 0; 
	LszNodeName = ConvertMultiByteToWideChar("CSIT-ZKS");
	sin.pwszName = LszNodeName; // szNodeName为本地或远程计算机名
	sin.pAuthInfo = 0;
	clsctx = CLSCTX_REMOTE_SERVER;//远程   
	mqi.pIID = &IID_IOPCServer;
	mqi.hr = 0;
	mqi.pItf = 0;
	clsctx = CLSCTX_REMOTE_SERVER;//远程   
	r1 = CoCreateInstanceEx(clsid, NULL, clsctx, sinptr, 1, &mqi);// 创建OPC服务器的浏览器对象
	m_pIOPCServer = (IOPCServer*)mqi.pItf;
	r1=m_pIOPCServer->AddGroup(
		L"grp1",		// [in] group name
		false,				// [in] not active, so no OnDataChange callback
		500,				// [in] Request this Update Rate from Server
		1000,		// [in] Client Handle, not necessary in this sample
		&TimeBias,			// [in] No time interval to system UTC time
		&PercentDeadband,	// [in] No Deadband, so all data changes are reported
		0,			// [in] Server uses english language to for text values
		&m_GrpSrvHandle,	// [out] Server handle to identify this group in later calls
		&RevisedUpdateRate,	// [out] The answer from Server to the requested Update Rate
		IID_IOPCGroupStateMgt,
		(LPUNKNOWN*)&m_pIOPCGroupStateMgt); // [out] pointer to the requested interface
	
	CComObject<COPCDataCallback>* pCOPCDataCallback;	// Pointer to Callback Object
	
	
    CComObject<COPCDataCallback>::CreateInstance(&pCOPCDataCallback);
	LPUNKNOWN pCbUnk;
    pCbUnk = pCOPCDataCallback->GetUnknown();
	r1 = AtlAdvise(	m_pIOPCGroupStateMgt,			 // [in] IUnknown Interface of the Connection Point
								pCbUnk,				 // [in] IUnknown Interface of the Callback object
								IID_IOPCDataCallback,// [in] Connection Point ID: The OPC Data Callback 
								&m_dwAdvise			 // [out] Cookie that that uniquely identifies the connection
								);
*/
	return true;
}

//断开OPCServer
bool COPCServer::disconnect()
{
	if(!is_connected())
		return false;

	HRESULT hr = S_OK;
	if(shut_down_connection){
		hr = AtlUnadvise(
			opc_server,
			IID_IOPCShutdown,
			shut_down_connection);
		shut_down_connection = 0;

		if(FAILED(hr)){
			CString msg(_T("AtlUnadvise IOPCShutdown failed."));
			if(theDoc)
				theDoc->ReportError(msg.GetBuffer(0), hr);
		}
	}

	//断开所有Group,并删除
	/*.....*/
	
	current_group =  NULL;
	while(!groups.IsEmpty())
		delete groups.RemoveHead();

	opc_server.Detach();
	
	return true;
}

//连接状态
bool COPCServer::is_connected()
{
	return opc_server.IsOk() ? true : false;
}

//获取错误信息
HRESULT COPCServer::GetErrorString(
				   HRESULT	dwError,
				   LCID		dwLocale,
				   LPWSTR*	ppString)
{
	return opc_server.GetErrorString(dwError, dwLocale, ppString);
}

OPCServerInfo* const COPCServer::get_server_info()
{
	return server_info;
}


//添加点
COPCGroup* COPCServer::add_group(COPCGroup *group)
{
	USES_CONVERSION;

	if(!group)
		return 0;
	
	OPCServerInfo* info = server_info;
	//add group
	LPCWSTR	group_name = T2OLE(group->get_name().GetBuffer(0));
	BOOL	active = group->get_active();
	ULONG	update_rate = group->get_update_rate();
	long	time_bias = group->get_time_bias();
	float	dead_band = group->get_dead_band();
	DWORD	local_id = group->get_local_id();
	DWORD	rate;
	
	HRESULT hr = opc_server.AddGroup(
		L"Chenmaoxiang",
		active,
		update_rate,
//		(OPCHANDLE)group,
		1000,
		&time_bias,
		&dead_band,
		local_id,
		&group->group_handle,
		&rate,
		IID_IOPCGroupStateMgt,
//		group->opc_group);
		(LPUNKNOWN*)&m_pIOPCGroupStateMgt);

	if(FAILED(hr)){
		CString msg;
		msg.Format(_T("Add Group: %s failed."), group_name);
		theDoc->ReportError(msg.GetBuffer(0), hr);

		return 0;
	}

#ifdef FULL_TEST
	IOPCGroupStateMgt* pTest=NULL;
	hr = opc_server.GetGroupByName( 
		L"Chenmaoxiang", 
		IID_IOPCGroupStateMgt, 
		(LPUNKNOWN*)&pTest );
	if( SUCCEEDED(hr) )
	{
		ASSERT( pTest == (IOPCGroupStateMgt*)group->opc_group );	// should get the same
		hr = pTest->SetName( group_name );				// set new name
		pTest->Release();
		if( FAILED(hr) )
		{
			theDoc->ReportError( _T("IOPCGroupStateMgt::SetName: "), hr );
		}
		else
		{
			// should now go by this new name
			hr = opc_server.GetGroupByName( 
				group_name, 
				IID_IOPCGroupStateMgt, 
				(LPUNKNOWN*)&pTest );
			if( SUCCEEDED(hr) )
			{
				ASSERT( pTest == (IOPCGroupStateMgt*)group->opc_group );
				pTest->Release();
			}
		}
	}
#endif//FULL_TEST


	//ADD TEST
	CComObject<COPCDataCallback>* pCOPCDataCallback;	// Pointer to Callback Object
	CComObject<COPCDataCallback>::CreateInstance(&pCOPCDataCallback);
	LPUNKNOWN pCbUnk;
    pCbUnk = pCOPCDataCallback->GetUnknown();
	DWORD m_dwAdvise = 0;

	//END TEST
	//OPC 2.0 connection point
	hr = AtlAdvise(
		m_pIOPCGroupStateMgt,
		pCbUnk,
		IID_IOPCDataCallback,
		&m_dwAdvise);
/*
	hr = AtlAdvise(
		group->opc_group,
		group->call_back->GetUnknown(),
		IID_IOPCDataCallback,
		&group->call_back_connection);
*/
	if(SUCCEEDED(hr))
		group->use_cp = true;
		
	if(!group->use_cp){		//不支持连接点
		CString msg;
		msg.Format(_T("%s: %s can't support IOPCDataCallback interface."),
			info->m_NodeName,
			info->m_ProgID);
		theDoc->ReportError(msg.GetBuffer(0), hr);
		
		//opc 1.0 data advise format
		FORMATETC format_etc;
		format_etc.tymed =  TYMED_HGLOBAL;
		format_etc.ptd = NULL;
		format_etc.dwAspect = DVASPECT_CONTENT;
		format_etc.lindex = -1;
		
		// IAdviseSink is an interface on OUR object that is passed to
		// the server for callbacks
		IAdviseSink *pAdviseSink = NULL;
		hr = group->advise_sink->QueryInterface(IID_IAdviseSink, (LPVOID *)&pAdviseSink);
		if( FAILED(hr) )
		{
			msg = _T("IAdviseSink: ");
			theDoc->ReportError(msg.GetBuffer(0), hr);

			group->opc_group.Detach();
			//opc_server.Detach();
			return 0;
		}
		
		// Get an IDataObject interface on the group
		DataObject dataObject;
		hr = dataObject.Attach( group->opc_group );
		if(FAILED(hr) || !dataObject.IsOk() )
		{
			//some servers don't do this, so don't quit altogether
			msg = _T("IDataObject not supported by this server\nNo data notifications will take place");
			theDoc->ReportError(msg.GetBuffer(0));
			
			return 0;
		}
		
		// Register our IAdvise with the group
		// Need to register both formats: data change, and write complete
		format_etc.cfFormat = OPCSTMFORMATWRITECOMPLETE ;
		hr = dataObject.DAdvise(&format_etc,
			ADVF_PRIMEFIRST,    // ADVF flag
			pAdviseSink,
			&group->connection2);
		if( FAILED(hr) )
		{
			msg = _T("IDataObject::DAdvise: : ");
			theDoc->ReportError(msg.GetBuffer(0), hr);
			
			return 0;
		}
		
			
		#ifdef DATATIMEFORMAT
			format_etc.cfFormat = OPCSTMFORMATDATATIME ;
		#else
			format_etc.cfFormat = OPCSTMFORMATDATA ;
		#endif // DATATIMEFORMAT

		hr = dataObject.DAdvise(&format_etc,
			ADVF_PRIMEFIRST,    // ADVF flag
			pAdviseSink,
			&group->connection1);
		pAdviseSink->Release();
		if( FAILED(hr) )
		{
			msg = _T("IDataObject::DAdvise: : ");
			theDoc->ReportError(msg.GetBuffer(0), hr);
			
			return 0;
		}
	}
	
	groups.AddTail(group);
	current_group = group;

	theDoc->UpdateAllViews(NULL, ADD_GROUP, (CObject*)group);
	return current_group;
}

//获取当前组
COPCGroup* COPCServer::get_current_group()
{
	return current_group;
}

//获取父服务器
COPCServer* COPCGroup::get_parent() const
{
	return parent;
}

OPCServer& COPCServer::get_opc_server()
{
	return opc_server;
}

COPCGroup* COPCServer::set_current_group(COPCGroup *group)
{
	if(group)
		current_group = group;
	
	return group;
}

//保存
void COPCServer::Serialize(CArchive &ar)
{
	CWaitCursor wait_cursor;
	//Lock wait(&item_cs);

	if(ar.IsStoring()){
		if(server_info){
			ar << server_info->m_ProgID;
			ar << server_info->m_NodeName;
			ar << server_info->m_Description;
			ar << server_info->m_clsid.Data1;
			ar << server_info->m_clsid.Data2;
			ar << server_info->m_clsid.Data3;
			
			int times = sizeof(server_info->m_clsid.Data4) / sizeof(BYTE);
			for(int i = 0; i < times; i++){
				ar << server_info->m_clsid.Data4[i];
			}
		}

		int group_count = groups.GetCount();
		ar << group_count;
		POSITION group_pos = groups.GetHeadPosition();
		while(group_pos){
			COPCGroup* group = groups.GetNext(group_pos);
			if(group)
				group->Serialize(ar);
		}
	}
	else{
		if(server_info)
			delete server_info;

		server_info = new OPCServerInfo;
		if(server_info){
			ar >> server_info->m_ProgID;
			ar >> server_info->m_NodeName;
			ar >> server_info->m_Description;
			ar >> server_info->m_clsid.Data1;
			ar >> server_info->m_clsid.Data2;
			ar >> server_info->m_clsid.Data3;

			int times = sizeof(server_info->m_clsid.Data4) / sizeof(BYTE);
			for(int i = 0; i < times; i++){
				ar >> server_info->m_clsid.Data4[i];
			}
		}

		if(!is_connected())		//连接OPC Server
			connect();		

		while(!groups.IsEmpty())
			delete groups.RemoveHead();
		
		int group_count = 0;
		ar >> group_count;
		while(group_count--){
			COPCGroup* group = new COPCGroup;
			if(group){
				group->parent = this;
				group->Serialize(ar);

				//add_group(group);
				//groups.AddTail(group);
			}	
		}
	}
}

//删除点
void COPCGroup::remove_item()
{
	if(current_item == NULL)
		return;

	OPCItemMgt item_mgt;
	HRESULT hr = item_mgt.Attach(opc_group);
	if(SUCCEEDED(hr)){
		HRESULT* errors = NULL;
		hr = item_mgt.RemoveItems(
			1,
			&current_item->hServerHandle,
			&errors);
		if(SUCCEEDED(hr))
			CoTaskMemFree(errors);

		EnterCriticalSection(&item_cs);
		
		POSITION pos = items.Find(current_item);
		if(pos)
			items.RemoveAt(pos);
		
		delete current_item;
		current_item = NULL;
		
		LeaveCriticalSection(&item_cs);
		
		theDoc->SetModifiedFlag(TRUE);
		theDoc->UpdateAllViews(NULL, UPDATE_GROUP, (CObject*)this);
	}
}

void COPCServer::remove_group(COPCGroup *group)
{
	Lock wait(&item_cs);
	if(group == NULL){
		group = current_group;
		current_group = 0;
	}

	POSITION group_pos = groups.Find(group);
	if(group_pos){
		groups.RemoveAt(group_pos);
		delete group;
	}

	theDoc->UpdateAllViews(NULL, UPDATE_SERVER, (CObject*)this);
}

//读取点
void COPCGroup::read_item(Item *item)
{
	
}

void COPCGroup::write_item(BOOL async, CString value, Item *item)
{

}

⌨️ 快捷键说明

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