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

📄 dlgopcserverlist.cpp

📁 OPC Client 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DlgOPCServerList.cpp : implementation file
//

#include "stdafx.h"
#include "TYOPCClient.h"
#include "DlgOPCServerList.h"
#include "DlgOPCPC.h"

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

//const CLSID CLSID_OpcServerList = {0x13486D51,0x4821,0x11D2,{0xA4,0x94,0x3C,0xB3,0x06,0xC1,0x00,0x00}};
//const IID IID_IOPCServerList = {0x13486D50,0x4821,0x11D2,{0xA4,0x94,0x3C,0xB3,0x06,0xC1,0x00,0x00}};

//版本号----可以从规范中查到
//#ifndef CATID_OPCDAServer10
static const CLSID CATID_OPCDAServer10 = 
{ 0x63d5f430, 0xcfe4, 0x11d1, { 0xb2, 0xc8, 0x0, 0x60, 0x8, 0x3b, 0xa1, 0xfb } };
// {63D5F430-CFE4-11d1-B2C8-0060083BA1FB}
//#endif

//#ifdef CATID_OPCDAServer20
static const CLSID CATID_OPCDAServer20 = 
{ 0x63d5f432, 0xcfe4, 0x11d1, { 0xb2, 0xc8, 0x0, 0x60, 0x8, 0x3b, 0xa1, 0xfb } };
// {63D5F432-CFE4-11d1-B2C8-0060083BA1FB}
//#endif

//#ifndef CATID_OPCDAServer30

static const CLSID CATID_OPCDAServer30 = 
{ 0xCC603642, 0x66D7, 0x48f1, { 0xb6, 0x9a, 0xb6, 0x25, 0xe7, 0x36, 0x52, 0xd7 } };
//[uuid(CC603642-66D7-48f1-B69A-B625E73652D7)] interface CATID_OPCDAServer30
//#endif
//--------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------

//------------------------
static LPCTSTR lpszDataAccessServers10 = _T("OPC Data Access Servers Version 1.0");
static LPCTSTR lpszDataAccessServers20 = _T("OPC Data Access Servers Version 2.0");
static LPCTSTR lpszDataAccessServers30 = _T("OPC Data Access Servers Version 3.0");
// image list indices
#define ILI_REMPC	    0
#define ILI_CATAGORY	1
#define ILI_COMPONENT	2
#define ILI_INTERFACE	3
//
//--------------------------------------------------------------------------------------------------------------
#define WM_TIMER_OPCBROWSE_EVENT 1000
#define WM_TIMER_OPCBROWSE_TIME   100
/////////////////////////////////////////////////////////////////////////////
// CDlgOPCServerList dialog


CDlgOPCServerList::CDlgOPCServerList(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgOPCServerList::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgOPCServerList)
	m_strID = _T("");
	m_strOPCName = _T("");
	m_strNote = _T("");
	//}}AFX_DATA_INIT

	m_pcOPCMgt=NULL;
	m_pcMapOPCBrowse=NULL;
	m_pSelOPCBrowse=NULL;
	m_pSelOPCInfo=NULL;

	m_bNameChanged=FALSE;
	m_nSelItem=OPC_PC;
	m_hSelItem=NULL;

	m_unOPCVersion=0;
}


void CDlgOPCServerList::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgOPCServerList)
	DDX_Control(pDX, IDC_REFLASH, m_ctrlReflash);
	DDX_Control(pDX, IDC_EDIT_NAME, m_ctrlName);
	DDX_Control(pDX, IDC_STATIC_ID, m_ctrlID);
	DDX_Control(pDX, IDC_TREE_OPCSERVER, m_ctrlTreeOPC);
	DDX_Text(pDX, IDC_EDIT_PROGID, m_strID);
	DDX_Text(pDX, IDC_EDIT_NAME, m_strOPCName);
	DDX_Text(pDX, IDC_EDIT_USETYPE, m_strNote);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgOPCServerList, CDialog)
	//{{AFX_MSG_MAP(CDlgOPCServerList)
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_OPCSERVER, OnSelchangedTreeOPCServer)
	ON_BN_CLICKED(IDC_ADD, OnAddOPCPC)
	ON_BN_CLICKED(IDC_MODIFY, OnModify)
	ON_EN_CHANGE(IDC_EDIT_NAME, OnChangeEditName)
	ON_BN_CLICKED(IDC_REFLASH, OnReflash)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgOPCServerList message handlers

BOOL CDlgOPCServerList::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	CenterWindow();	//居中

	CWnd* pBtnOK=GetDlgItem (IDOK);
	if(pBtnOK)
		pBtnOK->EnableWindow (FALSE);


	// Initialize the image list for the interfaces. The bitmap must use a 
	// purple background color, RGB (255, 0, 255), so that the CImageList
	// object can construct a mask.  The images are 16x16 pixels.  Set the
	// image list background color to CLR_NONE so masked pixels will be
	// transparent. 
	// Image number		Use
	//	0				not used
	//	1				not used
	//	2				Interface
	m_cImageList.Create (IDB_BROWSEOPC, 16, 4, RGB (255, 0, 255));
	m_cImageList.SetBkColor (CLR_NONE);
	m_ctrlTreeOPC.SetImageList (&m_cImageList, TVSIL_NORMAL);


	CWnd* pBtn;
	pBtn=GetDlgItem (IDC_MODIFY);
	pBtn->EnableWindow (FALSE);

	SetTimer(WM_TIMER_OPCBROWSE_EVENT,WM_TIMER_OPCBROWSE_TIME,NULL)	;

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CDlgOPCServerList::QueryOPCServer(HTREEITEM hParent,CLSID clsIDVersion)
{
	CLSID clsid;
	clsid = CLSID_OpcServerList;	//在opcenum_i.c中定义
   
	DWORD clsctx;
	clsctx = CLSCTX_LOCAL_SERVER;	//本地服务
	clsctx = CLSCTX_ALL;			//本地\远程服务
	try{
/*
	//*****************************************************************************
	//方法1:采用智能指针
	IOPCServerListPtr gpOPC;		//只能使用本地服务标示
	//
	// 创建OPC服务器的浏览器对象-----
	HRESULT hr=gpOPC->CreateInstance (clsid,NULL,clsctx) ;
	if(FAILED(hr))
	{
		_com_issue_error(hr);
		
		//本地服务
		clsctx = CLSCTX_LOCAL_SERVER;	
		hr=gpOPC.CreateInstance (clsid,NULL,clsctx) ;
		if(FAILED(hr))
		{
			_com_issue_error(hr);
			return;
		}
	}
//*/
	//*****************************************************************************
	//方法2:采用普通接口
	IOPCServerList *gpOPC = NULL;
	IID IIDOPCServerList=IID_IOPCServerList;	//在opcenum_i.c中定义
	// 创建OPC服务器的浏览器对象-----
	HRESULT hr = CoCreateInstance(clsid, NULL, clsctx,IIDOPCServerList ,(void**)&gpOPC);	

	if(S_OK!=hr)
		return;
	//*****************************************************************************


	
	// 查询OPC DA组件目录接口指针
	IOPCEnumGUID *pEnumGUID;
	
	hr = gpOPC->EnumClassesOfCategories( 
		1, &clsIDVersion, 
		1, &clsIDVersion, 
		(IEnumGUID**)&pEnumGUID); 
	if(S_OK!=hr)
		return;

	//获得支持OPC DA数据服务器的CLSID
	unsigned long c;
	while (S_OK == pEnumGUID->Next(1, &clsid, &c)) 
	{
		LPOLESTR pszProgID;
		LPOLESTR pszUserType;
		hr = gpOPC->GetClassDetails(&clsid, &pszProgID, &pszUserType);

		//打印OPC数据服务器的有关信息
		TRACE("ProgID = %ls, UserType = %ls\n", pszProgID, pszUserType);
#ifdef _UNICODE
		m_ctrlTreeOPC.InsertItem (wszProgID, ILI_COMPONENT, ILI_COMPONENT, hParent);
#else
		TCHAR szProgID [DEFBUFFSIZE];

		_wcstombsz (szProgID, pszProgID, sizeof (szProgID) / sizeof (TCHAR));
		m_ctrlTreeOPC.InsertItem (szProgID, ILI_COMPONENT, ILI_COMPONENT, hParent);
#endif
		CoTaskMemFree(pszProgID);
		CoTaskMemFree(pszUserType);
//		SysFreeString(pszProgID);	//Error
//		SysFreeString(pszUserType);
	}
	}catch(...)
	{
		printf("\n创建组件异常错误!\n");
	}
}

void CDlgOPCServerList::OnSelchangedTreeOPCServer(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here

	//判断是否修改
	NameChanged();

	//判断选项
	HTREEITEM hOPCPCItem=NULL;
	HTREEITEM hOPCVerItem=NULL;
	HTREEITEM hOPCItem=pNMTreeView->itemNew.hItem;
	m_hSelItem=hOPCItem;

	BOOL bBTN_OK=FALSE;

	// 判断选择的是否为子项(ProgID):
	hOPCVerItem=m_ctrlTreeOPC.GetParentItem (hOPCItem);
	if(hOPCVerItem)
		hOPCPCItem=m_ctrlTreeOPC.GetParentItem (hOPCVerItem);

	if (hOPCPCItem != NULL)
	{
		//得到选择项文本(ProgID):
		COPCInfo* pOPCInfo=(COPCInfo *)m_ctrlTreeOPC.GetItemData (hOPCItem);
		m_pSelOPCInfo=pOPCInfo;

		m_strID=pOPCInfo->m_strProgID ;
		m_strNote=pOPCInfo->m_strUserType ;
		m_strOPCName=pOPCInfo->m_strName ;

		m_ctrlID.SetWindowText(_T("ProgID"));

		//得到OPC Browse
		m_pSelOPCBrowse=(COPCBrowse *)m_ctrlTreeOPC.GetItemData (hOPCPCItem);

		//得到 OPC VERSION
		m_unOPCVersion=m_ctrlTreeOPC.GetItemData (hOPCVerItem);

		//Update controls:
		bBTN_OK=TRUE;
		//确保选择内容可见:
		m_ctrlTreeOPC.EnsureVisible (pNMTreeView->itemNew.hItem); 
		m_ctrlName.EnableWindow(TRUE);

		m_nSelItem=OPC_SERVER;
		m_ctrlReflash.EnableWindow(FALSE);
	}
	else if(hOPCVerItem==NULL)
	{	//OPC PC
		m_pSelOPCInfo=NULL;
		m_pSelOPCBrowse=(COPCBrowse *)m_ctrlTreeOPC.GetItemData (hOPCItem);
		
		m_strOPCName = m_pSelOPCBrowse->m_strPCName ;
		m_strID = m_pSelOPCBrowse->m_strPCIP ;
		m_strNote=m_pSelOPCBrowse->m_strNote ;
		m_ctrlID.SetWindowText(_T("IP :"));
		m_ctrlReflash.EnableWindow(TRUE);

		if(m_strOPCName==LOACAL_PC_NAME)
			m_ctrlName.EnableWindow(FALSE);
		m_nSelItem=OPC_PC;
	}
	else
	{
		m_strID = _T("");
		m_strOPCName = _T("");
		m_strNote = _T("");
		
		bBTN_OK=FALSE;
		m_pSelOPCInfo=NULL;
		m_nSelItem=OPC_NULL;

		m_ctrlReflash.EnableWindow(FALSE);
	}
	UpdateData (FALSE);

	m_strOldOPCName=m_strOPCName;
	//使OK键
	CWnd* pBtn;
	pBtn=GetDlgItem (IDOK);
	pBtn->EnableWindow (bBTN_OK);
	
	pBtn=GetDlgItem (IDC_EDIT_PROGID);	//ES_READONLY   
	pBtn->EnableWindow (bBTN_OK);

	pBtn=GetDlgItem (IDC_EDIT_USETYPE);
	pBtn->EnableWindow (bBTN_OK);

	*pResult = 0;
}

