1. Problem Summary
In WinCC V7.0, a C-script project function that opens a Picture Window configured with the TagPrefix property exhibits the following symptom pattern:
- The first invocation positions the window, sets
TagPrefix, writes the caption text, and displays the popup correctly. - The second invocation (different tag prefix value, different valve instance) updates the same on-screen picture window. Tag values shown inside the popup still resolve to the prefix supplied on the first call.
- Closing the popup and invoking the function again restores correct behavior — until the next rapid instance swap.
- A
printf("\r\n The name held in the prefix tag is now......%s",GetTagChar("TagPrefix"));diagnostic confirms the runtime tag does contain the new value; the rendering layer is simply not picking it up.
This is a well-known WinCC Picture Window caching behavior: TagPrefix is read by the Picture Window when the picture is loaded, not on every SetTagChar. Reassigning the prefix while the window holds an already-loaded picture has no visual effect until the picture is re-instantiated.
2. Reproduction: Failing Function
The original code illustrates the classic symptom. Save this as a project function in the WinCC Explorer under the project's C scripts:
void Valve(char* lpszPictureName, char* lpszObjectName,
char valveName[20], char TagPrefix1[3])
{
int x, y, left_pos, top_pos;
/* Read source-button position */
x = GetPropWord(lpszPictureName, lpszObjectName, "Left");
y = GetPropWord(lpszPictureName, lpszObjectName, "Top");
/* Center popup on the source button */
left_pos = x - 156;
/* Hide window BEFORE changing prefix */
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible ", 0);
SetTagChar("TagPrefix", TagPrefix1);
SetPropChar("1_MAIN","ValvePictureWindow","Caption Text", valveName);
SetPropWord("1_MAIN","ValvePictureWindow","Left", left_pos);
SetPropWord("1_MAIN","ValvePictureWindow","Top", y);
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible ", 1);
/* Set_Focus("1_MAIN","ValvePictureWindow"); */
printf("\r\n The name held in the prefix tag is now......%s",
GetTagChar("TagPrefix"));
}
This logic worked in WinCC V6.2 and earlier because the picture window was destroyed and re-instantiated on each call. In V7.0+ the picture window is a long-lived container, and TagPrefix is only consumed during picture instantiation.
3. Root Cause Analysis
Three interacting mechanisms cause the bug:
- Picture Window Lifecycle. A Picture Window on the parent picture is allocated once. The picture loaded inside it is instantiated on first display and re-instantiated only when the picture name property is changed (or the window is hidden for a full cycle under specific SP levels).
-
TagPrefix Binding Time. The
TagPrefixproperty on the Picture Window object is read at the moment the contained picture is loaded. Once the picture is in memory, internal tag references are already resolved against the prefix that was current at load time. Mutating the backingTagPrefixtag updates WinCC's tag manager but does not invalidate the picture's already-resolved prefix binding. -
Visibility Toggle Insufficiency. Setting
Visible = 0thenVisible = 1hides and re-shows the same picture instance. The picture is not unloaded, so the old prefix remains bound. Theprintfdiagnostic confirms the tag itself is correct — only the binding inside the picture window is stale.
GetTagChar("TagPrefix") returns the new prefix) but the popup still shows the old instance data, the binding has not been refreshed. The fix is to force a picture unload/reload.
4. The Three Working Patterns
Each pattern forces the Picture Window to re-instantiate the contained picture, which causes the runtime to re-read TagPrefix and rebuild internal references.
4.1 Pattern A — Clear and Reload Picture Name (Recommended)
Empty the picture name, set the new TagPrefix, then load the actual picture. This is the cleanest, lowest-risk pattern and survives all V7.0 SP levels.
void Valve(char* lpszPictureName, char* lpszObjectName,
char valveName[20], char TagPrefix1[3])
{
int x, y, left_pos, top_pos;
x = GetPropWord(lpszPictureName, lpszObjectName, "Left");
y = GetPropWord(lpszPictureName, lpszObjectName, "Top");
left_pos = x - 156;
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible", 0);
/* 1. Force unload of the currently loaded picture */
SetPropChar("1_MAIN","ValvePictureWindow","Picture Name", "");
/* 2. Update the prefix AFTER unload so it is consumed on reload */
SetTagChar("TagPrefix", TagPrefix1);
/* 3. Reload the real picture — runtime reads TagPrefix now */
SetPropChar("1_MAIN","ValvePictureWindow","Picture Name", "ValveFaceplate.pdl");
SetPropChar("1_MAIN","ValvePictureWindow","Caption Text", valveName);
SetPropWord("1_MAIN","ValvePictureWindow","Left", left_pos);
SetPropWord("1_MAIN","ValvePictureWindow","Top", y);
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible", 1);
}
4.2 Pattern B — Toggle Visibility With a New Tag Assignment Cycle
If you cannot change the picture name (for example, the picture is selected dynamically in Graphics Designer), force a full hide-show cycle around the SetTagChar:
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible", 0);
/* Allow the runtime one tick to fully tear down the picture instance */
SetTagChar("TagPrefix", ""); /* null-out the prefix */
SetPropChar("1_MAIN","ValvePictureWindow","Picture Name", "");
SetPropChar("1_MAIN","ValvePictureWindow","Picture Name", "ValveFaceplate.pdl");
SetTagChar("TagPrefix", TagPrefix1); /* assign the real prefix */
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible", 1);
4.3 Pattern C — Separate Picture Window Per Instance
For designs with up to a few dozen valves, allocate a dedicated Picture Window object on 1_MAIN per logical instance and route calls to the right window. This eliminates the reload problem entirely because each instance loads its own picture exactly once.
5. Position Math: Centering the Popup on the Source Button
The source code computes:
left_pos = x - 156;
This assumes the source button is approximately 312 px wide and the popup is 312 px wide, so subtracting half the popup width centers the popup horizontally on the button. A more robust formula generalizes the constants:
#define POPUP_WIDTH 312
#define POPUP_HEIGHT 180
int srcLeft = GetPropWord(lpszPictureName, lpszObjectName, "Left");
int srcTop = GetPropWord(lpszPictureName, lpszObjectName, "Top");
int srcW = GetPropWord(lpszPictureName, lpszObjectName, "Width");
int srcH = GetPropWord(lpszPictureName, lpszObjectName, "Height");
int left_pos = srcLeft + (srcW / 2) - (POPUP_WIDTH / 2);
int top_pos = srcTop + (srcH / 2) - (POPUP_HEIGHT / 2);
Left/Top properties are in parent picture coordinates, not screen coordinates. If the parent picture is panned inside a screen window, account for the screen window's Left/Top as well. Centering purely from GetPropWord on the source button will not align with the visible cursor if the parent picture is scrolled.
6. WinCC C Function Reference
| Function | Signature | Purpose |
|---|---|---|
GetPropWord |
DWORD GetPropWord(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName, LPCTSTR lpszPropertyName) |
Read a 16/32-bit property (Left, Top, Width, Height, etc.). |
SetPropBOOL |
BOOL SetPropBOOL(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName, LPCTSTR lpszPropertyName, BOOL bValue) |
Write a boolean property. Watch for trailing spaces in the property name (see §10). |
SetPropWord |
BOOL SetPropWord(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName, LPCTSTR lpszPropertyName, DWORD dwValue) |
Write a 16/32-bit property. |
SetPropChar |
BOOL SetPropChar(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName, LPCTSTR lpszPropertyName, LPCTSTR lpszValue) |
Write a string property (Picture Name, Caption Text, TagPrefix). |
SetTagChar |
BOOL SetTagChar(LPCTSTR lpszTagName, LPCTSTR lpszValue) |
Write a WinCC tag of type CHAR/String. |
GetTagChar |
LPCSTR GetTagChar(LPCTSTR lpszTagName) |
Read a WinCC tag of type CHAR/String. |
Set_Focus |
BOOL Set_Focus(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName) |
Move keyboard focus to a picture object. |
printf |
Standard C output | Diagnostics in the Global Script diagnostic window (start via Start > Run > dmf or via WinCC Explorer > Tools > Global Script Diagnostics). |
7. Picture Window Property Reference
| Property | Type | Notes |
|---|---|---|
Picture Name |
String | Path of the .pdl to instantiate. Changing this value is the only reliable way to force a re-instantiation. |
TagPrefix |
String | Prefix prepended to all unqualified tag names inside the picture. Read at picture-load time. |
Visible |
Bool | 0/1. Exact spelling required; do not add trailing whitespace. |
Left / Top
|
Word | Position in parent picture coordinates, in pixels. |
Width / Height
|
Word | Window size in pixels. |
Caption Text |
String | Header text for windowed picture windows. |
Window Border |
Bool | Show/hide OS-style border. |
Adapt Picture |
Bool | Stretch the contained picture to the window size. |
8. WinCC V7.0 vs V6.2 — Why the Script "Broke"
WinCC V6.2 and earlier had a less aggressive Picture Window caching layer. Calling the same C function repeatedly on an event often implicitly tore down and rebuilt the picture, so SetTagChar("TagPrefix", ...) took effect on the next call without any further intervention. In V7.0 the runtime's picture cache was tightened for performance, and the set TagPrefix then show window sequence stopped triggering a reload because the window was already showing a live instance.
This is a behavior change, not a bug in the strict sense. It is documented in the WinCC Information System under TagPrefix with the note that supplying a fresh picture name forces a refresh.
9. Project Function vs Direct Event Scripting
The symptom only emerges when the C code is moved into a project function called from a button event. When the same code is placed directly on a button's Click event, the click event's own teardown logic masks the problem. Project functions execute in a different lifecycle phase:
-
Direct event: The event handler executes in the same call stack as the click; the picture window's internal re-paint hook runs after the handler returns and re-reads
TagPrefix. -
Project function: The function is dispatched through the global script engine. The picture window's re-paint has often already happened by the time
SetTagCharruns, so the new prefix is never bound to the existing instance.
The picture-reload pattern in §4 is required regardless of where the C code lives, but the failure is more visible from a project function call.
10. Common Pitfalls in the Function
10.1 Trailing Space in Property Names
The original code uses "Visible " (with a trailing space) in two places. Some V7.0 builds tolerate this, others do not. The trailing space silently mismatches the property name and the call returns FALSE without setting an error. Always use the exact property name as listed in the Graphics Designer property view.
/* WRONG */
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible ", 0);
/* RIGHT */
SetPropBOOL("1_MAIN","ValvePictureWindow","Visible", 0);
10.2 Buffer Size Mismatch
The char valveName[20] and char TagPrefix1[3] declarations are stack arrays inside the C function. Pass strings longer than the buffer and the printf will print garbage or trigger undefined behavior. WinCC V7.0 strings are null-terminated, so always reserve one byte for the terminator:
char valveName[21]; /* 20 chars + '\0' */
char TagPrefix1[4]; /* 3 chars + '\0' */
10.3 Mismatched Tag Type
If the TagPrefix tag is configured as type TEXT 8 or TEXT 16 in the Tag Management, use SetTagChar for short strings (≤8 bytes) and the appropriate text-tag function for longer values. A mismatch between the tag's length and the value being assigned causes the assignment to fail silently.
10.4 Picture Window Without TagPrefix Property
Picture Windows created on a base picture do not automatically expose a TagPrefix property in older SP levels. Confirm the property is bound in Graphics Designer (right-click the Picture Window → Properties → TagPrefix tab) before relying on it from C.
11. Verification Procedure
- Open Global Script Diagnostics in WinCC Explorer (Tools > Global Script Diagnostics or run
dmf.exefrom the project directory). - Activate the runtime and click valve A's button. Verify the popup displays tag values for prefix A and the diagnostic line shows
The name held in the prefix tag is now......A_. - Close the popup, then click valve B's button. Verify the popup now displays tag values for prefix B and the diagnostic line shows
The name held in the prefix tag is now......B_. - Without closing, click valve C's button (if your UX allows). Verify the popup updates in place to prefix C without ghosting the previous prefix's data.
- Open the WinCC Information System and search for TagPrefix. Cross-check the runtime behavior against the documented binding-time semantics.
12. Best Practices
- Use Pattern A (clear picture name, set prefix, reload picture name) as the default. It is the only pattern that produces deterministic, repeatable behavior across V7.0 SP levels.
- Define
POPUP_WIDTH,POPUP_HEIGHT, and the default picture name as#defineconstants at the top of the project function file to keep the function reusable across screens. - Always capture
GetPropWordforLeft,Top,Width, andHeightof the source object — hardcoding offsets like-156is fragile when buttons are resized. - Wrap
printfdiagnostics in a compile-time flag (e.g.#ifdef _DEBUG_PRINTF_) to silence them in production runtime. - Reserve buffer sizes one byte larger than the longest expected string to leave room for the null terminator.
- Validate that the
TagPrefixtag exists in the tag manager and is of typeTEXT 8or compatible. A missing tag causesSetTagCharto fail silently. - If the project scales beyond a few dozen instances, switch to Pattern C (one Picture Window per instance) and remove the reload logic from the hot path.
TagPrefix property and Picture Window lifecycle, consult the Siemens Industry Online Support WinCC V7.0 documentation set and the WinCC Information System installed with the runtime. Search the WinCC Information System for the keyword TagPrefix.
Why does my WinCC V7.0 C script popup show stale data after a TagPrefix change?
The Picture Window only re-reads the TagPrefix property when the contained picture is re-instantiated. Mutating the backing tag with SetTagChar("TagPrefix", ...) updates the tag manager but does not invalidate the already-loaded picture's resolved tag references. Force a reload by clearing and re-assigning the picture's Picture Name property (Pattern A in §4).
Does toggling the Picture Window's Visible property force a TagPrefix refresh?
No. A Visible = 0 → Visible = 1 cycle hides and re-shows the same live picture instance. The internal prefix binding is preserved. You must change the Picture Name property (even to an empty string and back) to force re-instantiation.
Is TagPrefix still supported in WinCC V7.0?
Yes. The TagPrefix property is supported in WinCC V7.0 through V7.5 and in WinCC Professional (TIA Portal). The semantics are unchanged; the V7.0 Picture Window caching behavior simply makes the reload pattern mandatory, where V6.2 masked the issue with an implicit reload.
Why does my SetPropBOOL call to "Visible" return FALSE with no error?
The most common cause is a mismatch between the property name passed to SetPropBOOL and the canonical property name stored in the picture object. A trailing or leading space ("Visible ") silently mismatches. Always copy the property name directly from the Graphics Designer property view.
Should I use a project function or direct event scripting for the popup logic?
Both are valid. Project functions give you reusability across many buttons (e.g. a fleet of 50+ valves) but expose the TagPrefix binding issue more visibly. Direct event scripting masks the issue but does not scale. Use a project function with the Pattern A picture-reload sequence in §4 to get the best of both.
My printf diagnostic shows the correct TagPrefix but the popup still shows old data. What is the next check?
Confirm that the TagPrefix property is actually wired to the tag inside Graphics Designer (right-click the Picture Window → Properties → TagPrefix). If the property is bound to a hardcoded string instead of the tag, the tag update never reaches the picture. Then verify the Picture Name property is being changed in the same call — the tag update alone is not enough.