WinCC flexible QWERTY Keyboard: Two-Touch & Mid-String Insert

David Krause15 min read
HMI ProgrammingSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview

When the default Siemens on-screen keyboard does not fit the screen layout, language requirements, or aesthetic of a panel design, engineers often build a custom QWERTY screen in WinCC flexible 2008 Standard (SP2 through SP5 are the most widely deployed maintenance releases in the field). The design is straightforward at first glance: place a set of I/O fields for the user inputs, lay out a button grid that mimics Q, W, E, R, T, Y, ... and write a script that copies the pressed character into the active field. Two problems derail every first attempt at this build:

  1. Two-touch problem. The first touch on an I/O field selects the entire contents (this is the default behavior and is desirable). The second touch should drop the cursor inside the string so the user can edit, but the WinCC flexible I/O field exposes only a single Click event. There is no native DoubleClick event, no native way to detect the transition from "select-all" to "place-cursor".
  2. Mid-string insertion problem. Even if the cursor can be positioned, WinCC flexible does not publish the cursor offset of an I/O field to a tag, system function, or script. Without that offset, the keyboard can only append characters at the end of the string.

This article documents a working pattern for both problems using only standard WinCC flexible objects: an I/O field, a few internal integer tags, a set of soft-key buttons, and a VBScript function library. The pattern is fully compatible with the 2008 SP5 runtime and with the migration path to TIA Portal WinCC described in the Siemens FAQ "How do you create your own on-screen keyboard for a WinCC Runtime Advanced Station?". Where WinCC flexible 2008 reaches its limits, the article flags the upgrade path to WinCC Runtime Advanced / RT Professional and the documented keyboard layout handling at Select keyboard layout (Professional) - WinCC Runtime Professional.

Prerequisites

Before implementing the custom keyboard, confirm the following are available in the engineering station and on the target panel:

  • Engineering software: SIMATIC WinCC flexible 2008 Standard, SP2 or later. SP5 (released 2012) is the recommended service pack for all custom-script work because it ships the most stable VBScript runtime on Panels and Runtime PC.
  • Target panel family: any panel that supports WinCC flexible 2008 Standard (OP 77B, TP 177B, TP 177A, MP 177, MP 277, MP 377, or WinCC Runtime PC). The custom-keyboard pattern works on all of them; only the I/O field count limit per screen differs.
  • Panel type setting in the project: OP 77B, TP 177A, or older 4-inch panels do not support VBScript. Verify the panel type permits VBScript before committing to this design.
  • Tag budget: plan for at least 5 internal tags per I/O field that participates in the custom keyboard: one string tag for the value, one integer tag for the cursor position (offset, 0-based), one integer tag for the press state (0=idle, 1=armed, 2=editing), and one tag each for the active-field selector. A typical 10-field login screen therefore needs ~50 internal tags.
  • Script editor: open WinCC flexible's Scripts > VBScripts view; confirm Microsoft VBScript Regular Expressions is enabled (it is by default in 2008 SP3+).
Note on licensing: The VBScript editor and the runtime engine are bundled with the WinCC flexible 2008 Standard / Advanced authoring license. No additional runtime license key is required to execute the custom keyboard logic on a supported panel.

I/O Field Two-Touch Behavior Explained

WinCC flexible I/O fields support exactly three events that fire on a touch:

Event Trigger Available in WinCC flexible 2008
Click Fires once on press (release on the same pixel) — the same event whether it is the first or the Nth touch Yes
Change Fires when the operator accepts a new value (typically the "Enter" or the moment focus leaves the field) Yes
Activate / Deactivate Focus gain / loss Yes
DoubleClick — Not available on the I/O field object

The default touch sequence is therefore:

  1. Touch #1 → Click event fires → I/O field enters selection mode → entire string is highlighted.
  2. Touch #2 → Click event fires again → I/O field drops into edit mode → cursor is placed at the touch point inside the string.

From a VBScript perspective, both touches look identical: a single Click notification with no "which-press-of-the-day" qualifier. The detection must therefore be reconstructed in the application layer with a state tag.

Detecting the Second Touch with State Tags

The pattern uses a small finite state machine driven by a single integer tag per I/O field. The tag carries three meaningful values; all other values are reserved for future use and should be treated as idle.

Value State name Meaning Next valid value(s)
0 IDLE Field is not the active edit target. 1
1 ARMED Field has been touched once; full string is selected. 0, 2
2 EDITING Field has been touched a second time; cursor is positioned and character insertion is enabled. 0, 1

Wire the I/O field's Click event to a single VBScript function OnFieldClick(iFieldIndex). The function reads the current state tag, transitions it, and writes the result back. The pseudocode for the transition is:

Sub OnFieldClick(fieldIndex)
  Dim s : s = SmartTags("field_state_" & fieldIndex)
  Select Case s
    Case 0
      SmartTags("field_state_" & fieldIndex) = 1     ' ARMED: full string selected
      SmartTags("active_field") = fieldIndex
    Case 1
      SmartTags("field_state_" & fieldIndex) = 2     ' EDITING: cursor is placed
      SmartTags("active_field") = fieldIndex
    Case 2
      SmartTags("field_state_" & fieldIndex) = 0     ' IDLE: explicit clear
      SmartTags("active_field") = -1
  End Select
End Sub

The transition from 1 → 2 is the second-touch event the project needs. At that point, the keyboard's soft-key buttons switch from Replace mode to Insert mode, and the cursor-position tag becomes the authoritative target for character insertion.

Tracking Cursor Position in I/O Fields

WinCC flexible I/O fields do not expose the caret offset as a property, so a synthetic cursor must be maintained. Three viable approaches exist, listed in order of complexity:

Approach Mechanism Pros Cons
1. Virtual caret with arrow buttons Two dedicated soft keys (◀ ▶) on the custom keyboard increment/decrement a cursor integer tag clamped to [0, Len(value)] Trivial to implement; works on every panel User has to tap arrow keys; no direct tapping inside the string
2. Numeric input split into "row,column" coordinates On entering EDITING, switch the I/O field to a numeric mode and require the user to enter the column position as a number No extra UI Awkward UX; not a real QWERTY experience
3. ActiveX text control with published .SelStart Replace I/O fields with a Siemens-supplied or third-party ActiveX text control that exposes caret position Real cursor awareness, supports selection, supports long-press ActiveX may not be available on every panel; licensing differs per panel family

For a Panel-class target (TP/MP) Approach 1 is the practical choice because Approach 3 requires ActiveX support that is not present on 4-inch and 6-inch panels. The arrow keys live on the same screen as the QWERTY layout, and the cursor tag is a single 16-bit integer that the script clamps on every update.

Sub MoveCursor(direction)
  ' direction = -1 for left, +1 for right
  Dim idx : idx = SmartTags("active_field")
  If idx < 0 Then Exit Sub
  Dim val : val = SmartTags("field_value_" & idx)
  Dim pos : pos = SmartTags("field_cursor_" & idx)
  pos = pos + direction
  If pos < 0 Then pos = 0
  If pos > Len(val) Then pos = Len(val)
  SmartTags("field_cursor_" & idx) = pos
End Sub

The clamp is critical: if the cursor index falls outside the string the Mid() call in the next section will raise a runtime error and abort the script. The bound is [0, Len(value)], not [0, Len(value)-1], because the caret is conceptually allowed to sit one position past the last character (the standard text-editor convention).

Mid-String Insertion Logic

Once the state machine is in EDITING (state = 2) and the cursor integer has a valid value, character insertion is a direct application of VBScript's Left(), Mid(), and string concatenation:

Sub InsertChar(ch)
  Dim idx : idx = SmartTags("active_field")
  If idx < 0 Then Exit Sub
  If SmartTags("field_state_" & idx) <> 2 Then
    ' IDLE or ARMED: behave as append (overwrite is also acceptable)
    SmartTags("field_value_" & idx) = SmartTags("field_value_" & idx) & ch
    Exit Sub
  End If
  ' EDITING: insert at cursor position
  Dim val : val = SmartTags("field_value_" & idx)
  Dim pos : pos = SmartTags("field_cursor_" & idx)
  If pos < 0 Then pos = 0
  If pos > Len(val) Then pos = Len(val)
  Dim newVal
  newVal = Left(val, pos) & ch & Mid(val, pos + 1)
  SmartTags("field_value_" & idx) = newVal
  SmartTags("field_cursor_" & idx) = pos + 1     ' advance caret by 1
End Sub

Three behaviors fall out of this single function:

  • IDLE state (no field is active): the function exits without writing. Bind the QWERTY buttons' Enabled property to the inverted state of active_field <> -1 to grey out the keys.
  • ARMED state (full string selected): characters append. This matches the convention that the next typed character replaces the selection on the next Change event.
  • EDITING state (cursor positioned): characters insert at the caret, the string length grows by one, and the caret advances by one. The user can therefore type a continuous stream of letters in the middle of the field.

The companion deletion function uses the same cursor tag:

Sub DeleteChar()
  Dim idx : idx = SmartTags("active_field")
  If idx < 0 Then Exit Sub
  Dim val : val = SmartTags("field_value_" & idx)
  Dim pos : pos = SmartTags("field_cursor_" & idx)
  If pos <= 0 Then Exit Sub
  Dim newVal
  newVal = Left(val, pos - 1) & Mid(val, pos + 1)
  SmartTags("field_value_" & idx) = newVal
  SmartTags("field_cursor_" & idx) = pos - 1
End Sub

Building the Custom Keyboard Screen

A single screen carries the I/O fields at the top and the QWERTY grid below. The recommended layout for a 10-inch panel is:

  1. Row 1: the user-editable I/O fields (login name, password, parameter name, etc.), each linked to a field_value_N tag and configured with Display > Appearance > "Output / input".
  2. Row 2: QWERTY row 1: Q W E R T Y U I O P.
  3. Row 3: QWERTY row 2: A S D F G H J K L. Offset row 2 by half a key for a true QWERTY look; on 4-inch panels keep the keys aligned to the grid.
  4. Row 4: QWERTY row 3: Z X C V B N M.
  5. Row 5: space bar (wide button), < (cursor left), > (cursor right), DEL (delete char), CLR (clear field), ENT (accept & leave field).

Every key in rows 2-5 calls the same InsertChar function with the appropriate character literal. The CLR button resets the active field to the empty string and the cursor to 0. The ENT button transitions the field state back to IDLE and clears active_field.

Layout tip: Set the QWERTY button Width to 40 px and Height to 40 px on a 10-inch panel. On 4-inch panels drop to 24 × 24 px. The minimum tap target Siemens recommends is 20 × 20 px; below that the panel may not register a click reliably.

Verification & Commissioning

After the screen compiles, run through the following checks on the live panel or in the WinCC flexible RT simulation. Every check should pass before the project is released.

  1. Append on first touch. Touch an empty I/O field, then tap A. The string should read A.
  2. Select-all on re-touch. Touch the same field again. The full string A should be highlighted.
  3. Cursor placement on third touch. Touch the field a third time. The state should transition to EDITING and the cursor should land at the touched position (use an LED indicator bound to field_state_0 == 2 for visual confirmation).
  4. Mid-string insertion. Press the left arrow twice so the cursor tag reads 0, then tap B. The string should read BA and the cursor tag should now read 1.
  5. Delete at boundary. Move the cursor to position 0 and tap DEL. The script must exit cleanly (no runtime error) and the string must remain unchanged.
  6. Cross-field focus. Touch a second I/O field while the first is in EDITING. The first should auto-transition to IDLE and the second to ARMED. Verify with state LEDs.
  7. Long string stability. Type 64 characters into a field, then move the cursor with arrows to position 32 and insert another character. The string must remain exactly 65 characters long and the cursor must read 33.

For a deeper walk-through of the panel-side wiring and the recommended object arrangement see the official Siemens FAQ "How do you create your own on-screen keyboard for a WinCC Runtime Advanced Station?". The patterns described in that FAQ (button grid + tag for the active field + script that copies the pressed character into the active field) are the same primitives this article extends with cursor awareness.

Troubleshooting Matrix

Symptom on panel Likely root cause Fix
QWERTY keys do nothing active_field is -1; no I/O field has been touched, or the field's Click event was never wired to OnFieldClick Confirm the Events > Click property of every I/O field calls OnFieldClick with the correct index
Characters always append, never insert mid-string State tag never reaches value 2 (the EDITING transition is missing) Check the second-touch logic: state must go 0 → 1 → 2; confirm the Click event fires twice on rapid taps
Runtime error "Subscript out of range" in Mid() Cursor tag exceeded Len(value) or fell below 0 Re-clamp with the If pos < 0 / If pos > Len(val) guards shown above
Cursor jumps to end after every insert Cursor tag is being reset to Len(val) by the I/O field's own Change event Bind the Change event of the I/O field to a no-op or to a script that preserves field_cursor_N
Touches mis-registered on 4-inch panel Key size below the 20 × 20 px tap target minimum Increase key size or reduce the number of keys per row to 8
Works in RT simulation, fails on panel Panel firmware older than the project target; or the panel was compiled against a SP that the runtime does not have Update the panel image, or recompile the project against the panel's installed SP
Custom keyboard layout disappears after migration to TIA Portal WinCC flexible 2008 projects are migrated with the TIA Portal migration tool; VBScript is preserved but tag naming conventions may need manual adjustment Use the TIA Portal migration tool, then re-check all SmartTags() references; consider switching to the documented WinCC keyboard layout handling at Select keyboard layout (Professional) on RT Professional targets

Migration Notes: From WinCC flexible 2008 to TIA Portal

WinCC flexible 2008 reached end-of-life with the TIA Portal migration. Projects that use the custom keyboard pattern described in this article migrate cleanly, but three differences are worth flagging during commissioning on a TIA Portal target:

  • Tag access syntax. The SmartTags("name") VBScript accessor is retained in WinCC V15 and later, but the recommended pattern in current documentation is HMIRuntime.Tags("name").Read / .Write for explicit read-write clarity.
  • Runtime target. On TIA Portal the same pattern ports to WinCC Runtime Advanced (PC-based) and to WinCC Runtime Professional. On RT Professional, the documented keyboard layout can be selected directly from the project settings, which may make the custom keyboard unnecessary if the default layout is acceptable.
  • Event model. Comfort Panels and Unified Panels expose an explicit DoubleClick event on the I/O field. Once a project is migrated to a Comfort or Unified panel the entire state-machine workaround collapses into a single OnDoubleClick handler.

Field-Proven Caveats

Three constraints show up repeatedly on commissioning sites and should be checked before sign-off:

  1. Tag change polling. WinCC flexible updates SmartTags() at the configured acquisition cycle, default 1 s. If the cursor tag is bound to a rapid input (such as a hardware keyboard) the value seen by the script may lag the user. Lower the cycle to 100 ms for the cursor tag only — global changes slow down all other HMI updates.
  2. String length cap. WinCC flexible string tags are limited to 254 characters (S7-300/400 compatible) or 4000 characters (S7-1500 / TIA Portal compatible). The custom keyboard should refuse to insert beyond the cap with a visible warning.
  3. Password fields. When the custom keyboard is used to type a password, bind the I/O field's Display > Password input property. The string value in the tag is plain text; protect the PLC connection with the standard WinCC flexible user administration.

How do I detect the second touch on a WinCC flexible I/O field?

The I/O field fires only a single Click event for any press. Detect the second touch by attaching a state tag (0=IDLE, 1=ARMED, 2=EDITING) to the Click event handler. The first press writes 1, the second writes 2; the keyboard reads the transition from 1 to 2 to enable mid-string insertion.

How do I insert a character at the cursor position in a WinCC flexible I/O field?

Maintain a cursor integer tag that holds the caret offset (0 to Len(value)). Use the VBScript expression Left(val, pos) & ch & Mid(val, pos + 1) to splice the new character in, then increment the cursor tag by 1. Clamp the tag to [0, Len(value)] on every update to avoid runtime errors in Mid().

Can I read the real cursor position from a WinCC flexible I/O field?

No. The I/O field object in WinCC flexible 2008 does not publish the caret offset. The pragmatic workaround is to track a synthetic cursor with arrow soft keys and to enforce the boundary in the script. On TIA Portal Comfort and Unified panels the I/O field exposes a DoubleClick event and the synthetic cursor becomes unnecessary.

What is the minimum VBScript cycle to make a custom keyboard feel responsive?

Set the cursor tag acquisition cycle to 100 ms. Leave the rest of the project at the default 1 s cycle. Lowering the global cycle slows down all tag updates and is the most common cause of sluggish HMI behavior in custom-keyboard projects.

Where can I find Siemens' official guidance on custom on-screen keyboards?

Siemens publishes the FAQ "How do you create your own on-screen keyboard for a WinCC Runtime Advanced Station?" which describes the button-grid + active-field pattern. For TIA Portal targets the documented keyboard layout handling is described under Select keyboard layout (Professional) - WinCC Runtime Professional.

Back to blog