0% found this document useful (0 votes)
218 views

Q3876 Common Questions About ActiveX Controls in CitectSCADA

The document discusses common questions about using ActiveX controls in CitectSCADA. It addresses issues such as controls not working between versions, having to reinsert controls when making minor changes, setting array properties, receiving hardware alarms when going to ActiveX pages, and more.

Uploaded by

desrico20039088
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
218 views

Q3876 Common Questions About ActiveX Controls in CitectSCADA

The document discusses common questions about using ActiveX controls in CitectSCADA. It addresses issues such as controls not working between versions, having to reinsert controls when making minor changes, setting array properties, receiving hardware alarms when going to ActiveX pages, and more.

Uploaded by

desrico20039088
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Q3876 Common Questions about ActiveX Controls ArticleID: Q3876

in CitectSCADA Created: 4/06/2004


Last Updated: 1/02/2008
Suggested By: Jackie Lang

Applies To:
CitectSCADA 5.xx
CitectHMI 5.xx

Summary:
What are some of the most common questions about using ActiveX controls in CitectSCADA? 

Solution:
1. Why doesn’t the example in KB article Q3229 sometime work on the customer’s machine?

The Cicode function CreateControlObject() can use the object’s human readable name, its ProgID, or its GUID to create an instance. To keep backward
ProgID and GUID are always the same between different versions. However, the “human readable name” will change when a service patch is applied.
ADO Data Control 6.0 (OLEDB)” will change to “Microsoft ADO Data Control 6.0 (SP4) (OLEDB)” after Service Pack 4 is installed. But its GUID
00A0C922E820}, ProgID – “MSAdodcLib.Adodc.6” remain the same. Therefore, using ProgID or GUID to create an ActiveX control is a better programm

2. Why do I have to reinsert the control each time I make a minor change to the control and rebuild the OCX in VB?

With VB to develop an ActiveX control, you have to maintain "Binary Compatibility" of the control. Otherwise every time you build a new version or reb
create a new GUID for the control. It ends up you have to re­insert the control to the Citect page. Please do the following

1. Go to the VB project properties page.

2. Click on "Component" tab.

3. Select "Binary Compatibility" option.

4. Use "Browse" button to point the control that has been inserted in the containers (In your case, the container is CitectSCADA).

Before  you  rebuild  your  control,  you  have  to  close  Citect  Explorer  and  shut  down  Citect  runtime.  It  is  noted  that  to  keep  binary  compatibility,  do  not 
interfaces (but new public interfaces are allowed). To remove the obsolete ActiveX entries from Registry, please refer to the KB article Q3809.

3. How to avoid reinserting the control if I have to change some interfaces of my control?

There are two ways to insert an ActiveX control on a CitectSCADA page.

1. At design time, use Graphics Builder to insert an ActiveX control on a page. With this method, you will be able to pre­configure all properties (if your c
property page) and set up tag association. The configuration information of an ActiveX control is saved in CTF file. If the ActiveX control interface is mo
saved  with  a  page,  you  may  have  to  re­insert  and  re­configure  it.  Therefore,  you  have  to  document  the  configuration  including  tag  associations  to 
configured correctly each time it is inserted on the page.

