Skip to content

Commit ba3023c

Browse files
Fix #5: read live NUMERICUPDOWN/TRACKBAR value in @FORMGET; bump to v1.1.2
- @FORMGET value on NUMERICUPDOWN/TRACKBAR now reads the live control's current value via the GUI thread (falling back to the stored descriptor property when not realized), instead of returning the initial value. Matches the existing DATETIMEPICKER read path. (issue #5) - Release workflow now publishes a stably-named FormCast.zip alongside FormCast-v<tag>.zip so the version-independent releases/latest/download/FormCast.zip URL resolves to the latest release. - Bump version to 1.1.2 and add CHANGELOG entry.
1 parent 5e9f4a0 commit ba3023c

4 files changed

Lines changed: 76 additions & 5 deletions

File tree

.github/workflows/release.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ name: Release
33
# Release pipeline. Fires on pushes of tags matching v* (e.g. v1.0.0,
44
# v1.2.3-rc1). Builds the solution in Release, runs the full xUnit
55
# test suite as defense-in-depth against a tag on an untested commit,
6-
# stages the release tree, produces FormCast-v<tag>.zip, and publishes
7-
# a GitHub release with the zip attached and CHANGELOG.md as the body.
6+
# stages the release tree, produces FormCast-v<tag>.zip plus an
7+
# identical stably-named FormCast.zip (so the version-independent
8+
# .../releases/latest/download/FormCast.zip URL works), and publishes
9+
# a GitHub release with both zips attached and CHANGELOG.md as the body.
810
#
911
# Continuous integration for normal development lives in ci.yml and
1012
# fires on push/PR to main.
@@ -89,11 +91,18 @@ jobs:
8991
$tag = '${{ github.ref_name }}'
9092
Compress-Archive -Path release-stage/* -DestinationPath "FormCast-$tag.zip"
9193
94+
# Also publish a stably-named copy so the "latest release"
95+
# download URL is version-independent and can be hard-coded
96+
# in docs / installers:
97+
# .../releases/latest/download/FormCast.zip
98+
Copy-Item "FormCast-$tag.zip" "FormCast.zip"
99+
92100
- name: Create GitHub release
93101
uses: softprops/action-gh-release@v2
94102
with:
95103
files: |
96104
FormCast-*.zip
105+
FormCast.zip
97106
generate_release_notes: true
98107
body_path: CHANGELOG.md
99108
env:

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ and the project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.
77

88
See [README.md](README.md) for the feature overview and install instructions.
99

10+
## [1.1.2] -- 2026-06-01
11+
12+
### Fixed
13+
14+
- **NUMERICUPDOWN and TRACKBAR value get**: `@FORMGET` for the `value`
15+
property now reads the live control's current value instead of the
16+
initial descriptor value, so changes the user makes in the form are
17+
reflected. (issue #5)
18+
19+
### Changed
20+
21+
- **Release zip**: the release workflow now publishes an identically
22+
named `FormCast.zip` alongside the versioned `FormCast-v<tag>.zip`, so
23+
the version-independent
24+
`releases/latest/download/FormCast.zip` URL resolves to the latest
25+
release.
26+
1027
## [1.1.1] -- 2026-05-27
1128

1229
### Fixed

Directory.Build.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>1.1.1</Version>
4-
<AssemblyVersion>1.1.1.0</AssemblyVersion>
5-
<FileVersion>1.1.1.0</FileVersion>
3+
<Version>1.1.2</Version>
4+
<AssemblyVersion>1.1.2.0</AssemblyVersion>
5+
<FileVersion>1.1.2.0</FileVersion>
66
</PropertyGroup>
77
</Project>

src/FormCast/Plugin.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,12 @@ public int f_FORMGET(StringBuilder args)
11311131
{
11321132
result = TryReadDateTimePickerValue(seq, c);
11331133
}
1134+
else if (string.Equals(prop, "value", StringComparison.OrdinalIgnoreCase) &&
1135+
(string.Equals(c.Type, "NUMERICUPDOWN", StringComparison.OrdinalIgnoreCase) ||
1136+
string.Equals(c.Type, "TRACKBAR", StringComparison.OrdinalIgnoreCase)))
1137+
{
1138+
result = TryReadNumericValue(seq, c);
1139+
}
11341140
else
11351141
{
11361142
result = TryGetControlProperty(c, prop);
@@ -1282,6 +1288,45 @@ private string TryReadDateTimePickerValue(int seq, ControlDescriptor c)
12821288
return result;
12831289
}
12841290

1291+
/// <summary>
1292+
/// Read the live numeric value of a realized NUMERICUPDOWN or
1293+
/// TRACKBAR. Without this, FORMGET value falls through to the
1294+
/// descriptor's stored "value" property and returns the initial
1295+
/// value rather than what the user changed it to in the form.
1296+
/// Falls back to the stored property when the form has not been
1297+
/// realized.
1298+
/// </summary>
1299+
private string TryReadNumericValue(int seq, ControlDescriptor c)
1300+
{
1301+
Form? realized;
1302+
lock (_realizedFormsLock)
1303+
{
1304+
_realizedForms.TryGetValue(seq, out realized);
1305+
}
1306+
string fallback = c.Properties.TryGetValue("value", out string? v)
1307+
? v ?? string.Empty : string.Empty;
1308+
if (realized is null) { return fallback; }
1309+
1310+
string result = fallback;
1311+
_guiHost.Invoke(() =>
1312+
{
1313+
if (realized.IsDisposed) { return; }
1314+
System.Windows.Forms.Control? target = FindRealizedControl(realized, c.Id);
1315+
if (target is NumericUpDown nud)
1316+
{
1317+
// Value is a decimal; format invariantly so a
1318+
// control configured with DecimalPlaces > 0 keeps
1319+
// its fractional part instead of being truncated.
1320+
result = nud.Value.ToString(CultureInfo.InvariantCulture);
1321+
}
1322+
else if (target is TrackBar tb)
1323+
{
1324+
result = tb.Value.ToString(CultureInfo.InvariantCulture);
1325+
}
1326+
});
1327+
return result;
1328+
}
1329+
12851330
private string TryReadMemoText(int seq, ControlDescriptor c)
12861331
{
12871332
Form? realized;

0 commit comments

Comments
 (0)