📄 opcdata.cpp
字号:
// value of the item:
OPCITEMSTATE* pValue = NULL;
//get a pointer to the IOPCSyncIOInterface:
IOPCSyncIO* pIOPCSyncIO;
m_pIOPCItemMgt->QueryInterface(__uuidof(pIOPCSyncIO), (void**) &pIOPCSyncIO);
//从设备中读取项值:
HRESULT* pErrors = NULL; //存储错误代码
CString strItem;
COPCItem Item;
POSITION pos=m_cMapItem.GetStartPosition ();
while(pos)
{
m_cMapItem.GetNextAssoc (pos,strItem,(CObject *&)Item);
hServerItem=Item.GetServerHandle () ;
HRESULT hr = pIOPCSyncIO->Read (OPC_DS_DEVICE, 1, &hServerItem, &pValue, &pErrors);
_ASSERT(!hr);
_ASSERT(pValue!=NULL);
Item.SetValue (pValue[0].vDataValue); //设定项值
m_cMapItem.SetAt (strItem,(CObject *)&Item); //更新项
varValue = pValue[0].vDataValue;
}
}
BOOL COPCGroup::WriteItem(CString strItem, VARIANT& varValue)
{
COPCItem Item;
if(!m_cMapItem.Lookup (strItem,(CObject *&)Item))
return FALSE;
OPCHANDLE hServerItem=Item.GetServerHandle () ;
//得到IOPCSyncIO接口指针:
IOPCSyncIO* pIOPCSyncIO;
m_pIOPCItemMgt->QueryInterface(__uuidof(pIOPCSyncIO), (void**) &pIOPCSyncIO);
//写项值到OPCServer:
HRESULT* pErrors = NULL; //存储错误代码
HRESULT hr = pIOPCSyncIO->Write (1,&hServerItem, &varValue, &pErrors);
_ASSERT(!hr);
//Release memeory allocated by the OPC server:
CoTaskMemFree(pErrors);
pErrors = NULL;
//释放IOPCSyncIO接口:
pIOPCSyncIO->Release();
if(hr==TRUE)
{
//更新项值
Item.SetValue (varValue);
m_cMapItem.SetAt (strItem,(CObject *&)Item);
return TRUE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////
//COPCGroup: Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL( COPCGroup, CObject, VERSIONABLE_SCHEMA | 2 )
COPCGroup::COPCGroup()
{
m_hTreeItem=NULL;
// OPC Group properties:
m_strName = GROUP_DEFAULT_NAME;
m_dwUpdateRate = GROUP_DEFAULT_UPDATERATE;
m_dwLanguageID = GROUP_DEFAULT_LANGUAGEID;
m_lTimeBias = GROUP_DEFAULT_TIMEBIAS;
m_fDeadband = GROUP_DEFAULT_DEADBAND;
m_bActive = GROUP_DEFAULT_ACTIVESTATE;
m_dwUpdateMethod = GROUP_DEFAULT_UPDATEMETHOD;
m_hServer = NULL;
m_bValid = FALSE;
// Interface pointers :
m_pIOPCGroupStateMgt = NULL;
m_pIOPCPublicGroupStateMgt = NULL;
m_pIOPCItemMgt = NULL;
m_pIOPCSync = NULL;
m_pIOPCAsync = NULL;
m_pIDataObject = NULL;
m_pIOPCAsync2 = NULL;
m_pIConnPtContainer = NULL;
m_pIDataSink20 = NULL;
m_dwCookieDataSink20 = 0;
// m_pIAdviseSink = NULL;
m_dwCookieRead = 0;
m_dwCookieWrite = 0;
//
// m_bConnected=FALSE;
}
COPCGroup::~COPCGroup()
{
// ASSERT (m_cdwItems == 0);
ASSERT (m_pIOPCGroupStateMgt == NULL);
ASSERT (m_pIOPCPublicGroupStateMgt == NULL);
ASSERT (m_pIOPCItemMgt == NULL);
ASSERT (m_pIOPCSync == NULL);
ASSERT (m_pIOPCAsync == NULL);
ASSERT (m_pIDataObject == NULL);
ASSERT (m_pIOPCAsync2 == NULL);
ASSERT (m_pIConnPtContainer == NULL);
ASSERT (m_pIDataSink20 == NULL);
ASSERT (m_dwCookieDataSink20 == 0);
// ASSERT (m_pIAdviseSink == NULL);
// ASSERT (m_dwCookieRead == 0);
// ASSERT (m_dwCookieWrite == 0);
// 删除项数据
COPCItem* pItem=NULL;
CString rKey;
POSITION pos=m_cMapItem.GetStartPosition ();
while(pos)
{
m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);
TRACE("COPCGroup::~COPCGroup()---%s\n",rKey);
delete pItem;
pItem=NULL;
}
}
void COPCGroup::AddItem(COPCItem *pItem)
{
m_cMapItem.SetAt(pItem->GetItemID(),pItem);
m_cMapAlias.SetAt(pItem->GetAlias(),pItem);
m_strItemNames.RemoveAll ();
m_strItemNames.Add (pItem->GetAlias ());
//
OPCHANDLE hOPCHandle;
AddItemToOPC(1,&pItem->GetOPCITEMDEF (),&hOPCHandle);
pItem->SetServerHandle (hOPCHandle);
}
void COPCGroup::ConnectItemToOPC()
{
int nCount=m_cMapItem.GetCount();
if(nCount<=0)
return;
OPCITEMDEF* pOPCItemDef=NULL;
OPCHANDLE* pOPCHandle=NULL;
COPCItem* pItem=NULL;
CString rKey;
int nIndex=0;
try{
pOPCItemDef=new OPCITEMDEF[nCount];
pOPCHandle=new OPCHANDLE[nCount];
}catch(...){
CString strError;
if(pOPCItemDef)
delete[] pOPCItemDef;
else
strError.Format (_T("COPCGroup 连接 OPC 错误(OPCITEMDEF 申请内存)!"),m_strName);
if(pOPCHandle)
delete[] pOPCHandle;
else
strError.Format (_T("COPCGroup 连接 OPC 错误(OPCHANDLE 申请内存)!"),m_strName);
AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
return;
}
m_strItemNames.RemoveAll ();
POSITION pos=m_cMapItem.GetStartPosition ();
nIndex=0;
try{
while(pos)
{
m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);
pItem->GetOPCITEMDEF (pOPCItemDef[nIndex++]);
m_strItemNames.Add (pItem->GetAlias ());
}
}catch(...){
CString strError;
strError.Format (_T("COPCGroup 连接第%d项OPC Item[%s] GetOPCITEMDEF()错误\nOPC Item 共有%d项!"),nIndex,rKey,nCount);
AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
return;
}
//
AddItemToOPC(nCount,pOPCItemDef,pOPCHandle);
//Set Server Handle
pos=m_cMapItem.GetStartPosition ();
nIndex=0;
try{
while(pos)
{
m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);
pItem->SetServerHandle (pOPCHandle[nIndex++]);
// CString strError;
// strError.Format (_T("COPCGroup 连接第%d项OPC Item[%s] \nOPC Item 共有%d项!"),nIndex,rKey,nCount);
// AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
}
}catch(...){
CString strError;
strError.Format (_T("COPCGroup 连接第%d项OPC Item[%s]SetServerHandle() 错误\nOPC Item 共有%d项!"),nIndex,rKey,nCount);
if(pOPCItemDef)
delete[] pOPCItemDef;
else
strError.Format (_T("COPCGroup 连接 OPC 错误(OPCITEMDEF 申请内存)!"),m_strName);
if(pOPCHandle)
delete[] pOPCHandle;
else
strError.Format (_T("COPCGroup 连接 OPC 错误(OPCHANDLE 申请内存)!"),m_strName);
AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
return;
}
delete[] pOPCItemDef;
delete[] pOPCHandle;
}
void COPCGroup::AddItemToOPC(int nCount,OPCITEMDEF* pOPCItemDef,OPCHANDLE* pOPCHandle)
{
HRESULT hr;
// Array of items to add:
// OPCITEMDEF ItemArray[1] =
// {{
// /*szAccessPath*/ L"",
// /*szItemID*/ ITEM_ID, //项名称
// /*bActive*/ FALSE,
// /*hClient*/ 1,
// /*dwBlobSize*/ 0,
// /*pBlob*/ NULL,
// /*vtRequestedDataType*/ VT_R4, //数据类型
// /*wReserved*/0
// }};
//Add Result:
OPCITEMRESULT* pAddResult=NULL;
HRESULT* pErrors = NULL;
// Add an Item to the previous Group:
// hr = pIOPCItemMgt->AddItems(1, ItemArray, &pAddResult, &pErrors);
//
try{
if(m_pIOPCItemMgt)
hr = m_pIOPCItemMgt->AddItems(nCount, pOPCItemDef, &pAddResult, &pErrors);
else
AfxMessageBox(_T("COPCGroup 连接 OPC Item AddItemToOPC()错误::m_pIOPCItemMgt=NULL"), MB_OK| MB_ICONQUESTION);
_ASSERT(!hr);
}catch(...){
CString strError;
strError.Format (_T("COPCGroup 连接 OPC Item AddItemToOPC()错误"));
AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
return;
}
// Server handle for the added item:
// Item.SetServerHandle (pAddResult[0].hServer);
bool bLogMsg=false;
CString strTip=m_strName;
CString strItemID;
UINT unID=HINT_ITEM_ADD+HINT_EVENT_OFFSET;
switch(hr)
{
case E_FAIL:
strTip.Format (_T("[%s]组增加项--- 失败"),m_strName);
break;
case E_OUTOFMEMORY:
strTip.Format (_T("[%s]组增加项---没有足够内存"),m_strName);
break;
case E_INVALIDARG:
strTip.Format (_T("[%s]组增加项---内部参数错误"),m_strName);
break;
case S_OK:
case S_FALSE:
{
CString strTemp;
for(int nIndex=0;nIndex<nCount;nIndex++)
{
pOPCHandle[nIndex]=NULL;
switch(pErrors[nIndex])
{
case S_OK:
{
pOPCHandle[nIndex]=pAddResult[nIndex].hServer;
strTemp=_T(" 项增加 成功");
break;
}
case OPC_E_INVALIDITEMID:
{
strTemp=_T(" 项的ID结构错误");
break;
}
case OPC_E_UNKNOWNITEMID:
{
strTemp=_T(" 项无知的ID(OPCServer中不存在)");
break;
}
case OPC_E_BADTYPE:
{
strTemp=_T(" 项数据类型错误");
break;
}
case OPC_E_UNKNOWNPATH:
{
strTemp=_T(" 项数据访问路径错误");
break;
}
default:
;
}
#ifdef _UNICODE
DWORD dwLen;
dwLen = lstrlen (pOPCItemDef[nIndex].szItemID);
lstrcpyn (strItemID, pOPCItemDef[nIndex].szItemID, dwLen + 1);
#else
strItemID=pOPCItemDef[nIndex].szItemID ;
#endif
strTip.Format (_T("%s.%s[%s]"),m_strName,m_strItemNames.GetAt (nIndex),strItemID);
strTip+=strTemp;
//事件视中提示
LogMsg(unID,(CObject *)& strTip);
bLogMsg=true;
}
break;
}
default:
{
strTip.Format (_T("[%s]组增加项(不知道的错误)"),m_strName);
TRACE(_T("COPCGroup::AddItemToOPC()---no know error\n"));
}
}
m_strItemNames.RemoveAll ();
//事件视中提示
if(!bLogMsg) //返回值非 S_OK/S_FALSE:
LogMsg(unID,(CObject *)& strTip);
// release memory allocated by the server:
try{
if(pAddResult)
{
if(pAddResult->pBlob)
CoTaskMemFree(pAddResult->pBlob);
CoTaskMemFree(pAddResult);
pAddResult = NULL;
}
if(pAddResult)
{
CoTaskMemFree(pErrors);
pErrors = NULL;
}
}catch(...){
CString strError;
strError.Format (_T("COPCGroup 连接项OPC Item ::AddItemToOPC() Release CoTaskMemFree()错误!"));
AfxMessageBox(strError, MB_OK| MB_ICONQUESTION);
return;
}
}
BOOL COPCGroup::DelItem(const CString strItem)
{
COPCItem* pItem;
if(!m_cMapItem.Lookup (strItem,(CObject *&)pItem))
return FALSE;
OPCHANDLE hServerArray[1];
hServerArray[0] = pItem->GetServerHandle () ;
CStringArray cItems;
cItems.Add (strItem);
DelItemToOPC(1,hServerArray,&cItems);
m_cMapAlias.RemoveKey (pItem->GetAlias());
delete pItem;
pItem=NULL;
return m_cMapItem.RemoveKey (strItem);
}
BOOL COPCGroup::RemoveAllItemFromOPC()
{
//释放数据
int nItemCount=m_cMapItem.GetCount ();
if(0==nItemCount) //无数据
return TRUE;
//
OPCHANDLE *phServer=new OPCHANDLE[nItemCount];
int nIndex=0;
HRESULT* pErrors = NULL;
COPCItem* pItem=NULL;
CString rKey;
POSITION pos=m_cMapItem.GetStartPosition ();
while(pos)
{
m_cMapItem.GetNextAssoc(pos,rKey,(CObject *&)pItem);
//从服务器中释放
phServer[nIndex++]=pItem->GetServerHandle ();
//初始化数据
pItem->InitializeOPCData ();
}
m_pIOPCItemMgt->RemoveItems (nItemCount,phServer,&pErrors);
delete[] phServer;
CoTaskMemFree(pErrors); //释放内存
pErrors = NULL;
return TRUE;
}
void COPCGroup::DelItemToOPC(int nCount,OPCHANDLE* phServerArray,CStringArray *pcItems)
{
if(pcItems==NULL
||m_pIOPCItemMgt==NULL
)
return;
if(nCount<=0)
return;
//从服务器中移除项
// OPCHANDLE hServerArray[1];
// hServerArray[0] = Item.GetServerHandle () ;
HRESULT* pErrors; //存储错误代码
HRESULT hr = m_pIOPCItemMgt->RemoveItems(nCount, phServerArray, &pErrors);
_ASSERT(!hr);
CString strTip=m_strName;
UINT unID=HINT_ITEM_ADD+HINT_EVENT_OFFSET;
switch(hr)
{
case E_FAIL:
strTip.Format (_T("[%s]组删除项---操作 失败"),m_strName);
break;
case E_INVALIDARG:
strTip.Format (_T("[%s]组删除项---内部参数错误"),m_strName);
break;
case S_OK:
case S_FALSE:
{
CString strTemp;
for(int nIndex=0;nIndex<nCount;nIndex++)
{
if(S_OK==pErrors[nIndex])
{
strTemp=_T(" 项删除 成功");
}
else
{
strTemp=_T(" 项删除 失败(非法的句柄)");
}
#ifdef _UNICODE
DWORD dwLen;
dwLen = lstrlen (pcItems->GetAt (nIndex));
lstrcpyn (strTip, pOPCItemDef[nIndex].szItemID, dwLen + 1);
#else
strTip=pcItems->GetAt (nIndex);
#endif
strTip+=strTemp;
}
break;
}
default:
{
strTip.Format (_T("[%s]组删除项(不知道的错误)"),m_strName);
TRACE(_T("COPCGroup::DelItemToOPC()---no know error\n"));
}
}
//事件视中提示
LogMsg(unID,(CObject *)& strTip);
//释放内存
CoTaskMemFree(pErrors);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -