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

📄 connectdlg.cpp

📁 此文件为VC++开发环境下的OPC client trend 源代码
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////
//
//  OPC Trend VC++ Client:	ConnectDlg.CPP
//							(Source File)
//
/////////////////////////////////////////////////////////////////////////////
//
//          Author: Raphael Imhof
//    Initial Date: 11/04/98
//       $Workfile: ConnectDlg.cpp $
//       $Revision: 1 $
//           $Date: 7/27/99 5:24p $
//   Target System: Microsoft Windows NT 4.0
//     Environment: Visual C++ 5.0 / OPC DataAccess 1.0 / 2.0
//         Remarks: 
//
/////////////////////////////////////////////////////////////////////////////
//
//     Description: implementation of the CConnectDlg class.
//					Server enum/connect dialog
//					
//
/////////////////////////////////////////////////////////////////////////////
//
//  History of Changes     (Please remove very old comments and blank lines!)
//            $Log: /IDK/OPCServer/clients/VC++/Trend/ConnectDlg.cpp $
// 
// 1     7/27/99 5:24p Imhof
// 
// 1     7/27/99 5:19p Imhof
// 
// 6     1/23/99 10:26a Imhof
// New: CLSID_OPCServerList is imported form opcenum_clsid.c
// (Note: this CLSID differs from the spec; OPC will fix; works foe now)
// - Added error handler for EnumClassesOfCategories()
// 
// 5     1/15/99 7:04p Imhof
// Updated legal notice.
// 
// 4     12/16/98 4:02p Imhof
// Added a release for OPCEnum
// 
// 3     12/15/98 10:30a Imhof
// Modifications for OPC 2.0
// 
// 2     11/06/98 5:53p Imhof
// Added header, comment and made some small code changes.
// 
// 
//  $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 "trend.h"
#include "ConnectDlg.h"
#include <opccomn.h>
#include <opccomn_i.c>
#include <opcenum_clsid.c> //for CLSID_OPCServerList

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

const int MAX_KEYLEN = 256;

/////////////////////////////////////////////////////////////////////////////
// CConnectDlg dialog


CConnectDlg::CConnectDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CConnectDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CConnectDlg)
	m_sOPCServer = _T("");
	m_sOPCServerComputer = _T("");
	m_sSelectedOPCServer = _T("");
	//}}AFX_DATA_INIT

	memset(&m_clsidServer,0,sizeof(m_clsidServer));
}


void CConnectDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CConnectDlg)
	DDX_Control(pDX, IDC_SERVER_LIST, m_lbOPCServerList);
	DDX_Text(pDX, IDC_SERVER, m_sOPCServer);
	DDX_Text(pDX, IDC_SERVER_COMPUTER, m_sOPCServerComputer);
	DDX_LBString(pDX, IDC_SERVER_LIST, m_sSelectedOPCServer);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CConnectDlg, CDialog)
	//{{AFX_MSG_MAP(CConnectDlg)
	ON_LBN_SELCHANGE(IDC_SERVER_LIST, OnSelchangeServerList)
	ON_BN_CLICKED(IDC_FIND_SERVERS, OnFindServers)
	ON_LBN_DBLCLK(IDC_SERVER_LIST, OnDblclkServerList)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConnectDlg message handlers

BOOL CConnectDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	FindOPCServers();

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

/* old OPC 1.0 method
BOOL CConnectDlg::FindOPCServers_FromRegistry(LPCTSTR node)
{
	CWaitCursor wait;

	m_lbOPCServerList.ResetContent();

	// search the registry for OPC entries
	HKEY hk = HKEY_CLASSES_ROOT;
	if(node)
	{
		DWORD dwR = RegConnectRegistry ((LPTSTR)node, HKEY_CLASSES_ROOT, &hk);
		if(dwR != ERROR_SUCCESS)
			return FALSE;
	}

	TCHAR key[MAX_KEYLEN];
	for(int index=0; RegEnumKey(hk, index, key, MAX_KEYLEN) == ERROR_SUCCESS; index++)
	{
		HKEY hProgID;
		TCHAR dummy[MAX_KEYLEN];
		if(RegOpenKey(hk, key, &hProgID )==ERROR_SUCCESS )
		{
			LONG size=MAX_KEYLEN;
			if(RegQueryValue(hProgID, _T("OPC"), dummy, &size) == ERROR_SUCCESS )
			{
				TCHAR desc[MAX_KEYLEN];
				size = MAX_KEYLEN;
				RegQueryValue(hk, key, desc, &size);
				m_lbOPCServerList.AddString(key);
			}
			RegCloseKey(hProgID);
		}
		RegCloseKey(hk);
	}
	if(m_lbOPCServerList.GetCount() > 0)
		m_lbOPCServerList.SetCurSel(0);

   return TRUE;
}
*/

BOOL CConnectDlg::FindOPCServers(LPCTSTR node)
{
	USES_CONVERSION;

	CWaitCursor wait;

	m_lbOPCServerList.ResetContent();

	//1. connect to server list component
	CString					sNode(node);
	CComPtr<IOPCServerList>	pServerList;
	COSERVERINFO			si;
	MULTI_QI				qi;
	HRESULT					hRes;

	si.dwReserved1 = 0;
	if(sNode.IsEmpty())
		si.pwszName = NULL;
	else
		si.pwszName = T2OLE(sNode.GetBuffer(0));
	si.pAuthInfo = NULL;
	si.dwReserved2 = 0;

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

	hRes = CoCreateInstanceEx(CLSID_OPCServerList, NULL, CLSCTX_ALL, &si, 1, &qi);
	if (FAILED(hRes))
	{
		((CTrendApp*)AfxGetApp())->DisplayText(_T("CoCreateInstanceEx()"), hRes);
		return FALSE;
	}
	if (FAILED(qi.hr))
	{
		((CTrendApp*)AfxGetApp())->DisplayText(_T("Failed to connect to server"), qi.hr);
		return FALSE;
	}
		
	pServerList = (IOPCServerList*) qi.pItf;
	qi.pItf->Release();
	
	//2. enumerate the list
	CComPtr<IEnumGUID>	pEnumGUID;
	
	hRes = pServerList->EnumClassesOfCategories(1, &m_catid, 1, &m_catid, &pEnumGUID);
	if(SUCCEEDED(hRes))
	{
		/*
		how many elemets to retrieve for each Next()
		not configurable in options (we are dealing with only a few servers)
		*/
		const unsigned long ulNext = 100;  
		unsigned long count = 0;
		CLSID clsid[ulNext];

		do
		{
			hRes = pEnumGUID->Next(ulNext, clsid, &count);
			for(unsigned long index = 0; index < count; index++)
			{
				LPOLESTR pszProgID;
				LPOLESTR pszUserType;
				if(SUCCEEDED(pServerList->GetClassDetails(clsid[index], &pszProgID, &pszUserType)))
				{				   
					CString sOPCServer;
					sOPCServer.Format( _T("%s  (%s)"), OLE2A(pszProgID), OLE2A(pszUserType));
					int iPos = m_lbOPCServerList.AddString(sOPCServer);
				
					CLSID* pData = new CLSID;
					*pData = clsid[index];
					m_lbOPCServerList.SetItemDataPtr(iPos, pData);

					CoTaskMemFree(pszProgID);
					CoTaskMemFree(pszUserType);
				}
			}
		}
		while(hRes == S_OK);

		pEnumGUID.Release();
	}
	else
	{
		((CTrendApp*)AfxGetApp())->DisplayText(_T("EnumClassesOfCategories()"), hRes);
	}

	//3. disconnect
	pServerList.Release();

	if(m_lbOPCServerList.GetCount() > 0)
		m_lbOPCServerList.SetCurSel(0);

	return TRUE;
}

void CConnectDlg::OnSelchangeServerList() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

	m_sOPCServer = m_sSelectedOPCServer;
	m_clsidServer = *(CLSID*) m_lbOPCServerList.GetItemDataPtr(m_lbOPCServerList.GetCurSel());

	UpdateData(FALSE);
}

void CConnectDlg::OnFindServers() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);

	m_lbOPCServerList.ResetContent();

	FindOPCServers(m_sOPCServerComputer);	
}


void CConnectDlg::OnOK() 
{
	// TODO: Add extra validation here
	UpdateData(TRUE);

	if(m_sOPCServer.IsEmpty())
	{
		AfxMessageBox(IDS_CONNECT_OPC_SERVER_EMPTY);
		return;
	}

	CDialog::OnOK();
}

void CConnectDlg::OnDblclkServerList() 
{
	// TODO: Add your control notification handler code here
	OnOK();
}

BOOL CConnectDlg::DestroyWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	CLSID*	pData = NULL;
	UINT	count = m_lbOPCServerList.GetCount();

	for(UINT i = 0; i < count; i++)
	{
		pData = (CLSID*) m_lbOPCServerList.GetItemDataPtr(i);
		delete pData;
	}
	
	return CDialog::DestroyWindow();
}

⌨️ 快捷键说明

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