📄 itemadddlg.cpp
字号:
// Duplicate item, and select duplicate. Repeat as many times
// as user says:
for (int i = 0; i < dlg.m_cnDuplicateItems; i++)
SelectItem (-1, true, bDotBitAddress);
// Now that we are done, allow a repaint:
SetRedraw (true);
// Force a repaint:
Invalidate ();
}
}
// **************************************************************************
// OnDelete ()
//
// Description:
// Delete button event handler. Deletes the current item.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnDelete ()
{
// Delete the selected item (selected item index had better be
// less than the number of items in list):
if (m_nSelIndex < m_nListIndex)
{
// Get pointer to the selected item's object:
CKItem *pItem = (CKItem *) m_cItemList.GetAt (m_nSelIndex);
ASSERT (pItem != NULL);
// Delete the item object:
delete pItem;
// Remove the item from the list:
m_cItemList.RemoveAt (m_nSelIndex);
m_nListIndex--;
// Select the next item if there is one (i.e, the item that just
// took this positions place from the RemoveAt())
if (m_nSelIndex < m_nListIndex)
SelectItem (m_nSelIndex);
// Otherwise select the previous one:
else
SelectItem (m_nSelIndex - 1);
}
#ifdef _DEBUG
// Delete button should be disabled in this case. If not, assert
// false to catch problem in debugger.
else
ASSERT (FALSE);
#endif
}
// **************************************************************************
// OnNext ()
//
// Description:
// Next button event handler. Selects next item in list.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnNext ()
{
// Select the next item (selected item index had better be
// less than the number of items in list):
if (m_nSelIndex < m_nListIndex)
SelectItem (m_nSelIndex + 1);
#ifdef _DEBUG
// Next button should be disabled in this case. If not, assert
// false to catch problem in debugger.
else
ASSERT (FALSE);
#endif
}
// **************************************************************************
// OnPrevious ()
//
// Description:
// Previous button event handler. Selects previous item in list.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnPrevious ()
{
// Select the previous item (selected item index had better be
// less than the number of items in list):
if (m_nSelIndex > 0)
SelectItem (m_nSelIndex - 1);
#ifdef _DEBUG
// Previous button should be disabled in this case. If not, assert
// false to catch problem in debugger.
else
ASSERT (FALSE);
#endif
}
// **************************************************************************
// OnValidateItem ()
//
// Description:
// Validate button event handler. Validates selecte item's properties.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnValidateItem ()
{
// Validate the selected item:
HRESULT hr = Validate ();
// If validation fails, inform the user:
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, m_strItemID, strHR);
// Show message box with error string:
AfxMessageBox (strFailure);
}
}
// **************************************************************************
// Validate ()
//
// Description:
// Validates selected item's properties.
//
// Parameters:
// bool *pbDotBitAddress true if address has "dot bit address" format.
//
// Returns:
// HRESULT - Use FAILED or SUCCEEDED macro to test.
// **************************************************************************
HRESULT CKItemAddDlg::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 = m_bActive;
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);
}
// **************************************************************************
// OnBrowseFlat ()
//
// Description:
// Browse Flat check box event handler. Display list of items according to
// check box setting.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnBrowseFlat ()
{
// Update browse flat flag:
m_bBrowseFlat = ((CButton *) GetDlgItem (IDC_BROWSEFLAT))->GetCheck ();
// Resync browse position to root:
BrowseToRoot ();
// 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 organization setting:
if (hItem != NULL)
SelectBranch (hItem);
}
// **************************************************************************
// BrowseToRoot ()
//
// Description:
// Reset brows position to root object.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::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 (...)
{
}
}
// **************************************************************************
// OnAutoValidate ()
//
// Description:
// Auto validate check box event handler. Sets flag according to check box
// setting.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnAutoValidate ()
{
// Save new auto validate setting:
m_bAutoValidate = ((CButton *) GetDlgItem (IDC_AUTOVALIDATE))->GetCheck ();
}
// **************************************************************************
// OnBranchExpanding ()
//
// Description:
// Handles notification that the tree control's item is about to expand or
// collapse.
//
// Parameters:
// NMHDR *pNMHDR Contains information about a notification message.
// LRESULT *pResult A 32-bit value returned from a window procedure
// or callback function.
//
// Returns:
// void
// **************************************************************************
void CKItemAddDlg::OnBranchExpanding (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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -