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

📄 dlgopcitemadd.cpp

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

#include "stdafx.h"
#include "TYOPCClient.h"
#include "DlgOPCItemAdd.h"

#include "DlgModifyName.h"

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

// Registry sections;
static LPCTSTR lpszRegSection	= _T("Add Items");
static LPCTSTR lpszAutoValidate	= _T("Auto Validate");
static LPCTSTR lpszBrowseFlat	= _T("Browse Flat");

// Default add item list size:
#define DEF_ITEM_LIST_SIZE		16

// Branch dummy item data:
#define NULL_ITEM_NAME			_T("_QCNULL_DUMMY")
#define NULL_ITEM_DATA			0xFFFFFFFF

// Image list indices:
#define ILI_BRANCH				10
#define ILI_SELBRANCH			11
#define ILI_LEAF				3

// Access rights filter combo box indices:
#define CB_ACCESS_ANY			0
#define CB_ACCESS_READONLY		1
#define CB_ACCESS_WRITEONLY		2
#define CB_ACCESS_READWRITE		4
//
#define BEINGITEM_SELGROUP		10000000


/////////////////////////////////////////////////////////////////////////////
// CDlgOPCItemAdd dialog


CDlgOPCItemAdd::CDlgOPCItemAdd(COPCServer *pServer,CWnd* pParent /*=NULL*/)
	: CDialog(CDlgOPCItemAdd::IDD, pParent)
{
	//Initialize member variables:
	ASSERT (pServer != NULL);
	m_pServer = pServer;
	m_pIBrowse = pServer->GetIBrowse ();

	m_pBranchList=NULL;
	m_pLeafList=NULL;
	m_pAddItemList=NULL;

	m_pIItemMgt = pServer->GetSelGroup ()->m_pIOPCItemMgt;

	m_bActive=1;
	m_vtDataType=0;

	// Load registry settings.  These are settings we may want to use each time
	// we add some items:
	m_bAutoValidate = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszAutoValidate, FALSE);
	m_bBrowseFlat = AfxGetApp ()->GetProfileInt (lpszRegSection, lpszBrowseFlat, FALSE);

	// Allocate memory for add item list:
	try
		{
//		m_cAddItems.SetSize (DEF_ITEM_LIST_SIZE, DEF_ITEM_LIST_SIZE);
		m_cAddItems.SetSize (0, DEF_ITEM_LIST_SIZE);
		}
	catch (...)
		{
		ASSERT (FALSE);
		}

	//{{AFX_DATA_INIT(CDlgOPCItemAdd)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CDlgOPCItemAdd::~CDlgOPCItemAdd()
{
	// Save registry settings:
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszAutoValidate, m_bAutoValidate);
	AfxGetApp ()->WriteProfileInt (lpszRegSection, lpszBrowseFlat, m_bBrowseFlat);
}

void CDlgOPCItemAdd::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgOPCItemAdd)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgOPCItemAdd, CDialog)
	//{{AFX_MSG_MAP(CDlgOPCItemAdd)
	ON_NOTIFY(TVN_SELCHANGED, IDC_BRANCHLIST, OnSelChangedBranchList)
	ON_NOTIFY(TVN_ITEMEXPANDING, IDC_BRANCHLIST, OnItemExpandingBranchList)
	ON_NOTIFY(NM_DBLCLK, IDC_LEAFLIST, OnDblclkLeafList)
	ON_CBN_SELCHANGE(IDC_FILTERTYPE, OnSelChangeFilterType)
	ON_CBN_SELCHANGE(IDC_FILTERACCESS, OnSelChangeFilterAccess)
	ON_BN_CLICKED(ID_ADDITEM, OnAddItem)
	ON_BN_CLICKED(ID_DELITEM, OnDelItem)
	ON_NOTIFY(NM_CLICK, IDC_LEAFLIST, OnClickLeafList)
	ON_NOTIFY(NM_CLICK, IDC_ADDITEMLIST, OnClickAddItemlist)
	ON_NOTIFY(NM_DBLCLK, IDC_ADDITEMLIST, OnDblclkAddItemList)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgOPCItemAdd message handlers

