//---------------------------------------------------------
//?OPC?Custom?2.0?Sample
//?Asynchronous?IO?with?MFC?and?ATL
//?(c)?Siemens?AG?2000
//---------------------------------------------------------
//
//?Callback.h?:?Declaration?of?callback?class?and?definition?of?minor?methods
//
#include?"OPCRes.h"
class?COPCDataCallback?:public?CComObjectRoot,public?IOPCDataCallback
{
public:
COPCDataCallback()?{};
BEGIN_COM_MAP(COPCDataCallback)
COM_INTERFACE_ENTRY(IOPCDataCallback)
END_COM_MAP()
//?IOPCDataCallback
STDMETHODIMP??OnDataChange(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup,
/*?[in]?*/?HRESULT?hrMasterquality,
/*?[in]?*/?HRESULT?hrMastererror,
/*?[in]?*/?DWORD?dwCount,
/*?[size_is][in]?*/?OPCHANDLE?__RPC_FAR?*phClientItems,
/*?[size_is][in]?*/?VARIANT?__RPC_FAR?*pvValues,
/*?[size_is][in]?*/?WORD?__RPC_FAR?*pwQualities,
/*?[size_is][in]?*/?FILETIME?__RPC_FAR?*pftTimeStamps,
/*?[size_is][in]?*/?HRESULT?__RPC_FAR?*pErrors);
STDMETHODIMP??OnReadComplete(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup,
/*?[in]?*/?HRESULT?hrMasterquality,
/*?[in]?*/?HRESULT?hrMastererror,
/*?[in]?*/?DWORD?dwCount,
/*?[size_is][in]?*/?OPCHANDLE?__RPC_FAR?*phClientItems,
/*?[size_is][in]?*/?VARIANT?__RPC_FAR?*pvValues,
/*?[size_is][in]?*/?WORD?__RPC_FAR?*pwQualities,
/*?[size_is][in]?*/?FILETIME?__RPC_FAR?*pftTimeStamps,
/*?[size_is][in]?*/?HRESULT?__RPC_FAR?*pErrors);
STDMETHODIMP??OnWriteComplete(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup,
/*?[in]?*/?HRESULT?hrMastererr,
/*?[in]?*/?DWORD?dwCount,
/*?[size_is][in]?*/?OPCHANDLE?__RPC_FAR?*pClienthandles,
/*?[size_is][in]?*/?HRESULT?__RPC_FAR?*pErrors);
STDMETHODIMP??OnCancelComplete(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup)
{
return?S_OK;
};
void?InformAbout?(OPCRes?*pOPCRes)
{
m_pOPCRes?=?pOPCRes;
}
protected:
OPCRes?*?m_pOPCRes;
};
实现callback.cpp
#include?"stdafx.h"
#include?"pre_opc.h"
#include?"Callback.h"????//?for?OPC:?include?class?declaration?for?this?callback?class
#include?"../../HYWL01.h"
#include?"../../MainDlg.h"
CString?GetQualityText(UINT?qnr);
//text?description?from?quality?code
/
//
//?IOPCDataCallback?-?implementation
//?OnDataChange?called?by?OPC?server?when?the?OPC?server?has?detected?modified?data
//?(being?called?only?when?group?and?item?is?set?to?active)
STDMETHODIMP?COPCDataCallback::?OnDataChange(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup,
/*?[in]?*/?HRESULT?hrMasterquality,
/*?[in]?*/?HRESULT?hrMastererror,
/*?[in]?*/?DWORD?dwCount,
/*?[size_is][in]?*/?OPCHANDLE?__RPC_FAR?*phClientItems,
/*?[size_is][in]?*/?VARIANT?__RPC_FAR?*pvValues,
/*?[size_is][in]?*/?WORD?__RPC_FAR?*pwQualities,
/*?[size_is][in]?*/?FILETIME?__RPC_FAR?*pftTimeStamps,
/*?[size_is][in]?*/?HRESULT?__RPC_FAR?*pErrors)
{
DWORD?i,j;
for?(i?=?0;?i
{
for(?j?=?0?;?jGetAsyncCount()?;j++)//?j用来遍历每一个项
{
if(?(phClientItems[i]?==?j)?&&?(pErrors[i]?==?S_OK)?)//phClientItems[i]存放了有变化的异步项的序号
{
m_pOPCRes->m_ReadVal_A[j]=pvValues[i].intVal;
m_pOPCRes->m_ReadQu_A[j].Format("%s",GetQualityText(pwQualities[i]));
m_pOPCRes->m_ReadTs_A[j]=COleDateTime(?pftTimeStamps[i]?).Format();
break;
}
}
}
return?S_OK;
};
STDMETHODIMP?COPCDataCallback::OnReadComplete(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup,
/*?[in]?*/?HRESULT?hrMasterquality,
/*?[in]?*/?HRESULT?hrMastererror,
/*?[in]?*/?DWORD?dwCount,
/*?[size_is][in]?*/?OPCHANDLE?__RPC_FAR?*phClientItems,
/*?[size_is][in]?*/?VARIANT?__RPC_FAR?*pvValues,
/*?[size_is][in]?*/?WORD?__RPC_FAR?*pwQualities,
/*?[size_is][in]?*/?FILETIME?__RPC_FAR?*pftTimeStamps,
/*?[size_is][in]?*/?HRESULT?__RPC_FAR?*pErrors)
{
DWORD?i;
for?(i?=?0;?i
{
if(?pErrors[i]?==?S_OK)
{
m_pOPCRes->m_ReadVal_A[i]=pvValues[i].intVal;
m_pOPCRes->m_ReadQu_A[i].Format("%s",GetQualityText(pwQualities[i]));
m_pOPCRes->m_ReadTs_A[i]=COleDateTime(?pftTimeStamps[i]?).Format();
}
else
{
/*?error?case:?display?error?text?*/
CString?readQuality?=?GetQualityText(pErrors[i]);
m_pOPCRes->m_ReadQu_A[i]=readQuality;
}
}
return?S_OK;
};
//异步写入未实现
STDMETHODIMP?COPCDataCallback::OnWriteComplete(
/*?[in]?*/?DWORD?dwTransid,
/*?[in]?*/?OPCHANDLE?hGroup,
/*?[in]?*/?HRESULT?hrMastererr,
/*?[in]?*/?DWORD?dwCount,
/*?[size_is][in]?*/?OPCHANDLE?__RPC_FAR?*pClienthandles,
/*?[size_is][in]?*/?HRESULT?__RPC_FAR?*pErrors)
{
return?S_OK;
};
///
//品质值转换字符信息函数
CString?GetQualityText(UINT?qnr)
{
CString?qstr;
switch(qnr)
{
case?OPC_QUALITY_BAD:
qstr?=?"BAD";
break;
case?OPC_QUALITY_UNCERTAIN:
qstr?=?"UNCERTAIN";
break;
case?OPC_QUALITY_GOOD:
qstr?=?"GOOD";
break;
case?OPC_QUALITY_NOT_CONNECTED:
qstr?=?"NOT_CONNECTED";
break;
case?OPC_QUALITY_DEVICE_FAILURE:
qstr?=?"DEVICE_FAILURE";
break;
case?OPC_QUALITY_SENSOR_FAILURE:
qstr?=?"SENSOR_FAILURE";
break;
case?OPC_QUALITY_LAST_KNOWN:
qstr?=?"LAST_KNOWN";
break;
case?OPC_QUALITY_COMM_FAILURE:
qstr?=?"COMM_FAILURE";
break;
case?OPC_QUALITY_OUT_OF_SERVICE:
qstr?=?"OUT_OF_SERVICE";
break;
case?OPC_QUALITY_LAST_USABLE:
qstr?=?"LAST_USABLE";
break;
case?OPC_QUALITY_SENSOR_CAL:
qstr?=?"SENSOR_CAL";
break;
case?OPC_QUALITY_EGU_EXCEEDED:
qstr?=?"EGU_EXCEEDED";
break;
case?OPC_QUALITY_SUB_NORMAL:
qstr?=?"SUB_NORMAL";
break;
case?OPC_QUALITY_LOCAL_OVERRIDE:
qstr?=?"LOCAL_OVERRIDE";
break;
default:
qstr?=?"UNKNOWN?ERROR";
}
return?qstr;
}