void CDlgOPCServerList::SetOPCBrowse(COPCManagement *pcOPCMgt)
{
	m_pcOPCMgt=pcOPCMgt;
	m_pcMapOPCBrowse=pcOPCMgt->GetOPCBrowse ();
}

//查询OPC SERVER 
bool CDlgOPCServerList::QueryOPCServer(CString *pstrPC, CString *pstrIP,COPCBrowse*& pOPCBrowse)
{
	CLSID clsid;
	clsid = CLSID_OpcServerList;	//在opcenum_i.c中定义
   
	DWORD clsctx;
	clsctx = CLSCTX_LOCAL_SERVER;	//本地服务
	clsctx = CLSCTX_ALL;			//本地\远程服务
	try{
		//*****************************************************************************
		//方法2:采用普通接口
		IOPCServerList *gpOPC = NULL;
		IID IIDOPCServerList=IID_IOPCServerList;	//在opcenum_i.c中定义
		// 创建OPC服务器的浏览器对象-----
		HRESULT hr;
		//hr= CoCreateInstance(clsid, NULL, clsctx,IIDOPCServerList ,(void**)&gpOPC);	

		MULTI_QI multiIID;

		multiIID.pItf = NULL;
		multiIID.hr = 0;
		multiIID.pIID= &IIDOPCServerList;

		if(strcmp(*pstrPC,LOACAL_PC_NAME)==0)				//本地计算机
		{
			hr = CoCreateInstanceEx (
				clsid,										// CLSID
				NULL,										// No aggregation
				clsctx,										// connect to local, inproc and remote servers
				NULL,										// remote machine name 
				1,											// number of IIDS to query		
				&multiIID);									// array of IID pointers to query
		}
		else												//远程计算机
		{
			COSERVERINFO tCoServerInfo;
			ZeroMemory (&tCoServerInfo, sizeof (tCoServerInfo));

			// Allocate memory for the machine name string:
			int nSize = pstrIP->GetLength () * sizeof (WCHAR);
			tCoServerInfo.pwszName = new WCHAR [nSize];

			// Check validity of pointer.  If it's bad, there's no point in continuing:
			if (!tCoServerInfo.pwszName)
			{
				ASSERT (FALSE);
				return (false);
			}

			// Copy the machine name string into the server info structure:
	#ifdef _UNICODE
			// For Unicode builds, the contents of m_strRemoteMachine will
			// already be in wide character format, as demanded by COM, so
			// copy it as is.
			lstrcpyn (tCoServerInfo.pwszName, pstrIP, nSize);
	#else 
			// For ANSI builds, the contents of m_strRemoteMachine will not
			// be in wide character format, as demanded by COM, so we need
			// to reformat:
			mbstowcs (tCoServerInfo.pwszName, *pstrIP, nSize);
	#endif//_UNICODE
			hr = CoCreateInstanceEx (
				clsid,										// CLSID
				NULL,										// No aggregation
				clsctx,										// connect to local, inproc and remote servers
				&tCoServerInfo,								// remote machine name 
				1,											// number of IIDS to query		
				&multiIID);									// array of IID pointers to query
			
			delete [] tCoServerInfo.pwszName;
		}
		if(!SUCCEEDED (hr))
			return false;
		if(SUCCEEDED (multiIID.hr))
		{
			pOPCBrowse=new COPCBrowse;
			//OPC1.0
			TRACE("BrowsOPCServer OPC3.0\n");
			QueryOPCServer(pOPCBrowse->m_cMapOPC10, 
				(IOPCServerList*)multiIID.pItf ,CATID_OPCDAServer10);
			//OPC2.0
			TRACE("BrowsOPCServer OPC3.0\n");
			QueryOPCServer(pOPCBrowse->m_cMapOPC20,
				(IOPCServerList*)multiIID.pItf ,CATID_OPCDAServer20);
			//OPC3.0
			TRACE("BrowsOPCServer OPC3.0\n");
			QueryOPCServer(pOPCBrowse->m_cMapOPC30,
				(IOPCServerList*)multiIID.pItf ,CATID_OPCDAServer30);

⌨️ 快捷键说明

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