Problem Statement
HMI screens in TIA Portal WinCC expose a rich Open event model (OnOpen, OnActivate, OnLoaded) but lack a symmetric, first-class Close event. When an operator navigates away from a faceplate, pop-up, or sub-screen, there is no built-in OnClose callback in which the programmer can execute cleanup logic such as resetting a "screen-active" bit, flushing a buffer tag, or releasing a held alarm acknowledgement.
This is a recurring requirement for symmetric bit handling: set a status bit when the screen opens, clear it when the screen closes. The most robust, documented solution in WinCC Comfort, WinCC Professional, and WinCC Runtime Advanced is to host the screen in a Picture Window object and bind logic to its Display property event. Several alternative approaches exist (direct connection, global script with ActiveScreen, Win32 API handle lookup) and each is detailed below with parameter tables, VBScript examples, and commissioning steps.
Prerequisites
- Siemens TIA Portal V15.1 or later (V16, V17, V18, V19 also supported). Earlier V13/V14 projects can use the same procedure.
- WinCC Comfort, WinCC Advanced, or WinCC Professional runtime license.
- A target HMI device configured in the project tree (HMI_1 / KTP / Comfort Panel / IPC).
- A boolean PLC tag or internal HMI tag to act as the screen-active marker, for example
HMI_Tag_ScreenActiveof typeBool. - For VBScript methods: the runtime scripting environment enabled (default in Comfort/Professional; check HMI device → Runtime settings → Services → VBScript).
- For Win32 API methods: administrative access to the engineering station for testing; runtime panels do not expose Win32 handles.
ScreenActive. Substitute your project-specific tag name where shown. Tag addresses in the examples use symbolic naming; physical addresses (e.g. %DB101.DBX0.0) can be substituted if direct symbolic binding is not used.Architecture: Screen Lifecycle in WinCC Runtime
Before implementing a close-trigger, it helps to model the screen lifecycle as a state machine. Every WinCC screen object in the runtime exposes four observable lifecycle transitions:
- Loaded — the screen object is instantiated in memory.
-
Opened / Activated — the screen is the active picture;
OnActivatefires. - Deactivated — the operator navigates to a sibling screen; the object remains instantiated.
- Closed / Unloaded — the object is removed from memory (pop-ups, dynamically loaded screens, picture windows that switch source picture).
The Picture Window is special because it owns its own Display property — a boolean that toggles between 1 (visible) and 0 (hidden). This single property is the canonical hook for any logic that needs to fire on visibility change, and it is the recommended solution because it does not depend on screen change events that are not raised during certain navigation paths.
Method 1 — Picture Window Display Event (Recommended)
The Picture Window control (object type Picture Window, catalog under Controls → WinCC Controls) maintains a runtime property called Display. The property is accessible under Events → Property Topics → Miscellaneous → Display and is updated by the runtime whenever the picture transitions between visible and hidden states.
The Display event raises a Value parameter with the following semantics:
| Value | State | Meaning |
|---|---|---|
1 |
Display = True | Picture Window is currently visible (operator opened the screen) |
0 |
Display = False | Picture Window is hidden or unloaded (screen was closed) |
Configuration Steps
- Open the parent screen (e.g.
Screen_Overview) in the TIA Portal editor. - From Toolbox → Controls, drag a Picture Window onto the canvas.
- In the Picture Window properties, configure the Picture Name property to the screen you want to host (e.g.
Screen_Detail). You can leave this empty if you plan to assign the picture dynamically. - Right-click the Picture Window → Properties → Events.
- Navigate to Property Topics → Miscellaneous → Display.
- Add a new function list, VBScript, or direct connection that uses the
Valueparameter (see options below).
Option A: Function List with System Functions
Configure the function list to evaluate Value and either set or reset the tag:
- Insert Set Bit as the first action. Operand:
ScreenActive. Set/Reset: Set. (Optional — fires when screen opens.) - Insert a conditional branch: If → Compare tag → Value (local event parameter) = 0.
- Inside the branch, insert Reset Bit on
ScreenActive.
Option B: VBScript on the Display Event
Right-click the Display event and select Add VBScript function. Replace the generated stub with:
' Name: PictureWindow_Display_Changed
' Triggered by: Property Topics > Miscellaneous > Display (Value parameter)
Sub PictureWindow_Display_Changed(ByVal Item)
Dim pvDisplay
pvDisplay = Item.Value ' 1 = opened, 0 = closed
If pvDisplay = 1 Then
SmartTags("ScreenActive") = True
ElseIf pvDisplay = 0 Then
SmartTags("ScreenActive") = False
' Additional cleanup actions on close:
SmartTags("PopupDirty") = False
SmartTags("EditBuffer") = ""
End If
End Sub
The Item.Value argument is supplied automatically by the runtime and corresponds to the new Display property value after the transition.
Method 2 — Direct Connection on the Display Property
For the simplest possible implementation — no scripting required — use a direct connection between the Picture Window Display property and a tag.
- Right-click the Picture Window → Properties → Events → Property Topics → Miscellaneous → Display.
- Click the small lightning-bolt icon to create a Direct Connection.
- On the left side, select This object → Display as the source property.
- On the right side, select Tag → ScreenActive.
- Accept the default direction (read tag → write property). The runtime will write
1when the picture is visible and0when it is not visible.
Method 3 — Global VBScript Using ActiveScreen
If the host screen does not use a Picture Window, you can monitor the runtime's ActiveScreen property from a global scheduled task or a cyclic C/VBScript. HMIRuntime.ActiveScreen returns a reference to the currently active screen object.
Scheduled Task Configuration
- Open HMI device → Scheduled Tasks.
- Add a new task, name it
ScreenLifecycle_Watch, set trigger to Cyclic → 500 ms (or use Screen change event for reduced overhead). - Attach a VBScript action with the body below.
' Name: ScreenLifecycle_Watch
' Triggered by: Scheduled task (cyclic 500 ms) or Screen change event
Dim currentScreen, lastScreen, screenName
Set currentScreen = HMIRuntime.ActiveScreen
screenName = currentScreen.ScreenName
If screenName <> lastScreen Then
' Screen transition detected. If the new screen is NOT our tracked
' screen, the previously active screen was effectively closed.
If screenName <> "Screen_Detail" Then
SmartTags("ScreenActive") = False
SmartTags("LastClosedScreen") = lastScreen
Else
SmartTags("ScreenActive") = True
End If
lastScreen = screenName
End If
lastScreen must be declared as a module-level variable outside the Sub to retain state between cycles. In TIA Portal V17 and later, use Dim at script top-level scope, or persist lastScreen to an internal HMI tag.Method 4 — Button-Triggered Toggle on Screen Change
If the screen is always opened from a known button, you can drive the bit from the button's click event and from the next screen's OnOpen:
- On the Open Screen button: Activate Screen action → target screen; Set Bit action →
ScreenActive. - On the target screen's
OnOpenevent: confirmScreenActive= 1 (optional). - On the target screen's Back button: Reset Bit →
ScreenActive, then Activate Screen → previous screen.
This pattern is reliable for hierarchical navigation but breaks down when the operator closes the screen via an alarm, an external tag-driven ActivateScreen call, or a script.
Method 5 — Win32 API Window Handle Lookup
For WinCC Professional on a Windows-based runtime PC, the active picture window has a native Win32 handle accessible via the Win32 API. This is the most fragile method and is not supported on Comfort Panels. Use only when Methods 1–4 are unavailable.
' Declare at module top level
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function IsWindowVisible Lib "user32.dll" _
(ByVal hwnd As Long) As Long
Sub CheckWindowHandle()
Dim hWnd As Long
hWnd = FindWindow(vbNullString, "Screen_Detail")
If hWnd = 0 Then
' Window not found — treat as closed
SmartTags("ScreenActive") = False
ElseIf IsWindowVisible(hWnd) = 0 Then
' Window exists but is hidden
SmartTags("ScreenActive") = False
Else
SmartTags("ScreenActive") = True
End If
End Sub
Method Comparison Matrix
| Method | Scope | Requires Scripting | Reliability | Performance Impact | Panel Support |
|---|---|---|---|---|---|
| 1A — Picture Window Display (Function List) | Picture Window host | No | High | Negligible | Comfort, Advanced, Professional |
| 1B — Picture Window Display (VBScript) | Picture Window host | Yes | High | Negligible | Comfort, Advanced, Professional |
| 2 — Direct Connection | Picture Window host | No | High | None | Comfort, Advanced, Professional |
| 3 — Global Script / ActiveScreen | Global | Yes | Medium | Low (cyclic) / None (event) | Advanced, Professional |
| 4 — Button-driven Toggle | Per screen | No | Medium | None | All |
| 5 — Win32 API Handle | Global (PC only) | Yes | Low | Moderate | Professional (Windows runtime) |
Tag and Variable Configuration
Create the following tags in the HMI tag table (or connect to PLC tags of the same name):
| Tag Name | Data Type | Source | Purpose |
|---|---|---|---|
ScreenActive |
Bool | HMI internal or PLC | Set when target screen opens; reset when closed |
LastClosedScreen |
WString[32] | HMI internal | Captures which screen last triggered close (Method 3) |
PopupDirty |
Bool | HMI internal | Optional — flag indicating unsaved edits |
EditBuffer |
WString[64] | HMI internal | Optional — scratch buffer cleared on close |
If ScreenActive is sourced from the PLC, mark the connection as cyclic continuous with a 100 ms acquisition cycle. If it is sourced locally on the HMI, mark it internal tag with no PLC acquisition.
Verification and Commissioning Procedure
- Compile the HMI project (TIA Portal → HMI device → Compile → Software (rebuild all)). Resolve any warnings about unused event parameters.
- Download to the target device. On Comfort Panels, use Ethernet or USB; on PC runtime, use Start Runtime from TIA Portal.
- Open the RT logger (WinCC RT → Tools → Trace) and add the
ScreenActivetag for live monitoring. - Navigate to the host screen. Confirm the Picture Window shows the child picture and
ScreenActivetraces1. - Navigate away from the host screen (button or ActivateScreen). Confirm
ScreenActivetransitions to0within one RT cycle (typically 100–500 ms). - Force a screen change via PLC by setting a tag that drives ActivateScreenByTag in the HMI. Verify the close logic still fires.
- Power-cycle the panel. Verify the bit starts at
0after boot (expected because the Picture Window is not visible until invoked). - Repeat steps 4–6 with the operator logged out, to confirm the logic does not depend on user-rights state.
Troubleshooting Matrix
| Symptom | Likely Root Cause | Remediation |
|---|---|---|
| Bit never sets when screen opens | Picture Window Picture Name property is empty | Assign a screen to the Picture Name property under Miscellaneous |
| Bit never resets on close | Event attached to wrong Picture Window instance | Re-verify the event configuration under the correct object's Events → Property Topics → Miscellaneous → Display |
| Bit resets, then immediately re-sets | Close handler triggers another event that re-opens the picture | Inspect Activate Screen actions on the close handler; debounce with a 250 ms timer |
| VBScript error: Object variable not set |
Item parameter name typo or wrong argument order |
Use the engine-generated signature Sub Name(ByVal Item) exactly |
| Cyclic script lag > 1 s | 500 ms cycle is too long for the application | Reduce cycle to 200 ms, or switch to event-driven Screen change trigger |
| Direct connection writes stale value | Direction configured as write property → tag instead of read → write | In the direct connection dialog, set source = property, target = tag |
| Win32 API returns 0 in RT but works in simulator | FindWindow window title mismatch on the device locale | Print the actual caption with GetWindowText during a debug cycle |
Performance and Runtime Considerations
For panels with RT cycles below 200 ms, the cyclic ActiveScreen approach (Method 3) introduces measurable CPU load when more than ~10 screens are cycled per second. Prefer Screen change event scheduling in that case. The Picture Window Display event (Method 1) is fired by the runtime only on actual visibility transitions, so its overhead is independent of the RT cycle and is the most scalable approach for projects with frequent pop-ups.
VBScript runtime is single-threaded per HMI device. If your cleanup handler performs heavy work (file I/O, recipe operations), offload the time-critical reset to a function list and reserve VBScript for I/O-bound cleanup only.
Security and Audit Considerations
If the cleanup action is tied to a user-rights change (e.g. logging which user closed the screen), record the operator in a separate audit tag inside the same Display handler:
Sub PictureWindow_Display_Changed(ByVal Item)
If Item.Value = 0 Then
SmartTags("AuditLastCloseUser") = _
HMIRuntime.Runtime.Users.CurrentUser.Name
SmartTags("AuditLastCloseTime") = Now
End If
End Sub
Tags used for audit must be configured with adequate length (WString[64] minimum for usernames) and excluded from RT retention unless the project complies with the regulator's logging requirements.
Frequently Asked Questions
Does WinCC TIA Portal have a built-in OnClose event for screens?
No. WinCC Comfort, Advanced, and Professional expose OnLoaded, OnOpen, OnActivate, and OnDeactivate events, but no first-class OnClose. The recommended workaround is to host the screen in a Picture Window and use the Display property event, where Value = 0 corresponds to a hidden or unloaded picture.
Can the Picture Window Display event fire multiple times in quick succession?
Yes. If the picture changes rapidly (e.g. animated pop-up), Display fires on every transition. Debounce in the handler if downstream logic is expensive. A 100–250 ms minimum interval is typical for stable cleanup logic.
Why does my direct connection write the bit in the wrong direction?
The direct connection defaults to "write property from tag". Reverse the source and target so the source is the Picture Window's Display property and the target is your ScreenActive tag. Re-test by navigating away from the screen.
Will Method 3 (ActiveScreen) detect screen changes via PLC-driven ActivateScreen calls?
Yes. HMIRuntime.ActiveScreen reflects the runtime's current active picture regardless of whether the navigation originated from a button, a scheduled task, or a PLC-driven tag change. The cyclic script will detect the transition on its next scan.
Is VBScript required, or can I use C scripting for the cleanup handler?
C scripting is available on WinCC Professional only. The event signature is the same: void OnDisplayChanged(HMIObject* pObj, long Value) with Value = 1 for visible and Value = 0 for hidden. On Comfort Panels and WinCC Advanced, use VBScript or function lists.