BOOL CDlgOPCItemAdd::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	InitializeBrowser();

	m_pBtnAdd=(CButton*)GetDlgItem(ID_ADDITEM);
	m_pBtnDel=(CButton*)GetDlgItem(ID_DELITEM);

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

void CDlgOPCItemAdd::InitializeBrowser()
{
	//支列表指针
	m_pBranchList = (CTreeCtrl *) GetDlgItem (IDC_BRANCHLIST);
	ASSERT (m_pBranchList != NULL);

	//叶列表指针
	m_pLeafList = (CListCtrl *) GetDlgItem (IDC_LEAFLIST);
	ASSERT (m_pLeafList != NULL);

	//增加数据项列表指针
	m_pAddItemList = (CListCtrl *) GetDlgItem (IDC_ADDITEMLIST);
	ASSERT (m_pAddItemList != NULL);

	// Initialize the image list for the branch control.  These are the 
	// images that show up to the left of each item in list.  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-7				not used
	//	8				Branch
	//	9				Self branch
	m_cBranchImageList.Create (IDB_GROUPIMAGES, 16, 3, RGB (255, 0, 255));
	m_cBranchImageList.SetBkColor (CLR_NONE);
	m_pBranchList->SetImageList (&m_cBranchImageList, TVSIL_NORMAL);

	// Initialize the image list for the leaf control.  These are the images
	// that show up to the left of each item in list.  The bitmap must use a 
	// purple background color, RGB (255, 0, 255), so that the CImageList
	// object can construct a mask.  The images are 14x14 pixels.  Set the
	// image list background color to CLR_NONE so masked pixels will be
	// transparent. 
	//
	// Image number		Use
	//	0-2				not used
	//	3				Leaf
	m_cLeafImageList.Create (IDB_ITEMIMAGES, 14, 2, RGB (255, 0, 255));
	m_cLeafImageList.SetBkColor (CLR_NONE);
	m_pLeafList->SetImageList (&m_cLeafImageList, LVSIL_SMALL);

	//在叶列表中插入一列:
	CRect rc;
	m_pLeafList->GetClientRect (&rc);
	m_pLeafList->InsertColumn (0, _T(""), LVCFMT_LEFT, rc.Width ()-20);	

	//在增加数据列表中插入一列:
	m_cAddItemImageList.Create (IDB_ITEMIMAGES, 14, 2, RGB (255, 0, 255));
	m_cAddItemImageList.SetBkColor (CLR_NONE);
	m_pAddItemList->SetImageList (&m_cAddItemImageList, LVSIL_SMALL);
	m_pAddItemList->ModifyStyle (NULL,CCS_TOP);	//LVS_EDITLABELS|允许就地编辑
	m_pAddItemList->SetExtendedStyle (LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
	int nIndex=0;
	m_pAddItemList->GetClientRect (&rc);
	m_pAddItemList->InsertColumn (nIndex++, _T("项ID"), LVCFMT_LEFT, 250);	
	m_pAddItemList->InsertColumn (nIndex++, _T("名  称"), LVCFMT_LEFT, 150);	
	m_pAddItemList->InsertColumn (nIndex++, _T("数据类型"), LVCFMT_CENTER, 80);	
	m_pAddItemList->InsertColumn (nIndex++, _T("活动"), LVCFMT_CENTER, 60);	
	m_pAddItemList->InsertColumn (nIndex++, _T("访问路径"), LVCFMT_CENTER, rc.Width ()-460);	


	//初始化过滤条件:
	
	//支
	m_strFilterBranch = "*";	
	((CEdit *) GetDlgItem (IDC_FILTERBRANCH))->SetWindowText (m_strFilterBranch);
	
	//叶
	m_strFilterLeaf = "*";		
	((CEdit *) GetDlgItem (IDC_FILTERLEAF))->SetWindowText (m_strFilterLeaf);

	//数据类型
	m_vtFilterType = VT_EMPTY;
	((CComboBox *) GetDlgItem (IDC_FILTERTYPE))->SetCurSel (0);

	//数据访问方式
	m_dwFilterAccessRights = CB_ACCESS_ANY;	
	((CComboBox *) GetDlgItem (IDC_FILTERACCESS))->SetCurSel (CB_ACCESS_ANY);

	// Intialize browse controls if browsing is supported, otherwise
	// just disable the controls:
	if (m_pIBrowse != NULL)
		{
		// Create a wait cursor object.  This will cause the wait cursor, 
		// usually an hourglass, to be displayed.  When this object goes
		// out of scope, its destructor will restore the previous cursor
		// type.
		CWaitCursor wc;
		HRESULT hr;

		// Query the server name space:
		hr = m_pIBrowse->QueryOrganization (&m_OpcNameSpace);

		if (SUCCEEDED (hr))
			{
			// Browse root level:
			switch (m_OpcNameSpace)
				{
				case OPC_NS_HIERARCHIAL:
				case OPC_NS_FLAT:
					BrowseRootLevel ();
					break;

				// Did the foundation add a new type?
				default:
					ASSERT (FALSE);
					break;
				}
			}

		// We will assume a hierarchial search if the server fails this request:
		// (This allows us to work with any server that uses the ICONICS toolkit.)
		else
			{
			TRACE (_T("OPC: Attempting agressive browsing since the server failed on QueryOrganization ()\r\n"));

			m_OpcNameSpace = OPC_NS_HIERARCHIAL;
			BrowseRootLevel ();
			}
		}
}

void CDlgOPCItemAdd::BrowseRootLevel()
{
	HRESULT hr = E_FAIL;
	HTREEITEM hItem = NULL;

	try
		{
		// If hierarchial namespace:
		if (m_OpcNameSpace == OPC_NS_HIERARCHIAL)
			{
			// Re-initialize server's browse position to the root:
			do
				{
				// Use the OPC_BROWSE_UP rather than the OPC_BROWSE_TO which
				// is only supported in OOPC version 2.0.  We will have to 
				// browse up to root one level at a time.  Function will
				// fail when we are at root.
				hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_UP, L"\0");
				} while (SUCCEEDED (hr));

			// Insert our root level item:
			hItem = m_pBranchList->InsertItem (m_pServer->GetProgID (), 
				ILI_BRANCH, ILI_SELBRANCH, TVI_ROOT);

			// Set the item data and add a dummy child branch:
			m_pBranchList->SetItemData (hItem, DWORD (-1));
			AddDummyBranch (hItem);
			}

		// Else flat namespace:
		else
			{
			ASSERT (m_OpcNameSpace == OPC_NS_FLAT);

			// Insert our root level item (there is no need to add any dummy
			// branches since a flat space will only have one level of leaves)
			hItem = m_pBranchList->InsertItem (m_pServer->GetProgID (), 
				ILI_BRANCH, ILI_SELBRANCH, TVI_ROOT);
			}

		// Select root item:
		if (hItem)
			m_pBranchList->SelectItem (hItem);
		}
	
	catch (...)
		{
		m_pIBrowse = NULL;
//		UpdateStatus ();	//更新状态
		}
}

