Screen Script User Manual
Screen Script User Manual
The SCADA screen script has a .NET-based C# class structure. It can also be designed as a VB Script; the examples in this document use C#.
The code within the script is located in a class named MainClass. SCADA tag access, screen events, and operations on objects on the screen can be performed within this structure.
1. Screen Script Structure
The created screen script basically has a standard C# class structure.
C#
public class MainClass
{
public void Main()
{
// Code to be executed when the script starts
}
}
The Main() method is the primary method called by SCADA when starting the script. If no operation is required inside, it can be left empty, but since it is a part of SCADA’s script structure, it must not be deleted.
Event methods on the screen are generated by SCADA. The names or signatures of the event methods should not be changed, and the methods should not be deleted.
Events on the screen are defined in separate methods:
C#
public void Button_0_MouseDown(Object sender, EventArgs e)
{
// Code to run when the button is clicked
}
2. Required Libraries
The basic libraries used when working with screen objects are as follows:
C#
using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using Microsoft.CSharp;
using System.Drawing;
using System.Windows.Forms;
- System.Windows.Forms: Used for objects like Form, Button, CheckBox, Panel, Control, etc.
- System.Drawing: Used for visual properties like Color, Point, Size.
For example:
C#
Button_1.BackColor = Color.Green;
3. Object Types and Casting
When accessing objects on the screen, it is important to use the object in the correct C# type.
The base class for objects in Windows Forms is the Control class. Some SCADA-specific screen objects can also be accessed via the Control type.
Common properties can be accessed through an object defined as Control:
C#
Control TargetControl;
TargetControl.Width = 100;
TargetControl.Visible = true;
TargetControl.Enabled = false;
However, if object-specific properties or methods are to be accessed, the object must be cast to its actual type. For example:
C#
Button Button_0 = ScreenForm.Controls["Button_0"] as Button;
if (Button_0 != null)
{
Button_0.Text = "New Text";
Button_0.BackColor = Color.Green;
}
The as Button expression here casts the object to the Button type. If the cast fails, it returns null. Therefore, it is recommended to perform a null check before use.
4. Object Access Methods
The method of accessing objects varies depending on the object’s location on the screen and its intended use within the event.
Method 1: Direct via Form (Controls)
Used if a control is added directly to the main Form.
C#
public void Screen_Load(Object sender, EventArgs e)
{
Form ScreenForm = sender as Form;
Button Button_0 = ScreenForm.Controls["Button_0"] as Button;
if (Button_0 != null)
{
Button_0.Text = "New Text";
}
}
Warning: ScreenForm.Controls[“Button_0”] only works if Button_0 is located directly under ScreenForm.
For example:
ScreenForm
├── Button_0
└── Panel_0
In this structure, Button_0 can be found.
However:
ScreenForm
└── Panel_0
└── Button_0
In this structure, Button_0 cannot be found using ScreenForm.Controls[“Button_0”].
Method 2: Access via Container (Panel)
If an object is inside another control like a Panel, you can first access the container, then the target object.
For example:
ScreenForm
└── Panel_0
└── Button_0
C#
Control Panel_0 = ScreenForm.Controls["Panel_0"];
if (Panel_0 != null)
{
Button Button_0 = Panel_0.Controls["Button_0"] as Button;
if (Button_0 != null)
{
Button_0.Text = "New Text";
}
}
In this method, the container in which the object is located is known.
Method 3: Access via sender
When an event is triggered, the sender parameter represents the object itself that triggered the event.
C#
public void Button_0_MouseDown(Object sender, EventArgs e)
{
Control triggeredControl = (Control)sender;
// The triggeredControl variable represents
// the Button_0 object that triggered the event.
}
This method eliminates the need to access the triggering object again via Controls.
Method 4: Reaching the Main Form with FindForm()
Within an event, the FindForm() method can be used on the triggering object to reach the main Form it is located in.
C#
public void Button_1_MouseDown(Object sender, EventArgs e)
{
Control clickedButton = (Control)sender;
Form mainForm = clickedButton.FindForm();
if (mainForm != null)
{
mainForm.BackColor = Color.LightBlue;
}
}
FindForm() is especially useful when the object is located inside one or more containers.
For example:
ScreenForm
└── Panel_0
└── Panel_1
└── Button_0
Over Button_0 in this structure:
C#
Form ScreenForm = Button_0.FindForm();
the main Form can be reached.
Method 5: Deep Search with Controls.Find()
If the container of an object on the screen is unknown or if a search needs to be performed within child controls as well, Controls.Find() can be used.
Setting the second parameter to true ensures that the search is also performed within child controls.
C#
Control[] FoundControls = ScreenForm.Controls.Find("Button_0", true);
Button TargetControl = FoundControls.Length > 0 ? FoundControls[0] as Button : null;
if (TargetControl != null)
{
TargetControl.Text = "New Text";
}
For example:
ScreenForm
├── Panel_0
│ └── Button_0
└── Panel_1
└── Button_1
In this structure:
C#
ScreenForm.Controls.Find("Button_0", true);
Button_0 inside Panel_0 can be found by using this method.
Find() Result
Controls.Find() returns a Control[] array. Therefore, before using the object:
C#
FoundControls.Length > 0
a check must be performed.
Additionally, if there are multiple controls with the same name, multiple results may be returned. FoundControls[0] represents only the first found object. For this reason, it is recommended that control names on the screen be as unique as possible.
5. Comprehensive Example: Accessing a Button from Another Button
In the following example, when Button_0 is clicked, Button_1 at any level of the screen (including panels) is searched for and its color is changed.
C#
public void Button_0_MouseDown(Object sender, EventArgs e)
{
Control triggeredControl = (Control)sender;
Form mainForm = triggeredControl.FindForm();
if (mainForm != null)
{
Control[] foundControls = mainForm.Controls.Find("Button_1", true);
if (foundControls.Length > 0)
{
Button Button_1 = foundControls[0] as Button;
if (Button_1 != null)
{
Button_1.BackColor = Color.Green;
}
}
}
}
General execution order of this structure:
Event
↓
Get the triggering control via sender
↓
Reach the main Form via FindForm()
↓
Search for the target object via Controls.Find()
↓
Cast the found object to its actual type
↓
Use the object’s property or method
6. SCADA Tag Access
SCADA tags can be accessed in two basic ways.
1. Defining as a Field
Tags can be defined as fields within the class.
C#
public BOOL Beep;
In this method, tag values are read before the script runs, and the changed values are written back to the SCADA system after the script completes.
2. Dynamic Read/Write (TagRead and TagSet)
Tag values can be read or written dynamically while the script is running.
Reading:
C#
INT Value = (INT)TagRead("Tag_0");
If the tag specified with TagRead() is not found, it may return null. The returned value must be compatible with the expected data type.
Writing:
C#
BOOL Result = TagSet("Tag_0", 123);
Whether the TagSet() operation is successful can be checked via the returned result.
C#
if (Result)
{
// Tag writing operation successful
}
Warning: Ensure that the tag name is correct and the data type used is compatible with the tag.
7. Global and Local Variable Usage
If an object is to be used in multiple events, it can be defined as a field at the class level:
C#
public class MainClass
{
Form ScreenForm;
Button Button_0;
Control AlarmView_1;
}
These objects can be used from different event methods.
If an object is to be used in only a single event, it is sufficient to define it as a local variable within the method:
C#
public void Button_0_MouseDown(Object sender, EventArgs e)
{
Control triggeredControl = (Control)sender;
// Only used within this event.
}
8. Summary and Rules Table
| Condition / Topic | Recommended Usage / Rule |
| Object is directly on the Form | ScreenForm.Controls[“Button_0”] |
| Object is inside a specific Panel | Panel_0.Controls[“Button_0”] |
| Accessing the object that triggered the event | (Control)sender |
| Accessing the Main Form | .FindForm() via the sender object |
| Object location is unknown | Controls.Find(“ObjectName”, true) |
| Searching within child controls | Controls.Find(“ObjectName”, true) |
| Find() result | A Length > 0 check must be made first. |
| Multiple results | FoundControls[0] is only the first found object. It is recommended that control names be unique. |
| Casting | The object must be cast to its actual type to access its specific properties. |
| Use of ‘as’ | If the cast fails, it returns null; it must be checked before use. |
| SCADA specific objects | The Control type can be used for general properties. Casting to the appropriate type should be done for specific properties. |
| Global / Local variable | Objects to be used in multiple events can be defined as class-level fields, while objects used in a single event can be defined locally. |
| Event Methods | Event names and signatures created by SCADA should not be changed or deleted. |
| Tag access | The tag name and the data type used must be correct. TagRead and TagSet results should be checked appropriately. |