2. At runtime, use CreateControlObject(sClass, sName, x1, y1, x2, y2, sEventClass) to create an instance and use _ObjectSetProperty(hObject, sP
properties.  If  you  want  to  associate  CitectSCADA  tags  with  the  control  properties,  use  ObjectAssociatePropertyWithTag  (sObject  sP
sOnChangeEvent). To make them work for you, you have to put all these standard functions into your own function and call it on the "On Page Entry" eve
line  help  for  how  to  use  these  functions.  This  is  a  very  flexible  approach  that  allows  you  to  send  only  two  files  to  your  customer,  OCX  and  Cicode  f
interface is modified. Your customer will simply copy and paste the files, of course the OCX has to be re­registered. The downside of this approach is that
page is a little bit slower opening compared to the pre­configured approach with Graphics Builder.

Note: Currently, the ActiveX configuration is stored in the CTG as a blob of data. It would be good if there was some way to export and import this data
up and restored if the ActiveX object is having problems with a new version. We are seeking a solution to this problem.

4. Why are my associated tags not updated when the values of their corresponding properties are changed?

By default, the tag association is unidirectional. Whenever tag values change, their associated properties will be updated. However, if ActiveX propertie
tags  won’t  be  updated  as  CitectSCADA  doesn’t  know  whether  the  properties  have  changed.  To  have  CitectSCADA  automatically  update  the  asso
properties change, you need to specify an ActiveX event to each tag association.

However, there is a problem with this bi­directional updating. If an associated tag is in the status of “Read Pending”, its write will be ignored. This occurs i
on timing between “read” and “write” queues of associated tags. It is confirmed that there is a problem “Update association on” in “Tag Association” in V
The fix will be included in SPA of V542 and V550.

For now, a workaround could be used to avoid this problem, which is to use an event handler to update tag values in Cicode. For example, you want to
Property “Value1” on Event Click. Instead of using “Update association on” – Click, you should use

FUNCTION PageName_ANXX_Click(This OBJECT)

Integer Value;

Value = _ObjectGetProperty(ObjectByName("ANXX"), "Value1");

Tag1 = Value;

END

5. Why can’t I set an array type property of An ActiveX control in Cicode?

CitectSCADA doesn’t  support  the  array  properties  in  Cicode.  If  you  want  to  use  the  control  has  array  type  properties,  you  have  to  wrap  up  this  cont
interfaces that are supported by Cicode. For example, you are attempting to use the MS Flex grid ActiveX control with CitectSCADA. The ColWidth
array type property. In VB, this property can be set using the syntax MSFlexGrid1.ColWidth(n), where n is the column number (0, 1, 2, etc). To make it
you should do the following.
In VB, the wrapper should have a method, say,

Public Sub SetColWidth(Index As Long, Value As Long)

MSFlexGrid1.ColWidth(Index) = Value

End Sub

In Cicode, you should call this method to set MSFlexGrid1.ColWidth(0) = 100 using

_ObjectCallMethod(ObjectByName("An35"), "SetColWidth", 0, 100);

6. Why can’t I set an array type property of An ActiveX control in CiVBA?

It is confirmed that there is a problem in CiVBA. Take ListBox control of Microsoft Form 2.0 as an example. Set ColumnCount = 3, create a 6x3 array and
from Excel and CitectSCADA are shown in the following figures. The Excel result is correct as expected. However, CiVBA is not functional correctly altho
the three column values.

If you encounter the problem of this kind, you have to wrap up the control in the same way as described in the above article.

Figure 1. Result from Excel VBA

Figure 2. Result from CiVBA

7. Why do I sometime receive hardware alarms when I go to my ActiveX page?

The  most  common  cause  to  this  problem  is  that  the  initialisation  code  for  the  ActiveX  control  is  called  in  “On  page  entry”  event. This  is  the  timing  is
ActiveX control and CitectSCADA. If the initialisation code is called before an instance of the control is created on the page, CitectSCADA will gene
"Unrecognized  object  class  or  properties"  or  '355  ­  Object  has  no  interface  ­  ANXX'.  To  avoid  this  problem,  you  need  to  raise  an  event,  say,  OnSho
(assume the control written in VB). When this event fires, it will guarantee the instance of has been created. On the CitectSCADA side, you need to
default, the Cicode function looks like

FUNCTION PgaeName_ANXX_OnShow(This OBJECT, your event arguments)

Add your initialisation code here……..

………….

END

Otherwise, the user error handling must be implemented in your initialisation Cicode.

In version 6, a new page event is introduced, <On page shown>. This event will be fired after all objects on the page have been instantiated including 
safe to put your initialisation code in this event command field.

8. Why do I receive #COM when I access my ActiveX control page?

The  most  common  cause  to  this  problem  is  the  initialisation  code  for  the  ActiveX.  A  typical  example  is  to  use  ADODB.Connection  to  connect  to  a  r
UserControl_Initialize() in your VB ActiveX control. If it takes a long time to get connected or times out, it will cause #COM. The reason is that 
foreground objects. A long running function call in the  ActiveX control will impact on the CitectSCADA main thread and block everything else. So in th
asynchronised connection option to connect MS SQL server. As the asynchronised connection uses a different thread to the ActiveX control, CitectSC
this long running “task”. To use the asynchronised connection,

1. Declare the connection object with keyword “WithEvents”.

2. Use AsyncConnect option for connection open.

3. Add the code for populating recordset in Event

Connection_ConnectComplete.

If you still want to use synchronised connection, consider to reduce the connection timeout. By default, the property of “ConnectionTimeout” is 15 seconds

9. Why do I receive ODBC errors when I use CiRecipe control with DBF files?

It appears that the ODBC driver for DBF has a problem with releasing Windows resources (Handles). This problem occurs when you frequently open and
the instance of CiRecipe is running. When the page containing CiRecipe control is closed, the control resources should be released on termination. Ho
you start Windows Task Manager and select the “Handle Count” column on the “Process” tab, you will notice that the handle count will increase unde
have to use CiRecipe with DBF files, don’t close the CiRecipe page and just hide it when you navigate to other pages.
This problem may be caused by Borland Database Engine (BDE) when the ODBC driver for dBase is going through BDE. The following registry setting
BDE. This has been tested on Windows XP SP2 and the handle stops leaking.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Xbase]

