WinCC C-Script: Setting Default Object Colors for Alarm Fields

David Krause11 min read
SiemensTutorial / How-toWinCC
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

1. Overview

WinCC V7.x and TIA Portal WinCC Professional allow C and VB scripts to be attached to object properties in the Graphics Designer. When a script is bound to a color property (e.g., Background Color, Line Color, Font Color), the runtime calls the script every time the property must be evaluated. The script must return a value of the same data type as the property — in the case of colors, a signed 32-bit long integer. Returning a hard-coded color such as CO_LTGRAY from the function overrides whatever the engineer configured in the Graphics Designer, which is a common complaint when engineers want the script to apply alarm color logic only on an active alarm and leave the configured default color untouched when the alarm is inactive.

This reference documents four production-proven methods to introduce a "default color" in C-scripts:

  1. Centralized macro defined in apdefap.h.
  2. Direct return of CO_xxx color constants from a property script.
  3. Action-based color change (no return value, so the designer property is preserved).
  4. Read-modify-write using GetBackColor / GetForeColor to fall back to the original designer value.

The article applies to WinCC V7.4 SP1 through V8.0 and to WinCC Professional (TIA Portal) V15.1 through V19 for projects that still use the legacy ANSI-C scripting interface. All WinCC CO_xxx color constants originate from the WinCC header apdefap.h shipped with the installation.

2. Prerequisites

  • WinCC Explorer with a project open and the Graphics Designer running.
  • An object that has a property to which a C-script is already attached (e.g., an Alarm Field, Status Display, or a rectangle placed in a process picture).
  • Internal tag of type BYTE (or BOOL promoted to BYTE) that carries the alarm state used for color decision (e.g., tagColor).
  • Edit rights on the WinCC project database and on the Library subfolder.
  • Recommended: Siemens WinCC V7.5 SP2 Documentation as a reference for the ANSI-C function library.
  • For TIA Portal users: the legacy C-script editor is enabled (TIA Portal → Options → Settings → Visualization → Scripts → "Allow C scripts").

3. How WinCC Property Scripts Evaluate Colors

When a script is attached to a property of type Color, WinCC treats the script as the value source for that property. The runtime ignores whatever value is set in the Properties dialog the moment a script is bound. The script must return a long int in the range 0x00000000 to 0x00FFFFFF (or 0xFF000000 for the system default color when used with SetXXXColor functions).

Because the script replaces the designer value, the engineer must either:

  • Return the designer-configured color back to the runtime (using GetBackColor / GetForeColor), or
  • Return a single fixed color constant, or
  • Avoid the property-script binding altogether and use an Action that writes the color via SetBackColor / SetForeColor only when a condition is met.
Important: The "Color" property script return type is long int. Returning BOOL (as SetBackFlashColor / SetAlarmFieldColor do) is invalid for color properties. Use SetAlarmFieldColor only inside an Action, not as a property script return value.

4. Method 1 — Centralized Default-Color Macro in apdefap.h

The apdefap.h header file is located in <ProjectName>\Library. It is compiled into every ANSI-C function in the project, so a single #define made here becomes available to every script.

4.1 Procedure

  1. In WinCC Explorer, open the Global C Script editor (right-click → Open) or use a text editor with Administrator rights.
  2. Navigate to the project path: %ProgramData%\Siemens\Automation\WinCC\<ProjectName>\Library\apdefap.h.
  3. Add a macro entry, e.g.:
    #define MY_DEFAULT_COLOR CO_LTGRAY
  4. Save the file. WinCC does not need to be restarted, but all C-functions that reference the macro must be recompiled.
  5. In your object property script:
    int alarmstatus;
    alarmstatus = GetTagByte("tagColor");   // BYTE 0 = OK, 1 = Active/* When alarm is inactive return designer default;
       when active let SetAlarmFieldColor handle flashing */
    if (alarmstatus == 0) {
        return MY_DEFAULT_COLOR;          // long int 0x00C0C0C0
    } else {
        return CO_RED;                    // long int 0x000000FF
    }
Recompile required: A macro is a compile-time substitution. Changing CO_LTGRAY to CO_WHITE in apdefap.h does not propagate to already-compiled functions. Use the procedure in Section 8 to force a rebuild.

5. Method 2 — Direct Return of Color Constants

The simplest case is a property script that returns a hard-coded CO_xxx value. The runtime color table is defined in apdefap.h. The most commonly used values for alarm logic are:

Macro Hex (RGB) Typical use
CO_BLACK 0x000000 Power off / fault
CO_DKRED 0x000080 Critical alarm static
CO_RED 0x0000FF High-priority alarm (BGR encoding)
CO_GREEN 0x008000 Running / OK
CO_LTGREEN 0x00FF00 Ready / Healthy
CO_LTBLUE 0xFF0000 Manual / Override
CO_YELLOW 0x00FFFF Warning (low-priority alarm)
CO_LTGRAY 0xC0C0C0 Neutral / default background
CO_WHITE 0xFFFFFF Selected / focused
CO_MAGENTA 0x00FF00FF (high-bit set) Not used in alarm logic; reserved

