Dear Sir,
I have created a project that demonstrates the proper error handling and OPC quality recognition in the event handler.
The project file (SubscribeErrorHandling.zip) is attached to this post, and the most important part of the code (the ItemChanged event handler with the exception handling) is listed here:
// The handler for EasyDAClient.ItemChanged event
STDMETHOD(ItemChanged)(VARIANT varSender, VARIANT varEventArgs)
{
_tprintf(_T("\n"));
// Obtain the event arguments
IEasyDAItemChangedEventArgsPtr EasyDAItemChangedEventArgsPtr(varEventArgs);
// Display the item identification
IDAItemDescriptorPtr DAItemDescriptorPtr(EasyDAItemChangedEventArgsPtr->ItemDescriptor);
_tprintf(_T("Item ID: %s\n"), COLE2CT(_bstr_t(DAItemDescriptorPtr->ItemId)));
// Test exception
ICOMExceptionPtr ExceptionPtr(EasyDAItemChangedEventArgsPtr->Exception);
if (ExceptionPtr != NULL)
{
_tprintf(_T("*** Error\n"));
// Display the message and error code
_tprintf(_T("Message: %s\n"), COLE2CT(_bstr_t(ExceptionPtr->Message)));
_tprintf(_T("Error code: %d\n"), ExceptionPtr->ErrorCode);
return S_OK;
}
// At this point, we know then there was no exception, and therefore the VTQ (value/timestamp/quality) will be present.
IDAVtqPtr VtqPtr(EasyDAItemChangedEventArgsPtr->Vtq);
_tprintf(_T("Timestamp: %s\n"), COleDateTime(VtqPtr->Timestamp).Format());
_tprintf(_T("Quality: %d\n"), VtqPtr->Quality);
// A valid VTQ may contain no value, e.g. when the OPC quality is Bad.
if (!VtqPtr->HasValue())
{
_tprintf(_T("*** No value\n"));
return S_OK;
}
// We can now access the value (as a VARIANT), in Vtq->Value.
// This example just formats and displays the value using a function provided on the DAVtq object.
_tprintf(_T("Value: %s\n"), COLE2CT(_bstr_t(VtqPtr->DisplayValue())));
return S_OK;
}
I am not sure about the other parts of your question. Our events are not Windows messages, and my understanding is that therefore the MFC message maps cannot directly handle them.
Best regards