"BDE"=dword:00000002

10. Why do I need to consider if I use VB6 based ActiveX controls with CitectSCADA?

VB6  is  the  single  thread  programming  language.  CitectSCADA  as  an  ActiveX  container  will  treat  ActiveX  controls  as  foreground  objects.  Thus  a  ru
control will impact on the CitectSCADA main thread. For this reason, it is not recommended that an ActiveX control be running on CitectSCADA
such as trend servers. For example, if you had a control on a Citect trend server that has a long running method, you might experience missing trend sam

When you develop your ActiveX controls using VB6, don’t forget release references in UserControl_Terminate() event. Moreover, you also need to co
events to enhance communication between your control and CitectSCADA. For example, you can raise an event in UserControl_Show() to tell 
window has been added on a page. Once CitectSCADA catches this event, you can call a method to tell your control to change its background colour or 
 
UserControl.Extender.Name is used to identify the Control's current instance, but CitectSCADA doesn’t support the use of this property. So do not use th

11. Why can’t I change my ActiveX control’s font in Cicode?

Before v5.41 Cicode doesn’t support the font object as a property in ActiveX control. The example code given in Cicode in the CitectSCADA help does
is to use CiVBA. This bug has been fixed in V5.51 (MegaWatt).
  

12. Why can't I use tabbed controls in CitectSCADA?

CitectSCADA graphics is based on a single view per page' architecture, and while you can insert tabbed ActiveX controls onto a page in graphics builde
is no way to draw graphics onto the individual tabbed pages themselves.

In order to simulate a tabbed dialog in CitectSCADA, you can draw the graphics as required on a single page in Graphics Builder, group them together
property  of  all  the  objects  in  each  group  using  a  PageGetInt()  call.  Create  buttons  that  look  like  tabs  above  your  graphics  that  will  change  the  valu
appropriate graphics visible and all the rest invisible. The only problem with this is that it will be a bit messy in the Graphics Builder because all the pag
on top of each other.

13. Why can't I change the default identification of an ActiveX control in Graphics Builder with CiVBA?

CitectSCADA allows  the  default  identification  of  an  ActiveX  control  to  be  changed  at  design  time.  But  it  only  works  if  Cicode  is  used  to  refer  the  co
identification mapping is designed for runtime only and any access to ActiveX properties and methods by Cicode is through Cicode functions.

As for CiVBA, it uses the dot extension to access ActiveX properties and methods. Since the identification mapping is not started yet, CitectSCADA
default identification of an ActiveX control and compile errors “Undefined function ……” will be generated.

It is confirmed that there is a problem in CitectSCADA compiler in this regards.

14. How can I generate a Crystal Report on a graphics page?

You can use “Crystal Report Viewer Control” (crviewer.dll) in combination with “Crystal Runtime Application” (craxdrt.dll). Here is the example code that sh
a Crystal report using CiVBA. Note that this example uses version 8.0.0.371 of crviewer.dll that is shipped with Crystal Report 8.

1. Insert “Crystal Report Viewer Control” on a graphics page
2. Add a button on the page
3. In the command field, type
CIVBA

CreateReport "C:\Citect\Data\Reports\OperatorInput.rpt"

4. Save the page as “CRViewer”
5. Add the following code to your project.

Sub CreateReport(Byval sReportTemplate As string)