Direct return pattern (drop-in replacement for the original code in the question):

/* Property script bound to "Background Color" of an alarm object */
int alarmstatus;
alarmstatus = GetTagByte("tagColor");     /* 0 = no alarm, >0 = alarm */
if (alarmstatus) {
    return CO_RED;            /* Alarm active */
} else {
    return CO_LTGRAY;         /* Default background */
}

6. Method 3 — Action-Based Color Change

When you want the Graphics Designer default to remain the runtime value, do not bind the script to a property. Instead, attach the script as an Action (event-driven C-script) and call SetBackColor / SetForeColor only when an alarm is active. The WinCC ANSI-C Function Description lists the function signatures:

BOOL SetBackColor(LPCTSTR lpszPictureName,
                  LPCTSTR lpszObjectName,
                  long int lColor);
BOOL SetForeColor(LPCTSTR lpszPictureName,
                  LPCTSTR lpszObjectName,
                  long int lColor);

6.1 Triggering the action

Right-click the object in the Graphics Designer → Properties → Events tab → click the lightning icon on the desired trigger (commonly Mouse Click, Tag Change, or Picture Change). A return value is not used here, so the designer color is preserved.

6.2 Action example

/* Action script - bound to "tagColor" tag-change event */
int alarmstatus;
alarmstatus = GetTagByte("tagColor");
if (alarmstatus) {
    SetBackColor(lpszPictureName, lpszObjectName, CO_RED);
    SetForeColor(lpszPictureName, lpszObjectName, CO_WHITE);
} else {
    /* Restore designer-configured color */
    long int orig;
    orig = GetBackColor(lpszPictureName, lpszObjectName);
    SetBackColor(lpszPictureName, lpszObjectName, orig);
    /* No SetForeColor call -> designer default retained */
}

7. Method 4 — Read-Modify-Write via GetBackColor / GetForeColor

When a property script must be used (e.g., for dynamic color animation that WinCC requires as a property binding), preserve the designer value with a read at picture-open time, then return that stored value when no alarm is active. The relevant read APIs:

long int GetBackColor(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName);
long int GetForeColor(LPCTSTR lpszPictureName, LPCTSTR lpszObjectName);

7.1 Pattern

  1. On the object's Open Picture event, store the designer color in a project-internal tag of type long int (e.g., tagDefaultBg):
    SetTagLong("tagDefaultBg",
              GetBackColor(lpszPictureName, lpszObjectName));
  2. In the color property script:
    int alarmstatus;
    long int bgDefault;
    alarmstatus = GetTagByte("tagColor");
    bgDefault   = GetTagLong("tagDefaultBg");
    if (alarmstatus) {
        return CO_RED;
    } else {
        return bgDefault;   /* designer color preserved */
    }

For a list of additional color manipulation functions open the WinCC help and search the index for "color". Useful functions include SetBackFlashColor, SetForeFlashColor, SetBackColor, SetForeColor, and the flashing counterparts — note that flashing variants take two colors and a flash frequency, which is exactly the signature of SetAlarmFieldColor:

BOOL SetAlarmFieldColor(LPCTSTR lpszPictureName,
                        LPCTSTR lpszObjectName,
                        long int lColorOn,
                        long int lColorOff,
                        long int lFlashFreq);

8. Recompilation Procedure (after editing apdefap.h)

The apdefap.h file is parsed at compile time. Any change to a macro used by project functions requires a forced rebuild:

  1. Open Global C Script editor in WinCC Explorer.
  2. Menu: Edit → Compile All Functions. Wait for "Compile completed" in the status bar; check Output window for errors such as C0001: Undeclared identifier.
  3. For project-specific Actions: open each picture in the Graphics Designer and re-save it (File → Save). The "Compile All Functions" command does not touch Actions attached to events.
  4. To force a full project-wide C-script rebuild: WinCC Explorer → Graphics Designer → right-click → Convert Pictures. This re-compiles every C-script in every picture.
  5. Open Diagnostics in the WinCC Explorer and confirm no CSCRIPT-prefixed error messages are present.
  6. Activate the runtime (WinCC Explorer → Activate) and check the APDIAG output window — successful initialization shows "All C functions compiled successfully".

9. Disabling the Global Color Scheme

WinCC ships with a "Global Color Scheme" that propagates a project-wide color to objects. When the script is correctly returning a color but the object still displays the project default, the cause is usually the global color scheme override.

  1. Open the object's Properties dialog in the Graphics Designer.
  2. Expand Effects (or in older versions Miscellaneous).
  3. Set Global Color Scheme to No.
  4. Compile and save the picture.
  5. Re-test in runtime.
Note: Disabling the global color scheme affects the appearance of the configured design (Siemens HMI Style "WinCC Classic" vs. "WinCC Future"). Confirm with the HMI style guide that the design is approved for the project before switching off this option.

10. Color Constants Reference Table

