Using QuickOPC from Visual C++ 6.0: Difference between revisions
(Created page with "Category:C++ Category:Visual C++ Category:Visual C++ 6.0 Visual C++ 6.0 (also contained in Visual Studio 6.0) is still in use in some programming shops. Although...") |
No edit summary |
||
Line 6: | Line 6: | ||
This article explains the main differences, and how to overcome them. | This article explains the main differences, and how to overcome them. | ||
== The #import directive does not support the 'libid:' keyword == | |||
== There are no project-scope directory settings == | |||
== There is no CComSafeArray class == | |||
== Default character width may be 8 bits == | |||
== Example code == | |||
Below is a Visual C++ 6.0 example (ReadMultipleItems) modified from the one that we ship for Visual Studio 2012 or later. We have tested with a beta version of QuickOPC 2017.1, but it should work without changes with QuickOPC 2016.2 and many earlier versions as well. | |||
The main file below (ReadMultipleItems.cpp) #include-s (through stdafx.h) a QuickOPC.h file, which contains common QuickOPC imports and definitions. Both these files are also listed, further below. | |||
=== ReadMultipleItems.cpp === | |||
<syntaxhighlight lang="c++"> | |||
// $Header: $ | |||
// Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved. | |||
// ReadMultipleItems.cpp : Defines the entry point for the console application. | |||
// | |||
#include "stdafx.h" // Includes "QuickOpc.h", and other commonly used files | |||
#include <atlconv.h> | |||
// | |||
int _tmain(int argc, _TCHAR* argv[]) | |||
{ | |||
USES_CONVERSION; | |||
// Initialize the COM library. Note: If you choose STA, you will be responsible for pumping messages. | |||
CoInitializeEx(NULL, COINIT_MULTITHREADED); | |||
// Instatiate the EasyOPC-DA client object | |||
_EasyDAClientPtr ClientPtr(__uuidof(EasyDAClient)); | |||
_DAReadItemArgumentsPtr ReadItemArguments1Ptr(_uuidof(DAReadItemArguments)); | |||
ReadItemArguments1Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2"; | |||
ReadItemArguments1Ptr->ItemDescriptor->ItemId = L"Simulation.Random"; | |||
_DAReadItemArgumentsPtr ReadItemArguments2Ptr(_uuidof(DAReadItemArguments)); | |||
ReadItemArguments2Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2"; | |||
ReadItemArguments2Ptr->ItemDescriptor->ItemId = L"Trends.Ramp (1 min)"; | |||
_DAReadItemArgumentsPtr ReadItemArguments3Ptr(_uuidof(DAReadItemArguments)); | |||
ReadItemArguments3Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2"; | |||
ReadItemArguments3Ptr->ItemDescriptor->ItemId = L"Trends.Sine (1 min)"; | |||
_DAReadItemArgumentsPtr ReadItemArguments4Ptr(_uuidof(DAReadItemArguments)); | |||
ReadItemArguments4Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2"; | |||
ReadItemArguments4Ptr->ItemDescriptor->ItemId = L"Simulation.Register_I4"; | |||
COleSafeArray ArgumentsArray; | |||
ArgumentsArray.CreateOneDim(VT_VARIANT, 4); | |||
long i; | |||
i = 0; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments1Ptr)); | |||
i = 1; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments2Ptr)); | |||
i = 2; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments3Ptr)); | |||
i = 3; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments4Ptr)); | |||
//LPSAFEARRAY pArgumentsArray = ArgumentsArray.Detach(); | |||
COleSafeArray ResultArray(ClientPtr->ReadMultipleItems(&ArgumentsArray.parray), VT_VARIANT); | |||
//ArgumentsArray.Attach(pArgumentsArray); | |||
for (i = 0; i < ResultArray.GetOneDimSize(); i++) | |||
{ | |||
_variant_t vDAVtqResult; | |||
ResultArray.GetElement(&i, &vDAVtqResult); | |||
_DAVtqResultPtr DAVtqResultPtr = vDAVtqResult; | |||
_ExceptionPtr ExceptionPtr(DAVtqResultPtr->Exception); | |||
if (ExceptionPtr != NULL) | |||
{ | |||
_variant_t exceptionAsString(ExceptionPtr->ToString); | |||
_tprintf(_T("results(%d).Exception.ToString(): %s\n"), i, OLE2T(exceptionAsString.bstrVal)); | |||
continue; | |||
} | |||
_DAVtqPtr DAVtqPtr(DAVtqResultPtr->Vtq); | |||
_variant_t vtqAsString(DAVtqPtr->ToString); | |||
_tprintf(_T("results(%d).Vtq.ToString(): %s\n"), i, OLE2T(vtqAsString.bstrVal)); | |||
} | |||
// Release all interface pointers BEFORE calling CoUninitialize() | |||
ArgumentsArray.Clear(); | |||
ResultArray.Clear(); | |||
ClientPtr = NULL; | |||
CoUninitialize(); | |||
TCHAR line[80]; | |||
_putts(_T("Press Enter to continue...")); | |||
_fgetts(line, sizeof(line), stdin); | |||
return 0; | |||
} | |||
</syntaxhighlight> | |||
=== stdafx.h === | |||
<syntaxhighlight lang="c++"> | |||
// stdafx.h : include file for standard system include files, | |||
// or project specific include files that are used frequently, but | |||
// are changed infrequently | |||
// | |||
#if !defined(AFX_STDAFX_H__FEF9DF0F_01E8_4734_B0FC_90EB0159E0BF__INCLUDED_) | |||
#define AFX_STDAFX_H__FEF9DF0F_01E8_4734_B0FC_90EB0159E0BF__INCLUDED_ | |||
#define _WIN32_DCOM | |||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers | |||
#include <afx.h> | |||
#include <afxwin.h> // MFC core and standard components | |||
#include <afxext.h> // MFC extensions | |||
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls | |||
#ifndef _AFX_NO_AFXCMN_SUPPORT | |||
#include <afxcmn.h> // MFC support for Windows Common Controls | |||
#endif // _AFX_NO_AFXCMN_SUPPORT | |||
#include <iostream> | |||
#include "QuickOpc.h" | |||
// TODO: reference additional headers your program requires here | |||
//{{AFX_INSERT_LOCATION}} | |||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line. | |||
#endif // !defined(AFX_STDAFX_H__FEF9DF0F_01E8_4734_B0FC_90EB0159E0BF__INCLUDED_) | |||
</syntaxhighlight> | |||
=== QuickOPC.h === | |||
<syntaxhighlight lang="c++"> | |||
// $Header: $ | |||
// Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved. | |||
// This files imports all QuickOPC libraries (and system libraries they require), creating Compiler COM Support wrappers. | |||
// It also contains additional definitions for creating event sinks. | |||
#pragma once | |||
// #import system libraries | |||
// mscorlib | |||
#pragma warning(push) | |||
#pragma warning(disable:4278) // 'ReportEvent': identifier in type library 'BED7F4EA-1A96-11D2-8F08-00A0C9A6186D' is already a macro; use the 'rename' qualifier | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_MSCORLIB "libid:BED7F4EA-1A96-11D2-8F08-00A0C9A6186D" | |||
#else | |||
#define IMPORT_MSCORLIB "mscorlib.tlb" | |||
#endif | |||
#import IMPORT_MSCORLIB | |||
#pragma warning(pop) | |||
using namespace mscorlib; | |||
// System.Drawing | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_SYSTEM_DRAWING "libid:D37E2A3E-8545-3A39-9F4F-31827C9124AB" | |||
#else | |||
#define IMPORT_SYSTEM_DRAWING "System.Drawing.tlb" | |||
#endif | |||
#import IMPORT_SYSTEM_DRAWING | |||
using namespace System_Drawing; | |||
// System.Windows.Forms | |||
#pragma warning(push) | |||
#pragma warning(disable:4192) // automatically excluding 'IDataObject' while importing type library 'System.Windows.Forms.tlb' | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_SYSTEM_WINDOWS_FORMS "libid:215D64D2-031C-33C7-96E3-61794CD1EE61" | |||
#else | |||
#define IMPORT_SYSTEM_WINDOWS_FORMS "System.Windows.Forms.tlb" | |||
#endif | |||
#import IMPORT_SYSTEM_WINDOWS_FORMS | |||
#pragma warning(pop) | |||
using namespace System_Windows_Forms; | |||
// #import QuickOPC libraries | |||
// OpcLabs.BaseLib | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_OPCLABS_BASELIB "libid:ecf2e77d-3a90-4fb8-b0e2-f529f0cae9c9" | |||
#else | |||
#define IMPORT_OPCLABS_BASELIB "OpcLabs.BaseLib.tlb" | |||
#endif | |||
#import IMPORT_OPCLABS_BASELIB \ | |||
rename("value", "Value") | |||
using namespace OpcLabs_BaseLib; | |||
// OpcLabs.BaseLibForms | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_OPCLABS_BASELIBFORMS "libid:A0D7CA1E-7D8C-4D31-8ECB-84929E77E331" | |||
#else | |||
#define IMPORT_OPCLABS_BASELIBFORMS "OpcLabs.BaseLibForms.tlb" | |||
#endif | |||
#import IMPORT_OPCLABS_BASELIBFORMS | |||
using namespace OpcLabs_BaseLibForms; | |||
// OpcLabs.EasyOpcClassic | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_OPCLABS_EASYOPCCLASSIC "libid:1F165598-2F77-41C8-A9F9-EAF00C943F9F" | |||
#else | |||
#define IMPORT_OPCLABS_EASYOPCCLASSIC "OpcLabs.EasyOpcClassic.tlb" | |||
#endif | |||
#import IMPORT_OPCLABS_EASYOPCCLASSIC \ | |||
rename("itemId", "ItemId") \ | |||
rename("machineName", "MachineName") \ | |||
rename("requestedUpdateRate", "RequestedUpdateRate") \ | |||
rename("serverClass", "ServerClass") | |||
using namespace OpcLabs_EasyOpcClassic; | |||
// OpcLabs.EasyOpcUA | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_OPCLABS_EASYOPCUA "libid:E15CAAE0-617E-49C6-BB42-B521F9DF3983" | |||
#else | |||
#define IMPORT_OPCLABS_EASYOPCUA "OpcLabs.EasyOpcUA.tlb" | |||
#endif | |||
#import IMPORT_OPCLABS_EASYOPCUA \ | |||
rename("attributeData", "AttributeData") \ | |||
rename("browsePath", "BrowsePath") \ | |||
rename("endpointDescriptor", "EndpointDescriptor") \ | |||
rename("expandedText", "ExpandedText") \ | |||
rename("inputArguments", "InputArguments") \ | |||
rename("inputTypeCodes", "InputTypeCodes") \ | |||
rename("nodeDescriptor", "NodeDescriptor") \ | |||
rename("nodeId", "NodeId") \ | |||
rename("value", "Value") | |||
using namespace OpcLabs_EasyOpcUA; | |||
// OpcLabs.EasyOpcForms | |||
#if _MSC_VER >= 1300 | |||
#define IMPORT_OPCLABS_EASYOPCFORMS "libid:2C654FA0-6CD6-496D-A64E-CE2D2925F388" | |||
#else | |||
#define IMPORT_OPCLABS_EASYOPCFORMS "OpcLabs.EasyOpcForms.tlb" | |||
#endif | |||
#import IMPORT_OPCLABS_EASYOPCFORMS | |||
using namespace OpcLabs_EasyOpcForms; | |||
// DISPID-s | |||
#define DISPID_EASYAECLIENTCONFIGURATIONEVENTS_LOGENTRY 1 | |||
#define DISPID_EASYAECLIENTEVENTS_NOTIFICATION 2001 | |||
#define DISPID_EASYDACLIENTCONFIGURATIONEVENTS_LOGENTRY 1 | |||
#define DISPID_EASYDACLIENTEVENTS_ITEMCHANGED 1002 | |||
#define DISPID_EASYUACLIENTCONFIGURATIONEVENTS_LOGENTRY 1 | |||
#define DISPID_EASYUACLIENTEVENTS_DATACHANGENOTIFICATION 1002 | |||
#define DISPID_EASYUACLIENTEVENTS_EVENTNOTIFICATION 1003 | |||
#define DISPID_EASYUACLIENTEVENTS_SERVERCONDITIONCHANGED 1101 | |||
</syntaxhighlight> |
Revision as of 18:15, 22 February 2017
Visual C++ 6.0 (also contained in Visual Studio 6.0) is still in use in some programming shops. Although it is not a development environment that we officially target, it is perfectly possible to use QuickOPC from Visual C++ 6.0. QuickOPC exposes its API via COM, and that can be consumed from Visual C++ 6.0 well.
There are, however, some differences from the current Visual C++, and the examples we ship with QuickOPC do not work "out of the box" with Visual C++ 6.0.
This article explains the main differences, and how to overcome them.
The #import directive does not support the 'libid:' keyword
There are no project-scope directory settings
There is no CComSafeArray class
Default character width may be 8 bits
Example code
Below is a Visual C++ 6.0 example (ReadMultipleItems) modified from the one that we ship for Visual Studio 2012 or later. We have tested with a beta version of QuickOPC 2017.1, but it should work without changes with QuickOPC 2016.2 and many earlier versions as well.
The main file below (ReadMultipleItems.cpp) #include-s (through stdafx.h) a QuickOPC.h file, which contains common QuickOPC imports and definitions. Both these files are also listed, further below.
ReadMultipleItems.cpp
// $Header: $
// Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved.
// ReadMultipleItems.cpp : Defines the entry point for the console application.
//
#include "stdafx.h" // Includes "QuickOpc.h", and other commonly used files
#include <atlconv.h>
//
int _tmain(int argc, _TCHAR* argv[])
{
USES_CONVERSION;
// Initialize the COM library. Note: If you choose STA, you will be responsible for pumping messages.
CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Instatiate the EasyOPC-DA client object
_EasyDAClientPtr ClientPtr(__uuidof(EasyDAClient));
_DAReadItemArgumentsPtr ReadItemArguments1Ptr(_uuidof(DAReadItemArguments));
ReadItemArguments1Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2";
ReadItemArguments1Ptr->ItemDescriptor->ItemId = L"Simulation.Random";
_DAReadItemArgumentsPtr ReadItemArguments2Ptr(_uuidof(DAReadItemArguments));
ReadItemArguments2Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2";
ReadItemArguments2Ptr->ItemDescriptor->ItemId = L"Trends.Ramp (1 min)";
_DAReadItemArgumentsPtr ReadItemArguments3Ptr(_uuidof(DAReadItemArguments));
ReadItemArguments3Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2";
ReadItemArguments3Ptr->ItemDescriptor->ItemId = L"Trends.Sine (1 min)";
_DAReadItemArgumentsPtr ReadItemArguments4Ptr(_uuidof(DAReadItemArguments));
ReadItemArguments4Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2";
ReadItemArguments4Ptr->ItemDescriptor->ItemId = L"Simulation.Register_I4";
COleSafeArray ArgumentsArray;
ArgumentsArray.CreateOneDim(VT_VARIANT, 4);
long i;
i = 0; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments1Ptr));
i = 1; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments2Ptr));
i = 2; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments3Ptr));
i = 3; ArgumentsArray.PutElement(&i, &_variant_t((IDispatch*)ReadItemArguments4Ptr));
//LPSAFEARRAY pArgumentsArray = ArgumentsArray.Detach();
COleSafeArray ResultArray(ClientPtr->ReadMultipleItems(&ArgumentsArray.parray), VT_VARIANT);
//ArgumentsArray.Attach(pArgumentsArray);
for (i = 0; i < ResultArray.GetOneDimSize(); i++)
{
_variant_t vDAVtqResult;
ResultArray.GetElement(&i, &vDAVtqResult);
_DAVtqResultPtr DAVtqResultPtr = vDAVtqResult;
_ExceptionPtr ExceptionPtr(DAVtqResultPtr->Exception);
if (ExceptionPtr != NULL)
{
_variant_t exceptionAsString(ExceptionPtr->ToString);
_tprintf(_T("results(%d).Exception.ToString(): %s\n"), i, OLE2T(exceptionAsString.bstrVal));
continue;
}
_DAVtqPtr DAVtqPtr(DAVtqResultPtr->Vtq);
_variant_t vtqAsString(DAVtqPtr->ToString);
_tprintf(_T("results(%d).Vtq.ToString(): %s\n"), i, OLE2T(vtqAsString.bstrVal));
}
// Release all interface pointers BEFORE calling CoUninitialize()
ArgumentsArray.Clear();
ResultArray.Clear();
ClientPtr = NULL;
CoUninitialize();
TCHAR line[80];
_putts(_T("Press Enter to continue..."));
_fgetts(line, sizeof(line), stdin);
return 0;
}
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__FEF9DF0F_01E8_4734_B0FC_90EB0159E0BF__INCLUDED_)
#define AFX_STDAFX_H__FEF9DF0F_01E8_4734_B0FC_90EB0159E0BF__INCLUDED_
#define _WIN32_DCOM
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afx.h>
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <iostream>
#include "QuickOpc.h"
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__FEF9DF0F_01E8_4734_B0FC_90EB0159E0BF__INCLUDED_)
QuickOPC.h
// $Header: $
// Copyright (c) CODE Consulting and Development, s.r.o., Plzen. All rights reserved.
// This files imports all QuickOPC libraries (and system libraries they require), creating Compiler COM Support wrappers.
// It also contains additional definitions for creating event sinks.
#pragma once
// #import system libraries
// mscorlib
#pragma warning(push)
#pragma warning(disable:4278) // 'ReportEvent': identifier in type library 'BED7F4EA-1A96-11D2-8F08-00A0C9A6186D' is already a macro; use the 'rename' qualifier
#if _MSC_VER >= 1300
#define IMPORT_MSCORLIB "libid:BED7F4EA-1A96-11D2-8F08-00A0C9A6186D"
#else
#define IMPORT_MSCORLIB "mscorlib.tlb"
#endif
#import IMPORT_MSCORLIB
#pragma warning(pop)
using namespace mscorlib;
// System.Drawing
#if _MSC_VER >= 1300
#define IMPORT_SYSTEM_DRAWING "libid:D37E2A3E-8545-3A39-9F4F-31827C9124AB"
#else
#define IMPORT_SYSTEM_DRAWING "System.Drawing.tlb"
#endif
#import IMPORT_SYSTEM_DRAWING
using namespace System_Drawing;
// System.Windows.Forms
#pragma warning(push)
#pragma warning(disable:4192) // automatically excluding 'IDataObject' while importing type library 'System.Windows.Forms.tlb'
#if _MSC_VER >= 1300
#define IMPORT_SYSTEM_WINDOWS_FORMS "libid:215D64D2-031C-33C7-96E3-61794CD1EE61"
#else
#define IMPORT_SYSTEM_WINDOWS_FORMS "System.Windows.Forms.tlb"
#endif
#import IMPORT_SYSTEM_WINDOWS_FORMS
#pragma warning(pop)
using namespace System_Windows_Forms;
// #import QuickOPC libraries
// OpcLabs.BaseLib
#if _MSC_VER >= 1300
#define IMPORT_OPCLABS_BASELIB "libid:ecf2e77d-3a90-4fb8-b0e2-f529f0cae9c9"
#else
#define IMPORT_OPCLABS_BASELIB "OpcLabs.BaseLib.tlb"
#endif
#import IMPORT_OPCLABS_BASELIB \
rename("value", "Value")
using namespace OpcLabs_BaseLib;
// OpcLabs.BaseLibForms
#if _MSC_VER >= 1300
#define IMPORT_OPCLABS_BASELIBFORMS "libid:A0D7CA1E-7D8C-4D31-8ECB-84929E77E331"
#else
#define IMPORT_OPCLABS_BASELIBFORMS "OpcLabs.BaseLibForms.tlb"
#endif
#import IMPORT_OPCLABS_BASELIBFORMS
using namespace OpcLabs_BaseLibForms;
// OpcLabs.EasyOpcClassic
#if _MSC_VER >= 1300
#define IMPORT_OPCLABS_EASYOPCCLASSIC "libid:1F165598-2F77-41C8-A9F9-EAF00C943F9F"
#else
#define IMPORT_OPCLABS_EASYOPCCLASSIC "OpcLabs.EasyOpcClassic.tlb"
#endif
#import IMPORT_OPCLABS_EASYOPCCLASSIC \
rename("itemId", "ItemId") \
rename("machineName", "MachineName") \
rename("requestedUpdateRate", "RequestedUpdateRate") \
rename("serverClass", "ServerClass")
using namespace OpcLabs_EasyOpcClassic;
// OpcLabs.EasyOpcUA
#if _MSC_VER >= 1300
#define IMPORT_OPCLABS_EASYOPCUA "libid:E15CAAE0-617E-49C6-BB42-B521F9DF3983"
#else
#define IMPORT_OPCLABS_EASYOPCUA "OpcLabs.EasyOpcUA.tlb"
#endif
#import IMPORT_OPCLABS_EASYOPCUA \
rename("attributeData", "AttributeData") \
rename("browsePath", "BrowsePath") \
rename("endpointDescriptor", "EndpointDescriptor") \
rename("expandedText", "ExpandedText") \
rename("inputArguments", "InputArguments") \
rename("inputTypeCodes", "InputTypeCodes") \
rename("nodeDescriptor", "NodeDescriptor") \
rename("nodeId", "NodeId") \
rename("value", "Value")
using namespace OpcLabs_EasyOpcUA;
// OpcLabs.EasyOpcForms
#if _MSC_VER >= 1300
#define IMPORT_OPCLABS_EASYOPCFORMS "libid:2C654FA0-6CD6-496D-A64E-CE2D2925F388"
#else
#define IMPORT_OPCLABS_EASYOPCFORMS "OpcLabs.EasyOpcForms.tlb"
#endif
#import IMPORT_OPCLABS_EASYOPCFORMS
using namespace OpcLabs_EasyOpcForms;
// DISPID-s
#define DISPID_EASYAECLIENTCONFIGURATIONEVENTS_LOGENTRY 1
#define DISPID_EASYAECLIENTEVENTS_NOTIFICATION 2001
#define DISPID_EASYDACLIENTCONFIGURATIONEVENTS_LOGENTRY 1
#define DISPID_EASYDACLIENTEVENTS_ITEMCHANGED 1002
#define DISPID_EASYUACLIENTCONFIGURATIONEVENTS_LOGENTRY 1
#define DISPID_EASYUACLIENTEVENTS_DATACHANGENOTIFICATION 1002
#define DISPID_EASYUACLIENTEVENTS_EVENTNOTIFICATION 1003
#define DISPID_EASYUACLIENTEVENTS_SERVERCONDITIONCHANGED 1101