📄 connectdlg.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 + -