Macro Decimal (long int) Hex (RGB little-endian) Notes
CO_BLACK 0 0x000000
CO_DKRED 128 0x000080 Dark red, BGR-encoded
CO_DKGREEN 32768 0x008000 Dark green
CO_DKYELLOW 32896 0x008080 Dark yellow / olive
CO_DKBLUE 8388608 0x800000 Dark blue
CO_DKMAGENTA 8388736 0x800080 Dark magenta
CO_DKCYAN 8421376 0x808000 Dark cyan
CO_DKGRAY 8421504 0x808080 50 % gray
CO_RED 255 0x0000FF Bright red
CO_GREEN 65280 0x00FF00 Bright green
CO_YELLOW 65535 0x00FFFF Bright yellow
CO_BLUE 16711680 0xFF0000 Bright blue
CO_MAGENTA 16711935 0xFF00FF Bright magenta
CO_CYAN 16776960 0xFFFF00 Bright cyan
CO_LTGRAY 12632256 0xC0C0C0 Light gray — typical default
CO_WHITE 16777215 0xFFFFFF White

The high bit (0x80000000) is reserved and not part of the RGB triplet.

11. Verification

  1. Compile the project and confirm the output window shows zero errors and zero warnings.
  2. Activate runtime (Ctrl+F7 in WinCC V7, or the green arrow in TIA Portal).
  3. Force the alarm tag tagColor = 0; confirm the object shows the default color (either the macro value or the designer-configured value, depending on the method chosen).
  4. Set tagColor = 1 via the Tag Simulator (WinCC Explorer → Tools → Tag Simulation); confirm the object color changes to CO_RED.
  5. Reset tagColor = 0 and confirm the object returns to the default color within one runtime cycle (default 250 ms for tag-change-triggered actions).
  6. For flashing alarm fields using SetAlarmFieldColor, set the fourth parameter (flash frequency) to a value between 250 ms and 1000 ms; values outside this range are ignored or cause flicker on slow HMIs.

12. Troubleshooting Matrix

Symptom Likely cause Fix
Color never changes, stays default Global Color Scheme = Yes Object Properties → Effects → Global Color Scheme → No
Script compile error: "Undeclared identifier MY_DEFAULT_COLOR" Macro not visible in script context Verify macro is in apdefap.h; run Compile All Functions
Returns -1 or runtime shows "Invalid color" Return type mismatch; SetXXXColor returns BOOL Property script must return long int; use CO_xxx directly
Designer color lost after activating project Property script overrides designer value unconditionally Use Method 3 (Action-based) or Method 4 (read designer color)
Macro change has no effect at runtime Stale compiled function Run Compile All Functions, save all pictures, Convert Pictures
Flash frequency erratic on multi-monitor station Flash frequency too high for graphic adapter Set flash frequency ≥ 500 ms; avoid < 250 ms
C0001: Syntax error near 'int' Variable declared after executable code in ANSI-C Move all int, long, float declarations to the top of the function
Script returns correct color, APDiag shows "Function returns invalid value" Return value > 0x00FFFFFF (high bit set) Mask result: return (color & 0x00FFFFFF);
TIA Portal: "C script not allowed" C-script support disabled Options → Settings → Visualization → Scripts → enable legacy C
Color flashes but base color wrong SetAlarmFieldColor uses lColorOn/lColorOff instead of single color Pass two long-int colors; e.g., (CO_RED, CO_WHITE, 500)

13. Frequently Asked Questions

Why does the object color stay the same after my script returns CO_RED?

Check Object Properties → Effects → Global Color Scheme and set it to No. Also verify the script is actually attached to the property (right-click the property value field in the Properties dialog — a lightning icon indicates an active event or script binding).

Can I use SetAlarmFieldColor as a property script return value?

No. SetAlarmFieldColor returns BOOL, but a color property script must return a long int. Use SetAlarmFieldColor only inside an Action triggered by a tag change or a mouse event, not as the value source of a property.

How do I keep the color that I set in the Graphics Designer?

Use Method 3 (action-based color change) or Method 4 (read-modify-write with GetBackColor / GetForeColor). The simplest is an Action that only writes a new color when the alarm is active and leaves the designer value alone otherwise — the property script path is bypassed entirely.

Why does changing the macro in apdefap.h not change the runtime color?

Because apdefap.h is read at compile time. Use Global C Script → Compile All Functions, then re-save every picture, and finally run Graphics Designer → Convert Pictures to force every C-script to re-compile with the new macro value.

What is the default flash frequency for SetAlarmFieldColor?

The fifth parameter is a long int in milliseconds. Values from 0 to 100 are interpreted as "no flash". Practical values are 500–1000 ms. Below 250 ms the operator cannot perceive the flash, and below 100 ms the runtime ignores the request and treats the field as static.

Does this technique apply to TIA Portal WinCC Professional?

Yes, but only when the legacy C-script interface is enabled. In TIA Portal V18 and later, the preferred long-term path is VBScript or the dynamic SVG widget with property bindings to expressions, but the ANSI-C functions and the apdefap.h header continue to work identically to WinCC V7 for migration projects.

Back to blog