void CDlgOPCItemAdd::AddDummyBranch(HTREEITEM hParent)
{
	ASSERT (hParent != NULL);
	
	HTREEITEM hDummyItem;

	// Insert a dummy(哑巴) item:
	hDummyItem = m_pBranchList->InsertItem (NULL_ITEM_NAME, hParent);	//NULL_ITEM_NAME="_QCNULL_DUMMY"
	ASSERT (hDummyItem != NULL);
			
	m_pBranchList->SetItemData (hDummyItem, NULL_ITEM_DATA);
}

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

	// Select the branch:
	SelectBranch (pNMTreeView->itemNew.hItem);

	*pResult = 0;
}

void CDlgOPCItemAdd::SelectBranch(HTREEITEM hItem)
{
	ASSERT (hItem != NULL);

	int nPos;
	HRESULT hr;
	LPENUMSTRING pIEnumString;
	CStringArray strBranches;
	HTREEITEM hParentItem;

#ifndef _UNICODE
	WCHAR szFilter [DEFBUFFSIZE];
#endif

	// Get the new browse position from the item that was previously
	// selected:
	nPos = (int) m_pBranchList->GetItemData (hItem);
	//数型目录层次标识
	BOOL bBrowseFlat= -1==nPos ? TRUE:FALSE;	//在一级目录上
//	m_bBrowseFlat= -1==nPos ? TRUE:FALSE;	//在一级目录上
	
	nPos++;
	ASSERT (nPos >= 0);

	try
		{
		//重新定位OPC服务器的位置到根层
		// Re-intialize the server's position to the root level:
		do
			{
			// Use the OPC_BROWSE_UP rather than the OPC_BROWSE_TO which
			// is only supported in OOPC version 2.0.  We will have to 
			// browse up to root one level at a time.  Function will
			// fail when we are at root.
			hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_UP, L"\0");
			} while (SUCCEEDED (hr));

		// Now browse down to the new position:
		strBranches.SetSize (nPos + 1);
		hParentItem = hItem;

		//重新定位OPC服务器的位置到当前选择层
		//
		for (int i = 0; i <= nPos; i++)
			{
			ASSERT (hItem);
			strBranches [i] = m_pBranchList->GetItemText (hParentItem);
			TRACE(_T("%d %s\n"),i,strBranches [i]);
			hParentItem = m_pBranchList->GetParentItem (hParentItem);
			}

		hr = S_OK;

		// > 0 we do not want to include the "Root" item since the client
		// only uses this branch:
		while (SUCCEEDED (hr) && nPos-- > 0)	
			{
#ifdef _UNICODE
			hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_DOWN, strBranches [nPos]);
#else
			WCHAR szBranch [DEFBUFFSIZE];

			_mbstowcsz (szBranch, strBranches [nPos], sizeof (szBranch) / sizeof (WCHAR));
			hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_DOWN, szBranch);
#endif
			}
		
		// Browse for root level:
#ifdef _UNICODE
		hr = m_pIBrowse->BrowseOPCItemIDs (
//			m_bBrowseFlat ? OPC_FLAT : OPC_LEAF,	// provide items with children
			bBrowseFlat ? OPC_FLAT : OPC_LEAF,	// provide items with children
			m_strFilterLeaf,						// item id filtering
			m_vtFilterType,							// datatype filter
			m_dwFilterAccessRights,					// access rights filtering
			&pIEnumString);							// store the interface pointer here
#else
		_mbstowcsz (szFilter, m_strFilterLeaf, sizeof (szFilter) / sizeof (WCHAR));

		hr = m_pIBrowse->BrowseOPCItemIDs (
//			m_bBrowseFlat ? OPC_FLAT : OPC_LEAF,	// provide items with children
			bBrowseFlat ? OPC_FLAT : OPC_LEAF,	// provide items with children
			szFilter,								// item id filtering
			m_vtFilterType,							// datatype filter
			m_dwFilterAccessRights,					// access rights filtering
			&pIEnumString);							// store the interface pointer here
#endif

		// On success add the branches to the root:
  		if (SUCCEEDED (hr) && pIEnumString)
			{
			AddLeaves (pIEnumString);
			pIEnumString->Release ();
			}
		else
			throw (-1);
		}
	
	catch (...)
		{
		m_pIBrowse = NULL;
//		UpdateStatus ();
		}
}

void CDlgOPCItemAdd::AddLeaves(LPENUMSTRING pIEnumString)
{

⌨️ 快捷键说明

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