📄 item.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
//
// OPC DataAccess VC++ Client: Item.CPP
// (Source File)
//
/////////////////////////////////////////////////////////////////////////////
//
// Author: Raphael Imhof
// Initial Date: 11/04/98
// $Workfile: Item.cpp $
// $Revision: 2 $
// $Date: 9/09/99 11:01a $
// Target System: Microsoft Windows NT 4.0
// Environment: Visual C++ 5.0 / OPC DataAccess 1.0/2.0
// Remarks:
//
/////////////////////////////////////////////////////////////////////////////
//
// Description: implementation of the CItem class.
// Encapsulation of item related methods.
//
//
/////////////////////////////////////////////////////////////////////////////
//
// History of Changes (Please remove very old comments and blank lines!)
// $Log: /IDK/OPCServer/clients/VC++/InfoServerExplorer/Item.cpp $
//
// 2 9/09/99 11:01a Imhof
// DCS 3227: Set changed flag to true and set the timestamp for read sync
//
// 1 7/27/99 5:23p Imhof
//
// 1 7/27/99 5:19p Imhof
//
// 14 2/24/99 11:33a Imhof
// Changed the use of ValidateItem in EditItem()
//
// 13 1/15/99 6:43p Imhof
// Updated legal notice.
//
// 12 1/06/99 10:34a Imhof
// Added a changed attribute to the CItem class which is used to optimize
// the content view update.
//
// 11 12/28/98 3:20p Betrisey
// Do not Read the value of an item after changing its state from active
// to inactive and vice-versa.
// InfoServer automatically sends the new update value/quality.
//
// 10 12/14/98 4:46p Imhof
// Modifications for OPC 2.0
//
// 9 12/11/98 5:58p Imhof
// Made modifications for OPC 2.0.
//
// 8 12/03/98 1:53p Imhof
// Removed read after additems
//
// 7 11/10/98 2:20p Imhof
// Added file header's.
//
//
// $Nokeywords:$ (To avoid useless search while checking in.)
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998, Siemens Building Technologies, Inc. Landis Division
//
// SIEMENS BUILDING TECHNOLOGIES, INC. IS PROVIDING THE FOLLOWING
// EXAMPLES OF CODE AS SAMPLE ONLY.
//
// SIEMENS BUILDING TECHNOLOGIES, INC. MAKES NO REPRESENTATIONS
// OR WARRANTIES OF ANY KIND WITH RESPECT TO THE VALIDTY OF THE
// CODES OR DESIRED RESULTS AND DISCLAIMS ALL SUCH
// REPRESENTATIONS AND WARRANTIES, INCLUDING FOR EXAMPLE,
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE. SIEMENS BUILIDNG TECHNOLOGIES, INC. DOES NOT
// REPRESENT OR WARRANT THAT THE FOLLOWING CODE SAMPLES ARE
// ACCURATE, VALID, COMPLETE OR CURRENT.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "infoserverexplorer.h"
#include "Item.h"
#include "IOPCSyncIO.h"
#include "IOPCAsyncIO.h"
#include "IOPCAsyncIO2.h"
#include "IOPCItemMgt.h"
#include "ItemDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CItem, CObject)
CItem::CItem()
{
memset(&m_timeStamp,0, sizeof(FILETIME));
VariantClear(&m_value);
m_data_type = VT_EMPTY;
m_pGroup = NULL;
m_quality = OPC_QUALITY_UNCERTAIN;
m_bChanged = FALSE;
}
CItem::~CItem()
{
}
void CItem::Serialize(CArchive& ar)
{
CBase<IOPCItemMgt>::Serialize(ar);
if (ar.IsStoring())
{
// TODO: add storing code here
ar << m_data_type;
}
else
{
// TODO: add loading code here
ar >> m_data_type;
}
}
CGroup* CItem::GetGroup()
{
return m_pGroup;
}
void CItem::SetGroup(CGroup* pGroup)
{
m_pGroup = pGroup;
}
void CItem::SetDataType(VARTYPE data_type)
{
m_data_type = data_type;
}
VARTYPE CItem::GetDataType()
{
return m_data_type;
}
void CItem::SetQuality(WORD quality)
{
m_quality = quality;
}
WORD CItem::GetQuality()
{
return m_quality;
}
void CItem::SetValue(VARIANT value)
{
m_value.Copy(&value);
}
VARIANT CItem::GetValue()
{
return m_value;
}
void CItem::SetTimeStamp(FILETIME time_stamp)
{
m_timeStamp = time_stamp;
}
FILETIME CItem::GetTimeStamp()
{
return m_timeStamp;
}
BOOL CItem::IsChanged()
{
return m_bChanged;
}
void CItem::SetChanged(BOOL bChanged)
{
m_bChanged = bChanged;
}
BOOL CItem::CommandSync(CString sValue)
{
CIOPCSyncIO opcSyncIO(GetGroup()->GetInterface());
HRESULT res;
HRESULT* pErrors;
OPCHANDLE hServer = GetHandle();
COleVariant ItemValues(sValue); //input: string
BOOL bRet = FALSE;
ItemValues.ChangeType(GetDataType()); //COleVariant converts to the correct point type
res = opcSyncIO.Write(1, &hServer, &ItemValues, &pErrors);
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrors[0]))
{
bRet = TRUE;
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrors[0]);
}
}
else GetGroup()->GetInfoServer()->DisplayError(res);
CoTaskMemFree(pErrors);
return bRet;
}
BOOL CItem::CommandAsync(CString sValue)
{
HRESULT res;
HRESULT* pErrors;
OPCHANDLE hServer = GetHandle();
COleVariant ItemValues(sValue); //input: string
BOOL bRet = FALSE;
GetGroup()->CheckForOpenTransactions();
ItemValues.ChangeType(GetDataType()); //COleVariant converts to the correct point type
if(GetGroup()->GetInfoServer()->GetOPCVersion() >= OPC_VERSION_20)
{
CIOPCAsyncIO2 opcAsyncIO2(GetGroup()->GetInterface());
DWORD dwTransactionID = TRANSACTION_WRITE; //in (returned in OnWriteComplete()) can be any number
DWORD dwCancelID; //out
res = opcAsyncIO2.Write(1, &hServer, &ItemValues, dwTransactionID, &dwCancelID, &pErrors);
GetGroup()->SetCurrentTransactionID(dwTransactionID);
GetGroup()->SetCurrentCancelID(dwCancelID);
}
else
{
CIOPCAsyncIO opcAsyncIO(GetGroup()->GetInterface());
DWORD dwTransactionID; //out
res = opcAsyncIO.Write(GetGroup()->GetOPCSTMFormatWriteCompleteConnection() , 1, &hServer, &ItemValues, &dwTransactionID, &pErrors);
GetGroup()->SetCurrentTransactionID(dwTransactionID);
}
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrors[0]))
{
bRet = TRUE;
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrors[0]);
}
}
else GetGroup()->GetInfoServer()->DisplayError(res);
CoTaskMemFree(pErrors);
return bRet;
}
BOOL CItem::Cancel()
{
/* cancel an active async operation: read, write or group refresh
OPC 1.0: only a TransactionID is used
OPC 2.0: transaction and CancelID is used
Note: transaction handling is CGroup based
*/
HRESULT res;
BOOL bRet = FALSE;
if(GetGroup()->GetCurrentTransactionID() == 0)
{
((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("No active transaction !"));
return FALSE;
}
if(GetGroup()->GetInfoServer()->GetOPCVersion() >= OPC_VERSION_20)
{
CIOPCAsyncIO2 opcAsyncIO2(GetGroup()->GetInterface());
DWORD dwTransactionID = 6015; //in (returned in OnReadComplete()) can be any number
if(GetGroup()->GetCurrentCancelID() == 0)
{
//should not happen since TransactionID and CancelID are managed aleays together
((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("No active cancel ID !"));
return FALSE;
}
res = opcAsyncIO2.Cancel2(GetGroup()->GetCurrentCancelID());
}
else
{
CIOPCAsyncIO opcAsyncIO(GetGroup()->GetInterface());
res = opcAsyncIO.Cancel(GetGroup()->GetCurrentTransactionID());
}
if(SUCCEEDED(res))
{
GetGroup()->SetCurrentTransactionID(0);
GetGroup()->SetCurrentCancelID(0);
bRet = TRUE;
}
else GetGroup()->GetInfoServer()->DisplayError(res);
return bRet;
}
BOOL CItem::ReadAsync(OPCDATASOURCE dwSource)
{
HRESULT res;
HRESULT* pReadErrors;
OPCHANDLE hServer = GetHandle();
BOOL bRet = FALSE;
GetGroup()->CheckForOpenTransactions();
if(GetGroup()->GetInfoServer()->GetOPCVersion() >= OPC_VERSION_20)
{
CIOPCAsyncIO2 opcAsyncIO2(GetGroup()->GetInterface());
DWORD dwTransactionID = TRANSACTION_READ; //in (returned in OnReadComplete()) can be any number
DWORD dwCancelID; //out
res = opcAsyncIO2.Read(1, &hServer, dwTransactionID, &dwCancelID, &pReadErrors);
GetGroup()->SetCurrentTransactionID(dwTransactionID);
GetGroup()->SetCurrentCancelID(dwCancelID);
}
else
{
CIOPCAsyncIO opcAsyncIO(GetGroup()->GetInterface());
DWORD dwTransactionID; //out
if(GetGroup()->GetInfoServer()->GetDataChangeType() > 0) //0 = no timestamp; 1 = with timestamp
res = opcAsyncIO.Read(GetGroup()->GetOPCSTMFormatDataTimeConnection(), dwSource, 1, &hServer, &dwTransactionID, &pReadErrors);
else
res = opcAsyncIO.Read(GetGroup()->GetOPCSTMFormatDataConnection(), dwSource, 1, &hServer, &dwTransactionID, &pReadErrors);
GetGroup()->SetCurrentTransactionID(dwTransactionID);
}
if(SUCCEEDED(res))
{
if(FAILED(pReadErrors[0]))
{
GetGroup()->GetInfoServer()->DisplayError(pReadErrors[0]);
}
bRet = TRUE;
}
else GetGroup()->GetInfoServer()->DisplayError(res);
CoTaskMemFree(pReadErrors);
return bRet;
}
BOOL CItem::ReadSync(OPCDATASOURCE dwSource)
{
//value gets returned over the IAdvise sink
CIOPCSyncIO opcSyncIO(GetGroup()->GetInterface());
HRESULT res;
HRESULT* pErrors;
OPCHANDLE hServer = GetHandle();
OPCITEMSTATE* pItemValues; //out
BOOL bRet = FALSE;
res = opcSyncIO.Read( dwSource, 1, &hServer, &pItemValues, &pErrors);
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrors[0]))
{
//copy the value from pItemValues and write it in the content view
SetQuality(pItemValues->wQuality);
SetValue(pItemValues->vDataValue);
SetTimeStamp(pItemValues->ftTimeStamp);
//value needs to be updated in the view
SetChanged(TRUE);
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrors[0]);
}
bRet = TRUE;
}
else GetGroup()->GetInfoServer()->DisplayError(res);
VariantClear(&pItemValues->vDataValue);
CoTaskMemFree(pErrors);
CoTaskMemFree(pItemValues);
return bRet;
}
BOOL CItem::EditItem()
{
USES_CONVERSION;
HRESULT res;
CIOPCItemMgt opcItemMgt(GetGroup()->GetInterface());
CItemDlg dlg;
BOOL bRet = FALSE;
OPCITEMDEF ItemArray[1];
OPCITEMRESULT* pValidationResults;
HRESULT *pErrorValidate, *pErrorState, *pErrorDataType, *pErrorClientHandle;
ItemArray[0].szItemID = A2OLE(GetName());
ItemArray[0].szAccessPath = A2OLE("");
ItemArray[0].bActive = TRUE;
ItemArray[0].hClient = (OPCHANDLE)this;
ItemArray[0].dwBlobSize = 0;
ItemArray[0].pBlob = NULL;
ItemArray[0].vtRequestedDataType = GetDataType();
/*
ValidateItems is not necessary here, it checks if the item is still in the cache.
*/
res = opcItemMgt.ValidateItems(1, ItemArray,FALSE , &pValidationResults, &pErrorValidate);
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrorValidate[0]))
{
TRACE("get active state ???\n");
((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CIOPCItemMgt::ValidateItems() was successful."));
dlg.m_bActive = IsActive();
dlg.SetDataType(GetDataType());
dlg.m_dwClientHandle = (DWORD)this;
dlg.m_sItem = GetName();
if(IDOK == dlg.DoModal())
{
//res = opcItemMgt.SetActiveState(1, &pValidationResults->hServer, dlg.m_bActive, &pError);
VARTYPE DataType = dlg.GetDataType();
OPCHANDLE hServer = GetHandle();
res = opcItemMgt.SetActiveState(1, &hServer, dlg.m_bActive, &pErrorState);
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrorState[0]))
{
SetActive(dlg.m_bActive);
((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CIOPCItemMgt::SetActiveState() was successful."));
res = opcItemMgt.SetDatatypes(1, &hServer, &DataType, &pErrorDataType);
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrorDataType[0]))
{
((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CIOPCItemMgt::SetDataType() was successful."));
SetDataType(dlg.GetDataType());
/*
ChangeType
Read instead of only Variant::ChangeType()
otherwise the view can show an invalid value.
Example: RT4 value -> RTBOOL -> RT4 value would show -1
*/
//cjb : InfoServer should update the client automatically
// ReadSync(OPC_DS_CACHE);
if(dlg.m_dwClientHandle != (DWORD)this)
{
if(IDYES == AfxMessageBox(_T("Are you sure ?\n\nServer can't find client item afterwards."), MB_YESNOCANCEL | MB_ICONQUESTION ))
{
res = opcItemMgt.SetClientHandles(1, &hServer, &dlg.m_dwClientHandle, &pErrorClientHandle);
if(SUCCEEDED(res))
{
if(SUCCEEDED(pErrorClientHandle[0]))
{
//can't change own address !
((CInfoServerExplorerApp*)AfxGetApp())->DisplayText(_T("CIOPCItemMgt::SetClientHandles() was successful."));
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrorClientHandle[0]);
}
}
else
{
GetGroup()->GetInfoServer()->DisplayError(res);
}
CoTaskMemFree(pErrorClientHandle);
}
}
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrorDataType[0]);
}
}
else
{
GetGroup()->GetInfoServer()->DisplayError(res);
}
CoTaskMemFree(pErrorDataType);
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrorState[0]);
}
}
else
{
GetGroup()->GetInfoServer()->DisplayError(res);
}
CoTaskMemFree(pErrorState);
}
}
else
{
GetGroup()->GetInfoServer()->DisplayError(pErrorValidate[0]);
}
bRet = TRUE;
}
else
{
GetGroup()->GetInfoServer()->DisplayError(res);
}
CoTaskMemFree(pErrorValidate);
CoTaskMemFree(pValidationResults);
return bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -