infoserver.cpp

来自「此为Insight opc client InfoServerExplorer源」· C++ 代码 · 共 1,428 行 · 第 1/3 页

CPP
1,428
字号
					CoTaskMemFree(pGroupName);
					

				}
			}
			while(res_next == S_OK);

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

			TRACE("-->Release pIEnumUnknown ??\n");

			delete[] ppUnkn;
			pIEnumUnknown.Release();

			pDoc->SetModifiedFlag();
			return TRUE;
		}
		else
		{
			((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CreateGroupEnumerator()"), res);
		}
	}

	return FALSE;
}

BOOL CInfoServer::ReloadServer()
{
	USES_CONVERSION;

	HRESULT	res;
	CIPersistFile opcPersistFile(GetInterface());

	WCHAR	ww[20]; 

	wcscpy(ww, A2OLE("dummy"));
		
	res = opcPersistFile.Load(ww, 0);
	if(SUCCEEDED(res))
	{
		((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("ReloadServer() successful"));
		return TRUE;
	}
	else
	{
		((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("ReloadServer()"), res);
		return FALSE;
	}
}

BOOL CInfoServer::PrintStatistic()
{
	USES_CONVERSION;

	HRESULT	res;
	CIPersistFile opcPersistFile(GetInterface());

	WCHAR	ww[20]; 

	wcscpy(ww, A2OLE("dummy"));
		
	res = opcPersistFile.Save(ww, FALSE);
	if(SUCCEEDED(res))
	{
		((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("PrintStatistic() successful"));
		return TRUE;
	}
	else
	{
		((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("PrintStatistic()"), res);
		return FALSE;
	}
}

BOOL CInfoServer::ChooseServer()
{
	CConnectDlg		dlg;

	if(GetOPCVersion() < 2.0)
		dlg.m_catid = CATID_OPCDAServer10;
	else
		dlg.m_catid = CATID_OPCDAServer20;

	if(dlg.DoModal() != IDOK)
		return FALSE;
	
	if(IsConnected()) Disconnect();

	SetOPCServer(dlg.m_sOPCServer);
	SetOPCServerComputer(dlg.m_sOPCServerComputer);
	SetOPCServerCLSID(dlg.m_clsidServer);

	return TRUE;
}

BOOL CInfoServer::Connect()
{
	LPUNKNOWN				pUnkn = NULL;
	HRESULT					hr = S_OK;


	USES_CONVERSION;

	CWaitCursor wait;

/* old OPC 1.0 way to retrieve the CLSID (note: new method covers OPC 1.0 servers as well)

	HKEY					hCLSID;
	HKEY					hkRoot = HKEY_CLASSES_ROOT;
	const int				MAX_CLSID_KEY_LEN = 256;
	LONG					clsid_size = MAX_CLSID_KEY_LEN;
	TCHAR					clsidString[MAX_CLSID_KEY_LEN];
	CLSID					clsid;

	if(!m_sOPCServerComputer.IsEmpty())
	{
		DWORD dwR = RegOpenKey(hkRoot, (LPTSTR)(LPCTSTR)m_sOPCServer, &hCLSID );
		if( dwR != ERROR_SUCCESS )
		{		
			DWORD dwR = RegConnectRegistry ((LPTSTR)(LPCTSTR)m_sOPCServerComputer, HKEY_CLASSES_ROOT, &hkRoot);
			if( dwR != ERROR_SUCCESS )
				return FALSE;
		}
	}

	DWORD dwR = RegOpenKey(hkRoot, (LPTSTR)(LPCTSTR)m_sOPCServer, &hCLSID );
	if( dwR != ERROR_SUCCESS )
		return FALSE;

	dwR = RegQueryValue(hCLSID, _T("CLSID"), clsidString, &clsid_size );
	if( dwR != ERROR_SUCCESS )
		return FALSE;

	hr = CLSIDFromString( T2OLE(clsidString), &clsid );
	if( FAILED(hr))
	{
		((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CLSIDFromString()"), hr);
		return FALSE;
	}
*/

	// Create a running object from that class ID
	// (CLSCTX_ALL will allow in-proc, local and remote)
	if(m_sOPCServerComputer.IsEmpty() )
	{
		hr = CoCreateInstance(GetOPCServerCLSID(), NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID *)&pUnkn);
		if( FAILED(hr) || pUnkn == NULL)
		{
			CString sMsg;
			sMsg.Format( IDS_CONNECT_OPC_SERVER_ERROR, m_sOPCServer );
			sMsg += _T("\n CoCreateInstance()");
			
			((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(sMsg, hr);
	
			return FALSE;
		}
	}
	else
	{
		COSERVERINFO	si;
		MULTI_QI		qi;

		si.dwReserved1 = 0;
		si.pwszName = T2OLE(m_sOPCServerComputer.GetBuffer(0));
		si.pAuthInfo = NULL;
		si.dwReserved2 = 0;

		qi.pIID = &IID_IOPCServer;
		qi.pItf = NULL;
		qi.hr = 0;

		hr = CoCreateInstanceEx(GetOPCServerCLSID(), NULL, CLSCTX_ALL, &si, 1, &qi);
		if (FAILED(hr))
		{
			((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CoCreateInstanceEx()"), hr);
			return FALSE;
		}
		if (FAILED(qi.hr))
		{
			((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("Failed to connect to server"), qi.hr);
			return FALSE;
		}
		pUnkn = qi.pItf;
	}

	// Get the IOPCServer interface.
	m_pUnkn = pUnkn;
	//m_pUnkn->AddRef();
	pUnkn->Release();  // Don't need this anymore.
	pUnkn = NULL;

	m_bConnected = TRUE;
	m_pShutDownConnectionPoint->Init(this);

	((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("Successful to OPC server connected."));

	return TRUE;
}

BOOL CInfoServer::Disconnect()
{
	HRESULT hr = S_OK;
	
	CWaitCursor wait;

	if( m_pUnkn != NULL)
	{
		//remove groups
		int size = m_Groups.GetSize();
		for(int i = 0; i < size; i++)
		{
			RemoveGroup(&m_Groups[0]);			
		}

		m_pShutDownConnectionPoint->Term(this);

		m_pUnkn.Release();	//since it is a CComPtr not needed, but we want to disconnect !
	}

	m_bConnected = FALSE;

	((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("Successful from OPC server disconnected."));

	return TRUE;
}

BOOL CInfoServer::IsConnected()
{
	return m_bConnected;
}

void CInfoServer::SetConnected(BOOL bConnected)
{
	m_bConnected = bConnected;
}

BOOL CInfoServer::AddGroup(CGroup** group)
{
	USES_CONVERSION;

	CGroupDlg	dlg;
	HRESULT		res;

	if(IDOK != dlg.DoModal()) return FALSE;

	CIOPCServer	opcServer(m_pUnkn);

	DWORD						dwServerUpdateRate;	//out: servers rate
	CComPtr<IOPCGroupStateMgt>	pGRP = NULL; //out
	OPCHANDLE					hServerGroup; //out (server handle)

	//create before AddGroup because we need its address for the handle
	CGroup* new_group = new CGroup;

	res = opcServer.AddGroup(A2OLE(dlg.m_sGroup),
									dlg.m_bActive, 
									dlg.m_dwUpdateRate, 
									(OPCHANDLE)new_group,      
									&dlg.m_lTimeBias,
									&dlg.m_fDeadBand,
									dlg.m_dwLCID,
									&hServerGroup,
									&dwServerUpdateRate,
									IID_IOPCGroupStateMgt,
									(LPUNKNOWN*)&pGRP);
	if(SUCCEEDED(res))
	{
		
		new_group->SetInterface(pGRP);

		new_group->SetInfoServer(this);
		*group = new_group;
		m_Groups.Add(new_group);

		//retrieve all the data from the group
		//(server converts empty name to groupx)
		CIOPCGroupStateMgt	opcGroup(new_group->GetInterface());
		OPCHANDLE			hClientGroup; //out
		LPWSTR				pGroupName;
		BOOL				bActive;
		LONG				lTimeBias;
		float				fDeadBand;
		DWORD				dwLCID;

		res = opcGroup.GetState(	&dwServerUpdateRate, &bActive, &pGroupName,
									&lTimeBias, &fDeadBand, &dwLCID,
									&hClientGroup, &hServerGroup); 
		if(SUCCEEDED(res))
		{
			new_group->SetHandle(hServerGroup);
			new_group->SetActive(bActive);
			new_group->SetUpdateRate(dwServerUpdateRate);
			new_group->SetTimeBias(lTimeBias);
			new_group->SetDeadBand(fDeadBand);
			new_group->SetLCID(dwLCID);
			new_group->SetName(OLE2A(pGroupName));
			new_group->SetDataChangeEnabled(dlg.m_bDataChange, FALSE); //write to server in Advise

			// Establish a connection
			//
			new_group->Advise();

			((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("Group successfuly added."));

		}
		else
		{
			DisplayError(res);
			delete new_group;
			return FALSE;
		}
		CoTaskMemFree(pGroupName);
		
		return TRUE;
	}
	else
	{
		DisplayError(res);
		delete new_group;
		return FALSE;
	}
}

BOOL CInfoServer::CloneGroup(CGroup* pCloneSourceGroup, CGroup** pNewGroup)
{
	USES_CONVERSION;

	//execute clone
	CGroupDlg					dlg;
	HRESULT						res;
	CIOPCGroupStateMgt			opcGroupSource(pCloneSourceGroup->GetInterface());
	OPCHANDLE					hClientGroup; //out -> in => no modification
	OPCHANDLE					hServerGroup; //out: not used
	DWORD						dwUpdateRate; //out: servers rate
	LPWSTR						pGroupNameSource;
	LPWSTR						pGroupNameCopy;
	CComPtr<IOPCGroupStateMgt>	pGRP;		  //out
	BOOL						bRet = FALSE;

	if(SUCCEEDED(opcGroupSource.GetState(	&dlg.m_dwUpdateRate, &dlg.m_bActive,     
											&pGroupNameSource,
											&dlg.m_lTimeBias,
											&dlg.m_fDeadBand,
											&dlg.m_dwLCID,
											&hClientGroup,
											&hServerGroup
										)))
	{
		dlg.m_sGroup = OLE2A(pGroupNameSource);

		//ask for new name
		if(IDOK == dlg.DoModal()) 
		{
			/*
				clone group creates the group disabled, but with above dialog the user 
				can enable it.
			*/
			res = opcGroupSource.CloneGroup(	A2OLE(dlg.m_sGroup),
												IID_IOPCGroupStateMgt,
												(LPUNKNOWN*)&pGRP);
			if(SUCCEEDED(res))
			{			
				//we call get state here only to het the handle for the new group !
				//temp out
				CIOPCGroupStateMgt	opcGroupClone(pGRP);
				BOOL				bActive;
				long				lTimeBias;
				float				fDeadBand;
				LCID				dwLCID;

				
				//we need to retrieve the client handle for the SetState() !
				//we don't want to change it !
				if(SUCCEEDED(opcGroupClone.GetState(	&dwUpdateRate, &bActive,     
										&pGroupNameCopy,
										&lTimeBias,
										&fDeadBand,
										&dwLCID,
										&hClientGroup,
										&hServerGroup
										)))
				{
					CGroup* new_group = new CGroup;
					hClientGroup = (OPCHANDLE)new_group;
					if(SUCCEEDED(opcGroupClone.SetState(	&dlg.m_dwUpdateRate,
															&dwUpdateRate,
															&dlg.m_bActive, 										  
															&dlg.m_lTimeBias,
															&dlg.m_fDeadBand,
															&dlg.m_dwLCID,
															&hClientGroup)))
					{
						//CGroup* new_group = new CGroup;
						
						new_group->SetInterface(pGRP);
						new_group->SetInfoServer(this);
						new_group->SetName(OLE2A(pGroupNameCopy));
						new_group->SetHandle(hServerGroup);
						
						new_group->SetActive(dlg.m_bActive);
						new_group->SetUpdateRate(dwUpdateRate);
						new_group->SetTimeBias(dlg.m_lTimeBias);
						new_group->SetDeadBand(dlg.m_fDeadBand);
						new_group->SetLCID(dlg.m_dwLCID);
						new_group->SetDataChangeEnabled(dlg.m_bDataChange, FALSE); //write to server in Advise

						*pNewGroup = new_group;
						m_Groups.Add(new_group);

						// Establish a connection
						//
						new_group->Advise();

						((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("Group successfuly cloned."));
						
						bRet = TRUE;
					}
					else
					{
						delete new_group;
					}
				}
				CoTaskMemFree(pGroupNameCopy);
			}
		}
	}
	CoTaskMemFree(pGroupNameSource);

	return bRet;
}

BOOL CInfoServer::ReCreateGroupOnServer(CGroup** group)
{
	USES_CONVERSION;

	HRESULT						res;
	CIOPCServer					opcServer(m_pUnkn);
	DWORD						rate;	//out: servers rate
	OPCHANDLE					hGroup; //out
	CComPtr<IOPCGroupStateMgt>	pGRP;	//out

	//need l-values
	long m_lTimeBias = (*group)->GetTimeBias();
	float m_fDeadBand = (*group)->GetDeadBand();


	res = opcServer.AddGroup(A2OLE((*group)->GetName()),
									(*group)->IsActive(), 
									(*group)->GetUpdateRate(), 
									(OPCHANDLE)(*group),      
									&m_lTimeBias,
									&m_fDeadBand,
									(*group)->GetLCID(),
									&hGroup,
									&rate,
									IID_IOPCGroupStateMgt,
									(LPUNKNOWN*)&pGRP);
	if(SUCCEEDED(res))
	{
		(*group)->SetHandle(hGroup);
		(*group)->SetUpdateRate(rate);
		(*group)->SetInterface(pGRP);
		(*group)->SetInfoServer(this);

		// Establish a connection
		//
		(*group)->Advise();

		((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("Group successfuly added."));
		
		return TRUE;
	}
	else
	{
		DisplayError(res);

⌨️ 快捷键说明

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