📄 opc_user.cpp
字号:
// OPC_USER.cpp : implementation of the OPC user class
//
#include "stdafx.h"
#include "CLIENT.h"
#include "iadvsink.h"
#include "iopcdatacallback_imp.h"
#include "iopcshutdown_imp.h"
#include "opc_user.h"
//---- extern in OPC_DATA.CPP
extern UINT gfmtData;
extern UINT gfmtDatatime;
extern UINT gfmtWrite;
STDAPI GetOPCGroupHeaderFromSTM(LPFORMATETC pFE, LPSTGMEDIUM pSTM, OPCGROUPHEADER **ppGroupHeader);
STDAPI GetOPCGroupHeaderWriteFromSTM(LPFORMATETC pFE, LPSTGMEDIUM pSTM, OPCGROUPHEADERWRITE **ppGroupHeaderWrite);
STDAPI GetOPCItemHeader2FromSTM(
LPFORMATETC pFE,
DWORD dwItemIndex,
OPCGROUPHEADER *pGroupHeader,
OPCITEMHEADER2 **ppItemHeader2,
VARIANT * pvDataValue);
STDAPI GetOPCItemHeader1FromSTM(
LPFORMATETC pFE,
DWORD dwItemIndex,
OPCGROUPHEADER *pGroupHeader,
OPCITEMHEADER1 **ppItemHeader1,
VARIANT * pvDataValue);
STDAPI GetOPCItemHeaderWriteFromSTM(
LPFORMATETC pFE,
DWORD dwItemIndex,
OPCGROUPHEADERWRITE *pGroupHeaderWrite,
OPCITEMHEADERWRITE **ppItemHeaderWrite);
/////////////////////////////////////////////////////////////////////////////
// CClientOPCGroup
// constructor/destructor
CClientOPCGroup::CClientOPCGroup(IOPCServer* pServer, IMalloc* pIMalloc)
{
m_pIServer = pServer;
m_pIMalloc = pIMalloc;
// Initialize the member variables
m_hServerGroup = 0;
m_szGroupName = NULL;
m_pUnk = NULL;
m_pIOPCGroupStateMgt = NULL;
m_pIOPCItemMgt = NULL;
m_pIOPCSyncIO = NULL;
m_pIOPCAsyncIO = NULL;
m_pIDataObject = NULL;
m_pIEnumOPCItemAttrb = NULL;
m_dwAdviseData = 0;
m_dwAdviseDataTime = 0;
m_dwAdviseWriteComplete = 0;
m_AsyncState = OPC_ASYNC_NON;
m_dwRefreshID = 0;
m_hLastClientHandle = 0;
m_bIsReleased = FALSE;
m_pCPC = NULL;
m_pCallbackCP = NULL;
m_pASIO2 = NULL;
m_MyCallback = NULL;
m_MyCookie = 0L;
m_dwTransactionID = 0;
}
CClientOPCGroup::~CClientOPCGroup()
{
free(m_szGroupName);
GroupRelease();
}
/////////////////////////////////////////////////////////////////////
// CClientOPCGroup utlities
void CClientOPCGroup::Initialize( LPCTSTR szName,
OPCHANDLE hServer,
OPCHANDLE hClient,
LPUNKNOWN * ppUnk)
{
m_szGroupName = CCrack::WSTRClone(CCrack::wszFromSTR(szName));
m_hServerGroup = hServer;
m_hClientGroup = hClient;
m_pUnk = *ppUnk;
m_pUnk->QueryInterface(IID_IOPCGroupStateMgt,(VOID**)&m_pIOPCGroupStateMgt);
m_pUnk->QueryInterface(IID_IOPCItemMgt,(VOID**)&m_pIOPCItemMgt);
m_pUnk->QueryInterface(IID_IOPCSyncIO,(VOID**)&m_pIOPCSyncIO);
m_pUnk->QueryInterface(IID_IOPCAsyncIO,(VOID**)&m_pIOPCAsyncIO);
m_pUnk->QueryInterface(IID_IDataObject,(VOID**)&m_pIDataObject);
if(m_pIOPCAsyncIO)
m_AsyncState = OPC_ASYNC_SUPPORTED;
if(m_pIOPCItemMgt)
{
//IID_IEnumOPCItemAttributes
HRESULT hr = m_pIOPCItemMgt->CreateEnumerator(IID_IEnumOPCItemAttributes, (LPUNKNOWN*)&m_pIEnumOPCItemAttrb);
if(FAILED(hr)){
CString szError;
szError.Format("CreateEnumerator Failed : %x",hr);
AfxMessageBox(szError);
}
}
if(m_pIDataObject == NULL)
return;
m_pSink = new CImpIAdviseSink( this ) ;
if(m_pSink == NULL) return;
FORMATETC formatetc;
formatetc.dwAspect = DVASPECT_CONTENT ;
formatetc.ptd = NULL ;
formatetc.tymed = TYMED_HGLOBAL ;
formatetc.lindex = - 1 ;
m_pSink->AddRef();
formatetc.cfFormat = gfmtData;
m_pIDataObject->DAdvise( &formatetc, 0, m_pSink, &m_dwAdviseData );
m_pSink->AddRef();
formatetc.cfFormat = gfmtDatatime;
m_pIDataObject->DAdvise( &formatetc, 0, m_pSink, &m_dwAdviseDataTime );
m_pSink->AddRef();
formatetc.cfFormat = gfmtWrite;
m_pIDataObject->DAdvise( &formatetc, 0, m_pSink, &m_dwAdviseWriteComplete );
m_szAsyncInfo="";
}
// Called by cloneGroup, allow copy of items of the first group to the second
void CClientOPCGroup::CloneItems( LPCTSTR szName,
OPCHANDLE hServer,
OPCHANDLE hClient,
LPUNKNOWN * ppUnk)
{
if(m_pIEnumOPCItemAttrb)
{
OPCITEMATTRIBUTES * pstItemAttr;
ULONG celtFetched;
// CloneGroup also its items
m_pIEnumOPCItemAttrb->Reset();
while(m_pIEnumOPCItemAttrb->Next(1, &pstItemAttr, &celtFetched) == S_OK)
{
if(NULL == pstItemAttr) continue;
CClientOPCItem * pItem = new CClientOPCItem(this);
HRESULT * pError = NULL;
if(pItem == NULL)
{
m_pIOPCItemMgt->RemoveItems(1, &(pstItemAttr->hServer), &pError);
if(pError)
m_pIMalloc->Free(pError);
}
else
{
pItem->ItemInitialize(pstItemAttr);
InsertItem(pItem);
}
if(pstItemAttr->szAccessPath)
m_pIMalloc->Free(pstItemAttr->szAccessPath);
if(pstItemAttr->szItemID)
m_pIMalloc->Free(pstItemAttr->szItemID);
m_pIMalloc->Free(pstItemAttr);
}//while(m_pIEnumOPCItemAttrb->Next(1
}//if(m_pIEnumOPCItemAttrb)
}
void CClientOPCGroup::GroupRelease()
{
POSITION posItem = m_MapItemList.GetStartPosition();
LPVOID pKey;
CClientOPCItem * pItem;
if(m_bIsReleased) return;
while(posItem)
{
HRESULT * pError = NULL;
m_MapItemList.GetNextAssoc(posItem, pKey, (VOID*&)pItem);
if(pItem)
{
m_pIOPCItemMgt->RemoveItems(1, &(pItem->m_hServer), &pError);
if(pError)
m_pIMalloc->Free(pError);
delete pItem;
}
}
m_MapItemList.RemoveAll();
m_MapItemListBis.RemoveAll();
if(m_pIDataObject)
{
if(m_dwAdviseData)
{
m_pIDataObject->DUnadvise( m_dwAdviseData );
m_pSink->Release();
m_dwAdviseData = 0;
}
if(m_dwAdviseDataTime)
{
m_pIDataObject->DUnadvise( m_dwAdviseDataTime );
m_pSink->Release();
m_dwAdviseDataTime = 0;
}
if(m_dwAdviseWriteComplete)
{
m_pIDataObject->DUnadvise( m_dwAdviseWriteComplete );
m_pSink->Release();
m_dwAdviseWriteComplete = 0;
}
m_pIDataObject->Release();
m_pIDataObject = NULL;
}
if(m_pIOPCGroupStateMgt)
{
m_pIOPCGroupStateMgt->Release();
m_pIOPCGroupStateMgt = NULL;
}
if(m_pIOPCItemMgt)
{
m_pIOPCItemMgt->Release();
m_pIOPCItemMgt = NULL;
}
if(m_pIOPCSyncIO)
{
m_pIOPCSyncIO->Release();
m_pIOPCSyncIO = NULL;
}
if(m_pIOPCAsyncIO)
{
m_pIOPCAsyncIO->Release();
m_pIOPCAsyncIO = NULL;
}
if(m_pIEnumOPCItemAttrb)
{
m_pIEnumOPCItemAttrb->Release();
m_pIEnumOPCItemAttrb = NULL;
}
if(m_pUnk)
{
m_pUnk->Release();
m_pUnk = NULL;
}
if (m_pCallbackCP)
{
m_pCallbackCP->Unadvise(m_MyCookie);
m_pCallbackCP->Release();
m_pCallbackCP = NULL;
}
if (m_pASIO2)
{
m_pASIO2->Release();
m_pASIO2 = NULL;
}
if (m_MyCallback)
{
m_MyCallback->Release();
m_MyCallback = NULL;
}
m_bIsReleased = TRUE;
}
CString CClientOPCGroup::GetGroupName()
{
CString szGroupName;
szGroupName = CCrack::strFromWCHAR(m_szGroupName);
return szGroupName;
}
CString CClientOPCGroup::GetAsyncInfo()
{
CString szInfo;
szInfo = m_szAsyncInfo;
return szInfo;
}
// To know only if group is active
HRESULT CClientOPCGroup::GroupGetActive(BOOL* pbActive)
{
if(m_pIOPCGroupStateMgt)
{
DWORD dwUpdateRate;
LPWSTR szName;
LONG lTimeBias;
FLOAT fPercentDeadband;
DWORD dwLCID;
OPCHANDLE hClient;
OPCHANDLE hServer;
// All pointer must be valid !
return (m_pIOPCGroupStateMgt->GetState( &dwUpdateRate,
pbActive,
&szName,
&lTimeBias,
&fPercentDeadband,
&dwLCID,
&hClient,
&hServer));
}
return E_FAIL;
}
CString CClientOPCGroup::GetGroupStateInfo()
{
CString szInfo;
szInfo = "";
if(m_pIOPCGroupStateMgt)
{
HRESULT hr;
DWORD dwUpdateRate;
BOOL bActive;
LPWSTR szName;
LONG lTimeBias;
FLOAT fPercentDeadband;
DWORD dwLCID;
OPCHANDLE hClient;
OPCHANDLE hServer;
hr = m_pIOPCGroupStateMgt->GetState( &dwUpdateRate,
&bActive,
&szName,
&lTimeBias,
&fPercentDeadband,
&dwLCID,
&hClient,
&hServer);
if(SUCCEEDED(hr))
{
szInfo += CCrack::strDWORD(dwUpdateRate);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strBOOL(bActive);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strFromWCHAR(szName);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strLONG(lTimeBias);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strFLOAT(fPercentDeadband);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strDWORD(dwLCID);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strDWORD_X((DWORD)hClient);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strDWORD_X((DWORD)hServer);
szInfo += CCrack::strSeparator();
// supported interfaces
szInfo += CCrack::strYESNO(m_pUnk);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strYESNO(m_pIOPCGroupStateMgt);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strYESNO(m_pIOPCSyncIO);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strYESNO(m_pIOPCAsyncIO);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strYESNO(m_pIDataObject);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strYESNO(m_pIOPCItemMgt);
szInfo += CCrack::strSeparator();
szInfo += CCrack::strYESNO(m_pIEnumOPCItemAttrb);
}
}
return szInfo;
}
BOOL CClientOPCGroup::CanCancelRefresh()
{
return (m_AsyncState == OPC_ASYNC_WAITING) ? TRUE : FALSE;
}
BOOL CClientOPCGroup::CanbeRefresh()
{
return (m_AsyncState != OPC_ASYNC_SUPPORTED || m_MapItemList.IsEmpty()) ? FALSE : TRUE;
}
void CClientOPCGroup::SetGroupName(LPCTSTR szNewName)
{
free(m_szGroupName);
m_szGroupName = CCrack::WSTRClone(CCrack::wszFromSTR(szNewName));
}
OPCHANDLE CClientOPCGroup::GetNewClientHandle()
{
InterlockedIncrement((long*)&m_hLastClientHandle);
return m_hLastClientHandle;
}
/////////////////////////////////////////////////////////////////////
//
// CClientOPCItem
//
// constructor/destructor
CClientOPCItem ::CClientOPCItem(CClientOPCGroup* pParent)
{
m_szAccessPath = NULL;
m_szItemID = NULL;
m_bActive = FALSE;
m_hClient = 0;
m_hServer = 0;
m_vtRequestedDataType = VT_EMPTY;
m_vtCanonicalDataType = VT_EMPTY;
memset(&m_vData, 0, sizeof(VARIANT));
m_vData.vt = VT_EMPTY;
m_wQuality = OPC_QUALITY_UNCERTAIN;
m_pParentGroup = pParent;
m_nImage = 0;
}
CClientOPCItem::~CClientOPCItem()
{
ItemRelease();
}
/////////////////////////////////////////////////////////////////////
//
// CClientOPCItem
//
// utlities
void CClientOPCItem::ItemRelease()
{
/* if(m_pIOPCItem)
{
m_pIOPCItem->Release();
m_pIOPCItem = NULL;
}*/
if(m_szAccessPath)
{
free(m_szAccessPath);
m_szAccessPath = NULL;
}
if(m_szItemID)
{
free(m_szItemID);
m_szItemID = NULL;
}
}
void CClientOPCItem::ItemInitialize(OPCITEMDEF *pItemDef, OPCITEMRESULT *pItemResult)
{
if(pItemDef->szAccessPath)
m_szAccessPath = CCrack::WSTRClone(pItemDef->szAccessPath);
if(pItemDef->szItemID)
m_szItemID = CCrack::WSTRClone(pItemDef->szItemID);
m_bActive = pItemDef->bActive;
m_hClient = pItemDef->hClient;
m_hServer = pItemResult->hServer;
m_vtRequestedDataType = pItemDef->vtRequestedDataType;
//mv980408 m_vData.vt = m_vtCanonicalDataType = pItemResult->vtCanonicalDataType;
m_vtCanonicalDataType = pItemResult->vtCanonicalDataType;
m_vData.vt = m_vtRequestedDataType;
}
void CClientOPCItem::ItemInitialize(OPCITEMATTRIBUTES * pItemAttr)
{
if(pItemAttr->szAccessPath)
m_szAccessPath = CCrack::WSTRClone(pItemAttr->szAccessPath);
if(pItemAttr->szItemID)
m_szItemID = CCrack::WSTRClone(pItemAttr->szItemID);
m_bActive = pItemAttr->bActive;
m_hClient = pItemAttr->hClient;
m_hServer = pItemAttr->hServer;
m_vtRequestedDataType = pItemAttr->vtRequestedDataType;
//mv980408 m_vData.vt = m_vtCanonicalDataType = pItemAttr->vtCanonicalDataType;
m_vtCanonicalDataType = pItemAttr->vtCanonicalDataType;
m_vData.vt = m_vtRequestedDataType;
}
CString CClientOPCItem::GetItemString()
{
CString szInfo;
CString szTemp;
if((m_wQuality & OPC_QUALITY_GOOD) == OPC_QUALITY_GOOD ||//(11 0000 00)
m_wQuality == OPC_QUALITY_BAD_LASTVALUE)
szTemp = CCrack::strVARIANTData(m_vData);
else
{
//uncertain
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -