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