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

📄 browserdlg.cpp

📁 最简单的VC编写的OPC客户端程序
💻 CPP
字号:
// BrowserDlg.cpp : implementation file
//
//--------------------------------------------------------- 
// (c) COPYRIGHT 2003,2004 http://www.opc-china.com INC.
// ALL RIGHTS RESERVED
// Original Author:Jigang Si
// Original Author Email:economic@126.com 
//--------------------------------------------------------- 
#include "stdafx.h"
#include "Browser.h"
#include "BrowserDlg.h"
#include "comutil.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define OPC_ACCESS_READ 1
#define OPC_ACCESS_WRITE 2
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBrowserDlg dialog

CBrowserDlg::CBrowserDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBrowserDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBrowserDlg)
	m_AccessRight = -1;
	m_BrType = -1;
	m_DataType = -1;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	
}

void CBrowserDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBrowserDlg)
	DDX_Control(pDX, IDC_ITEMID_TREE, m_MyTree);
	DDX_Control(pDX, IDC_DATATYPE_COMBO, m_DataTypeCtrl);
	DDX_Control(pDX, IDC_BROWSEFILTERTYPE_COMBO, m_BrTypeCtrl);
	DDX_Control(pDX, IDC_ACCESSRIGHT_COMBO, m_AccessRightCtrl);
	DDX_CBIndex(pDX, IDC_ACCESSRIGHT_COMBO, m_AccessRight);
	DDX_CBIndex(pDX, IDC_BROWSEFILTERTYPE_COMBO, m_BrType);
	DDX_CBIndex(pDX, IDC_DATATYPE_COMBO, m_DataType);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBrowserDlg, CDialog)
	//{{AFX_MSG_MAP(CBrowserDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_START_BUTTON, OnStartButton)
	ON_BN_CLICKED(IDC_EXIT_BUTTON, OnExitButton)
	ON_CBN_SELCHANGE(IDC_ACCESSRIGHT_COMBO, OnSelchangeAccessrightCombo)
	ON_CBN_SELCHANGE(IDC_BROWSEFILTERTYPE_COMBO, OnSelchangeBrowsefiltertypeCombo)
	ON_CBN_SELCHANGE(IDC_DATATYPE_COMBO, OnSelchangeDatatypeCombo)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBrowserDlg message handlers

BOOL CBrowserDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	m_AccessRight = 0;
	m_BrType = 0;
	m_DataType = 0;
	m_AccessRightCtrl.SetCurSel(m_AccessRight);
    m_BrTypeCtrl.SetCurSel(m_BrType);
    m_DataTypeCtrl.SetCurSel(m_DataType);
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	pIMalloc=NULL;
	pIOPCBrowse=NULL;
	pIOPCServer=NULL;
	HRESULT r1;
    
    r1 = CoInitialize(NULL);

    if (FAILED(r1))
    {
        AfxMessageBox("COM初始化失败");
        exit(1);
    }

    // Also get access to the COM memory manager
    //
    r1 = CoGetMalloc(MEMCTX_TASK, &pIMalloc);

    if (FAILED(r1))
    {
        AfxMessageBox("GetMalloc失败!");
		CoUninitialize();
        pIMalloc=NULL;
        exit(1);
    }
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CBrowserDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CBrowserDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CBrowserDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
//---------------------------------------------------------
// CreateOPCBrowser
// 通过指定OPC服务器的名字获得一个IOPCBrowseServerAddressSpace接口
//---------------------------------------------------------
IOPCBrowseServerAddressSpace* CBrowserDlg::CreateOPCBrowser(WCHAR *szName)
{
	CLSID clsid;
    HRESULT r1, r2, r3;
    IUnknown *pUNK;
    IOPCBrowseServerAddressSpace *pBrowse;
	

	pBrowse=NULL;
    // 通过名字获得 CLSID 
    r1 = CLSIDFromProgID(szName, &clsid);
    if(FAILED(r1))
    {
     
		AfxMessageBox("CLSIDFromProgID失败");
        pUNK=NULL;
    }

    // 创建一个OPC服务器对象
    //
    r2 = CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER ,IID_IUnknown, (void**)&pUNK);

    
    if (FAILED(r2))
    {
		AfxMessageBox("CoCreateInstance失败,不能创建OPC服务器!");
        pUNK=NULL;
    }
 
	if (pUNK)
    {
		// 请求获得一个IOPCServer接口
		//
		r3 = pUNK->QueryInterface(IID_IOPCServer, (void**)&pIOPCServer);
		if (FAILED(r3))
		{
		  AfxMessageBox("没用IOPCServer接口,连接OPC服务器失败");
		  pIOPCServer=NULL;
		  return NULL;
		}
		else
        {
    		// 请求获得一个IOPCBrowseServerAddressSpace 接口
		    //
			r3 = pIOPCServer->QueryInterface(IID_IOPCBrowseServerAddressSpace, (void**)&pBrowse);
			if (FAILED(r3))
			{
			  AfxMessageBox("没用IOPCBrowseServerAddressSpace");
			  return NULL;
			}
    
        }
		pUNK->Release();
		pUNK=NULL;
	}	
	
     return pBrowse;  

}


void CBrowserDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	if(pIMalloc)
    {
		pIMalloc->Release();
		pIMalloc=NULL;
        CoUninitialize();
	}
	CDialog::OnOK();
}
//---------------------------------------------------------
// BrowseLevel
// 建立树状的地址空间
//---------------------------------------------------------
void CBrowserDlg::BrowseLevel(HTREEITEM gParent,CString FullName,IOPCBrowseServerAddressSpace *pIOPCBrowse)
{
    HRESULT r1;
    IEnumString * pEnum;
   	TV_INSERTSTRUCT		tvstruct;
	
    // Query for the Browser Interface
    OPCBROWSETYPE   brType ;
    LPCWSTR         szFilt = L"*";
    VARTYPE         vtFilt; 
    DWORD           arFilt;

	if(m_DataType==0)
	{
		vtFilt = VT_EMPTY;
	}

    if(m_DataType==1)
	{
		vtFilt = VT_UI1;
	}

    if(m_DataType==2)
	{
		vtFilt = VT_UI2;
	}

    if(m_DataType==3)
	{
		vtFilt = VT_BOOL;
	}
    
	if(m_DataType==4)
	{
		vtFilt = VT_BSTR;
	}

	if(m_AccessRight== 0)
	{
		arFilt= OPC_ACCESS_READ;
	}
	else if(m_AccessRight==1)
	{
		arFilt=OPC_ACCESS_WRITE;
	}

	if(m_BrType==0)
	{
		brType=OPC_BRANCH;
		// (1) Browse Branches
		r1 = pIOPCBrowse->BrowseOPCItemIDs(brType, szFilt, vtFilt, arFilt, &pEnum);
		if (FAILED(r1))
		{			
			AfxMessageBox("BrowseOPCItemIDs错误");
		}		
		else 
		{
			HRESULT r2 = S_OK;
			ULONG actual;
			LPOLESTR pStr;
     
			HTREEITEM Parent=NULL;

			if (pEnum) 
			{
				while((r2 = pEnum->Next(1, &pStr, &actual)) == S_OK)
				{
					tvstruct.hParent = gParent;
					tvstruct.hInsertAfter = TVI_SORT;
					tvstruct.item.pszText = _com_util::ConvertBSTRToString(pStr);
					tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
					Parent=m_MyTree.InsertItem(&tvstruct);
					HRESULT r3 = S_OK;
					r3 = pIOPCBrowse->ChangeBrowsePosition(
									OPC_BROWSE_DOWN, pStr);
					if (FAILED(r3))
					{
						AfxMessageBox("ChangeBrowsePosition(BROWSE_DOWN)错误");
					}
					else
					{   
						BrowseLevel(Parent,FullName + (LPWSTR)LPCTSTR(pStr),pIOPCBrowse);
					}
					pIMalloc->Free(pStr); 
					// Free the string(s) that Next Returned
				}
				
				if (FAILED(r2))
				{
					AfxMessageBox("Next错误");

				}
				pEnum->Release(); 
				// Release the interface
			}
			else 
			{				
				AfxMessageBox("空的分支!");
			}
		}
        brType = OPC_LEAF;

		// (1) Browse Leaves
		r1 = pIOPCBrowse->BrowseOPCItemIDs(brType, szFilt, vtFilt, arFilt, &pEnum);
		if (FAILED(r1))
		{
			AfxMessageBox("BrowseOPCItemIDs错误");

		}
		else
		{
			HRESULT r2 = S_OK;
			LPOLESTR pStr;
			LPOLESTR pName;
			ULONG actual;
			
			// Got an IEnumString with Leaves...

			if (pEnum) {
				while((r2 = pEnum->Next(1, &pStr, &actual)) == S_OK) {
					tvstruct.hParent = gParent;
					tvstruct.hInsertAfter = TVI_SORT;
					pIOPCBrowse->GetItemID(pStr, &pName);
					tvstruct.item.pszText = _com_util::ConvertBSTRToString(pName);
					tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
					m_MyTree.InsertItem(&tvstruct);
					pIMalloc->Free(pStr); 					
				}
				if (FAILED(r2)) {
					AfxMessageBox("Next错误");
				}
				pEnum->Release(); 
				// Release the interface
			}
			else {
				AfxMessageBox("空的分支");

			}
		}

		HRESULT r3 = S_OK;

		r3 = pIOPCBrowse->ChangeBrowsePosition(	OPC_BROWSE_UP, L"");
	}
    else if(m_BrType==1)
	{
		brType = OPC_FLAT;

		// (1) Browse Leaves
		r1 = pIOPCBrowse->BrowseOPCItemIDs(brType, szFilt, vtFilt, arFilt, &pEnum);
		if (FAILED(r1))
		{			
			AfxMessageBox("BrowseOPCItemIDs错误");
		}
		else
		{
			HRESULT r2 = S_OK;
			LPOLESTR pStr;
			LPOLESTR pName;
			ULONG actual;
			
			//Got an IEnumString with Leaves...

			if (pEnum) {
				while((r2 = pEnum->Next(1, &pStr, &actual)) == S_OK) {
					
					tvstruct.hParent = gParent;
					tvstruct.hInsertAfter = TVI_SORT;
					pIOPCBrowse->GetItemID(pStr, &pName);
					tvstruct.item.pszText =  _com_util::ConvertBSTRToString(pName);
					tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
					m_MyTree.InsertItem(&tvstruct);                
					pIMalloc->Free(pStr); 
					// Free the string(s) that Next Returned
				}
				if (FAILED(r2)) {
					AfxMessageBox("Next错误");

				}
				pEnum->Release(); 
				// Release the interface
			}
			else {
				AfxMessageBox("空的分支");

			}
		}
	}
}

