📄 additemdlg.cpp
字号:
{
do
{
hr = m_pIBrowse->ChangeBrowsePosition (OPC_BROWSE_UP, L"\0");
} while (SUCCEEDED (hr));
}
}
catch (...)
{
}
}
void CAddItemDlg::OnTvnItemexpandingBranchlist(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 CAddItemDlg::OnTvnSelchangedBranchlist(NMHDR *pNMHDR, LRESULT *pResult)
{
NM_TREEVIEW* pnmtv = (NM_TREEVIEW*)pNMHDR;
// Select the branch:
SelectBranch (pnmtv->itemNew.hItem);
*pResult = 0;
}
void CAddItemDlg::OnCancel()
{
for (int nIndex = 0; nIndex < m_nListIndex; nIndex++)
{
// Get next element in list:
CHotOpcItem *pItem = (CHotOpcItem *) m_cItemList.GetAt (nIndex);
ASSERT (pItem != NULL);
// Delete it:
delete pItem;
}
CDialog::OnCancel();
}
void CAddItemDlg::OnCbnSelchangeDatatype()
{
UpdateData (true);
// We will consider ourselves modified if there is an item ID defined:
m_bModified = !m_strItemID.IsEmpty ();
// Update control status:
UpdateStatus ();
}
void CAddItemDlg::OnEnChangeAccesspath()
{
// TODO: 如果该控件是 RICHEDIT 控件,则它将不会
// 发送该通知,除非重写 CDialog::OnInitDialog()
// 函数并调用 CRichEditCtrl().SetEventMask(),
// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
UpdateData (true);
// We will consider ourselves modified if there is an item ID defined:
m_bModified = !m_strItemID.IsEmpty ();
// Update control status:
UpdateStatus ();
}
void CAddItemDlg::OnEnChangeItemid()
{
UpdateData (true);
// We will consider ourselves modified if there is an item ID defined:
m_bModified = !m_strItemID.IsEmpty ();
// Update control status:
UpdateStatus ();
}
void CAddItemDlg::OnOK()
{
if (OnApplyChange ())
{
// Terminate the list. Will allow us to process list using
// "while (element)" loop if we want:
if (m_nListIndex > 0)
m_cItemList.SetAtGrow (m_nListIndex, NULL);
CDialog::OnOK();
}
}
void CAddItemDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
// If showing dialog, set focus to item ID edit box:
if (bShow)
GetDlgItem (IDC_ITEMID)->SetFocus ();
}
void CAddItemDlg::OnNMDblclkLeaflist(NMHDR *pNMHDR, LRESULT *pResult)
{
int nSelItem;
// Get selected item index:
nSelItem = m_pLeafList->GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
// If index looks good, get properties of selected item and
// update all other controls accordingly:
if (nSelItem >= 0)
{
HRESULT hr;
WCHAR szItemID [MAX_PATH];
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)
{
// Update selector to end of the list:
m_nSelIndex = m_nListIndex;
// Re-initialize for new item:
m_strItemID = lpszQualifiedID;
m_strAccessPath.Empty ();
UpdateData (false);
// Apply new dataset:
m_bModified = true;
OnApplyChange ();
// 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("OTC: 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;
}
bool CAddItemDlg::OnApplyChange ()
{
// No need to apply changes unless we are modified:
if (m_bModified)
{
CHotOpcItem *pItem = NULL;
// Make sure member variables have values currently displayed in
// associated controls:
UpdateData (true);
// If auto validating, validate item before applying changes.
if (m_bAutoValidate)
{
// Validate currently selected item:
HRESULT hr = Validate ();
// If item is invalid, then inform user of problem and give him
// option of continuing:
if (FAILED (hr))
{
// Define a string format for the validation return code:
CString strHR;
strHR.Format (_T("0x%08X"), hr);
// Define a string format for the validation return code:
CString strFailure;
strFailure.FormatMessage ("IDS_VALIDATE_ITEM_FAILED_CONTINUE %s %s", m_strItemID, strHR);
// Show message bow with error string. Give user of option of
// continuing. If user clicks "NO", return now without applying
// changes:
if (AfxMessageBox (strFailure, MB_YESNO | MB_ICONQUESTION) == IDNO)
return (false);
}
}
// If we make it here, it is OK to apply changes.
// If selected index is the same as list control index, then we
// need to create a new item and add to the list:
if (m_nSelIndex == m_nListIndex)
{
try
{
// Create a new item object and add it to the list:
pItem = new CHotOpcItem (m_pGroup);
m_cItemList.SetAtGrow (m_nListIndex++, pItem);
}
catch (...)
{
ASSERT (FALSE);
}
}
// else we are modifying an item already in list:
else
{
pItem = (CHotOpcItem *) m_cItemList.GetAt (m_nSelIndex);
ASSERT (pItem != NULL);
}
// Set item properties:
pItem->SetAccessPath (m_strAccessPath);
pItem->SetActive (TRUE);
pItem->SetDataType (m_vtDataType);
pItem->SetItemID (m_strItemID);
// Set modified flag:
m_bModified = false;
}
// Return true to indicate success:
return (true);
}
HRESULT CAddItemDlg::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);
// Allocate memory for our item definition:
OPCITEMDEF *pItems = (OPCITEMDEF *) CoTaskMemAlloc (sizeof (OPCITEMDEF));
// If allocation succeeds, perform validation:
if (pItems)
{
// Initialize some variables:
HRESULT *pErrors = NULL;
OPCITEMRESULT *pResults = NULL;
WCHAR *pszItemID = NULL;
WCHAR *pszAccessPath = NULL;
// Check to make sure we have an item ID (debug only):
ASSERT (!m_strItemID.IsEmpty ());
// Allocate memory for item ID string:
pszItemID = (WCHAR *) CoTaskMemAlloc ((m_strItemID.GetLength () + 1) * sizeof (WCHAR));
// COM requires us to put strings in UNICODE format.
#ifdef _UNICODE
// This is a UNICODE build so just copy item ID string "as is"
// to allocated memory:
lstrcpyn (pszItemID, m_strItemID, m_strItemID.GetLength () + 1);
#else
// This is an ANSI build so convert item ID string to UNICODE and
// place result in allocated memory:
_mbstowcsz (pszItemID, m_strItemID, m_strItemID.GetLength () + 1);
#endif
// If an access path is specified, then convert its string to UNICODE
// and copy it to allocated memory:
if (!m_strAccessPath.IsEmpty ())
{
// First allocate memory for the access path string:
pszAccessPath = (WCHAR *) CoTaskMemAlloc ((m_strAccessPath.GetLength () + 1) * sizeof (WCHAR));
// Convert if necessary and copy result to allocated memory:
#ifdef _UNICODE
lstrcpyn (pszAccessPath, m_strAccessPath, m_strAccessPath.GetLength () + 1);
#else
_mbstowcsz (pszAccessPath, m_strAccessPath, m_strAccessPath.GetLength () + 1);
#endif
}
// Fill in item def structure:
pItems->bActive = true;
pItems->dwBlobSize = 0;
pItems->hClient = NULL;
pItems->pBlob = NULL;
pItems->szAccessPath = pszAccessPath;
pItems->szItemID = pszItemID;
pItems->vtRequestedDataType = m_vtDataType;
// Validate the single item, (no blob requested):
try
{
// Request server to validate item described initem def structure
// through the group's item management interface:
hr = m_pIItemMgt->ValidateItems (1, pItems, FALSE, &pResults, &pErrors);
// If server reports that item is valid, we may still have to modify
// the data type. We will also validate "dot bit address" format.
if (hr == S_OK)
{
// Modify the data type to what the server will use:
m_vtDataType = pResults->vtCanonicalDataType;
// Update the dialog controls to reflect data type change:
UpdateData (false);
// Flag as modified:
m_bModified = true;
// Verify dot bit address setting:
if (pbDotBitAddress)
{
// Assume false until proven otherwise:
*pbDotBitAddress = false;
// Data type must be VT_BOOL for dot bit address, It it's not,
// fall through with flag set to false:
if (m_vtDataType == VT_BOOL)
{
// To determine if truly a dot bit address, strip off
// bit number and see if its still valid.
// First free previous results,
if (pResults)
{
CoTaskMemFree (pResults);
pResults = NULL;
}
// and previous errors:
if (pErrors)
{
CoTaskMemFree (pErrors);
pErrors = NULL;
}
// Get position of "dot" character:
WCHAR *pwch = wcsrchr (pItems->szItemID, L'.');
if (pwch)
{
// Replace "dot" with NULL terminator, effectively stripping
// off the whole "dot bit number" portion of the address:
*pwch = L'\0';
// Reset the requested data type to VT_EMPTY. We are only
// interested in seeing if the address is valid for some
// unspecified data type.
pItems->vtRequestedDataType = VT_EMPTY;
// Request server to validate the "stripped" address:
if (SUCCEEDED (m_pIItemMgt->ValidateItems (1, pItems, FALSE, &pResults, &pErrors)))
{
// If the server reports that the "stipped" address is valid, and
// that it corresponds to some data type other than VT_BOOL,
// then the original address is truely a "dot bit" address:
if (pResults->vtCanonicalDataType != VT_EMPTY && pResults->vtCanonicalDataType != VT_BOOL)
*pbDotBitAddress = true;
}
}
}
}
}
// else if server reports that item is not valid. Assign item
// error for return:
else
{
hr = pErrors [0];
}
}
// Catch exceptions:
catch (...)
{
// Probably something wrong with interface pointer, so invalidate it:
m_pIItemMgt = NULL;
// Update dialog control status:
UpdateStatus ();
}
// Free allocations (COM requires us to do this):
CoTaskMemFree (pItems);
if (pszItemID)
CoTaskMemFree (pszItemID);
if (pszAccessPath)
CoTaskMemFree (pszAccessPath);
if (pResults)
CoTaskMemFree (pResults);
if (pErrors)
CoTaskMemFree (pErrors);
}
// Return validation return code:
return (hr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -