Difference between revisions of "Using QuickOPC from Visual C++ 6.0"

From OPC Labs Knowledge Base
Jump to navigation Jump to search
(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...")
 
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