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

📄 dlgopcitemadd.cpp

📁 OPC Client 源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	ULONG celt = 1;			
	LPOLESTR rgelt;			
	ULONG celtFetched = 0;	
	int nIndex = 0;

#ifndef _UNICODE
	TCHAR szBuffer [DEFBUFFSIZE];
#endif

	// Delete any leaves that are presently being displayed:
	m_pLeafList->DeleteAllItems ();

	// Start at the beginning of the list:
	pIEnumString->Reset ();	
	pIEnumString->Next (celt, &rgelt, &celtFetched);

	// Add each leaf to the leaf control:
	while (celtFetched > 0) 
		{
		// Insert the leaf:
#ifdef _UNICODE
		m_pLeafList->InsertItem( nIndex++, rgelt, ILI_LEAF);
#else
		_wcstombsz (szBuffer, rgelt, sizeof (szBuffer) / sizeof (TCHAR));
		m_pLeafList->InsertItem (nIndex++, szBuffer, ILI_LEAF);
#endif

		// Free the branch name:
		CoTaskMemFree (rgelt);	

		// Re-initialize and get the next item:
		celt = 1;
		celtFetched = 0;
		pIEnumString->Next (celt, &rgelt, &celtFetched);
		}

	// Select first leaf by default:
	if (m_pLeafList->GetItemCount ())
		m_pLeafList->SetItemState (0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}

void CDlgOPCItemAdd::OnItemExpandingBranchList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// Cast notification header to tree view notification header:
	NM_TREEVIEW* pnmtv = (NM_TREEVIEW*) pNMHDR;

	// Expand branch:
	if (pnmtv->action & TVE_EXPAND)
		{
		ExpandBranch (pnmtv->itemNew.hItem);
		}

	// else delete child branches on collapse:
	else if (pnmtv->action & TVE_COLLAPSE)
		{
		DeleteChildBranches (pnmtv->itemNew.hItem);
		}

	*pResult = 0;
}

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

	int nPos;
	HRESULT hr;
	LPENUMSTRING pIEnumString;

#ifndef _UNICODE
	WCHAR szFilter [DEFBUFFSIZE];
#endif

	// Get the new browse position from the item that was previously
	// selected:
	nPos = (int) m_pBranchList->GetItemData (hItem);
	nPos++;
	ASSERT (nPos >= 0);

	try
		{
		// 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:
		CStringArray strBranches;
		HTREEITEM hParentItem;

		strBranches.SetSize (nPos + 1);
		hParentItem = hItem;

		for (int i = 0; i <= nPos; i++)
			{
			ASSERT (hItem);
			strBranches [i] = m_pBranchList->GetItemText (hParentItem);
			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 (OPC_BRANCH,				// provide items with children
										  m_strFilterBranch,		// id filtering
										  VT_EMPTY,					// no datatype filtering on a branch
										  0,						// no access filtering on a branch
										  &pIEnumString);			// store the interface pointer here
#else
		_mbstowcsz (szFilter, m_strFilterBranch, sizeof (szFilter) / sizeof (WCHAR));
		hr = m_pIBrowse->BrowseOPCItemIDs (OPC_BRANCH,				// provide items with children
										  szFilter,					// id filtering
										  VT_EMPTY,					// no datatype filtering on a branch
										  0,						// no access filtering on a branch
										  &pIEnumString);			// store the interface pointer here
#endif

		// On success add the branches to the root:
		if (SUCCEEDED (hr) && pIEnumString)
			{
			AddBranches (pIEnumString, hItem, m_pBranchList->GetItemData (hItem) + 1);
			pIEnumString->Release ();
			}
		else
			{
			RemoveDummyBranch (hItem);
			throw (-1);
			}
		}
	
	catch (...)
		{
		m_pIBrowse = NULL;
//		UpdateStatus ();
		}
}

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

	HTREEITEM hItem;
	hItem = m_pBranchList->GetChildItem (hParent);

	while (hItem)
		{
		m_pBranchList->DeleteItem (hItem);
		hItem = m_pBranchList->GetChildItem (hParent);
		}
	
	AddDummyBranch (hParent);
}

void CDlgOPCItemAdd::AddBranches(LPENUMSTRING pIEnumString, HTREEITEM hParent, DWORD dwData)
{
	ASSERT (hParent != NULL);

	ULONG celt = 1;			
	LPOLESTR rgelt;			
	ULONG celtFetched = 0;	
	TCHAR szBuffer [DEFBUFFSIZE];

	// Remove the dummy branch if one exists:
	RemoveDummyBranch (hParent);

	// Start at the beginning of the list:
	pIEnumString->Reset ();	
	pIEnumString->Next (celt, &rgelt, &celtFetched);	//引出

	// Add each branch to the browse control:
	while (celtFetched > 0) 
		{
		HTREEITEM hNewItem = NULL;

		// COM requis that all strings be sent in UNICODE format.
		// Convert if necessary and copy to szBuffer:
#ifdef _UNICODE
		lstrcpyn (szBuffer, rgelt, sizeof (szBuffer) / sizeof (TCHAR));
#else
		_wcstombsz (szBuffer, rgelt, sizeof (szBuffer) / sizeof (TCHAR));
#endif

		// Insert the branch:
		hNewItem = m_pBranchList->InsertItem (szBuffer, ILI_BRANCH, ILI_SELBRANCH, hParent);
		m_pBranchList->SetItemData (hNewItem, dwData);	

		// Always fake each branch into having a sub item in the tree:
		AddDummyBranch (hNewItem);

		// Free the branch name:
		CoTaskMemFree (rgelt);	

		// Re-initialize and get the next item:
		celt = 1;
		celtFetched = 0;
		pIEnumString->Next (celt, &rgelt, &celtFetched);
		}
}

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

	HTREEITEM hDummyItem;

	// Get child item:
	hDummyItem = m_pBranchList->GetChildItem (hParent);
	while (hDummyItem)
		{
		CString strItem = m_pBranchList->GetItemText (hDummyItem);
		
		if (strItem.CompareNoCase (NULL_ITEM_NAME) == 0)
			{
			if (m_pBranchList->GetItemData (hDummyItem) == NULL_ITEM_DATA)
				{
				m_pBranchList->DeleteItem (hDummyItem);
				break;
				}
			}

		hDummyItem = m_pBranchList->GetNextSiblingItem (hDummyItem);
		}
}

void CDlgOPCItemAdd::OnDblclkLeafList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	int nSelItem;
	//得到选择项:
	nSelItem = m_pLeafList->GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);

	if(nSelItem>=0)
		OnAddItem();
	return;

	//以下代码可以通过OnAddItem()替代
	if (nSelItem >= 0)
		{
		HRESULT hr;
		WCHAR szItemID [DEFBUFFSIZE];
		LPWSTR lpszQualifiedID;

		// COM requires all strings to be in UNICODE format. Convert
		// item ID if needed, then copy to allocated buffer:
#ifdef _UNICODE
		lstrcpyn (szItemID, m_pLeafList->GetItemText (nSelItem, 0), sizeof (szItemID) / sizeof (WCHAR));
#else
		_mbstowcsz (szItemID, m_pLeafList->GetItemText (nSelItem, 0), sizeof (szItemID) / sizeof (WCHAR));
#endif

		try
			{
			// If we are using a flat browse space, then we need to browse to
			// root first:
			if (m_bBrowseFlat)
				BrowseToRoot ();

			// User browser to get item's fully qualified ID:
			hr = m_pIBrowse->GetItemID (szItemID, &lpszQualifiedID);

			// If we succeeded, update controls:
			if (SUCCEEDED (hr) && lpszQualifiedID)
				{
				//得到ID:
				m_strItemID = lpszQualifiedID;
//				m_strAccessPath.Empty ();
				UpdateData (false);

				//增加新项:
				AddItem();

				// Update control state:
//				UpdateStatus ();

				// Free server allocation for qualified item id:
				CoTaskMemFree (lpszQualifiedID);
				}
		
			// If we didn't get qualified ID, issue a trace statement for debugging:
			else
				{
				TRACE (_T("OPC: Unable to get the qualified item id for %s\r\n"), 
					m_pLeafList->GetItemText (nSelItem, 0));
				}
			}
		
		// Catch exceptions:
		catch (...)
			{
			m_pIBrowse = NULL;
//			UpdateStatus ();
			}
		}

	*pResult = 0;
}


void CDlgOPCItemAdd::OnSelChangeFilterType() 
{
	// TODO: Add your control notification handler code here
	// Get pointer to data type filter combo box:
	CComboBox *pCombo = (CComboBox *)GetDlgItem (IDC_FILTERTYPE);

	// Get the selected data type string:
	CString strType;
	pCombo->GetLBText (pCombo->GetCurSel (), strType);

	// Convert that string to a variant type:
	m_vtFilterType = COPCItem::VartypeFromString (strType);

	// Get currently selected item:
	HTREEITEM hItem = m_pBranchList->GetSelectedItem ();
	
	// Select current item.  This will cause us to re-browse to position.
	// Data will come back from browser using new filter settings:
	if (hItem != NULL)
		SelectBranch (hItem);
	
	
}

void CDlgOPCItemAdd::OnSelChangeFilterAccess() 
{
	// TODO: Add your control notification handler code here
	// Get the access rights:
	m_dwFilterAccessRights = 
		((CComboBox *) GetDlgItem (IDC_FILTERACCESS))->GetCurSel ();

	// Get currently selected item:
	HTREEITEM hItem = m_pBranchList->GetSelectedItem ();
	
	// Select current item.  This will cause us to re-browse to position.
	// Data will come back from browser using new filter settings:
	if (hItem != NULL)
		SelectBranch (hItem);
	
}

void CDlgOPCItemAdd::BrowseToRoot()
{
	try
		{
		// Try to browse to root in one step using "OPC_BROWSE_TO" (this
		// is not supported and will fail for OPC 1.0 servers):
		HRESULT hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_TO, L"");
		
		// If that fails, browse to root one level at a time using "OPC_BROWSE_UP".
		// (Browse up will fail when we are at root.)
		if (FAILED (hr))
			{
			do
				{
				hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_UP, L"\0");
				} while (SUCCEEDED (hr));
			}
		}
	
	catch (...)
		{
		}
}

// **************************************************************************
// Validate ()
//
// Description:
//  证实选择项的属性
//
// Parameters:
//  bool	*pbDotBitAddress	true if address has "dot bit address" format.
//
// Returns:
//  HRESULT - Use FAILED or SUCCEEDED macro to test.
// **************************************************************************
HRESULT CDlgOPCItemAdd::Validate(bool *pbDotBitAddress/*= NULL */)
{
	// Assume invalid until proven otherwisw:
	HRESULT hr = E_FAIL;

	// Make sure data in member variables represents current control settings:
	UpdateData (true);

	//申请分配OPCITEMDEF内存:
	OPCITEMDEF *pItems = (OPCITEMDEF *) CoTaskMemAlloc (sizeof (OPCITEMDEF));

	//如果分配成功执行验证:
	if (pItems)
		{
		//初始化变量:
		HRESULT *pErrors = NULL;
		OPCITEMRESULT *pResults = NULL;
		WCHAR *pszItemID = NULL;
		WCHAR *pszAccessPath = NULL;

		//检查数据项ID (debug only):
		ASSERT (!m_strItemID.IsEmpty ());

		//字符转换:
		//首先分配内存
		pszItemID = (WCHAR *) CoTaskMemAlloc ((m_strItemID.GetLength () + 1) * sizeof (WCHAR));

		// COM 要求字符串使用UNICODE格式.
#ifdef _UNICODE
		//宽字符复制:
		lstrcpyn (pszItemID, m_strItemID, m_strItemID.GetLength () + 1);
#else
		// 将ANSI转换成UNICODE:
		_mbstowcsz (pszItemID, m_strItemID, m_strItemID.GetLength () + 1);
#endif

		//访问路径有效
		if (!m_strAccessPath.IsEmpty ())
			{
			//首先分配内存:
			pszAccessPath = (WCHAR *) CoTaskMemAlloc ((m_strAccessPath.GetLength () + 1) * sizeof (WCHAR));

			//字符格式转换:
#ifdef _UNICODE
			lstrcpyn (pszAccessPath, m_strAccessPath, m_strAccessPath.GetLength () + 1);

⌨️ 快捷键说明

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