Dim crpApp As Object
Dim crpReport As Object

    'Clear the source, or “Memory full” error if func called twice
    CRViewer_AN35.ReportSource = crpReport

    'Create an instance of crystal runtime application
    Set crpApp = CreateObject("CrystalRuntime.Application")

    'Open Report Template and create a report object
    Set crpReport = crpApp.OpenReport(sReportTemplate, 1)

    'Discard any saved data
    crpReport.DiscardSavedData

    'Set report source, CRViewer_AN35 is the default instance name
    CRViewer_AN35.ReportSource = crpReport
    CRViewer_AN35.ViewReport
 
    Set crpApp = Nothing
    Set crpReport = Nothing

End Sub

To extend the above functionality, add the following function to your code and a button on the page calling this function. Now you should be able to navig
and display a selected Crystal Report.
FUNCTION OpenCrystalReport()
STRING sFile;
    sFile = FormOpenFile("Open", "*.RPT", "Report Files (*.RPT)|*.RPT|");
    IF FileExist(sFile) THEN
        VbCallRun(VbCallOpen("CreateReport", sFile));
    END
END

Please note that a care must be taken when implementing Crystal Report functionality in CitectSCADA. As the viewer is regarded as a foreground obje
critical CitectSCADA box, such as alarm, trend or IO servers. Do not draw significant data to the Crystal Report viewer, using parameters to limit the repo

To customise the appearance of the Crystal Report Viewer control, please refer to its documentation shipped with Crystal Report package.

15. How can I print out a Crystal Report without user prompt?

In this application, only the “Crystal Runtime Application” (craxdrt.dll) is required in code. Here is the example code that shows you how to do it.

Sub PrintReport(Byval sReportTemplate As string)


Dim crpApp As Object
Dim crpReport As Object
 
    'Create an instance of crystal runtime application
    Set crpApp = CreateObject("CrystalRuntime.Application")
    
    'Open Report Template and create a report object
    Set crpReport = crpApp.OpenReport(sReportTemplate, 1)
    
    'Discard any saved data
    crpReport.DiscardSavedData
 
    'Prints the report to default printer
    'PrintOut([promptUser],[numberOfCopy],[collated],[startPageN], [stopPageN])
    crpReport.PrintOut False, 1, False, 1, 1
 
    Set crpApp = Nothing
    Set crpReport = Nothing
End Sub

The above example is to print the first page of the report on the default printer. Note that if your report has parameters to be provided, you have to implem
property of report object and pass the desired values; otherwise the user prompt for parameter entries will pop up. For details, please refer to the doc
Crystal Report, version 8.0.0.371.

It is also possible to automate report printout using a CitectSCADA event. To do so, you have to call this VB function via a Cicode function as the eve
functions directly. For example, your Cicode function is defined as

FUNCTION PrintCrystalReport()
    VbCallRun(VbCallOpen("PrintReport", "C:\Reports\Inventory.rpt"));
END

Now you can add function “PrintCrystalReport” in the action field in your report trigger event.

16. How can I use the Microsoft Text Voice control in CitectSCADA to convert text to speech?

The “Text Voice” ActiveX control is used to convert text to voice like a “document reader”. It is also very useful in the alarm system with speakers.

The  control  (VText.dll)  is  located  in  C:\Windows\Speech  for  WindowsXP  and  C:\Winnt\Speech  for  Windows2000.  For  Windows  NT,  you  have  to  down
Microsoft website. The example code is given here to show how to implement it in Cicode.

GLOBAL OBJECT goVText;


FUNCTION VTextInit();
STRING sClassID;

    sClassID = "{2398E32F­5C6E­11D1­8C65­0060081841DE}";
    
    //ProgID "Vtext.Vtext.1"
    goVText = CreateObject(sClassID);
END

 
// Function converts text to voice
FUNCTION VTextSpeak(STRING sText);
    _ObjectCallMethod(goVText, "Speak", sText);
END

Add VTextInit  in  the  start  up  code  of  your  project.  As  goVText  is  declared  as  a  global  variable,  the  object  will  remain  in  existence  until  the  variable 
assigned or is set to NullObject.

It is noted that this functionality cannot be implemented in CiVBA as the module variables are not supported in CiVBA.

17. Why can’t I see some properties on the property list for tag association?

This will depend on how attributes of these properties are set up in the ActiveX control. For example, a property can be hidden from Property Browser, b
at runtime. If VB6 is used to develop a control, use Procedure Attributes to enable the “Don’t show in Property Browser” attribute for a selected property.

Some generic properties are deliberately removed from the property list as they are not supported by CitectSCADA, such as “Visible” and “Left”. If you
“Visible” property, you will get a hardware alarm of “invalid parameter”. However, if you use CiVBA to set this property, the error will be logged in the K
“Class does not support Automation or does not support expected interface”. It is noted that Cicode and CiVBA are different code processes and some e
aligned yet.

18. How do I hide, resize and reposition my control at runtime?
The interfaces for resize, visibility and movement of controls are not implemented in CitectSCADA as an ActiveX container. So you cannot use propert
“Visible”, “Width” and “Height” to manipulate its visibility or size.

Graphically, an ActiveX control is treated as a CitectSCADA object. So it is possible to use the object properties to achieve these functionalities. For exa
Properties  ­  “Scaling  (Vertical  /  Horizontal)”,  and  change  its  value  to  resize  the  control.  Similarly  use  a  digital  tag  to  toggle  the  control  visibility,  and  u
Horizontal)” properties to change the control’s location on a page.

The “Movement” properties are equivalent to the control’s “Top” and “Left” properties. The “Scaling” properties are equivalent to the control’s “Width” an
the “Visibility” property is equivalent to the control’s “Visible” property.

See also KB Article Q3899 and Q3900

19. Why can't I ignore optional arguments of an Active control method in Cicode?

CitectSCADA does  not  support  optional  arguments  of  a  method  in  Cicode.  So  you  have  to  provide  each  optional  argument  required  by  a  method  wh
used. Take the ListBox control of Microsoft Form 2.0 as an example. Method AddItem has two arguments and both of them are optional as shown below.

Sub AddItem([pvargItem], [pvargIndex])
Member of MSForms.ListBox

If you use Microsoft Object Browser, it can be seen that any arguments enclosed by [ ] indicate they are optional. Here is an example how to use this m
ListBox is inserted at AN35 on a graphics page and 10 Items are to be added with two leading 0 in the index.

FUNCTION AddItems()
INT Index;
STRING sItemName;
    FOR Index = 0 TO 9 DO
        sItemName = "Item " + Index:#00;
        _ObjectCallMethod(ObjectByName("AN35"), "AddItem", sItemName, Index);
    END
END

The result is shown in the following Figure. Please note that the ListBox index is zero based and must be continuous.

20. Why doesn’t enabling the “Persist ActiveX Data between Page Transitions” option for the MS Forms ListBox control perform the way it imp

There  is  a  misunderstanding  about  the  <Persist ActiveX  Data  between  Page  Transitions>  option  implemented  in  CitectSCADA  V6.  This  option  is
settings  of  an  ActiveX  control  through  public  interfaces  to  a  temporary  data  file  which  will  then  be  reloaded  to  the  ActiveX  control  when  the  page 
persistence of ActiveX control’s data, the control must have public properties and they should be

1. Read / Write.
2. Single value
3. CitectSCADA supported data type

How the control behaviors after the saved properties have been reloaded will depend on the control itself. In the example of ListBox control, the popu
own memory and will be lost after the control is destroyed on page change. If the data is not implemented through property interfaces, CitectSCADA
persist it. However, if the ListBox control is implemented in the way that all of its items are loaded from a data source, such as a file or SQL table, then
could be used to reload the items from the data source on the property change event. In this case, the data of ListBox control will be persisted.

In summary, the <Persist ActiveX Data between Page Transitions> option will only persist data of the properties that meet the above requirement.

21. Why does one of my ActiveX control methods work differently after having upgraded from V5.42 to V6.00?

It appears to be the problem of automation interfaces.

Prior to version 6, we did not check type of parameters passed to an ActiveX control method. So data are always copied back to the passed parameters 
demands for richer and better performing ActiveX controls have meant that this policy has had to be strictly enforced from version 6 onwards, as the perf
relative terms, reasonably large. For these reasons, we do not copy data after the automation call unless the parameter is marked with the [out] in the i
Similarly if marked as [out] but not [in] we do not bother copying data before the automation call.

If your ActiveX  control  is  written  in  VB6,  you  have  to  clearly  define  the  parameter  as  ByRef  in  the  method  of  your  ActiveX  control  if  the  method  m
parameter.  It  is  noted  that  if  you  don’t  declare  the  type,  arguments  or  parameters  in  Visual  Basic  are  ByRef  by  default.  So  if  data  of  parameters  n
parameters must be declared as ByVal.

Keywords:
 

Related Links

Attachments

© Schneider Electric (Australia) Pty Ltd     Disclaimer

You might also like