📄 opc_user.cpp
字号:
if((m_wQuality >> 6) == 0x1)
{
szTemp = CCrack::strVARIANTData(m_vData);
if(m_wQuality != OPC_QUALITY_UNCERTAIN_LASTVALUE)
szTemp = _T("(Uncertain)");
}
//bad
else
szTemp = _T("Bad");
}
szInfo.Format(_T("%s\t%s\t%s\t%s\t%s\t%s\t%s"),
CCrack::strFromWCHAR(m_szItemID),
CCrack::strFromWCHAR(m_szAccessPath),
szTemp,
CCrack::strOPCQuality(m_wQuality),
CCrack::strFileTimeWithMs(m_ftTimeStamp),
CCrack::strVARTYPE(m_vtCanonicalDataType),
CCrack::strVARTYPE(m_vtRequestedDataType));
return szInfo;
}
void CClientOPCItem::ItemSetClientHandle(OPCHANDLE hClientNew)
{
m_pParentGroup->m_MapItemListBis.RemoveKey((void*)m_hClient);
m_hClient = hClientNew;
m_pParentGroup->m_MapItemListBis.SetAt((void*)m_hClient, this);
}
void CClientOPCGroup::ReadItems(
OPCDATASOURCE dwSource,
DWORD dwNumItems,
OPCHANDLE * phServer,
BOOL bAsync)
{
OPCITEMSTATE * pItemValues = NULL;
HRESULT * pErrorsTab = NULL;
HRESULT hr;
DWORD i;
CString szTemp;
if(bAsync)
{
if((m_pIOPCAsyncIO) || (m_pASIO2))
{
m_dwTransactionID++;
DWORD dwTransactionID = m_dwTransactionID;
if (m_pIOPCAsyncIO)
hr = m_pIOPCAsyncIO->Read(m_dwAdviseDataTime, dwSource,dwNumItems,phServer,&dwTransactionID,&pErrorsTab);
else
hr = m_pASIO2->Read(dwNumItems,phServer,dwTransactionID,&m_dwCancelID,&pErrorsTab);
szTemp.Format(_T("++ AsyncRead TransID=%04lu NbItems=%04lu Source=%s Result="),
dwTransactionID, dwNumItems, CCrack::strOPCDataSource(dwSource));
m_szAsyncInfo += szTemp;
szTemp.Format(_T("%s\r\n"),CCrack::strOPCError(hr));
m_szAsyncInfo += szTemp;
m_pIMalloc->Free(pErrorsTab);
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
}
return;
}
szTemp.Format(_T("++ syncRead TransID=%04lu NbItems=%04lu Source=%s Result="),m_dwTransactionID,dwNumItems, CCrack::strOPCDataSource(dwSource));
m_szAsyncInfo += szTemp;
hr = m_pIOPCSyncIO->Read(dwSource, dwNumItems, phServer, &pItemValues, &pErrorsTab);
m_szAsyncInfo += CCrack::strOPCError(hr);
m_szAsyncInfo += "\r\n";
if(SUCCEEDED(hr)){
for(i = 0; i < dwNumItems; i ++)
{
CClientOPCItem * pItem = FindItemByKey(phServer[i]);
if(pItem)
{
pItem->SetItemData( &(pItemValues[i].hClient),
&(pItemValues[i].ftTimeStamp),
&(pItemValues[i].wQuality),
&(pItemValues[i].vDataValue),
&pErrorsTab[i]);
if (pErrorsTab != NULL){
if (pErrorsTab[i] != S_OK){
CString szTemp;
szTemp.Format(" Bad Item : %s\r\n",CCrack::strFromWCHAR(pItem->m_szItemID));
m_szAsyncInfo += szTemp;
}
}
}
}
}
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
if(pErrorsTab)
m_pIMalloc->Free(pErrorsTab);
if(pItemValues)
m_pIMalloc->Free(pItemValues);
}
void CClientOPCGroup::WriteItems( DWORD dwNumItems,
OPCHANDLE * phServer,
double dblValue,
BOOL bAsync)
{
VARIANT * pItemValues = NULL;
HRESULT * pErrors = NULL;
HRESULT hr;
DWORD i;
pItemValues = new VARIANT[dwNumItems];
if(pItemValues == NULL)
{
AfxMessageBox(_T(" Write failed : out of memory in CLIENT !"));
return;
}
for(i = 0; i < dwNumItems; i ++)
{
CClientOPCItem * pItem = FindItemByKey(phServer[i]);
if(pItem)
{
CCrack::VariantInitEx(&pItemValues[i], dblValue, pItem->m_vtRequestedDataType);
}
else
pItemValues[i].vt = VT_EMPTY;
}
CString szTemp;
if(bAsync)
{
if((m_pIOPCAsyncIO) || (m_pASIO2))
{
m_dwTransactionID++;
DWORD dwTransactionID = m_dwTransactionID;
if (m_pIOPCAsyncIO)
hr = m_pIOPCAsyncIO->Write(m_dwAdviseWriteComplete,dwNumItems,phServer,pItemValues,&dwTransactionID, &pErrors);
else
hr = m_pASIO2->Write(dwNumItems,phServer,pItemValues,dwTransactionID,&m_dwCancelID, &pErrors);
szTemp.Format(_T("++ AsyncWrite TransID=%04lu NbItems=%04lu Result="),
dwTransactionID, dwNumItems);
m_szAsyncInfo += szTemp;
szTemp.Format(_T("%s\r\n"),CCrack::strOPCError(hr));
m_szAsyncInfo += szTemp;
for(i = 0; i < dwNumItems; i ++)
VariantClear(&pItemValues[i]);
delete []pItemValues;
m_pIMalloc->Free(pErrors);
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
}
return;
}
hr = m_pIOPCSyncIO->Write(dwNumItems, phServer, pItemValues, &pErrors);
szTemp.Format(_T("++ AsyncWrite TransID=%04lu NbItems=%04lu Result="),m_dwTransactionID, dwNumItems);
m_szAsyncInfo += szTemp;
szTemp.Format(_T("%s\r\n"),CCrack::strOPCError(hr));
m_szAsyncInfo += szTemp;
for(i = 0; i < dwNumItems; i ++){
CClientOPCItem * pItem = FindItemByKey(phServer[i]);
if(pItem){
if (pErrors != NULL){
if (pErrors[i] != S_OK){
CString szTemp;
szTemp.Format(" Bad Item : %s\r\n",CCrack::strFromWCHAR(pItem->m_szItemID));
m_szAsyncInfo += szTemp;
}
}
}
VariantClear(&pItemValues[i]);
}
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
delete []pItemValues;
if(pErrors)
m_pIMalloc->Free(pErrors);
}
void CClientOPCItem::SetItemData(
OPCHANDLE * phClient,
FILETIME * pftTimeStamp,
WORD * pwQuality,
VARIANT * pvData,
HRESULT * phError)
{
if(phClient)
m_hClient = *phClient;
if(pftTimeStamp)
m_ftTimeStamp = *pftTimeStamp;
if(pwQuality)
m_wQuality = *pwQuality;
if(pvData)
{
switch(m_wQuality)
{
case OPC_QUALITY_GOOD:
case OPC_QUALITY_BAD_LASTVALUE:
case OPC_QUALITY_UNCERTAIN_LASTVALUE:
{
VARTYPE vt;
if(pvData->vt == VT_EMPTY) return;
// MF_981218 :ARRAY
if((pvData->vt&VT_ARRAY)==VT_ARRAY) return;
vt = (VT_EMPTY == m_vData.vt)?m_vtCanonicalDataType:m_vData.vt;
VariantChangeType(&m_vData, pvData, 0, vt);
break;
}
default: break;
}
}
}
void CClientOPCGroup::Refresh()
{
if((m_pIOPCAsyncIO == NULL) && (m_pASIO2 == NULL)) return;
DWORD dwConnection;
HRESULT hr;
dwConnection = (m_dwAdviseDataTime)?m_dwAdviseDataTime:m_dwAdviseData;
if (m_pASIO2)
{
m_dwTransactionID++;
hr = m_pASIO2->Refresh2(OPC_DS_DEVICE,m_dwTransactionID,&m_dwRefreshID);
}
else
hr = m_pIOPCAsyncIO->Refresh(dwConnection,OPC_DS_DEVICE,&m_dwRefreshID);
if(SUCCEEDED(hr))
{
m_AsyncState = OPC_ASYNC_WAITING;
}
else
{
m_AsyncState = OPC_ASYNC_SUPPORTED;
m_dwRefreshID = 0;
}
CString szTemp;
szTemp.Format(_T("++ Refresh TransID=%04lu Result=%s\r\n"),
m_dwRefreshID, CCrack::strOPCError(hr));
m_szAsyncInfo += szTemp;
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
}
void CClientOPCGroup::CancelRefresh()
{
if((m_pIOPCAsyncIO == NULL) && (m_pASIO2 == NULL)) return;
if(m_AsyncState != OPC_ASYNC_WAITING) return;
HRESULT hr;
CString szTemp;
if (m_pASIO2) // si V2
hr = m_pASIO2->Cancel2(m_dwRefreshID);
else
hr = m_pIOPCAsyncIO->Cancel(m_dwRefreshID);
szTemp.Format(_T("++ CancelRefresh TransID=%04lu Result=%s\r\n"),m_dwRefreshID, CCrack::strOPCError(hr));
m_dwRefreshID = 0;
m_szAsyncInfo += szTemp;
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
}
void CClientOPCGroup::GetDataFromStorageMedium(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
{
VARIANT vNewData;
DWORD i;
HRESULT hr;
BOOL bWriteCallback = FALSE;
BOOL bRefreshStateView = FALSE;
CClientOPCItem * pItem;
OPCGROUPHEADER * pGroupHeader;
if(pFE->cfFormat == gfmtData)
{
OPCITEMHEADER2 * pItemHeader2;
hr = GetOPCGroupHeaderFromSTM(pFE, pSTM, &pGroupHeader);
if(FAILED(hr)) return;
if(pGroupHeader->dwTransactionID != 0)
{
CString szTemp;
szTemp.Format(_T("-- Callback TransID=%04lu NbItems=%04lu Fmt=DATA Result=%s\r\n"),
pGroupHeader->dwTransactionID,
pGroupHeader->dwItemCount,
CCrack::strOPCError(pGroupHeader->hrStatus));
m_szAsyncInfo += szTemp;
bRefreshStateView = TRUE;
if(pGroupHeader->dwTransactionID == m_dwRefreshID)
m_AsyncState = OPC_ASYNC_CALLBACK;
}
for(i = 0; i < pGroupHeader->dwItemCount; i ++)
{
hr = GetOPCItemHeader2FromSTM(pFE, i, pGroupHeader, &pItemHeader2, &vNewData);
if(SUCCEEDED(hr))
{
pItem = FindItemByKeyBis(pItemHeader2->hClient);
if(pItem)
{
pItem->SetItemData( NULL,
NULL,
&(pItemHeader2->wQuality),
&vNewData);
}
}
}
if(pGroupHeader->dwTransactionID == m_dwRefreshID)
{
m_AsyncState = OPC_ASYNC_SUPPORTED;
m_dwRefreshID = 0;
}
GlobalUnlock(pGroupHeader);
}//if(pFE->cfFormat == gfmtData)
else if(pFE->cfFormat == gfmtDatatime)
{
OPCITEMHEADER1 * pItemHeader1;
hr = GetOPCGroupHeaderFromSTM(pFE, pSTM, &pGroupHeader);
if(FAILED(hr)) return;
if(pGroupHeader->dwTransactionID != 0)
{
CString szTemp;
szTemp.Format(_T("-- Callback TransID=%04lu NbItemst=%04lu Fmt=DATATIME Result=%s\r\n"),
pGroupHeader->dwTransactionID,
pGroupHeader->dwItemCount,
CCrack::strOPCError(pGroupHeader->hrStatus));
m_szAsyncInfo += szTemp;
bRefreshStateView = TRUE;
if(pGroupHeader->dwTransactionID == m_dwRefreshID)
m_AsyncState = OPC_ASYNC_CALLBACK;
}
for(i = 0; i < pGroupHeader->dwItemCount; i ++)
{
hr = GetOPCItemHeader1FromSTM(pFE, i, pGroupHeader, &pItemHeader1, &vNewData);
if(SUCCEEDED(hr))
{
pItem = FindItemByKeyBis(pItemHeader1->hClient);
if(pItem)
{
pItem->SetItemData( NULL,
&(pItemHeader1->ftTimeStampItem),
&(pItemHeader1->wQuality),
&vNewData);
}
}
}
if(pGroupHeader->dwTransactionID == m_dwRefreshID)
{
m_AsyncState = OPC_ASYNC_SUPPORTED;
m_dwRefreshID = 0;
}
GlobalUnlock(pGroupHeader);
}//if(pFE->cfFormat == gfmtDatatime)
else if(pFE->cfFormat == gfmtWrite)
{
OPCGROUPHEADERWRITE * pGroupHeaderWrite;
OPCITEMHEADERWRITE * pItemHeaderWrite;
hr = GetOPCGroupHeaderWriteFromSTM(pFE, pSTM, &pGroupHeaderWrite);
if(FAILED(hr)) return;
bWriteCallback = TRUE;
if(pGroupHeaderWrite->dwTransactionID != 0)
{
CString szTemp;
szTemp.Format(_T("-- Callback TransID=%04lu NbItems=%04lu Fmt=WRITECOMPLETE Result=%s\r\n"),
pGroupHeaderWrite->dwTransactionID,
pGroupHeaderWrite->dwItemCount,
CCrack::strOPCError(pGroupHeaderWrite->hrStatus));
m_szAsyncInfo += szTemp;
bRefreshStateView = TRUE;
}
for(i = 0; i < pGroupHeaderWrite->dwItemCount; i ++)
{
hr = GetOPCItemHeaderWriteFromSTM(pFE, i, pGroupHeaderWrite, &pItemHeaderWrite);
if(SUCCEEDED(hr))
{
pItem = FindItemByKeyBis(pItemHeaderWrite->hClient);
if (pItemHeaderWrite->dwError != S_OK){
CString szTemp;
szTemp.Format(" Bad Item : %s\r\n",CCrack::strFromWCHAR(pItem->m_szItemID));
m_szAsyncInfo += szTemp;
}
}
}
GlobalUnlock(pGroupHeaderWrite);
}
if (bRefreshStateView)
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED_ASYNC, 0, (LPARAM)this);
if(!bWriteCallback)
::PostMessage(AfxGetMainWnd()->m_hWnd, WM_OPCCLIENTNOTIFIED, 0, (LPARAM)this);
return;
}
CClientOPCItem* CClientOPCGroup::FindItemByKey(OPCHANDLE hServer)
{
CClientOPCItem * pItem = NULL;
m_MapItemList.Lookup((void*)hServer, (void*&)pItem);
return pItem;
}
CClientOPCItem* CClientOPCGroup::FindItemByKeyBis(OPCHANDLE hClient)
{
CClientOPCItem * pItem = NULL;
m_MapItemListBis.Lookup((void*)hClient, (void*&)pItem);
return pItem;
}
void CClientOPCGroup::InsertItems(DWORD dwNumItems, OPCHANDLE *phServer)
{
}
void CClientOPCGroup::InsertItem(CClientOPCItem* pItem)
{
m_MapItemList.SetAt((void*)pItem->ItemGetKey(), (void*&)pItem);
m_MapItemListBis.SetAt((void*)pItem->ItemGetKeyBis(), (void*&)pItem);
}
void CClientOPCGroup::RemoveItems(DWORD dwNumItems, OPCHANDLE *phServer)
{
for(DWORD i = 0; i < dwNumItems; i ++)
{
CClientOPCItem * pItem = FindItemByKey(phServer[i]);
if(pItem) RemoveItem(pItem);
}
}
void CClientOPCGroup::RemoveItem(CClientOPCItem* pItem)
{
m_MapItemList.RemoveKey((void*)pItem->ItemGetKey());
m_MapItemListBis.RemoveKey((void*)pItem->ItemGetKeyBis());
delete pItem;
}
void CClientOPCGroup::InitializeV2(LPCTSTR szName,
OPCHANDLE hServer,
OPCHANDLE hClient,
LPUNKNOWN * ppUnk)
{
m_szGroupName = CCrack::WSTRClone(CCrack::wszFromSTR(szName));
m_hServerGroup = hServer;
m_hClientGroup = hClient;
m_pUnk = *ppUnk;
// Create a callback instance
//
m_MyCallback = new IOPCCallback_Imp(this);
m_MyCallback -> AddRef();
// Establish a connection
//
m_pUnk->QueryInterface(IID_IOPCGroupStateMgt,(VOID**)&m_pIOPCGroupStateMgt);
m_pUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&m_pCPC);
m_pUnk->QueryInterface(IID_IOPCAsyncIO2, (void**)&m_pASIO2);
m_pUnk->QueryInterface(IID_IOPCItemMgt,(VOID**)&m_pIOPCItemMgt);
m_pUnk->QueryInterface(IID_IOPCSyncIO,(VOID**)&m_pIOPCSyncIO);
m_szAsyncInfo="";
if(m_pASIO2)
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_pCPC)
{
m_pCPC->FindConnectionPoint(IID_IOPCDataCallback, &m_pCallbackCP);
if (m_pCallbackCP)
m_pCallbackCP->Advise(m_MyCallback, &m_MyCookie);
m_pCPC->Release();
m_pCPC = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -