📄 itempropertiesdlg.cpp
字号:
dwLen = lstrlen (pItem->GetItemID ());
pItemArray->szItemID = (WCHAR *) CoTaskMemAlloc ((dwLen + 1) * sizeof (WCHAR));
#ifdef _UNICODE
lstrcpyn (pItemArray->szItemID, pItem->GetItemID (), dwLen + 1);
#else
MultiByteToWideChar (CP_ACP, 0, pItem->GetItemID (), -1, pItemArray->szItemID, dwLen + 1);
#endif
// Load other item properties into item defintion structure:
pItemArray->bActive = pItem->IsActive (); // active state
pItemArray->hClient = (OPCHANDLE) pItem; // client handle to item
pItemArray->dwBlobSize = 0; // no blob support
pItemArray->pBlob = NULL;
pItemArray->vtRequestedDataType = pItem->GetDataType (); // requested data type
// Issue request to add item:
hr = m_pIItemMgt->AddItems (1, pItemArray, &pResults, &pErrors);
// If request succeeded, we will still need to look at errors,
// and free memory, and update our item object:
if (SUCCEEDED (hr))
{
// If there were no error, update the item object:
if (pErrors && SUCCEEDED (pErrors [0]))
{
// Set valid state:
pItem->SetValid (TRUE);
// Update item (we now know the server handle to OPC
// item associated with our CKItem object. Server may
// have added the item, but not accepted our requested
// data type or access rights. Update item object with
// properties server returned:
pItem->SetServerHandle (pResults->hServer);
pItem->SetDataType (pResults->vtCanonicalDataType);
pItem->SetAccessRights (pResults->dwAccessRights);
}
// COM places the responsibility of freeing the result
// and errors memory on us. These will have been allocated
// by the server only if request succeeded:
if (pResults)
CoTaskMemFree (pResults);
if (pErrors)
CoTaskMemFree (pErrors);
}
// Free the string memory we allocated:
if (pItemArray->szAccessPath)
CoTaskMemFree (pItemArray->szAccessPath);
if (pItemArray->szItemID)
CoTaskMemFree (pItemArray->szItemID);
// Free the item definition memory:
CoTaskMemFree (pItemArray);
}
}
// Notify the view of the update:
CKMainWnd *pWnd = (CKMainWnd *) AfxGetMainWnd ();
if (pWnd)
pWnd->PostMessage (UM_ITEM_READD, 0, (LPARAM) pItem);
}
catch (...)
{
m_pIItemMgt = NULL;
}
}
}
// **************************************************************************
// OnOK ()
//
// Description:
// OK button event handler.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemPropertiesDlg::OnOK ()
{
// Apply current changes:
OnApply ();
// Perform default processing:
CDialog::OnOK ();
}
// **************************************************************************
// OnActive ()
//
// Description:
// Active check box event handler.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemPropertiesDlg::OnActive ()
{
// We won't be able to reset OPC item's active state unless we have
// a pointer to the item management interface:
if (m_pIItemMgt)
{
// Get pointer to selected item object:
CKItem *pItem = GetSelectedItem ();
ASSERT (pItem != NULL);
try
{
// Get OPC server's handle to associated OPC item:
OPCHANDLE hServer = pItem->GetServerHandle ();
HRESULT *pErrors= NULL;
// Get the inverse of the current active state. This will be
// the state we try to set the OPC item:
BOOL bActive = pItem->IsActive () ? FALSE : TRUE;
// Try to set the state of the OPC item.
if (SUCCEEDED (m_pIItemMgt->SetActiveState (1, &hServer, bActive, &pErrors)))
{
// Succeeded in changing state of OPC item. Update the state of
// our CKItem object to reflect this:
pItem->SetActive (bActive);
// It is up to us to free the memory the server allocated
// for the errors array:
if (pErrors)
CoTaskMemFree (pErrors);
// Set our modified flag:
m_bModified = true;
}
else
{
// On failure revert back to current settings.
// Reset active state member variable associated control:
m_bActive = pItem->IsActive ();
UpdateData (FALSE);
}
}
catch (...)
{
m_pIItemMgt = NULL;
// On failure revert back to current settings.
// Reset active state member variable associated control:
m_bActive = pItem->IsActive ();
UpdateData (FALSE);
}
}
}
// **************************************************************************
// OnChangeDataType ()
//
// Description:
// Data type combo box change event handler.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemPropertiesDlg::OnChangeDataType ()
{
// We won't be able to reset OPC item's data type unless we have a
// pointer to the item management interface:
if (m_pIItemMgt)
{
// Get pointer to selected item:
CKItem *pItem = GetSelectedItem ();
ASSERT (pItem != NULL);
try
{
// Update member variables associated with controls:
UpdateData (TRUE);
// If data type has changed, try to update the associated
// OPC item:
if (m_vtDataType != pItem->GetDataType ())
{
// Get OPC server's handle to associated OPC item:
OPCHANDLE hServer = pItem->GetServerHandle ();
HRESULT *pErrors= NULL;
// Create a variate to pass request data type to server with:
VARTYPE vtType = m_vtDataType;
// Try to reset the data type:
if (m_pIItemMgt->SetDatatypes (1, &hServer, &vtType, &pErrors) == S_OK)
{
// Succeeded to change the data type. Update our CKItem
// object's data type to reflect this:
pItem->SetDataType (vtType);
// It is up to us to free the memory the server allocated
// for the errors array:
if (pErrors)
CoTaskMemFree (pErrors);
// Set our modified flag:
m_bModified = true;
}
else
{
// On failure revert back to current settings.
// Construct an error message with invalid data type:
CString strType;
StringFromVartype (vtType, strType);
CString strErr;
strErr.Format (IDS_FAILED_TO_SETDATATYPE, strType);
// Show error message in a message bos:
AfxMessageBox (strErr);
// Reset data type member variable associated control:
m_vtDataType = pItem->GetDataType ();
UpdateData (FALSE);
}
}
}
catch (...)
{
m_pIItemMgt = NULL;
// On failure revert back to current settings.
// Reset data type member variable associated control:
m_vtDataType = pItem->GetDataType ();
UpdateData (FALSE);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CKItemPropertiesDlg helpers
/////////////////////////////////////////////////////////////////////////////
// **************************************************************************
// GetSelectedItem ()
//
// Description:
// Called to return a pointer to selected item object.
//
// Parameters:
// none
//
// Returns:
// CKItem* - Pointer to selected item object.
// **************************************************************************
CKItem* CKItemPropertiesDlg::GetSelectedItem ()
{
// Get pointer to CKItem object for object array. It's index will
// be the same as index of selected item in list control.
return ((CKItem *) m_pItemList->GetAt (m_nSelIndex));
}
// **************************************************************************
// SelectItem ()
//
// Description:
// Called to select an item.
//
// Parameters:
// int nIndex Index of item to select.
//
// Returns:
// void
// **************************************************************************
void CKItemPropertiesDlg::SelectItem (int nIndex)
{
// Apply changes to currently selected item:
OnApply ();
// Select the new item:
CKItem *pItem = NULL;
m_nSelIndex = nIndex;
ASSERT (m_nSelIndex <= m_cnItems);
// Item list object array gives us a pointer to the CKItem object
// assocated with the selection:
pItem = (CKItem *) m_pItemList->GetAt (m_nSelIndex);
ASSERT (pItem != NULL);
// Update the member variables associated with controls:
m_strAccessPath = pItem->GetAccessPath ();
m_bActive = pItem->IsActive ();
m_vtDataType = pItem->GetDataType ();
m_strItemID = pItem->GetItemID ();
// Update control status:
UpdateStatus ();
}
// **************************************************************************
// UpdateStatus ()
//
// Description:
// Update the status of controls attached to this dialog based on current
// properties of selected item.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemPropertiesDlg::UpdateStatus ()
{
// 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;
// Save handle of item with focus. We will have to change the focus
// if this item is disabled:
HWND hWnd = ::GetFocus ();
// Enable next button if we are not at the end of the list:
m_cNext.EnableWindow (m_nSelIndex < m_cnItems - 1);
// Enable the previous button if we are not at the beginning of the list:
m_cPrev.EnableWindow (m_nSelIndex > 0);
// Allow the user to modify item ID and access path only if item is invalid:
CKItem *pItem = GetSelectedItem ();
ASSERT (pItem != NULL);
GetDlgItem (IDC_ITEMID)->EnableWindow (!pItem->IsValid ());
GetDlgItem (IDC_ACCESSPATH)->EnableWindow (!pItem->IsValid ());
// Load appropriate datatypes (based on current data type and
// item valid state):
// First get pointer to data type combo box:
CComboBox *pCombo = (CComboBox *)GetDlgItem (IDC_DATATYPE);
// then reset it:
pCombo->ResetContent ();
// then load new entries:
if (pItem->IsValid ())
{
// If current data type is an array type:
if (pItem->GetDataType () & VT_ARRAY)
{
pCombo->AddString (_T("Byte Array"));
pCombo->AddString (_T("Char Array"));
pCombo->AddString (_T("Word Array"));
pCombo->AddString (_T("Short Array"));
pCombo->AddString (_T("DWord Array"));
pCombo->AddString (_T("Long Array"));
pCombo->AddString (_T("Float Array"));
pCombo->AddString (_T("Double Array"));
}
// else if it is not an array type"
else
{
pCombo->AddString (_T("Boolean"));
pCombo->AddString (_T("Byte"));
pCombo->AddString (_T("Char"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -