Overview
Siemens WinCC (TIA Portal and WinCC V7.x) picture windows let a single display container host multiple faceplates, but a common engineering problem is that graphics inside the picture window fail to refresh until the window is closed and reopened. The root cause is almost always a polling-based update cycle combined with a property binding that only re-evaluates when the container is reloaded. This reference covers three C-script and one VBS approach for forcing immediate picture updates, and explains how to consolidate start/stop controls into one reusable faceplate that drives any motor or valve tag.
Prerequisites
- Siemens WinCC Professional (TIA Portal V16 or later) or WinCC V7.4 SP3 / V7.5 with the C scripting option enabled
- Configured PLC connection tags (e.g.
Motor1_state,Motor1_ctrl) - One source PDL containing the picture window object and one or more faceplate PDLs (e.g.
start.pdl,motor.pdl,valve.pdl) - Knowledge of the project's tag naming convention; this guide assumes a
<TAG>_stateand<TAG>_ctrlpair - WinCC Graphics Designer with the C compiler configured (Project Properties > Options > C-Script Compiler)
Understanding the Update Cycle Problem
Picture window content refresh is tied to the configured update cycle of the host picture. When an internal tag drives a dynamic property (such as the PictureName property of a Picture Window), the property is only re-evaluated when the host picture's update event fires. If the update cycle is set to a fixed interval (e.g. 1 s) and the tag is also a polled value, a change of value will not be visible until the next cycle boundary. Configuring the update to Upon change is supported for picture-level update events, but only triggers a repaint of objects that have their own dynamic bindings; picture windows reloading their PictureName still depend on the host picture's redraw.
C Script API for Picture Window Control
WinCC exposes the following C functions for picture window manipulation. All three are declared in the project header and resolve at compile time.
| Function | Purpose | Typical Use |
|---|---|---|
SetPropChar() |
Writes a string to a property of a named object in a named picture | Change picture name, visibility, or caption of a picture window from a C action |
SetTagPrefix() |
Sets the tag namespace prefix used to resolve SetTagWord() etc. within a function |
Switch the active tag prefix when a button click selects a different motor |
SetPictureName() |
Loads a new PDL into a picture window at runtime | Open a different faceplate PDL inside the picture window |
SetTagChar() |
Writes a string value to a WinCC tag | Drive a PictureName binding that is connected to an internal text tag |
GetTagChar() |
Reads a string value from a WinCC tag | Build dynamic tag names from a current selection |
Method 1: SetPropChar Function
The most direct approach. Declare the function with its full prototype and call it from a button click event or a tag-change C action.
Function prototype:
void SetPropChar(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName, LPCTSTR lpszPropertyName, char* szValue);Example call from a button's C action:
SetPropChar("butexam.pdl", "mainpw", "PictureName", "pict1.pdl");Where:
-
butexam.pdl- the host picture containing the picture window -
mainpw- the name of the picture window object inside that picture -
PictureName- the property of the picture window to modify (string) -
pict1.pdl- the target faceplate to load into the picture window
To also toggle visibility (required if the picture window was hidden), chain a second call:
SetPropChar("butexam.pdl", "mainpw", "Visible", "1");Method 2: Internal Text Tag for PictureName
This is the cleanest approach for projects that use the picture window as a faceplate host. It removes the need to call SetPropChar from a button; the picture window's PictureName property is bound to an internal text tag and updated from any C action via SetTagChar.
Step-by-Step
- In the Graphics Designer, create an internal text tag named
SelectedFaceplate. - Select the picture window object, open the Miscellaneous folder in the Properties dialog, and assign
SelectedFaceplateto the Picture Name attribute. - From any button C action, write the desired PDL name to the tag:
SetTagChar("SelectedFaceplate", "motor1.pdl"); - To close the faceplate, write an empty string:
SetTagChar("SelectedFaceplate", "");
This method is recommended for production code because it allows both manual and tag-driven faceplate selection without C recompilation, and it survives Hot-Build cycles in TIA Portal V17 and later.
Method 3: SetTagPrefix and SetPictureName Pair
Use this approach when a button or script must load a different picture in the picture window without disturbing other parts of the runtime. The classic two-line pattern is:
SetTagPrefix("start.PDL", "overview", "");
SetPictureName("start.PDL", "overview", "my.PDL");
Where:
-
start.PDL- the source picture that contains the picture window -
overview- the name of the picture window object -
my.PDL- the destination faceplate to load
SetTagPrefix establishes the tag-resolution context for the subsequent calls in the same function. If the picture window is being driven by a tag prefix that differs from the current project prefix (common in multi-area projects), call SetTagPrefix first to avoid runtime errors caused by tag resolution failures.
VBScript Alternative for Runtime Tag Manipulation
For purely button-driven flows (clicking a motor icon to write the selected tag name), VBScript inside the Graphics Designer is often faster to author than C. The pattern below implements a reusable motor control faceplate driven by a single internal 8-bit text tag POSITIO:
Sub OnClick(Byval Item)
Dim mtrtag1
Set mtrtag1 = HMIRuntime.ActiveScreen.ScreenItems("mtr1text")
Dim mtrtag2
Set mtrtag2 = HMIRuntime.Tags("POSITIO")
mtrtag2.Write mtrtag1.Text
End Sub
The companion control faceplate's START button reads the selection and appends a suffix to build the target control tag dynamically:
Sub OnClick(Byval Item)
Dim positio, strConc, ctrl
Set positio = HMIRuntime.Tags("POSITIO")
positio.Read
strConc = positio.Value & "_ctrl"
Set ctrl = HMIRuntime.Tags(strConc)
ctrl.Write "1" ' write start command
End Sub
The _ctrl and _state suffix convention is the standard way to consolidate N motor/valve faceplates into one physical picture window, provided every tag in the project follows the same naming rule.
Reusable Faceplate Pattern
Combining the above techniques yields a single faceplate that can drive any motor in the plant:
- One central picture
motor_control.pdlcontains a picture window namedPWMotorand aSTART/STOPbutton pair. - The picture window's
PictureNameproperty is bound to internal text tagSelectedFaceplate. - When a user clicks a motor icon in any overview screen, a C action writes the motor's base tag name (e.g.
Motor3) toSelectedFaceplate, which loadsmotor_zoom.pdlinto the picture window. - The
STARTbutton readsMotor3, appends_ctrl, and writes the start command; theSTOPbutton writes the stop command to the same tag. - Status displays (text, color, animation) inside
motor_zoom.pdlare bound toMotor3_stateand refresh on the standard 250 ms update cycle.
This pattern is what allows one physical faceplate to control all motors in the plant, rather than maintaining N copies of the same PDL with hard-coded tag names.
Forcing a Refresh on a Bit Change
If a particular display element inside the picture window still does not repaint when the underlying bit changes, the cause is typically a property that is bound to a calculated expression rather than a direct tag. There are two proven fixes:
Fix A: Use SetTagChar to force a re-evaluation
// In a C action triggered on the tag change event of Motor3_state
char buf[64];
sprintf(buf, "%d", GetTagWord("Motor3_state"));
SetTagChar("Motor3_dispCache", buf);
Binding the display to Motor3_dispCache (a separate tag) instead of the direct source tag forces a value change that the Graphics Designer will repaint on the next update tick.
Fix B: Use SetPropChar to write the same value back
// On a tag change C action tied to the bit
char* prop = (GetTagBit("Motor3_state") ? "1" : "0");
SetPropChar("motor_zoom.pdl", "StatusIndicator", "ProcessValue", prop);
This bypasses the picture-level update event entirely and writes the new property value directly to the object.
Update Cycle Configuration
| Property | Path | Recommended Setting |
|---|---|---|
| Picture update (general) | Picture properties > Update > Cycle | 250 ms for status, 1 s for non-critical |
| Picture update (events) | Picture properties > Update > Events > Upon change | Enable for bit-driven status |
| C action trigger | Action configuration > Trigger > Tag change | Bind to the source tag, not the display tag |
| Internal tag update | Tag properties > Update | Upon change for picture-name tags |
Verification
- Compile the C action (Build > Compile All) and verify there are no warnings related to
SetPropCharor unresolved tag references. - Start WinCC Runtime and open the Graphics Designer with Tag Simulation enabled.
- Force the source tag to change with Tag Simulation; confirm the picture window content updates within one update cycle (default 250 ms).
- Click each motor icon and verify the picture window loads the correct faceplate PDL, then click
STARTand confirm the corresponding<TAG>_ctrlwrites the expected value. - Inspect the WinCC Diagnostic Viewer (ApDiag.exe) for any
SETPROPCHARerrors; a return code other than zero indicates an invalid PDL name or object name. - Stress-test by cycling the source tag at 2 Hz for 60 seconds; the picture window must not drop updates or freeze.
Troubleshooting Matrix
| Symptom | Likely Cause | Corrective Action |
|---|---|---|
| Picture window does not load new PDL on button click | Wrong object name or picture name in SetPropChar call |
Verify spelling and case in the Graphics Designer; use Tag Simulation with logging |
| Status display updates only after closing and reopening the faceplate | Display bound to a calculated expression with static caching | Bind to a dedicated internal cache tag; use Fix A above |
VBScript error: "Object variable not set" on HMIRuntime.Tags(...)
|
Internal tag not declared or has wrong data type | Confirm the tag exists in WinCC Explorer; use 8-bit text type for tag name variables |
| Tag change C action fires but picture does not repaint | Trigger tag is correct but the action writes to a property that is not dynamic | Enable the dynamic flag on the target property in the Properties dialog |
| Picture window loads but contains stale data | Picture-level update cycle is set too long for the source tag | Lower the host picture update cycle to 250 ms or use a tag-change action |
| High CPU on runtime when using Upon change | Source tag changes faster than 1 Hz | Add a debounce internal tag, or switch to a fixed 250 ms cycle |
Field-Commissioning Checklist
- Confirm the C compiler is installed and the project options point to a valid WinCC include directory (typically
C:\Program Files\Siemens\Automation\WinCC\aplib\include). - Document the tag naming convention (
<TAG>_state/<TAG>_ctrl) in the project HMI tag dictionary. - For every picture window, decide whether the binding will be to an internal text tag (Method 2) or to a direct C action (Method 1) and document the choice.
- Run the full picture-change scenario on the target runtime (PC Runtime or Comfort Panel) before PLC integration, to isolate HMI defects from PLC defects.
- Capture the WinCC version in the project notes; the function signatures are stable from WinCC V7.0 onward, but the TIA Portal V16+ project tree stores them in
Scripts\Libraries\WinCC\apdefap.h.
How do I change the update cycle to "Upon change" in a WinCC C script?
Open the picture properties in the Graphics Designer, navigate to the Update tab, and set the cycle to Upon change. For C actions that must trigger on a tag transition, configure the action's trigger as a tag-change event bound to the source tag; the action then fires whenever the tag value changes, regardless of the picture update cycle.
Why does my picture window content not update until I close and reopen it?
Most often the display property is bound to a calculated expression or to a tag whose update cycle does not match the source tag's cycle. Bind the display to a dedicated internal cache tag and write to it from a tag-change C action, or use SetPropChar to write the new property value directly to the named object.
Can one faceplate control all motors in the project?
Yes. Use a single picture window with its PictureName property bound to an internal text tag. When the operator clicks a motor icon, write the motor's base tag name to the internal text tag and load a generic motor_zoom.pdl. The faceplate's start/stop buttons read the base tag, append _ctrl or _state, and write the command or read the status, allowing N motors to be driven from one physical faceplate.
What is the difference between SetPropChar, SetTagPrefix, and SetPictureName?
SetPropChar writes a property value to a named object in a named picture and is the most general-purpose function. SetTagPrefix sets the tag namespace context for the current C function. SetPictureName directly loads a new PDL into a picture window and is the most concise when only the picture content needs to change. Use SetTagPrefix + SetPictureName together when the active tag prefix is not the project default.
Does this work in TIA Portal WinCC Professional the same as WinCC V7?
Yes, the function signatures and usage are identical between WinCC V7.x and TIA Portal WinCC Professional V16+. The only differences are project tree location (TIA stores scripts under PLC_1\HMI_1\Scripts) and the absence of the legacy VBScript compatibility shim on TIA V17+ projects targeting S7-1500 panels.