Controls PDF
Controls PDF
Controls PDF
Controls
v.8.10
© 2019 Ing. Punzenberger COPA-DATA GmbH
Distribution and/or reproduction of this document or parts thereof in any form are permitted solely with
the written permission of the company COPA-DATA. Technical data is only used for product description
and are not guaranteed qualities in the legal sense. Subject to change, technical or otherwise.
Contents
2 Controls......................................................................................................................................................... 5
3 General .......................................................................................................................................................... 6
3.1 Access zenon API.............................................................................................................................................. 6
3.2 Methods............................................................................................................................................................... 8
3.2.1 CanUseVariables....................................................................................................................................................... 8
3.2.2 MaxVariables ............................................................................................................................................................. 9
3.2.3 VariableTypes ............................................................................................................................................................ 9
3.2.4 zenonExit ..................................................................................................................................................................... 9
3.2.5 zenonExitEd ................................................................................................................................................................ 9
3.2.6 zenonInit .................................................................................................................................................................. 10
3.2.7 zenonInitEd ............................................................................................................................................................. 10
4 ActiveX ........................................................................................................................................................ 10
4.1 Develop ActiveX elements ..........................................................................................................................11
4.1.1 Methods ................................................................................................................................................................... 11
4.2 Example LatchedSwitch (C++) ..................................................................................................................13
4.2.1 Interface .................................................................................................................................................................... 13
4.2.2 Control ...................................................................................................................................................................... 14
4.2.3 Methods ................................................................................................................................................................... 17
4.2.4 Operate and display ............................................................................................................................................ 20
4.2.5 zenon Interface ...................................................................................................................................................... 22
4.3 Example CD_SliderCtrl (C++) .....................................................................................................................22
4.3.1 Interface .................................................................................................................................................................... 22
4.3.2 Control ...................................................................................................................................................................... 23
4.3.3 Methods ................................................................................................................................................................... 26
4.3.4 Operate and display ............................................................................................................................................ 28
4.3.5 zenon Interface ...................................................................................................................................................... 30
4.4 Example :NET control as ActiveX (C#) ....................................................................................................30
4.4.1 Creat Windows Form Control .......................................................................................................................... 30
4.4.2 Change .NET User Control to dual control ................................................................................................. 33
4.4.3 Work via VBA with ActiveX in the Editor ..................................................................................................... 37
4.4.4 <Connect CD_PRODUCTNAME> variables with the .NET user control .......................................... 38
6 WPF .............................................................................................................................................................. 73
Welcome to COPA-DATA help
ZENON VIDEO-TUTORIALS
You can find practical examples for project configuration with zenon in our YouTube channel
(https://www.copadata.com/tutorial_menu). The tutorials are grouped according to topics and give an
initial insight into working with different zenon modules. All tutorials are available in English.
GENERAL HELP
If you cannot find any information you require in this help chapter or can think of anything that you
would like added, please send an email to [email protected].
PROJECT SUPPORT
You can receive support for any real project you may have from our Support Team, who you can
contact via email at [email protected].
2 Controls
In zenon you can integrate own controls. For this following is available:
.NET user controls (on page 42) (For implementing in zenon see also .NET controls in manual
Screens.)
ActiveX (on page 10) (For implementing in zenon see also ActiveX in manual Screens.)
WPF
5 | 73
General
Information
You can find information about how to use the zenon programming interfaces
(PCE, VBA, VSTA) in manual Programming Interfaces.
Attention
Errors in applications such as ActiveX, PCE, VBA, VSTA, WPF and external
applications that access zenon via the API can also influence the stability of
Runtime.
3 General
Controls for zenon can be implemented via ActiveX, .NET and WPF. Via VBA/VSTA you can access the
zenon API.
6 | 73
General
EXAMPLE
The COM object of a zenon variable is temporarily saved in a Member in order to access it later in the
Paint Event of the control.
zenon.Variable m_cVal = null;
public bool zenon>Init(zenon.Element dispElement)
{
if (dispElement.CountVariable > 0) {
try {
m_cVal = dispElement.ItemVariable(0);
if (m_cVal != null) {
object obRead = m_cVal.get_Value((object)-1);
UserText = obRead.ToString();
}
}catch { }
}
return true;
}
public bool zenonExit()
{
try {
if (m_cVal != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(m_cVal);
m_cVal = null;
}
}
catch { }
return true;
}
7 | 73
General
3.2 Methods
ActiveX and .NET controls which use zenon variables need certain methods.
3.2.1 CanUseVariables
Prototype: short CanUseVariables();
For the dynamic element (via button Variable) you can only state zenon variables with the
type stated via method VariableTypes (on page 9) in the number stated by method
MaxVariables (on page 9).
0: The control cannot use zenon variables or does not have the method.
You can state variables with all types without restricting the number. In the Runtime
however they only can be used with VBA.
8 | 73
General
3.2.2 MaxVariables
Prototype: short MaxVariables();
Here the number of variables is defined, that can be selected from the variable list.
If 1 is returned, multi-select is disabled in the variable list. A warning is displayed when several variables
are selected anyway.
3.2.3 VariableTypes
Prototype: short VariableTypes();
The value returned by this method is used as a mask for the usable variable types in the variable list. The
value is an AND relation from the following values (defined in zenon32/dy_type.h):
Value 1 Value 2 Equivalent
3.2.4 zenonExit
Prototype: boolean zenonExit();
This method is called by the zenon Runtime when the ActiveX control is closed.
3.2.5 zenonExitEd
Equals zenonExit (on page 9) and is executed in closing the ActiveX in the Editor.
9 | 73
ActiveX
Therewith you can also react to changes in the ActiveX e.g. values changes in Editor.
3.2.6 zenonInit
Prototype: boolean zenonInit(IDispatch*dispElement);
With this method (in the Runtime) the ActiveX control gets a pointer to the dispatch interface of the
dynamic element. With this pointer zenon variables linked to the dynamic element can be accessed.
You define the sorting order of the handed over variables in the configuration of the ActiveX element
with the help of buttons Down or Up.
The Element Input dialog appears after double-clicking the ActiveX element or after selecting property
ActiveX settings in the element properties in node Representation.
3.2.7 zenonInitEd
Equals zenonInit (on page 10) and is executed on opening the ActiveX (double click the ActiveX) in the
Editor.
4 ActiveX
With ActiveX the functionality of the zenon Runtime and Editor can be enhanced autonomously.
You can find information about the dynamic element ActiveX in manual Screens in chapter ActiveX.
10 | 73
ActiveX
The control now defines by itself, how many zenon variables it can use and of what type they may be.
Additionally the properties of the control can also be defined by the dynamic element.
For this the interface (dispatch interface) of the control must support a number of certain methods (on
page 11) .
4.1.1 Methods
Each ActiveX control which can use zenon variables must contain the following methods:
CanUseVariables (on page 8)
MaxVariables (on page 9)
VariableTypes (on page 9)
zenonExit (on page 9)
zenonExitEd (on page 9)
zenonInit (on page 10)
zenonInitEd (on page 10)
It does not matter, which dispatch ID the methods have in the interface. On calling the methods zenon
receives the correct ID from the interface.
4.1.1.1 CanUseVariables
Prototype: short CanUseVariables();
For the dynamic element (via button Variable) you can only state zenon variables with the
type stated via method VariableTypes (on page 9) in the number stated by method
MaxVariables (on page 9).
0: The control cannot use zenon variables or does not have the method.
You can state variables with all types without restricting the number. In the Runtime
however they only can be used with VBA.
11 | 73
ActiveX
4.1.1.2 MaxVariables
Prototype: short MaxVariables();
Here the number of variables is defined, that can be selected from the variable list.
If 1 is returned, multi-select is disabled in the variable list. A warning is displayed when several variables
are selected anyway.
4.1.1.3 VariableTypes
Prototype: short VariableTypes();
The value returned by this method is used as a mask for the usable variable types in the variable list. The
value is an AND relation from the following values (defined in zenon32/dy_type.h):
Value 1 Value 2 Equivalent
4.1.1.4 zenonExit
Prototype: boolean zenonExit();
This method is called by the zenon Runtime when the ActiveX control is closed.
12 | 73
ActiveX
4.1.1.5 zenonExitEd
Equals zenonExit (on page 9) and is executed in closing the ActiveX in the Editor.
Therewith you can also react to changes in the ActiveX e.g. values changes in Editor.
4.1.1.6 zenonInit
Prototype: boolean zenonInit(IDispatch*dispElement);
With this method (in the Runtime) the ActiveX control gets a pointer to the dispatch interface of the
dynamic element. With this pointer zenon variables linked to the dynamic element can be accessed.
You define the sorting order of the handed over variables in the configuration of the ActiveX element
with the help of buttons Down or Up.
The Element Input dialog appears after double-clicking the ActiveX element or after selecting property
ActiveX settings in the element properties in node Representation.
4.1.1.7 zenonInitEd
Equals zenonInit (on page 10) and is executed on opening the ActiveX (double click the ActiveX) in the
Editor.
The status of the element is displayed with four bitmaps which can be selected in the properties dialog
of the control in the zenon Editor.
4.2.1 Interface
The control LatchedSwitch has the following dispatch interface:
[ uuid(EB207159-D7C9-11D3-B019-080009FBEAA2),
helpstring(Dispatch interface for LatchedSwitch Control), hidden ]
dispinterface _DLatchedSwitch
{
properties:
// NOTE - ClassWizard will maintain method information here.
13 | 73
ActiveX
methods:
// NOTE - ClassWizard will maintain method information here.
// Use extreme caution when editing this section.
//{{AFX_ODL_METHOD(CLatchedSwitchCtrl)
//}}AFX_ODL_METHOD
[id(6)] short CanUseVariables();
[id(7)] short VariableTypes();
[id(8)] short MaxVariables();
[id(9)] boolean zenonInit(IDispatch* dispElement);
[id(10)] boolean zenonExit();
[id(DISPID_ABOUTBOX)] void AboutBox();
};
The properties SwitchOn to LatchedOff contain the bitmaps for displaying the four different states of
the control. The bitmaps themselves are stored in objects of the class CScreenHolder. The property
SollwertDirekt defines if the input of set values is done via a dialog or directly by clicking the control.
4.2.2 Control
Implementing the control is done with the class CLatchedSwitchCtrl. As members this class has the
CScreenHolder objects for the storage of the bitmaps. Additionally three dispatch drivers for the
dynamic element and the variables are generated:
class CLatchedSwitchCtrl : public COleControl
{
DECLARE_DYNCREATE(CLatchedSwitchCtrl)
// Constructor
public:
CLatchedSwitchCtrl();
// Overrides
14 | 73
ActiveX
// Implementation
protected:
~CLatchedSwitchCtrl();
// Message maps
//{{AFX_MSG(CLatchedSwitchCtrl)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Dispatch maps
//{{AFX_DISPATCH(CLatchedSwitchCtrl)
BOOL m_sollwertDirekt;
afx_msg void OnSollwertDirektChanged();
afx_msg LPPICTUREDISP GetSwitchOn();
afx_msg void SetSwitchOn(LPPICTUREDISP newValue);
afx_msg LPPICTUREDISP GetSwitchOff();
afx_msg void SetSwitchOff(LPPICTUREDISP newValue);
afx_msg LPPICTUREDISP GetLatchedOn();
afx_msg void SetLatchedOn(LPPICTUREDISP newValue);
afx_msg LPPICTUREDISP GetLatchedOff();
afx_msg void SetLatchedOff(LPPICTUREDISP newValue);
afx_msg short CanUseVariables();
afx_msg short VariableTypes();
afx_msg short MaxVariables();
afx_msg BOOL zenonInit(LPDISPATCH dispElement);
15 | 73
ActiveX
DECLARE_DISPATCH_MAP()
// Event maps
//{{AFX_EVENT(CLatchedSwitchCtrl)
//}}AFX_EVENT
DECLARE_EVENT_MAP()
CString szVariable[2];
IElement m_dElement;
IVariable m_dLatchVar, m_dSwitchVar;
enum {
//{{AFX_DISP_ID(CLatchedSwitchCtrl)
dispidSollwertDirekt = 1L,
dispidSwitchOn = 2L,
dispidSwitchOff = 3L,
dispidLatchedOn = 4L,
dispidLatchedOff = 5L,
dispidCanUseVariables = 6L,
16 | 73
ActiveX
dispidVariableTypes = 7L,
dispidMaxVariables = 8L,
dispidZenOnInit = 9L,
dispidZenOnExit = 10L,
//}}AFX_DISP_ID
};
};
4.2.3 Methods
The following methods are used:
CanUseVariables (on page 17)
VariableTypes (on page 17)
MaxVariables (on page 18)
zenonInit (on page 18)
zenonExit (on page 19)
4.2.3.1 CanUseVariables
This method returns 1, so zenon variables can be used.
short CLatchedSwitchCtrl::CanUseVariables()
{
return 1;
}
4.2.3.2 VariableTypes
The control only can work with bit variables, so 0x0004 is returned.
short CLatchedSwitchCtrl::VariableTypes()
{
17 | 73
ActiveX
4.2.3.3 MaxVariables
Two variables can be used. Therfore 2 is returned.
short CLatchedSwitchCtrl::MaxVariables()
{
return 2; // 2 variables
}
4.2.3.4 zenonInit
This method gets the Dispatchdriver of the variables via the Dispatchpointer of the dynamic element.
With this Pointer the variable values are read and written when clicking and drawing the control.
m_dElement = IElement(dispElement);
Element.m_lpDispatch->AddRef();
if (m_dElement.GetCountVariable() >= 2)
short iIndex = 0;
m_dSwitchVar = IVariable(m_dElement.ItemVariable(COleVariant(iIndex)));
m_dLatchVar = IVariable(m_dElement.ItemVariable(COleVariant(++iIndex)));
return TRUE;
18 | 73
ActiveX
Information
Element.m_lpDispatch->AddRef();
Objects that are not used are automatically deleted from the memory. This must
be carried out by the programming. The programmer determines whether an
object - based on a reference counter - can be removed.
COM uses the IUnknow methods AddRef and Release to administer the
number of references of interfaces to an object.
In this case, each AddRef and each Release substitute call up a central
implementation to the object. A Release then unlocks the complete object if the
reference counter has reached zero.
4.2.3.5 zenonExit
This method releases the dispatch driver.
BOOL CLatchedSwitchCtrl::zenonExit()
{
m_dElement.ReleaseDispatch();
m_dSwitchVar.ReleaseDispatch();
m_dLatchVar.ReleaseDispatch();
return TRUE;
}
19 | 73
ActiveX
If m_iSollwertDirekt is 0, a dialog for the selection of the set value is opened, otherwise the current
value of the switching variable is inverted.
If the locking variable has the value 1, only a MessageBeep is executed. No value can be set via the
control.
void CLatchedSwitchCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rcBounds;
GetWindowRect(&rcBounds);
COleVariant coleValue((BYTE)TRUE);
BOOL bLatch = (BOOL)VariantToDouble((LPVARIANT)&m_dLatchVar.GetValue());
BOOL bSwitch = (BOOL)VariantToDouble((LPVARIANT)&m_dSwitchVar.GetValue());
if (bLatch) // Locked!!!
MessageBeep(MB_ICONEXCLAMATION);
else
{
if (m_sollwertDirekt)
{
bSwitch = !bSwitch;
}
else
{
CSollwertDlg dlg;
dlg.m_iSollwert = bSwitch ? 1 : 0;
if (dlg.DoModal() == IDOK)
{
20 | 73
ActiveX
if (dlg.m_iSollwert == 2) // Toggle
bSwitch = !bSwitch;
else
bSwitch = (BOOL)dlg.m_iSollwert;
}
}
coleValue = (double)bSwitch;
m_dSwitchVar.SetValue(coleValue);
}
COleControl::OnLButtonDown(nFlags, point);
}
4.2.4.2 Drawing
On drawing the control the values of the variables are read via their dispatch drivers, and accordingly
one of the four defined graphics is displayed. When the value of a variable changes, the control is
updated by the OnDraw routine.
void CLatchedSwitchCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!m_dElement)
{
vRes = m_dSwitchVar.GetValue();
bVal1 = (BOOL)VariantToDouble(&vRes);
}
21 | 73
ActiveX
vRes = m_dLatchVar.GetValue();
bVal1 = (BOOL)VariantToDouble(&vRes);
}
For our control theses are the classes IElement and IVariable. They are defined in zenrt32.h and
zenrt32.cpp.
4.3.1 Interface
The control CD_SliderCtrl has the following dispatch interface:
22 | 73
ActiveX
[ uuid(5CD1B01D-015E-11D4-A1DF-080009FD837F),
helpstring(Dispatch interface for CD_SliderCtrl Control), hidden
]
dispinterface _DCD_SliderCtrl
{
properties: //*** Properties of the controls
4.3.2 Control
Implementing the control is done with the class CD_SliderCtrlCtrl. This class has a standard Windows
CSliderCtrl as a member, with which the control is subclassed. The interfaces IVaribale and IElement
contain zenon interfaces which had to be integrated. These are deduced from COleDispatchDriver.
class CCD_SliderCtrlCtrl : public COleControl
{
DECLARE_DYNCREATE(CCD_SliderCtrlCtrl)
private: //*** member variables
BOOL m_bInitialized;
BOOL m_bShowVertical;
BOOL m_bTicksBoth;
long m_nRangeStart;
long m_nRangeEnd;
long m_nTickOrientation;
IVariable m_interfaceVariable;
23 | 73
ActiveX
IElement m_interfaceElement;
CSliderCtrl m_wndSliderCtrl;
public:
CCD_SliderCtrlCtrl();
//{{AFX_VIRTUAL(CCD_SliderCtrlCtrl)
public:
virtual void OnDraw (CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void DoPropExchange (CPropExchange* pPX);
virtual void OnResetState ();
//}}AFX_VIRTUAL
protected:
~CCD_SliderCtrlCtrl();
//*** methods for the conversion from variant
double VariantToDouble(const VARIANT FAR *vValue);
//{{AFX_MSG(CCD_SliderCtrlCtrl)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void HScroll(UINT nSBCode, UINT nPos);
afx_msg void HScroll(UINT nSBCode, UINT nPos);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
24 | 73
ActiveX
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
//{{AFX_DISPATCH(CCD_SliderCtrlCtrl)
afx_msg BOOL GetTickOnBothSides();
afx_msg void SetTickOnBothSides (short nNewValue);
afx_msg BOOL GetShowVertical();
afx_msg void SetShowVertical(BOOL bNewValue);
afx_msg short GetTickOrientation();
afx_msg void SetTickOrientation (short nNewValue);
afx_msg BOOL zenonInit(LPDISPATCH pElementInterface);
afx_msg BOOL zenonExit();
afx_msg short VariableTypes();
afx_msg short CanUseVariables();
afx_msg short MaxVariables();
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
//{{AFX_EVENT(CCD_SliderCtrlCtrl)
//}}AFX_EVENT
DECLARE_EVENT_MAP()
public:
enum {
//{{AFX_DISP_ID(CCD_SliderCtrlCtrl)
dispidShowVertical = 1L,
dispidTicksOnBothSides = 2L,
dispidTickOrientation = 3L,
dispidZenOnInit = 4L,
dispidZenOnExit = 5L,
dispidVariableTypes = 6L,
dispidCanUseVariables = 7L,
dispidMaxVariables = 8L,
//}}AFX_DISP_ID
};
25 | 73
ActiveX
};
4.3.3 Methods
The following methods are used:
CanUseVariables (on page 26)
VariableTypes (on page 26)
MaxVariables (on page 27)
zenonInit (on page 27)
zenonExit (on page 28)
4.3.3.1 CanUseVariables
This method returns 1 so zenon variables can be used.
short CCD_SliderCtrlCtrl::CanUseVariables()
{
return 1;
}
4.3.3.2 VariableTypes
The control can work with word, byte, doubleword and float variables. You will find a list of the possible
data types in the general description (on page 9) of this method.
short CCD_SliderCtrlCtrl::VariableTypes()
{
0x0002 | // Byte
0x0008 | // D-Word
0x0010 | // Float
0x0020; // D-Float
}
26 | 73
ActiveX
4.3.3.3 MaxVariables
Only one variable can be linked to this control.
short CCD_SliderCtrlCtrl::MaxVariables()
{
return 1; // 1 variables
}
4.3.3.4 zenonInit
The parameter dispElement contains the interface for the dynamic element. With this element the
linked zenon variable determined. If it is valid, the area of the SlideCtrl is set. Additionally the settings for
the display (number of ticks, …) are set. If no variable is linked, the display range is set to 0 to 0. Thus the
SliderCtrl cannot be changed. The variable m_bInitialized defines that values can be set from now on.
BOOL CCD_SliderCtrlCtrl::zenonInit(LPDISPATCH dispElement)
{
//*** Determine the variable using the zenon element
m_interfaceElement = IElement(pElementInterface);
if (m_interfaceElement.GetCountVariable() > 0) {
short nIndex = 0;
m_interfaceVariable = IVariable
(m_interfaceElement.ItemVariable(COleVariant(nIndex)));
}
27 | 73
ActiveX
m_wndSliderCtrl.SetRange(0,0,TRUE);
return FALSE;
}
m_bInitialized = TRUE;
return TRUE;
}
4.3.3.5 zenonExit
In this method the zenon interfaces are released again.
BOOL CCD_SliderCtrlCtrl::zenonExit()
{
m_interfaceElement.ReleaseDispatch();
m_interfaceVariable.ReleaseDispatch();
return TRUE;
}
4.3.4.1 Drawing
With DoSuperclassPaint the SliderCtrl is drawn (as is is a subclassed control). If at the moment of
drawing the slider is moved, the variable m_bInitialized gets the value FALSE. This makes sure that the
value can be changed. Normally the value of the variable is read and displayed with the method SetPos
of the SliderCtrl.
void CCD_SliderCtrlCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
COleVariant cValue(m_interfaceVariable.GetValue());
int nValue = (int) VariantToDouble(&cValue.Detach());
m_wndSliderCtrl.SetPos(nValue);
}
}
28 | 73
ActiveX
A value is sent to the hardware, when the slider is moved. In the methods Hscroll or Vscroll the value is
sent to the hardware (depending if it is a horizontal or a vertical slider).
void CCD_SliderCtrlCtrl::HScroll(UINT nSBCode, UINT nPos)
{
switch (nSBCode) {
case TB_LINEUP:
case TB_PAGEUP:
case TB_LINEDOWN:
case TB_PAGEDOWN:
case TB_THUMBTRACK:
case TB_THUMBPOSITION:{
29 | 73
ActiveX
For our control theses are the classes IElement and IVariable. They are defined in zenrt32.h and
zenrt32.cpp.
Attention
When using zenon COM objects with self-created user controls or external
applications, they must be enabled using the Marshal.ReleaseComObject
method. Enabling by means of the Marshal.FinalReleaseComObject method
must not be used, because this leads to a malfunction of zenon Add-ins.
Information
The screenshots for this theme are only available in English.
30 | 73
ActiveX
1. Start Visual Studio 2008 and create a new Windows Form Control Library project:
31 | 73
ActiveX
3. Open the Control Designer and add the desired control; in our case a text box:
4. Normally controls have properties. Open the Code Designer via View Code and ass the desired
properties which should be available externally.
In our example: Externally visible property „UserText" with get and set access which contains the
text of the text box:
32 | 73
ActiveX
The Windows Forms Control can now be used in other Windows Forms projects.
Important: The control must be inserted manually in the control tool box via Choose Items.
33 | 73
ActiveX
1. Open the project and activate property Register for COM interop in the Build settings:
34 | 73
ActiveX
[assembly: ClassInterface(ClassInterfaceType.AutoDual)]
3. Open the code designer via View Code and add the necessary ActiveX attributes and using
entries. Via menu Tools/Create GUID create a new GUID for the GUID attribute:
35 | 73
ActiveX
4. For the control to be selectable as Active X user interface control, you must add the functions
to the following control classes:
RegisterClass
UnregisterClass
36 | 73
ActiveX
7. Add the extended Windows Form Control as ActiveX control to the zenon Editor:
37 | 73
ActiveX
2. Assign his macro to the ActiveX control via properties VBA macros/Init of the ActiveX element.
NECESSARY METHODS
public bool zenOnInit (on page 40) (Is called up during control initializing in the zenon
Runtime.)
public bool zenOnInitED (on page 40) (Is used in the Editor.)
public bool zenOnExit() (on page 41) (Is called up during control destruction in the zenon
Runtime.)
public bool zenOnExitED() (on page 41) (Is used in the Editor.)
public short CanUseVariables() (on page 41) (Supports linking variables.)
38 | 73
ActiveX
public short VariableTypes() (on page 41) (Supported data types by the control)
public MaxVariables() (on page 42)(Maximum number of variables which can be linked to the
control.)
ADD REFERENCE
1. Select in Microsoft Visual Studio under Add References the zenon Runtime object library in
order to be able to access the zenon API in the control.
2. Add the enhanced functions in the class code of the control in order to access the whole zenon
API.
39 | 73
ActiveX
In our example the COM object of a zenon variable is temporarily saved in a Member in order
to access it later in the Paint event of the control.
You can configure the sequence of the sent variables in the Enter Element dialog with the buttons down
or up. The dialog "element input" opens if:
you double click the ActiveX element or
select Properties in the context menu or
select the ActiveX settings property in the Representation node of the property window
40 | 73
ActiveX
41 | 73
.NET user controls
1: Multi-select is disabled in the variable list. A warning is displayed when several variables are selected
anyway.
You can find information about .NET controls in ActiveX in manual Screens in chapter .NET controls.
Attention
When using zenon COM objects with self-created user controls or external
applications, they must be enabled using the Marshal.ReleaseComObject
method. Enabling by means of the Marshal.FinalReleaseComObject method
must not be used, because this leads to a malfunction of zenon Add-ins.
Above all the differences between container control and ActiveX control are:
CD_DotNetControlContainer control ActiveX control
Does not have to be registered at Must be registered as Active X at the
the computer. computer (regsrv32).
For changes at the controller only For changes at the controller the TLB must
the DLL must be changed. be registered again.
Access via VBA and VSTA only Easy access via VBA and VSTA.
42 | 73
.NET user controls
5.2.1 General
The CD_DotNetControlContainer therefore acts as a wrapper between the user control and the zenon
ActiveX element. All methods used in the following example and all public methods and properties are
passed on via the CD_DotNetControlContainer from the user control to the ActiveX and can be used by
zenon; also in VBA and VSTA.
If there is a reference to the zenon programming interface in the user control, you can directly access
>CD_PRODUCTNAME< objects.
43 | 73
.NET user controls
Ensure that the same path is used on all computers in the zenon network for Editor and Runtime.
Hint: Select an absolute path, for example: C:\Controls. Enter the path as fixed in Remote-Transport and
in the .NET Control Container. Use Remote-Transport to harmonize this path with all computers.
You can configure the sequence of the sent variables in the Enter Element dialog with the buttons down
or up. The dialog "element input" opens if:
you double click the ActiveX element or
select Properties in the context menu or
select the ActiveX settings property in the Representation node of the property window
44 | 73
.NET user controls
1: Multi-select is disabled in the variable list. A warning is displayed when several variables are selected
anyway.
An additional function should automatically detect the change of value of the variable in zenon and
display the new value automatically in the control.
Information
The screenshots for this theme are only available in English.
WORK STEPS
1. First you create a new project in VS and use project type „Windows Forms Control Library“
45 | 73
.NET user controls
3. In the next step you create the user control. For this use two text boxes one each for the input
and the output and a button for writing new values to the zenon variable.
Name:
the first text box "txtGetZenonVariable"
the second text box "txtSetZenonVariable"
the button "btnSetZenonVariable"
46 | 73
.NET user controls
After that the "zenOn" reference should be visible in the reference list.
5. In the next step create a global variable of type zenon.variable in the code of the
zenon_CD_DotNetControlContainer.cs:
47 | 73
.NET user controls
In the following methods we define whether <CD_PRODUTCNAME> variables and data types
are used and how many variables may be handed over:
7. In the next step define in the Click-Event of button btnSetZenonVariable that when you click the
button the value of text box txtSetZenonVariable is written to the zenon variable and then the
content of the text box is deleted.
8. To react to a value change of the variable, you need the Paint Event of the control. The Paint
Event is also triggered if the value of the initialized zenon variable changes and it can therefore
be used to update values. As variables which are referenced in the zenon ActiveX element are
automatically advised, you can generally refrain from using the zenon.OnlineVariable container
in the control.
48 | 73
.NET user controls
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using zenOn;
namespace zenon_CD_DotNetControlContainer
public zenon_CD_DotNetControlContainer()
InitializeComponent();
/// <summary>
/// This public Method will be called by the initialization of the control during
/// </summary>
/// <returns></returns>
49 | 73
.NET user controls
//Control
if (dispElement.CountVariable > 0)
try
m_cVal = dispElement.ItemVariable(0);
catch { }
return true;
// <summary>
/// This public Method will be called by the release of the control during
/// </summary>
/// <returns></returns>
try
if (m_cVal != null)
50 | 73
.NET user controls
System.Runtime.InteropServices.Marshal.ReleaseComObject(m_cVal);
m_cVal = null;
catch { }
return true;
/// <summary>
/// </summary>
/// <returns></returns>
/// <summary>
/// </summary>
/// <returns></returns>
/// <summary>
51 | 73
.NET user controls
/// </summary>
/// <returns></returns>
/// <summary>
/// This will be triggered by clicking the Button. The new Value will
/// </summary>
m_cVal.set_Value(0,txtSetZenonVariable.Text.ToString());
this.txtSetZenonVariable.Text = string.Empty;
/// <summary>
/// This will be triggered by painting the User Control or the Value of the Variable changed.
/// After the value of the Variable changed the Control will be new painted and the new Value
/// </summary>
if (m_cVal != null)
52 | 73
.NET user controls
this.txtGetZenonVariable.Text = m_cVal.get_Value(0).ToString();
return;
else
return;
CREATE RELEASE
AT last create a Release in order to integrate the completed DLL in zenon or in the
CD_DotNetControlContainer.
For this it is necessary that you switch from Debug to Release in the settings.
53 | 73
.NET user controls
1. Create an internal variable of type String and set the string length to 30.
2. In the zenon project node Project/Files/Others add the DLL of the created .NET user controls.
Here, the file is copied to the Additional file at file system level.
3.
The DLL is located in the Visual Studio Project output folder under
...\bin\Release\zenon_CD_DotNetControlContainer.dll.
4. In the project select the ActiveX element and drag it in a zenon screen.
The dialog Configuration is opened
Select the CD_DotNetControlContainer.Container control.
54 | 73
.NET user controls
Click on button Load in order to select the path of the project folder, for example:
C:\ProgramData\COPA-DATA\SQL\9888419d-251e-4595-b396-9be42367997c\FILES\zenon\
custom\additional\zenon_CD_DotNetControlContainer.dll
Note: Controls should always be saved in the project's Additional folder. They are thus taken
into account during backups and transfers. In doing so, the path is to be defined as relatively
close to the save location. Alternatively, you can, for Path, use the Absolute option; however, in
doing so, it must be ensured that there is the same directory structure on the target system.
55 | 73
.NET user controls
6. In the last step link a variable with the control via button Variables.
The variable selected first is automatically linked with our globally defined variable (.NET
UserControl) via public method zenonInit. The linking with the control is carried out after the
Runtime start.
56 | 73
.NET user controls
If you enter a value in the second text box and then confirm it with button Set zenon variable,
the value is written to the zenon variable. (The btnSetZenonVariable_Click event is carried out.)
57 | 73
.NET user controls
the value is directly written in the first text box via the Paint event of the .NET control.
2. Enhance the code by a property (Information) and add the properties get and set to the
property. They allow you to read and write the text of the label.
3. Create a new release for our user control and copy it to folder additional of the zenon project.
Do not forget: zenon Editor must be closed before you do this!
58 | 73
.NET user controls
Delete the old DLL and restart the zenon Editor. If the DLL is still in the folder, just delete it a
second time. Now you can import the changed DLL. The CD_DotNetContainerControl and the
ActiveX are updated automatically.
4. In the zenon Editor click on the ActiveX and open the property window.
Now you can see the new property Information in the selection window of the control and
you can also set a value.
59 | 73
.NET user controls
5. In order to able to work with the CD_DotNetControlContainer in VSTA or VBA, you first need
the reference to the control. After VSTA has been opened for the project (ProjectAddin), you
must add the reference of the CD_DotNetControlContainer.
6. With the following code you can set the value of our property Information anew.
7. Finally:
create a new zenon function Execute VSTA macro
link the function to a button
In the Runtime the label is changed from myInformation to New Information by clicking on the
button.
60 | 73
.NET user controls
Attention
When using zenon COM objects with self-created user controls or external
applications, they must be enabled using the Marshal.ReleaseComObject
method. Enabling by means of the Marshal.FinalReleaseComObject method
must not be used, because this leads to a malfunction of zenon Add-ins.
Information
The screenshots for this theme are only available in English.
61 | 73
.NET user controls
1. Start Visual Studio 2008 and create a new Windows Form Control Library project:
62 | 73
.NET user controls
3. Open the Control Designer and add the desired control; in our case a text box:
4. Normally controls have properties. Open the Code Designer via View Code and ass the desired
properties which should be available externally.
In our example: Externally visible property „UserText" with get and set access which contains the
text of the text box:
63 | 73
.NET user controls
The Windows Forms Control can now be used in other Windows Forms projects.
Important: The control must be inserted manually in the control tool box via Choose Items.
64 | 73
.NET user controls
1. Open the project and activate property Register for COM interop in the Build settings:
65 | 73
.NET user controls
[assembly: ClassInterface(ClassInterfaceType.AutoDual)]
3. Open the code designer via View Code and add the necessary ActiveX attributes and using
entries. Via menu Tools/Create GUID create a new GUID for the GUID attribute:
66 | 73
.NET user controls
4. For the control to be selectable as Active X user interface control, you must add the functions
to the following control classes:
RegisterClass
UnregisterClass
67 | 73
.NET user controls
7. Add the extended Windows Form Control as ActiveX control to the zenon Editor:
68 | 73
.NET user controls
2. Assign his macro to the ActiveX control via properties VBA macros/Init of the ActiveX element.
NECESSARY METHODS
public bool zenOnInit (on page 40) (Is called up during control initializing in the zenon
Runtime.)
public bool zenOnInitED (on page 40) (Is used in the Editor.)
public bool zenOnExit() (on page 41) (Is called up during control destruction in the zenon
Runtime.)
public bool zenOnExitED() (on page 41) (Is used in the Editor.)
public short CanUseVariables() (on page 41) (Supports linking variables.)
69 | 73
.NET user controls
public short VariableTypes() (on page 41) (Supported data types by the control)
public MaxVariables() (on page 42)(Maximum number of variables which can be linked to the
control.)
ADD REFERENCE
1. Select in Microsoft Visual Studio under Add References the zenon Runtime object library in
order to be able to access the zenon API in the control.
2. Add the enhanced functions in the class code of the control in order to access the whole zenon
API.
70 | 73
.NET user controls
In our example the COM object of a zenon variable is temporarily saved in a Member in order
to access it later in the Paint event of the control.
You can configure the sequence of the sent variables in the Enter Element dialog with the buttons down
or up. The dialog "element input" opens if:
you double click the ActiveX element or
select Properties in the context menu or
select the ActiveX settings property in the Representation node of the property window
71 | 73
.NET user controls
72 | 73
WPF
1: Multi-select is disabled in the variable list. A warning is displayed when several variables are selected
anyway.
6 WPF
With the WPF dynamic element, valid WPF/XAML files in zenon can be integrated and displayed.
You can find extensive documentation about WPF elements in zenon and tutorials for designers,
developers and people configuring projects in the zenon WPF element manual.
73 | 73