📄 dlgopcserverlist.cpp
字号:
// 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 + -