void CBrowserDlg::OnStartButton() 
{
	// TODO: Add your control notification handler code here
	CWaitCursor wait;

	pIOPCBrowse = CreateOPCBrowser(L"Matrikon.OPC.Simulation");
    m_MyTree.DeleteAllItems( );
	BrowseLevel(0,L"",pIOPCBrowse);

	if(pIOPCBrowse)
	{
		pIOPCBrowse->Release();
		pIOPCBrowse=NULL;
	}
	if(pIOPCServer)
	{
		pIOPCServer->Release();
		pIOPCServer=NULL;
	}		
}

void CBrowserDlg::OnExitButton() 
{
	// TODO: Add your control notification handler code here
	OnClose();
}

void CBrowserDlg::OnSelchangeAccessrightCombo() 
{
	// TODO: Add your control notification handler code here
    m_AccessRight =	m_AccessRightCtrl.GetCurSel();	
}

void CBrowserDlg::OnSelchangeBrowsefiltertypeCombo() 
{
	// TODO: Add your control notification handler code here
   m_BrType = m_BrTypeCtrl.GetCurSel();	
}

void CBrowserDlg::OnSelchangeDatatypeCombo() 
{
	// TODO: Add your control notification handler code here
	m_DataType = m_DataTypeCtrl.GetCurSel();	
}

⌨️ 快捷键说明

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