<?xml version="1.0" encoding="UTF-8"?><rss version="2.0">	<channel>	<title>TMS Software</title>	<link>https://www.tmssoftware.com</link>	<language>en</language>	<pubDate>Fri, 10 Jul 2026 12:38:00 +0100</pubDate>	<docs>http://blogs.law.harvard.edu/tech/rss</docs>	<ttl>1440</ttl>	<generator>TMS Software</generator>	<image>		<url>https://www.tmssoftware.com/site/img/tmslogo.png</url>		<title>TMS Software</title>		<link>https://www.tmssoftware.com</link>	</image>
	<item>
		<title><![CDATA[ï»¿A New Home for TMS Documentation]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2501</link>
		<author>Pieter Scheldeman</author>
		<pubDate>Fri, 10 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿<h4 style="color: rgb(0, 0, 0);">Intro</h4>
<p>Documentation is where most developers meet a component for the first time. It should be fast to browse, honest about what the control does, and easy to read at 8 a.m. or midnight. That is why we have rebuilt the TMS documentation from the ground up: a single, modern site with a consistent structure, real screenshots, full-text search, and code you can copy straight into a project.</p>

<p>The new site lives at <a href="https://doc.tmssoftware.com" target="_blank">doc.tmssoftware.com</a>. Each product family is its own self-contained site, so <a href="https://www.tmssoftware.com/site/tmsfncuipack.asp" target="_blank">TMS FNC UI Pack</a> and every other product share the exact same look, navigation, and search &#151; while still deploying independently.</p>

<h4>What Is New</h4>
<ul>
<li><p><strong>One consistent structure:</strong> every product has an Overview, a Components catalog, Product Guides, Release Notes, and a full API Reference in the same order, so once you learn one product you know them all.</p></li>
<li><p><strong>Task-oriented guides:</strong> instead of a wall of property names, guides explain <em>why</em> and <em>when</em> to use a feature, with a runnable example for every workflow.</p></li>
<li><p><strong>Qt-style API reference:</strong> each class page shows unit family, inheritance, implemented interfaces, and grouped properties, methods and events &#151; with inherited API separated from what the class itself declares.</p></li>
<li><p><strong>Light and dark themes:</strong> a single click switches the whole site, and the screenshots switch with it.</p></li>
<li><p><strong>Full-text search:</strong> instant results across guides, API and pages, faceted by type.</p></li>
<li><p><strong>Real, verified content:</strong> screenshots are captured from the live control, and code snippets are checked against the current source.</p><p><br></p></li>
</ul>

<h4>One Look, Light or Dark</h4>
<p>Here is the same page &#151; the TMS FNC UI Pack Data Grid landing page &#151; in both themes. Notice the consistent frame: the product catalog on the left, breadcrumbs and content in the middle, an &#147;In this article&#148; outline on the right, and search plus the theme toggles in the top bar. The hero screenshot even follows the theme you pick.</p>

<p><img src="http://tmssoftware.com/site/img/newdoc/doc-datagrid-light.png" style="max-width: 100%;" data-filename="doc-datagrid-light.png" alt="TMS FNC Data Grid documentation page in light theme, showing the component sidebar, breadcrumbs, hero screenshot and article outline"></p>

<p><img src="http://tmssoftware.com/site/img/newdoc/doc-datagrid-dark.png" style="max-width: 100%;" data-filename="doc-datagrid-dark.png" alt="The same TMS FNC Data Grid documentation page in dark theme"></p>

<h4>Guides That Teach</h4>
<p>Feature guides are the heart of the new docs. They open with the use case, explain the concepts, and back every workflow with a runnable snippet and a screenshot of the real UI state. The Data Grid <em>Filtering</em> guide, for example, walks from a one-line live search box all the way to Excel-style header dropdowns and advanced filter expressions &#151; with a detailed outline so you can jump straight to the step you need.</p>

<p><img src="http://tmssoftware.com/site/img/newdoc/doc-filtering-guide.png" style="max-width: 100%;" data-filename="doc-filtering-guide.png" alt="The Data Grid Filtering guide page, showing an intro callout, explanatory prose with inline code, a comparison table of filtering UIs, and a deep in-article outline"></p>

<p>And because setup-heavy workflows need more than a property table, every guide backs its explanation with a compilable snippet. Enabling the filter row with header filter dropdowns on the grid looks like this:</p>

<pre class="delphi" name="code">procedure TForm1.FormCreate(Sender: TObject);
begin
  TMSFNCDataGrid1.BeginUpdate;
  try
    TMSFNCDataGrid1.Options.Filtering.Enabled := True;
    TMSFNCDataGrid1.Options.Filtering.Row := True;
    TMSFNCDataGrid1.Options.Filtering.DropDown := True;
    TMSFNCDataGrid1.Options.Filtering.MultiColumn := True;
  finally
    TMSFNCDataGrid1.EndUpdate;
  end;
end;</pre>

<p>Snippets like this are validated against the current source, so the property paths and call order stay correct as the product evolves.</p><p><br></p>

<h4>Search Across Everything</h4>
<p>Every family site ships with instant full-text search. Start typing and you get ranked results across guides, API members and pages, faceted by type &#151; with keyboard navigation so you never have to reach for the mouse.</p>

<p><img src="http://tmssoftware.com/site/img/newdoc/doc-search.png" style="max-width: 100%;" data-filename="doc-search.png" alt="Full-text search results for the query filter, showing 120 results faceted into All, API, Guides and Pages tabs, with matching terms highlighted across several products"></p>

<h4>Finding Your Way Around</h4>
<p>Each product overview offers two clear routes to the same information:</p>

<ul>
<li><p><strong>By component:</strong> Overview â†&#39; Components â†&#39; the component landing page â†&#39; its guides and API. Best when you know which control you need.</p></li>
<li><p><strong>By API:</strong> Overview â†&#39; API Reference, grouped by component first rather than a flat alphabetical dump. Best when you are looking up a specific class or member.</p></li>
</ul>

<p>Component guides live with the component, and cross-cutting topics (JSON persistence, SVG, getting started) live under Product Guides, so a page is always where you would expect it to be.</p><p><br></p>

<h4>What Is Next</h4>
<p>The new site currently focuses on the TMS FNC product family, which is where we started rolling out the new format. That is only the beginning.</p>

<p>Over the coming period we will be moving the remaining legacy documentation into the new system, including content that today lives in standalone PDF files. As each product is migrated, its guides, examples, and API reference will be rewritten to the same structure &#151; consistent navigation, real themed screenshots, verified snippets, and full-text search &#151; so the whole TMS catalog eventually shares one modern home instead of a mix of older sites and separate PDFs.</p><p><br></p>

<h4>Conclusion</h4>
<p>The new TMS documentation site is a consistent, searchable, theme-aware home for every product, built so that guides teach, screenshots reflect the real control, and code samples compile. The TMS FNC UI Pack Data Grid pages are a good place to start exploring the new format.</p>

<p>Visit <a href="https://doc.tmssoftware.com" target="_blank">doc.tmssoftware.com</a> and browse the TMS FNC UI Pack section to see it in action.</p>
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿Filtering in Delphi: Visual Filter Building]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2497</link>
		<author>Gjalt Vanhouwaert</author>
		<pubDate>Thu, 9 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		
		<p>In the <a href="https://tmssoftware.com/site/blog.asp?post=2492">previous blog post</a>, we looked at how <b>TTMSFNCFilterBuilder</b> can be used to build filters as a structured model instead of manually creating one long filter string.</p>

<p>That structure gives us a lot of flexibility as developers.<br> But in many applications, the filter is not something the developer should define completely in code.</p>

<p>At some point, users need a way to create or change filters themselves.</p>

<p>And we probably don&#39;t want them to write something like this:</p>

<pre class="delphi" name="code">(Age &gt; 18 AND Country = &#39;BE&#39;) OR (Age &gt; 21 AND Country = &#39;US&#39;)</pre>

<p>This is where the filter dialogs come in.</p><p><br></p>

<h3>Visual Filtering</h3>

<p>The idea is simple.</p>

<p>Instead of asking users to write filter text manually, we let them build the filter visually.</p>

<p>They select:</p>

<ul> <li>the field they want to filter on</li> <li>the operator they want to use</li> <li>the value they want to compare with</li> </ul>

<p>The dialog then creates the filter structure internally and generates the correct filter text.</p>

<p>Because the dialog knows the type of each field, it can also limit the available operators to those that make sense for that field.</p>

<p>So a text field will not show the same operators as a number field, and a boolean field will not show operators that require a text value.</p>

<p>This means that operator mismatch errors are avoided before the filter is even created.</p><p><br></p>

<h3>TTMSFNCDataSetFilterDialog</h3><p style="text-align: center; "><img src="https://www.tmssoftware.com/site/img/blog/FilterSeries/FilterSeriesFilterDialog.png" style="width: 80%;" alt="TMS Software Delphi  Components tmsfncuipack"><br></p>

<p>The easiest way to start is with <b>TTMSFNCDataSetFilterDialog</b>. This control is available in our <a href="https://tmssoftware.com/site/tmsfncuipack.asp">TMS FNC UI Pack</a>.</p>

<p>This dialog is specifically made for working with a <code>TDataSet</code>.</p>

<p>You can connect it to a dataset:</p>

<pre class="delphi" name="code">DataSetFilterDialog.DataSet := ClientDataSet1;</pre>

<p>When the dialog is opened, it can use the dataset fields to determine which fields are available and which data type they have.</p>

<p>This makes the setup very small, while still giving the user a guided way to create a filter.</p>

<p>The generated result can be assigned directly to the dataset filter.</p>

<pre class="delphi" name="code">ClientDataSet1.Filter := DataSetFilterDialog.FilterText; ClientDataSet1.Filtered := ClientDataSet1.Filter &lt;&gt; &#39;&#39;;</pre>

<p>In most cases you don&#39;t even need to manually handle the generated filter text, because the dialog is designed to work directly with the dataset.</p><p><br></p>

<h3>Editing Existing Filters</h3>

<p>The dialog is not only useful for creating new filters.</p>

<p>If the dataset already has a filter text assigned, the dialog can parse it and rebuild the visual structure.</p>

<p>This makes it possible to open an existing filter, change it visually, and write the updated filter text back to the dataset.</p>

<p>So instead of replacing existing filtering logic, the dialog helps to make it easier to manage.</p><p><br></p>

<h3>New: Design-Time Filter Editor</h3>

<p>Since the latest release, <b>TTMSFNCDataSetFilterDialog</b> is also available as a design-time editor for the <code>Filter</code> property of a <code>TDataSet</code>.</p>

<p>This means you no longer need to type the filter text manually in the Object Inspector.</p>

<p>You can open the visual filter dialog, select the fields, operators and values, and let the editor generate the filter text for you.</p>

<p>This is especially useful when setting up filters during development.</p>

<p>You immediately get visual guidance, and because only valid operators are available for the selected field type, invalid operator combinations can be avoided.</p>

<p>The generated filter text is then written back to the dataset <code>Filter</code> property.</p><p><br></p>

<h3>TTMSFNCFilterDialog</h3>

<p>While <b>TTMSFNCDataSetFilterDialog</b> focuses on datasets, <b>TTMSFNCFilterDialog</b> is the more general version.</p>

<p>It uses the same FilterBuilder structure internally, but it is not tied to a <code>TDataSet</code>.</p>

<p>This makes it usable in situations where the data comes from another control or another source.</p>

<p>For example, when using a <b>TTMSFNCDataGrid</b>, the dialog needs to know which columns are available and what data type they represent.</p>

<p>This can be configured directly through the dialog properties or by preparing the <code>FilterBuilder</code> first.</p>

<pre class="delphi" name="code">FilterDialog.FilterBuilder.DataColumns.Clear; FilterDialog.FilterBuilder.DataColumns.AddColumn(&#39;Age&#39;, fdtNumber); FilterDialog.FilterBuilder.DataColumns.AddColumn(&#39;Country&#39;, fdtText); FilterDialog.FilterBuilder.DataColumns.AddColumn(&#39;Active&#39;, fdtBoolean);</pre>

<p>By defining these columns up front, the dialog can again show the correct fields and only the matching operators.</p><p style="text-align: center; "><img src="https://www.tmssoftware.com/site/img/blog/FilterSeries/FilterSeriesDateEditor.png" style="width: 40%;" alt="TMS Software Delphi  Components tmsfncuipack"><br></p>

<p>Events can still be used when you want to fill the available columns dynamically, but for many cases configuring the columns directly is the most straightforward approach.</p><p><br></p>

<h3>Using the Dialog with TTMSFNCDataGrid</h3><p style="text-align: center;"><img src="https://tmssoftware.com/site/img/blog/fncui/datagridfilterdialogblog_1.png" style="width: 60%;" alt="TMS Software Delphi  Components tmsfncuipack"><br></p>

<p>The <b>TTMSFNCDataGrid</b> now also supports the filter dialog directly.</p>

<p>This means that the grid can offer a visual advanced filtering experience without requiring the user to write the filter text manually.</p>

<p>The dialog uses the grid columns to build the available filter fields and then applies the resulting filter to the grid.</p>

<p>This is useful when the filter becomes more complex than a simple column filter.</p>

<p>For example, when you want to combine multiple conditions:</p>

<pre class="delphi" name="code">(Age &gt; 18 AND Country = &#39;BE&#39;) OR (Active = True)</pre>

<p>The user can build this visually, while the grid receives a valid filter structure.</p><p><br></p>

<h3>Why This Matters</h3>

<p>Using a visual filter dialog gives a few practical advantages:</p>

<ul> <li>Users don&#39;t need to know the actual field names.</li> <li>Only operators that match the selected field type are shown.</li> <li>AND/OR mismatch errors are prevented while building the filter.</li> <li>Values can be entered with guidance based on the field type.</li> <li>Existing filters can be opened and edited visually.</li> <li>Nested filter groups with <code>AND</code> and <code>OR</code> become easier to create.</li> <li>The generated filter text can still be used with the existing filtering mechanism.</li> </ul>

<p>The important part is that the dialog doesn&#39;t introduce a separate filtering system.</p>

<p>It builds on the same structured filter logic from the FilterBuilder and helps users create that structure visually.</p><p><br></p>

<h3>Next Step</h3>

<p>With the FilterDialog, users can create filters in a guided way through a dialog.</p>

<p>In the next blog post, we&#39;ll take this one step further with <b>TTMSFNCFilterView</b>.</p>

<p>Instead of opening a dialog, users will interact directly with controls such as checkboxes, combo boxes, sliders and date pickers, while the filter is updated automatically in the background.</p>
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿TMS BIZ July 2026: External Logins, Custom Password Hashing, and More]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2496</link>
		<author>Wagner Landgraf</author>
		<pubDate>Thu, 9 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		
		<p>The July 2026 update of <strong><a href="https://www.tmssoftware.com/site/tmsbizintro.asp">TMS BIZ</a></strong> is out, and it&#39;s a big one for anyone building authenticated, data-driven Delphi backends. The headline is identity brokering in TMS Sphinx &#151; "Login with Google / Microsoft" for your own apps &#151; but there&#39;s a lot more under the hood: pluggable password hashing, external-only login pages, chunked streaming in XData, cleaner REST URLs, X.509-based JWT verification in the core library, and a batch of stability fixes across Sparkle and Aurelius.</p>

<p>Here&#39;s a tour of what&#39;s new, roughly in order of how much it&#39;s likely to change the way you build apps.</p><p><br></p>

<h3>1. Login with Google, Microsoft and more &#151; identity brokering in TMS Sphinx</h3>

<p><strong><a href="https://www.tmssoftware.com/site/sphinx.asp">TMS Sphinx</a></strong> is an <a href="https://oauth.net/2/">OAuth 2.0</a> and <a href="https://openid.net/connect/">OpenID Connect</a> authentication and authorization server framework for Delphi. With this release, Sphinx can act as an <strong>identity broker</strong>: it delegates authentication to an upstream provider like Google or Microsoft Entra, receives the result, maps it to a local user, and still issues its own tokens and manages its own sessions.</p>

<p>In practice, that means you can now add a row of familiar <em>"Continue with Google"</em> / <em>"Sign in with Microsoft"</em> buttons to your login page &#151; or transparently route a corporate customer to <em>their</em> identity provider &#151; with almost no plumbing on your side. PKCE, <code>state</code>, <code>nonce</code>, token validation and user reconciliation are all handled for you.</p>

<p>This feature is large enough to deserve its own article, which walks through registering a provider, adding the buttons, automatic user provisioning, multi-tenant Entra and more:</p>

<p>ðŸ‘‰ <strong><a href="https://www.tmssoftware.com/site/blog.asp?post=2494">Login with Google, Microsoft and More &#151; Identity Brokering in TMS Sphinx</a></strong></p>

<p>The rest of this post covers everything <em>else</em> in the release.</p><p><br></p>

<h3>2. Bring your own password hashing (TMS Sphinx)</h3>

<p>Sphinx has always hashed and salted stored passwords for you. But security requirements differ: your organization may mandate a specific algorithm (bcrypt, argon2, a particular PBKDF2 configuration), or you may be migrating users from a legacy system whose hashes you need to keep verifying.</p>

<p>You can now <strong>replace Sphinx&#39;s password hashing entirely</strong>. Implement the new <code>IPasswordHasher</code> interface and assign it to <code>TSphinxConfig.PasswordHasher</code>. Every hash and verify operation Sphinx performs goes through your implementation:</p>

<pre><code>uses
  Sphinx.PasswordHasher, Sphinx.Entities;

type
  TBcryptPasswordHasher = class(TInterfacedObject, IPasswordHasher)
  public
    function HashPassword(User: TUser; const Password: string): string;
    function VerifyHashedPassword(User: TUser; const HashedPassword,
      ProvidedPassword: string): Boolean;
  end;

function TBcryptPasswordHasher.HashPassword(User: TUser;
  const Password: string): string;
begin
  // Delegate to your bcrypt/argon2/PBKDF2 routine of choice.
  // The returned value should carry algorithm id, parameters and salt.
  Result := MyBcrypt.HashPassword(Password);
end;

function TBcryptPasswordHasher.VerifyHashedPassword(User: TUser;
  const HashedPassword, ProvidedPassword: string): Boolean;
begin
  Result := MyBcrypt.Verify(ProvidedPassword, HashedPassword);
end;
</code></pre>

<p>Wire it up once at startup:</p>

<pre><code>  SphinxConfig1.PasswordHasher := TBcryptPasswordHasher.Create;
</code></pre>

<p>When no custom hasher is assigned, Sphinx keeps using its built-in default. A couple of things to keep in mind: the returned hash should embed everything <code>VerifyHashedPassword</code> needs to validate it later, and the implementation is shared across concurrent requests &#151; so make it <strong>stateless and thread-safe</strong>.</p><p><br></p>

<h3>3. External-only login and a smoother sign-out (TMS Sphinx)</h3>

<p>Two more Sphinx additions round out the authentication experience.</p>

<p><strong>Hide the password form entirely.</strong> If you want users to sign in <em>only</em> through external providers, set:</p>

<pre><code>  SphinxConfig1.LoginOptions.AllowPasswordLogin := False;
</code></pre>

<p>The login page then shows just the provider buttons &#151; no username/password fields. (There&#39;s a safeguard: if no external providers happen to be available, the local form is still shown so you can&#39;t accidentally lock everyone out.)</p>

<p><strong>Redirect back after single sign-out.</strong> <code>TSphinxLogin.LogoutAndEndSession</code> and its web counterpart <code>TSphinxWebLogin.LogoutAndEndSession</code> now accept an optional post-logout redirect URI, so the browser can return to a page of your choosing once the SSO session ends:</p>

<pre><code>  SphinxWebLogin1.LogoutAndEndSession(&#39;https://myapp.com/goodbye&#39;);
</code></pre>

<p>For <strong><a href="https://www.tmssoftware.com/site/tmswebcore.asp">TMS Web Core</a></strong> apps, the new <code>TSphinxWebLogin.ManualCallbackCheck</code> property lets you suppress the automatic OAuth callback check that runs when the component loads, giving you explicit control over when the login flow starts. This release also fixes a Base64 URL-safe decoding issue that affected JWT payloads containing non-ASCII characters in Web Core, and resolves an access violation when <code>AuthResult</code> was read before login.</p><p><br></p>

<h3>4. Streaming responses of unknown size (TMS XData)</h3>

<p><strong><a href="https://www.tmssoftware.com/site/xdata.asp">TMS XData</a></strong> is a framework for building REST APIs in Delphi, built on top of Aurelius and Sparkle. A common pattern is a <a href="https://doc.tmssoftware.com/biz/xdata/guide/service-operations.html">service operation</a> that returns a <code>TStream</code> &#151; a generated report, an export, a proxied download.</p>

<p>Until now, that stream needed a known size so XData could set <code>Content-Length</code>. This release adds support for <strong>streams of unknown size</strong> &#151; those whose <code>Size</code> returns a negative value, such as non-seekable pipes or live-generated content. In that case XData automatically switches to <strong>chunked transfer encoding</strong> instead of a fixed <code>Content-Length</code>:</p>

<pre><code>function TReportService.Export: TStream;
begin
  // A non-seekable stream whose final size isn&#39;t known up front.
  // XData sends it with chunked transfer encoding automatically.
  Result := TMyLiveExportStream.Create;
end;
</code></pre>

<p>Just as importantly, the stream is now copied to the client in <strong>buffered blocks</strong> rather than loaded into memory all at once &#151; so large downloads no longer spike your server&#39;s memory usage.</p><p><br></p>

<h3>5. Cleaner REST URLs with key-as-segment (TMS XData)</h3>

<p>By OData convention, XData addresses a single entity with a parenthesized key: <code>/Customer(1)</code>. Many REST clients and API gateways prefer the more conventional path-segment style <code>/Customer/1</code>.</p>

<p>The XData client can now speak that dialect. Set the new <code>EntityKeyAsSegment</code> property and the client builds segment-style URLs:</p>

<pre><code>  Client := TXDataClient.Create;
  Client.Uri := &#39;https://server/tms/xdata&#39;;
  Client.EntityKeyAsSegment := True;

  // Requests /Customer/1 instead of /Customer(1)
  Customer := Client.Get&lt;TCustomer&gt;(1);
</code></pre>

<h3><br></h3><h3>6. X.509 certificate-based JWT verification (TMS BIZ Core Library)</h3>

<p>The <strong>TMS BIZ Core Library (BCL)</strong> is the foundation the other libraries build on, including the JOSE/JWT implementation used across Sphinx and XData. This release syncs it with the latest upstream <a href="https://github.com/paolo-rossi/delphi-jose-jwt">Delphi JOSE JWT</a> library and adds several useful capabilities.</p>

<p>The most notable: <strong>verifying <a href="https://jwt.io/">JWT</a> signatures against an X.509 certificate.</strong> If a token issuer publishes its signing key as a PEM-encoded certificate (rather than a raw JWK), you can now extract the public key straight from that certificate:</p>

<pre><code>uses
  Bcl.Jose.Core.JWS, Bcl.Jose.Core.Base;

var
  JWS: TJWS;
begin
  JWS := TJWS.Create(nil);
  try
    JWS.SetKeyFromCert(CertificatePem);   // PEM-encoded X.509 certificate
    JWS.CompactToken := TheJwtToken;
    if JWS.VerifySignature then
      // signature is valid
  finally
    JWS.Free;
  end;
end;
</code></pre>

<p>Alongside that, this version brings stricter, safer token handling and a few new helpers:</p>

<ul>
  <li><code>TJWS.CheckCompactToken</code> now validates that each decoded token part is valid UTF-8 and well-formed JSON before accepting the token.</li>
  <li>New <code>TJOSEBytes.IsValidString</code> and <code>TJSONUtils.IsValidJSON</code> methods let you validate token parts before deserialization.</li>
  <li><code>TJWTClaims.ClaimExists</code> is now public, so you can check whether a claim is present.</li>
  <li><code>TJSONUtils.SetJSONRttiValue</code> now handles dynamic-array claim values, and new <code>IsJSONBool</code> / <code>GetJSONBool</code> helpers read JSON booleans correctly.</li>
  <li>JWT validation error messages are more descriptive, making token failures easier to diagnose.</li>
  <li>A <code>Pointer</code>/<code>Integer</code> cast that misbehaved on 64-bit platforms has been corrected.</li>
</ul>

<h3><br></h3><h3>7. Aurelius: documented dataset and a cached-updates fix</h3>

<p><strong><a href="https://www.tmssoftware.com/site/aurelius.asp">TMS Aurelius</a></strong> is an ORM framework for Delphi. Two improvements land this cycle.</p>

<p>First, <a href="https://doc.tmssoftware.com/biz/aurelius/api/Aurelius.Bind.Dataset/TAureliusDataset"><code>TAureliusDataset</code></a> &#151; the <code>TDataset</code> descendant that binds Aurelius objects to Delphi&#39;s data-aware controls &#151; now has <strong>full reference documentation</strong> for the class, its associated types, and all public properties and methods, plus an improved guide chapter. If you build VCL/FMX UIs directly over your entities, this fills in a lot of previously undocumented surface area.</p>

<p>Second, a correctness fix in <a href="https://doc.tmssoftware.com/biz/aurelius/guide/object-manager.html">cached updates</a>: when calling <code>TObjectManager.ApplyUpdates</code> with cached updates enabled, extra actions generated during the flush (for example, persisting a new object inside an <code>OnInserted</code> handler) were cached but never executed &#151; silently discarded at the end of the call. Those actions are now applied correctly.</p><p><br></p>

<h3>8. Sparkle: stability under real-world conditions</h3>

<p><strong><a href="https://www.tmssoftware.com/site/sparkle.asp">TMS Sparkle</a></strong> is the high-performance HTTP server framework underpinning XData, RemoteDB and Sphinx. Two robustness fixes ship here:</p>

<ul>
  <li>The Indy-based server no longer crashes when a client disconnects before the response is sent, in setups using an <code>IOHandler</code> such as TaurusTLS under Linux.</li>
  <li>Re-entrant requests dispatched synchronously on the same thread &#151; for example, an in-process engine serving a nested request issued from within a handler &#151; no longer lose the outer request&#39;s context. Sparkle now saves and restores the previous context instead of clearing it unconditionally.</li>
</ul>

<h3><br></h3><h3>Getting the update</h3>

<p>All of these libraries ship together as part of <strong>TMS BIZ</strong>. Existing customers can update through their usual channel; if you&#39;re evaluating, grab the trial from the <a href="https://www.tmssoftware.com/">TMS Software website</a>.</p>

<p>The quickest way to get the update is with <strong><a href="https://www.smartsetup.org">Smart Setup</a></strong> &#151; the free package manager for TMS products. It resolves dependencies, downloads and builds everything for you, so you can move from this announcement to the new bits with a single command:</p>

<pre><code>tms update tms.biz.*
</code></pre>

<p>Prefer a UI? The Smart Setup GUI does the same with a single click.</p>

<p>For the full details, see the per-product release notes:</p>

<ul>
  <li><a href="https://doc.tmssoftware.com/biz/sphinx/guide/release-notes.html">TMS Sphinx release notes</a></li>
  <li><a href="https://doc.tmssoftware.com/biz/xdata/about/whats-new.html">TMS XData what&#39;s new</a></li>
  <li><a href="https://doc.tmssoftware.com/biz/aurelius/about/whats-new.html">TMS Aurelius what&#39;s new</a></li>
  <li><a href="https://doc.tmssoftware.com/biz/bcl/guide/release-notes.html">TMS BCL release notes</a></li>
</ul>

<p>And don&#39;t miss the deep dive on the release&#39;s marquee feature: <strong><a href="https://www.tmssoftware.com/site/blog.asp?post=2494">Login with Google, Microsoft and More &#151; Identity Brokering in TMS Sphinx</a></strong>.</p>

		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿TMS FNC Family Updated with a New Install Experience]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2495</link>
		<author>Aaron Decramer</author>
		<pubDate>Fri, 3 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		<p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">The installers for the <b>TMS FNC product family</b> are getting a major upgrade. Both trial and registered editions are moving to a new installation flow that is faster to set up, easier to maintain, and fully aligned with the latest RAD Studio target platforms.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top"><img src="https://www.tmssoftware.com/site/img/blog/fnc_family_update.png" style="width: 100%;" alt="TMS Software Delphi  Components "><br></p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">This update applies across the full TMS FNC range, including <a href="https://www.tmssoftware.com/site/tmsfncapptools.asp" target="_blank">TMS FNC AppTools</a>, <a href="https://www.tmssoftware.com/site/tmsfncblox.asp" target="_blank">TMS FNC Blox</a>, <a href="https://www.tmssoftware.com/site/tmsfncchart.asp" target="_blank">TMS FNC Chart</a>, <a href="https://www.tmssoftware.com/site/tmsfnccloudpack.asp" target="_blank">TMS FNC Cloud Pack</a>, <a href="https://www.tmssoftware.com/site/tmsfnccore.asp" target="_blank">TMS FNC Core</a>, <a href="https://www.tmssoftware.com/site/tmsfncdashboardpack.asp" target="_blank">TMS FNC Dashboard Pack</a>, <a href="https://www.tmssoftware.com/site/tmsfncganttchart.asp" target="_blank">TMS FNC Gantt Chart</a>, <a href="https://www.tmssoftware.com/site/fncgridexcelbridge.asp" target="_blank">TMS FNC Grid Excel Bridge</a>, <a href="https://www.tmssoftware.com/site/tmsfncmaps.asp" target="_blank">TMS FNC Maps</a>, <a href="https://www.tmssoftware.com/site/tmsfncpushnotifications.asp" target="_blank">TMS FNC Push Notifications</a>, <a href="https://www.tmssoftware.com/site/tmsfncuipack.asp" target="_blank">TMS FNC UI Pack</a>, <a href="https://www.tmssoftware.com/site/tmsfncwebsocket.asp" target="_blank">TMS FNC WebSocket</a>, and <a href="https://www.tmssoftware.com/site/tmsfncwxpack.asp" target="_blank">TMS FNC WX Pack</a>.<br><br></p><h3>A modern installer experience</h3><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">The new installers bring a consistent and streamlined setup experience across all TMS FNC products. Whether you are evaluating a trial or installing as a registered user, the process is now simpler and more predictable.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">This transition also modernizes the underlying installer technology. It ensures compatibility with the latest RAD Studio versions and target platforms, including Windows on Arm (Arm64EC). The result is a smoother setup process and better alignment with modern development environments.<br><br></p><h3>Installing TMS FNC products</h3><h4><b>Registered versions (via TMS Smart Setup)</b></h4><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">All registered TMS FNC products are now available exclusively through <a href="https://doc.tmssoftware.com/smartsetup/" target="_blank">TMS Smart Setup</a>. Before installing, make sure to uninstall any classic installations via the Windows control panel.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">If you are new to TMS Smart Setup, consult the Smart Setup documentation to install the <code>tms</code> command-line tool. Once installed, you can install individual products with commands such as:</p><pre>tms install tms.fnc.uipack<br>tms install tms.fnc.chart<br>tms install tms.fnc.core</pre><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">This approach ensures you always have access to the latest versions with minimal effort.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top"><br>Prefer a visual workflow? You can also manage installations through <a href="https://www.tmssoftware.com/site/tmsdashboard.asp" target="_blank">TMS Dashboard,</a> a centralized interface for installing, updating, and maintaining all your TMS components.<br><br><img src="https://www.tmssoftware.com/site/img/dev/dashboard/tmsdashboard.png" style="width: 829px;" alt="TMS Software Delphi  Components "><br><br><br></p><h4>Trial versions</h4><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">Want to evaluate a TMS FNC product? Simply visit the product page of your choice, click Free Trial, enter your email address, and select your IDE.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">The trial downloads immediately, and you will receive a trial key that can be entered during installation. This provides a quick and straightforward way to explore the capabilities of each component.<br><br></p><h3>Moving forward</h3><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">With this migration, the entire <b>TMS FNC product family</b> benefits from a cleaner installation experience, tighter integration with TMS Smart Setup, and improved support for modern multi-device development using Delphi and C++Builder.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">This marks an important step in unifying installation and update workflows across the TMS ecosystem, following earlier updates to other product lines.</p><p class="my-2 [&amp;+p]:mt-4 [&amp;_strong:has(+br)]:inline-block [&amp;_strong:has(+br)]:align-top">As always, your feedback is invaluable. Try the new installation flow for your TMS FNC products and let us know how we can continue improving the experience.</p>
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿Login with Google, Microsoft and More: Identity Brokering in TMS Sphinx]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2494</link>
		<author>Wagner Landgraf</author>
		<pubDate>Fri, 3 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		<p>Almost every modern application offers it: a row of buttons that say <em>"Continue with Google"</em>, <em>"Sign in with Microsoft"</em>, or <em>"Login with Apple"</em>. Users have come to expect it &#151; they don&#39;t want yet another password to remember, and you don&#39;t want the liability of storing one. At the same time, corporate customers increasingly demand that your app authenticate against <em>their</em> identity provider, so employees use the same single sign-on they use for everything else.</p>

<p>Until now, wiring this up in a Delphi backend meant a lot of plumbing: redirect dances, PKCE, state and nonce handling, token validation, and the headache of mapping an external account to a user in your own database &#151; repeated for every provider you wanted to support.</p>

<p>The next version of <strong>TMS Sphinx</strong> removes that plumbing. Sphinx can now act as an <strong>identity broker</strong>, delegating authentication to upstream providers like Google or Microsoft Entra while still issuing and controlling its own tokens, users and sessions.</p>

<p><img src="https://download.tmssoftware.com/business/images/blog/26-07-02-sphinx-external-providers.png" alt="Login page with external providers" style="width: 100%; max-width: 502px; height: auto;"></p><p><br></p>

<h3>A quick refresher on TMS Sphinx</h3>

<p><strong><a href="https://www.tmssoftware.com/site/sphinx.asp">TMS Sphinx</a></strong> is an <a href="https://oauth.net/2/">OAuth 2.0</a> and <a href="https://openid.net/connect/">OpenID Connect</a> authentication and authorization server framework for Delphi. It lets you add secure, standards-based login to your own applications &#151; desktop, web, mobile and APIs &#151; with Sphinx acting as the identity provider that issues and validates tokens.</p>

<p>Your client applications already talk to Sphinx as their OpenID Connect provider. With identity brokering, that doesn&#39;t change at all. The new part happens entirely on the server side.</p><p><br></p>

<h3>What is identity brokering?</h3>

<p>An <strong>identity broker</strong> (also called an <em>IdP proxy</em> or <em>identity federation</em>) sits between your applications and one or more external identity providers:</p>

<ul>
  <li>Your client apps keep talking <strong>only to Sphinx</strong>, exactly as before.</li>
  <li>Behind the scenes, Sphinx delegates the actual authentication to an <strong>upstream</strong> provider &#151; Google, Microsoft Entra, a corporate IdP, even another Sphinx server.</li>
  <li>Sphinx receives the upstream result, maps that external identity to a <strong>local user</strong>, and completes the original request with its own <strong>Sphinx-issued</strong> tokens.</li>
</ul>

<p>The key benefit: the tokens your applications receive are always issued and signed by Sphinx. The upstream tokens are used only to establish <em>who the user is</em>, and are then discarded (unless you explicitly choose to keep them). Your scopes, your claims, your sessions, your user database &#151; all stay under your control.</p>

<p>This is exactly what you want when you need to:</p>

<ul>
  <li>Offer familiar <strong>"Login with Google / Microsoft / GitHub / Apple / Facebook"</strong> buttons.</li>
  <li>Authenticate users against an existing <strong>corporate identity provider</strong> for a B2B customer.</li>
  <li>Support <strong>multi-tenant</strong> scenarios where different customers use different identity providers.</li>
  <li>Keep issuing your own tokens and managing your own users regardless of how people sign in.</li>
</ul>

<h3><br></h3><h3>Registering an upstream provider</h3>

<p>Providers are registered in the new <code>ExternalProviders</code> collection of <code>TSphinxConfig</code>. You can add them at design time (double-click the <code>ExternalProviders</code> property) or from code. At a minimum you give the provider a unique name, the authority URL, and the client id/secret you registered for Sphinx at that provider:</p>

<pre><code>  Provider := SphinxConfig1.ExternalProviders.Add;
  Provider.Name := &#39;google&#39;;
  Provider.DisplayName := &#39;Google&#39;;
  Provider.Authority := &#39;https://accounts.google.com&#39;;
  Provider.ClientId := &#39;your-client-id&#39;;
  Provider.ClientSecret := &#39;your-client-secret&#39;;
  Provider.Scope := &#39;openid email profile&#39;;
  Provider.AutoDiscover := True;
</code></pre>

<p>When <code>AutoDiscover</code> is <code>True</code> (the default), Sphinx fetches the provider&#39;s discovery document from <code>Authority + "/.well-known/openid-configuration"</code> to learn its endpoints automatically. The redirect URI you register at the upstream provider is always Sphinx&#39;s own callback endpoint, <code>oauth/external/callback</code>.</p>

<p>That&#39;s it. No manual handling of authorization codes, PKCE verifiers, state, nonce or token validation &#151; Sphinx does all of it for you.</p><p><br></p>

<h3>Adding "Login with..." buttons</h3>

<p>To let the <strong>end user</strong> pick a provider on the Sphinx login page, just set <code>ShowInLoginPage</code> to <code>True</code>. Use <code>DisplayName</code> for the button text and <code>IconUrl</code> for the icon:</p>

<pre><code>  Provider := SphinxConfig1.ExternalProviders.Add;
  Provider.Name := &#39;google&#39;;
  Provider.DisplayName := &#39;Google&#39;;
  Provider.IconUrl := &#39;img/providers/google.svg&#39;; // a built-in icon
  Provider.ShowInLoginPage := True;
  // ... authority, client id/secret, scope as above
</code></pre>

<p>A nice touch: Sphinx <strong>ships ready-to-use, brand-colored icons</strong> for the most common providers, so you don&#39;t have to source and host them yourself. Just point <code>IconUrl</code> at one of the built-in relative paths:</p>

<table>
  <thead>
    <tr><th>Provider</th><th><code>IconUrl</code> value</th></tr>
  </thead>
  <tbody>
    <tr><td>Google</td><td><code>img/providers/google.svg</code></td></tr>
    <tr><td>Microsoft</td><td><code>img/providers/microsoft.svg</code></td></tr>
    <tr><td>GitHub</td><td><code>img/providers/github.svg</code></td></tr>
    <tr><td>Apple</td><td><code>img/providers/apple.svg</code></td></tr>
    <tr><td>Facebook</td><td><code>img/providers/facebook.svg</code></td></tr>
  </tbody>
</table>

<p>The user clicks the button, authenticates at the provider&#39;s own consent screen, and comes right back &#151; logged into your app.</p>

<p><img src="https://download.tmssoftware.com/business/images/blog/26-07-02-sphinx-google-consent.png" alt="Google consent screen" style="width: 100%; max-width: 884px; height: auto;"></p>

<p>Want a login page with <strong>no password form at all</strong>? Set <code>LoginOptions.AllowPasswordLogin := False</code> and the page shows only the provider buttons (with a safeguard that still shows the local form if no providers happen to be available, so you can&#39;t lock everyone out).</p><p><br></p>

<h3>Delegating transparently (no buttons)</h3>

<p>Sometimes you don&#39;t want the user to choose &#151; you want a specific client, tenant or scope to <em>always</em> authenticate against a particular provider. The <code>OnResolveExternalProvider</code> event is the single decision point that turns brokering on for a request:</p>

<pre><code>procedure TForm1.SphinxConfig1ResolveExternalProvider(Sender: TObject;
  Args: TResolveExternalProviderArgs);
begin
  // Transparently delegate every request to the corporate identity provider.
  Args.ProviderName := &#39;corporate-idp&#39;;
end;
</code></pre>

<p>Because the logic is entirely yours, you can delegate only for certain clients or tenants and fall back to the normal Sphinx login for everyone else. The user never sees a Sphinx login screen at all &#151; they go straight to the corporate IdP and back.</p><p><br></p>

<h3>Mapping the external user to a local user &#151; without code</h3>

<p>After the upstream login completes, Sphinx needs to know which <strong>local</strong> user that identity corresponds to. The recommended, durable key is the pair <em>(provider, subject)</em> &#151; the provider name plus the stable <code>sub</code> claim, which (unlike an e-mail address) never changes. Sphinx persists this in a new link table via the <code>TUserLogin</code> entity.</p>

<p>For the common cases you don&#39;t have to write a single line of code. Just configure the new built-in reconciliation policy:</p>

<pre><code>  // Link an external sign-in to an existing account by verified e-mail...
  SphinxConfig1.ExternalLoginOptions.AllowAutoLinkByEmail := True;
  // ...and create a brand-new local account on first sign-in.
  SphinxConfig1.ExternalLoginOptions.AllowAutoProvision := True;
</code></pre>

<p>With this, Sphinx automatically:</p>

<ol>
  <li>Resolves an existing link by <em>(provider, subject)</em>.</li>
  <li>If none, links to an existing user matching by verified e-mail.</li>
  <li>If still none, provisions a new local user from the upstream profile.</li>
</ol>

<p>All options default to <strong>off</strong>, so nothing happens automatically until you opt in. When a new user is created, the <code>OnExternalUserProvisioned</code> event fires so you can finish the account (assign roles, copy profile fields, etc.).</p>

<p>And if a provider doesn&#39;t return everything you require &#151; Facebook, famously, returns no e-mail &#151; Sphinx automatically shows a <strong>"complete your profile"</strong> step asking the user for the missing field, then continues. Again, no code on your part.</p><p><br></p>

<h3>Full control when you need it</h3>

<p>For everything else, the <code>OnExternalSignIn</code> event gives you complete control over the mapping. It receives convenient access to the subject, e-mail and verification status, plus a user manager bound to the current request:</p>

<pre><code>procedure TForm1.SphinxConfig1ExternalSignIn(Sender: TObject;
  Args: TExternalSignInArgs);
var
  User: TUser;
begin
  // Resolve first by the durable link (provider + subject).
  User := Args.UserManager.FindByLogin(Args.ProviderName, Args.Subject);

  // First sign-in: match an existing account by e-mail and remember the link.
  if User = nil then
  begin
    if not Args.EmailVerified then
    begin
      Args.Reject(&#39;A verified email is required&#39;);
      Exit;
    end;
    User := Args.UserManager.FindByEmail(Args.Email);
    if User &lt;&gt; nil then
      Args.UserManager.AddLogin(User, Args.ProviderName, Args.Subject);
  end;

  Args.User := User;
end;
</code></pre>

<h3><br></h3><h3>Built for the real world</h3>

<p>A few details that show this is more than a demo feature:</p>

<ul>
  <li><strong>Multi-tenant Microsoft Entra works out of the box.</strong> When a provider&#39;s issuer is a <code>{tenantid}</code> template (as Entra returns for the <code>organizations</code>/<code>common</code> authorities), Sphinx resolves the placeholder with each token&#39;s tenant id before validating &#151; so issuer validation stays <strong>enabled</strong> and secure, no workarounds needed.</li>
  <li><strong>Two-factor authentication is respected.</strong> An external sign-in still honors the user&#39;s Sphinx 2FA configuration. Or, when the upstream already performed MFA, you can trust it and skip the second challenge with <code>Args.SkipTwoFactor := True</code>.</li>
  <li><strong>You can keep the upstream tokens.</strong> Enable <code>ExternalLoginOptions.SaveTokens</code> and Sphinx persists the upstream <code>access_token</code>, <code>refresh_token</code> and <code>id_token</code> so your app can later call the provider&#39;s APIs on the user&#39;s behalf via <code>GetAuthenticationToken</code>.</li>
  <li><strong>Security is built in.</strong> PKCE, <code>state</code> and <code>nonce</code> are generated and validated by Sphinx, the callback is bound to the originating browser with a single-use cookie, and client secrets never leave the server.</li>
</ul>

<h3><br></h3><h3>Try it in the Simple demo</h3>

<p>The <strong>Simple</strong> demo server (<code>demos/Simple/Server</code>) ships a ready-to-fill template in <code>ConfigureExternalProviders</code> (<code>MainForm.pas</code>). Register the demo&#39;s callback URL, <code>http://localhost:2001/tms/sphinx/oauth/external/callback</code>, as an authorized redirect URI in the <a href="https://console.cloud.google.com/">Google Cloud Console</a>, drop in your own client id and secret, and a <strong>"Continue with Google"</strong> button appears on the login page. The demo&#39;s <code>OnExternalSignIn</code> handler resolves the user by link, falls back to e-mail, and provisions a local user on first sign-in &#151; so the whole brokered flow works end to end.</p><p><br></p>

<h3>Conclusion</h3>

<p>Identity brokering brings one of the most-requested features in modern authentication to Delphi developers, with very little effort:</p>

<ul>
  <li><strong>Better user experience</strong> &#151; familiar "Login with..." buttons and no extra passwords.</li>
  <li><strong>Enterprise-ready</strong> &#151; authenticate against corporate identity providers and multi-tenant Entra.</li>
  <li><strong>You stay in control</strong> &#151; Sphinx always issues its own tokens and owns your users, scopes and sessions.</li>
  <li><strong>Less code</strong> &#151; automatic reconciliation, provisioning and profile completion mean common scenarios need almost no code at all.</li>
</ul>

<p>To dive deeper, read the full <strong><a href="https://doc.tmssoftware.com/biz/sphinx/guide/identity-broker.html">Identity brokering documentation</a></strong> and the <strong><a href="https://doc.tmssoftware.com/biz/sphinx/guide/release-notes.html">release notes</a></strong>, and learn more about <strong>TMS Sphinx</strong> on its <strong><a href="https://www.tmssoftware.com/site/sphinx.asp">product page</a></strong>.</p>

		
		
		
		
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿TMS FNC UI Pack 7.2]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2491</link>
		<author>Pieter Scheldeman</author>
		<pubDate>Thu, 2 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		
		
		
		<p><span style="background-color: darkgray; color: white; padding: 4px 8px; text-align: center; border-radius: 5px; font-size: 1.5em;">TMS FNC UI Pack 7.2</span></p>

<h4 style="color: rgb(0, 0, 0);">Intro</h4>
<p>In many applications, a grid is more than a table on a form. It can represent different views of the same workflow: a summary, a sales overview, an inventory list, a log, or a temporary working set. Traditionally, switching between those views often means clearing and rebuilding the grid, copying data around, or keeping multiple grid controls alive.</p>

<p>In <a href="https://www.tmssoftware.com/site/tmsfncuipack.asp" target="_blank">TMS FNC UI Pack 7.2</a>, <code>TTMSFNCDataGrid</code> adds a powerful new way to handle this with <code>TTMSFNCDataGridRendererSource</code> and the grid&#39;s <code>RendererSource</code> property.</p>

<p>A renderer source acts as a complete standalone grid layer. It contains its own renderer, its own data, its own appearance and its own state. Assigning that source to a grid makes the grid render that layer by reference.</p>

<p><img src="data:image/png;base64,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" style="max-width: 100%;" data-filename="renderer-source-own-layer.png" alt="TMS FNC DataGrid RendererSource own layer screenshot"></p>

<h4>What RendererSource Does</h4>
<p>The new <code>RendererSource</code> property lets one <code>TTMSFNCDataGrid</code> switch between different prepared renderer layers. Each layer can have different columns, rows, data, styling and scroll behavior.</p>

<p>Setting <code>RendererSource</code> to <code>nil</code> uses the grid&#39;s own built-in renderer and data. Assigning a <code>TTMSFNCDataGridRendererSource</code> switches the grid to that external layer.</p>

<ul>
<li><p><strong>One grid, multiple layers:</strong> switch between complete grid states without rebuilding the grid from scratch.</p></li>
<li><p><strong>Layer-specific data:</strong> each renderer source keeps its own cells, rows and columns.</p></li>
<li><p><strong>Layer-specific appearance:</strong> each source can have its own colors, selection style and layout settings.</p></li>
<li><p><strong>Live by reference:</strong> the grid does not copy the layer; edits are made on the active renderer source.</p></li>
<li><p><strong>State preservation:</strong> when you switch away from a layer and return later, that layer still has its own data and state.</p><p><br></p></li>
</ul>

<h4>Preparing Renderer Layers</h4>
<p>The included demo prepares two external renderer sources: a blue <strong>Sales by Region</strong> layer and a green <strong>Product Inventory</strong> layer. Each source owns its own <code>Renderer</code>.</p>

<pre class="delphi" name="code">private
  FSalesLayer: TTMSFNCDataGridRendererSource;
  FInventoryLayer: TTMSFNCDataGridRendererSource;

procedure TFormRendererSource.FormCreate(Sender: TObject);
begin
  SeedGridOwnData;

  FSalesLayer := TTMSFNCDataGridRendererSource.Create(Self);
  FSalesLayer.Name := &#39;SalesLayer&#39;;
  BuildSalesLayer;

  FInventoryLayer := TTMSFNCDataGridRendererSource.Create(Self);
  FInventoryLayer.Name := &#39;InventoryLayer&#39;;
  BuildInventoryLayer;
end;</pre>

<p>The grid starts with its own built-in layer. The external layers are prepared up front, but they are not shown until they are assigned to the grid.</p><p><br></p>

<h4>Sales by Region</h4>
<p>The first renderer source uses a blue theme and contains regional quarterly sales data. The grid switches to this layer without changing the grid control itself.</p>

<p><img src="data:image/png;base64,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" style="max-width: 100%;" data-filename="renderer-source-sales-layer.png" alt="TMS FNC DataGrid RendererSource sales layer screenshot"></p>

<pre class="delphi" name="code">procedure TFormRendererSource.BuildSalesLayer;
var
  r: TTMSFNCDataGridRenderer;
begin
  r := FSalesLayer.Renderer;
  r.BeginUpdate;
  try
    r.CellAppearance.FixedLayout.Fill.Color := gcSteelblue;
    r.CellAppearance.FixedLayout.Font.Color := gcWhite;
    r.CellAppearance.NormalLayout.Fill.Color := gcAliceblue;
    r.CellAppearance.SelectedLayout.Fill.Color := gcLightsteelblue;
    r.Options.Column.Stretching.Enabled := True;

    r.FixedRowCount := 1;
    r.ColumnCount := 6;
    r.RowCount := 6;

    r.Cells[0, 0] := &#39;Region&#39;;
    r.Cells[1, 0] := &#39;Q1&#39;;
    r.Cells[2, 0] := &#39;Q2&#39;;
    r.Cells[3, 0] := &#39;Q3&#39;;
    r.Cells[4, 0] := &#39;Q4&#39;;
    r.Cells[5, 0] := &#39;Total&#39;;
  finally
    r.EndUpdate;
  end;
end;</pre><p><br></p>

<h4>Product Inventory</h4>
<p>The second renderer source uses a green theme and contains product inventory data. It has a different column layout, different values and different styling, but it is still displayed through the same grid.</p>

<p><img src="data:image/png;base64,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" style="max-width: 100%;" data-filename="renderer-source-inventory-layer.png" alt="TMS FNC DataGrid RendererSource inventory layer screenshot"></p>

<pre class="delphi" name="code">procedure TFormRendererSource.BuildInventoryLayer;
var
  r: TTMSFNCDataGridRenderer;
begin
  r := FInventoryLayer.Renderer;
  r.BeginUpdate;
  try
    r.CellAppearance.FixedLayout.Fill.Color := gcSeagreen;
    r.CellAppearance.FixedLayout.Font.Color := gcWhite;
    r.CellAppearance.NormalLayout.Fill.Color := gcHoneydew;
    r.CellAppearance.SelectedLayout.Fill.Color := gcDarkseagreen;
    r.Options.Column.Stretching.Enabled := True;

    r.FixedRowCount := 1;
    r.ColumnCount := 5;
    r.RowCount := 7;

    r.Cells[0, 0] := &#39;Product&#39;;
    r.Cells[1, 0] := &#39;SKU&#39;;
    r.Cells[2, 0] := &#39;In Stock&#39;;
    r.Cells[3, 0] := &#39;Reorder Level&#39;;
    r.Cells[4, 0] := &#39;Status&#39;;
  finally
    r.EndUpdate;
  end;
end;</pre><p><br></p>

<h4>Switching Layers</h4>
<p>Once the layers are prepared, switching the grid is just a property assignment:</p>

<pre class="delphi" name="code">procedure TFormRendererSource.btnSalesClick(Sender: TObject);
begin
  TMSFNCDataGrid1.RendererSource := FSalesLayer;
end;

procedure TFormRendererSource.btnInventoryClick(Sender: TObject);
begin
  TMSFNCDataGrid1.RendererSource := FInventoryLayer;
end;

procedure TFormRendererSource.btnDefaultClick(Sender: TObject);
begin
  TMSFNCDataGrid1.RendererSource := nil;
end;</pre>

<p>This makes it possible to build dashboards, inspectors, drill-down views and alternate data views while keeping the UI simple: one visible grid, multiple prepared renderer layers.</p><p><br></p>

<h4>Editing the Active Layer</h4>
<p>The grid facade always targets the active layer. If the sales layer is active, grid edits affect the sales renderer source. If the inventory layer is active, edits affect the inventory renderer source. When the grid is using its own built-in renderer, edits affect the grid&#39;s own data.</p>

<pre class="delphi" name="code">procedure TFormRendererSource.btnAddRowClick(Sender: TObject);
var
  newRow: Integer;
begin
  TMSFNCDataGrid1.BeginUpdate;
  try
    newRow := TMSFNCDataGrid1.RowCount;
    TMSFNCDataGrid1.RowCount := newRow + 1;
    TMSFNCDataGrid1.Cells[0, newRow] := Format(&#39;Added row %d&#39;, [newRow]);
  finally
    TMSFNCDataGrid1.EndUpdate;
  end;
end;</pre>

<p>Because each renderer source keeps its own state, changes remain with that layer even after switching to another layer and back.</p><p><br></p>

<h4>Where This Helps</h4>
<p><code>RendererSource</code> is especially useful when an application needs to reuse the same grid area for different kinds of information:</p>

<ul>
<li><p><strong>Dashboards:</strong> switch between summary, sales and inventory views.</p></li>
<li><p><strong>Master-detail screens:</strong> show different detail grids without creating multiple visible controls.</p></li>
<li><p><strong>Data inspectors:</strong> keep separate layouts for different object types.</p></li>
<li><p><strong>Temporary working views:</strong> let users edit a layer and return to it later with its state intact.</p><p><br></p></li>
</ul>

<h4>Installing TMS FNC UI Pack 7.2</h4>
<p>TMS FNC UI Pack 7.2 is also available through the modern installation workflow. As described in the <a href="https://tmssoftware.com/site/blog.asp?post=2481" target="_blank">modernized installer blog post</a>, TMS is moving product installation to the newer Smart Setup based flow.</p>

<pre class="delphi" name="code">tms self-update

tms install tms.fnc.*</pre>

<p>If you are migrating from classic installers, first uninstall older TMS FNC UI Pack installations from the previous setup flow before installing through Smart Setup. This keeps the IDE paths, package registrations and product folders clean.</p><p><br></p>

<h4>Conclusion</h4>
<p><code>RendererSource</code> in <code>TTMSFNCDataGrid</code> adds a clean way to work with multiple complete grid layers from a single visible grid. Each layer can keep its own data, appearance and state, while the grid can switch between them with one assignment.</p>

<p>For applications that need flexible data views, dashboards or context-sensitive grids, TMS FNC UI Pack 7.2 makes the architecture simpler and the user experience smoother.</p>


		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿TMS FNC Core to help to make the free QR and Barcode generation component cross-framework and cross-platform]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2493</link>
		<author>Bruno Fierens</author>
		<pubDate>Wed, 1 Jul 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		
		
		
		<div>The FNC variant of this free barcode and QR code library is a good example of what <a href="https://www.tmssoftware.com/site/tmsfnccore.asp" target="_blank">TMS FNC Core</a> is designed to enable: <b>one Delphi code base that can be surfaced through multiple application frameworks</b> without forking the core implementation.</div><div><br></div><div>In practical terms, this means the same barcode and QR code generation engine can be used from:</div><div><br></div><ul><li>Windows VCL applications</li><li>FireMonkey desktop applications on Windows and macOS</li><li>Native FireMonkey mobile applications on iOS and Android</li><li>Linux FireMonkey applications</li><li>TMS WEB Core web client application<br><br></li></ul><p>The source is available in this repository and on GitHub:</p><div><a href="https://github.com/tmssoftware/Bar_QRCodes4D" target="_blank">https://github.com/tmssoftware/Bar_QRCodes4D</a></div><div><br></div><div>That combination is what makes this library technically interesting. The value is not only that it generates barcodes and QR codes, but that it does so through an FNC-based architecture that scales from classic desktop development to browser clients and native mobile apps.</div><div><br></div><div><h4>Architecture: Thin Platform Units Around A Shared Core</h4><div>The implementation in the FNC folder follows a clean pattern. There are framework-specific units such as:</div><div><br></div><ul><li>FNC\VCL.TMSFNCBarCode.pas</li><li>FNC\FMX.TMSFNCBarCode.pas</li><li>FNC\WEBLib.TMSFNCBarCode.pas</li><li>FNC\VCL.TMSFNCQRCode.pas</li><li>FNC\FMX.TMSFNCQRCode.pas</li><li>FNC\WEBLib.TMSFNCQRCode.pas</li></ul><div>These units bring in the appropriate graphics, control, and utility classes for each framework, but the functional implementation is shared through common include files:</div><div><pre class="delphi" name="code">{$I TMSFNCBarCodeCommon.inc}</pre></div><div>and</div><div><pre class="delphi" name="code">{$I TMSFNCQRCodeCommon.inc}</pre></div><div><br></div><div>This is a very effective use of the TMS FNC Core abstraction layer. Platform-specific adaptation stays thin, while the generation logic, rendering behavior, and export features remain centralized. That reduces duplication, keeps behavior aligned across frameworks, and makes the code base significantly easier to evolve.</div><div><br></div><div>For Delphi developers, that is the real payoff: framework neutrality without giving up the native component model.</div><div><br></div><div><h4>Why This Is Especially Relevant For FireMonkey</h4><div>The FireMonkey angle deserves special attention. Once the barcode and QR code logic is implemented against TMS FNC Core, the same components can flow naturally into FMX applications, including native mobile applications.</div><div><br></div><div>That means developers can use the same code base not only in desktop applications, but also in iOS and Android apps built with FireMonkey. For scenarios such as inventory, ticketing, event check-in, field services, healthcare workflows, or retail companion apps, that is a very compelling proposition: no separate mobile-specific barcode generation library is needed.</div><div><br></div><div><h4>The Hosted TMS WEB Core Demo</h4><div>The technical story becomes even more convincing when there is a live browser deployment thanks to <a href="https://www.tmssoftware.com/site/tmswebcore.asp" target="_blank">TMS WEB Core</a> showing the exact same component model at work. That is what the demo with full source code under FNC\Demo provides, and the hosted version is available here:</div><div><br></div><div><a href="https://www.tmssoftware.com/site/webcore/barqrcodes" target="_blank">https://www.tmssoftware.com/site/webcore/barqrcodes</a></div><div><br></div><div>Below is a capture of the hosted demo:</div><div><img src="https://www.tmssoftware.com/site/img/blog/barqrcodes.gif" style="width: 705px;" alt="TMS Software Delphi  Components tmsfnccore"><br></div><div><br></div><div>This is not a mock-up. It is a real TMS WEB Core application using the FNC-based barcode and QR code components in the browser. The demo does not rely on elaborate setup code. It starts a standard web form and lets the components do the work.</div><div><div><br></div><div>The main form, implemented in FNC\Demo\Umainform.pas, contains:</div><div><br></div><ul><li>a page control with separate QR code and barcode tabs</li><li>a TTMSFNCQRCode component</li><li>a TTMSFNCBarCode component</li><li>text input controls for QR and barcode content</li><li>a combobox for selecting barcode symbologies</li><li>export buttons for SVG and PNG</li></ul><div>The QR code tab exposes free text entry and live rendering, while the barcode tab exposes both a value field and a barcode type selector.</div><div><br></div><h4>Demo Code: Direct And Practical</h4><div>The QR code update path is intentionally straightforward:</div><div><pre class="delphi" name="code">procedure TForm1.WebEdit1Change(Sender: TObject);
begin
  TMSFNCQRCode1.Text := WebEdit1.Text;
end;</pre></div><div>As the user edits the text, the QR code component updates immediately. That is the kind of direct event-driven programming model Delphi developers expect, and the browser deployment preserves it.</div><div><br></div><div>The barcode side follows the same pattern:</div><div><pre class="delphi" name="code">procedure TForm1.WebEdit2Change(Sender: TObject);
begin
  TMSFNCBarCode1.Value := WebEdit2.Text;
end;</pre></div><div>Here too, the component API stays simple. A value property is assigned, and the visual result updates accordingly.</div><div><br></div><h4>Barcode type selection</h4><div>The demo also contains a small but useful layer around barcode type selection. A local enum lists the supported barcode types, and the form populates the combobox at startup:</div><div><pre class="delphi" name="code">procedure TForm1.WebFormCreate(Sender: TObject);
var
  BarcodeType: TTMSBarcodeType;
begin
  for BarcodeType := Low(TTMSBarcodeType) to High(TTMSBarcodeType) do
    WebComboBox1.Items.Add(TMSBarcodeTypeName(BarcodeType));

  WebComboBox1.ItemIndex := 1;
  WebPageControl1.ActivePageIndex := 0;
end;</pre></div><div>When the selection changes, the demo assigns a format-appropriate sample value:</div><div><pre class="delphi" name="code">procedure TForm1.WebComboBox1Change(Sender: TObject);
var
  BarcodeType: TTMSBarcodeType;
begin
  BarcodeType := TTMSBarcodeType(WebComboBox1.ItemIndex);
  TMSFNCBarCode1.Value := SampleValue(BarcodeType);
  WebEdit2.Text := TMSFNCBarCode1.Value;
end;</pre></div><div>Barcode formats can be slighly different for different barcode types.&nbsp;So supplying a valid sample content per barcode type makes the demo more useful.&nbsp;</div><div><br></div><h4>Export To SVG And PNG</h4><div>The export story is another strong point because it shows that the component is not limited to on-screen rendering. The demo exposes both SVG and PNG export from the same form.</div><div><br></div><div><b>SVG export:</b></div><div><pre class="delphi" name="code">procedure TForm1.WebButton1Click(Sender: TObject);
begin
  if WebPageControl1.ActivePageIndex = 0 then
    TMSFNCQRCode1.SaveToSVG(&#39;qrcode.svg&#39;);

  if WebPageControl1.ActivePageIndex = 1 then
    TMSFNCBarCode1.SaveToSVG(&#39;barcode.svg&#39;);
end;</pre></div><div><b>PNG export:</b></div><div><pre class="delphi" name="code">procedure TForm1.WebButton2Click(Sender: TObject);
begin
  if WebPageControl1.ActivePageIndex = 0 then
    TMSFNCQRCode1.SaveToPNG(&#39;qrcode.png&#39;);

  if WebPageControl1.ActivePageIndex = 1 then
    TMSFNCBarCode1.SaveToPNG(&#39;barcode.png&#39;);
end;</pre></div><div><br></div><h4>One Technical Investment, Many Targets</h4><div>The broader point of the FNC implementation is clear. By coding against TMS FNC Core, the library is no longer boxed into a VCL-only story. The same underlying implementation can be surfaced in:</div><div><br></div><ul><li>classic Windows desktop applications</li><li>cross-platform FireMonkey desktop applications</li><li>native FireMonkey mobile applications</li><li>browser-based TMS WEB Core applications</li></ul><div>That is a strong technical result with a clear business benefit. You invest in one code base, one API style, and one component model, then reuse it across the places where your users actually are.</div><div><br></div><div>If you want to inspect the code, the GitHub repository is here:</div><div><br></div><div><a href="https://github.com/tmssoftware/Bar_QRCodes4D" target="_blank">https://github.com/tmssoftware/Bar_QRCodes4D</a></div><div><br></div><div>If you want to see it running immediately, try the hosted demo here:</div><div><br></div><div><a href="https://www.tmssoftware.com/site/webcore/barqrcodes" target="_blank">https://www.tmssoftware.com/site/webcore/barqrcodes</a></div><div><br></div><div>We hope you enjoy integrating QR and bar code creation in your Delphi apps, be it VCL apps, FireMonkey cross-platform apps or web client applications created with TMS WEB Core. We are eager to learn what other libraries you want to have available in the FNC concept. Let us know and we&#39;ll investigate.</div></div><div><br></div></div></div></div>
		
		
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿Filtering in Delphi: Generating, Parsing and Matching Filters]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2492</link>
		<author>Gjalt Vanhouwaert</author>
		<pubDate>Thu, 25 Jun 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		<p><img src="https://www.tmssoftware.com/site/img/blog/fnc_filter_v2.png" style="width: 829px;" alt="TMS Software Delphi Components"><br>
</p><p><br></p>

<p>In the <a href="https://tmssoftware.com/site/blog.asp?post=XXXX">previous blog post</a>, we looked at why filtering can become difficult when everything is handled as a string.</p>

<p>A filter like this is simple enough:</p>

<pre class="delphi" name="code">Age &gt; 18</pre>

<p>But once you start combining multiple conditions, adding brackets, switching between <code>AND</code> and <code>OR</code>, validating field names, and converting values to the right type, it becomes harder to keep everything under control.</p>

<p>That is where the <b>TTMSFNCFilterBuilder</b> comes in.<br><br></p>

<h3>From Filter Text to Filter Structure</h3>

<p>The idea behind the FilterBuilder is simple:<br>
Instead of building one long filter string manually, we build the filter as a structure.</p>

<p>The starting point for this structure is the <code>Filter</code> property.</p>

<pre class="delphi" name="code">FilterBuilder.Filter</pre>

<p>This filter contains the expressions and groups that define the filtering logic.</p>

<p>Every filter expression consists of three parts:</p>

<ul>
<li>The field or column name</li>
<li>The comparison operator</li>
<li>The value to compare against</li>
</ul>

<p>For example:</p>

<pre class="delphi" name="code">Age &gt; 18</pre>

<p>Can be represented as:</p>

<ul>
<li>Field: <code>Age</code></li>
<li>Operator: <code>feoLargerThan</code></li>
<li>Value: <code>18</code></li>
</ul>

<p>By storing these parts separately, the filter becomes easier to build, inspect, validate, and eventually convert into filter text. It also avoids a lot of fragile string concatenation. Instead of manually writing operators such as <code>&gt;</code> or <code>=</code>, you work with predefined operators such as <code>feoLargerThan</code> and <code>feoEqual</code>.<br><br></p>

<h3>Building Expressions</h3>

<p>The smallest building block of a filter is an expression.</p>

<p>An expression describes a single condition.</p>

<pre class="delphi" name="code">FilterBuilder.Filter.AddExpression(&#39;Age&#39;, feoLargerThan, 18);</pre>

<p>Notice that we are not building a string here. We are simply describing the filter logic.</p>

<p>At this point, the FilterBuilder doesn&#39;t care whether the final output will be used for a <code>TDataSet</code>, OData, a universal filter expression, or a completely custom format.<br><br></p>

<h3>Combining Expressions with Groups</h3>

<p>Most filters contain multiple conditions.</p>

<p>For example:</p>

<pre class="delphi" name="code">Age &gt; 18 AND Country = &#39;BE&#39;</pre>

<p>The FilterBuilder combines expressions through groups.</p>

<p>The root filter itself is already a group and has its own group operator.</p>

<pre class="delphi" name="code">FilterBuilder.Filter.GroupOperator := fgoAND;</pre>

<p>Every expression that is added to this filter is automatically combined using <code>AND</code>.</p>

<p>If needed, you can simply change the operator to <code>OR</code>.</p>

<pre class="delphi" name="code">FilterBuilder.Filter.GroupOperator := fgoOR;</pre>

<h3><br>Nested Groups</h3>

<p>The real strength of this approach becomes apparent when more complex filters are required.</p>

<p>Consider the following example:</p>

<pre class="delphi" name="code">(Age &gt; 18 AND Country = &#39;BE&#39;) OR (Age &gt; 21 AND Country = &#39;US&#39;)</pre>

<p>Writing this manually isn&#39;t too difficult, but maintaining it quickly becomes harder as more conditions are added.</p>

<p>With the FilterBuilder, you simply create two groups.</p>

<pre class="delphi" name="code">var
  BelgiumGroup,
  USGroup: TTMSFNCFilterBuilderGroup;
begin
  FilterBuilder.Filter.GroupOperator := fgoOR;

  BelgiumGroup := FilterBuilder.Filter.AddGroup;
  BelgiumGroup.GroupOperator := fgoAND;
  BelgiumGroup.AddExpression(&#39;Age&#39;, feoLargerThan, 18);
  BelgiumGroup.AddExpression(&#39;Country&#39;, feoEqual, &#39;BE&#39;);

  USGroup := FilterBuilder.Filter.AddGroup;
  USGroup.GroupOperator := fgoAND;
  USGroup.AddExpression(&#39;Age&#39;, feoLargerThan, 21);
  USGroup.AddExpression(&#39;Country&#39;, feoEqual, &#39;US&#39;);
end;</pre>

<p>Every group can contain:</p>

<ul>
<li>Expressions</li>
<li>Other groups</li>
<li>Its own <code>AND</code> or <code>OR</code> operator</li>
</ul>

<p>Because groups can contain other groups, filters can be nested indefinitely without manually keeping track of brackets.<br><br></p>

<h3>Generating Filter Text</h3>

<p>Once the filter structure has been created, generating the filter text becomes trivial.</p>

<pre class="delphi" name="code">ShowMessage(FilterBuilder.FilterText);</pre>

<p>For the nested example above, the generated filter text would be similar to:</p>

<pre class="delphi" name="code">(Age &gt; 18 AND Country = &#39;BE&#39;) OR (Age &gt; 21 AND Country = &#39;US&#39;)</pre>

<p>The FilterBuilder generates the complete expression, including operators and brackets.</p>

<p>When the selected format matches the syntax expected by a <code>TDataSet</code>, the generated text can immediately be assigned to the dataset.</p>

<pre class="delphi" name="code">FilterBuilder.FormatType := fftDelphiDataSet;

DataSet.Filter := FilterBuilder.FilterText;
DataSet.Filtered := DataSet.Filter &lt;&gt; &#39;&#39;;</pre>

<p>In other words, the FilterBuilder doesn&#39;t replace Delphi&#39;s filtering mechanism&#151;it simply provides a much safer and easier way to generate the filter text.<br><br></p>

<h3>Parsing Existing Filter Text</h3>

<p>The process also works in reverse.</p>

<p>If you already have filter text that follows one of the supported formats, the FilterBuilder can parse it back into its internal structure.</p>

<pre class="delphi" name="code">if FilterBuilder.ParseExpression(&#39;Age &gt; 18 AND Country = &#39;&#39;BE&#39;&#39;&#39;) then
begin
  // The filter text was parsed successfully
end;</pre>

<p>This allows existing filters to be visualized, modified, validated, or reused without having to recreate them manually.</p>

<p>Of course, parsing depends on the selected formatting rules. The expression text needs to follow the configured syntax and format type in order to be parsed successfully. When the expression is not valid, <code>ParseExpression</code> returns <code>False</code>. And you have an event available to have a calculated quess where the error might be.<br><br></p>

<h3>Supporting Different Filter Formats</h3>

<p>One of the biggest advantages of separating the filter structure from the generated text is that the output format can easily be changed.</p>

<p>The same filter logic can be used for multiple targets.</p>

<p>For example, a Delphi DataSet filter doesn&#39;t use the same syntax as an OData filter.</p>

<p>Changing the output is simply a matter of selecting another format.</p>

<pre class="delphi" name="code">FilterBuilder.FormatType := fftOData;<br>FilterText ==&gt; (Age gt 18 and Country eq &#39;BE&#39;) or (Age gt 21 and Country eq &#39;US&#39;)</pre>

<p>The available format types are:</p>

<ul>
<li><code>fftDelphiDataSet</code> for Delphi DataSet filter syntax</li>
<li><code>fftUniversalFilterExpressions</code> used in the TMS FNC DataGrid</li>
<li><code>fftOData</code> for OData query syntax</li>
<li><code>fftCustom</code> for a fully customized parse format</li>
</ul>

<p>This means you only build the filter once, while the FilterBuilder generates the appropriate output for the destination.<br><br></p>

<h3>Matching Data Without Filter Text</h3>

<p>Generating filter text is only one way of using the FilterBuilder.</p>

<p>Sometimes you don&#39;t want to apply a filter string at all.</p>

<p>For example, when working with custom controls, collections of objects, or any data that isn&#39;t connected to a <code>TDataSet</code>, you can validate the data directly against the filter structure.</p>

<p>Before validating rows, the builder needs to know which data columns are available and in which order values will be supplied.</p>

<pre class="delphi" name="code">FilterBuilder.AddDataColumn(&#39;Age&#39;, fdtNumber);
FilterBuilder.AddDataColumn(&#39;Country&#39;, fdtText);</pre>

<p>This can then be used with <code>ValidateFilterRow</code>.</p>

<pre class="delphi" name="code">var
  Values: TTMSFNCFilterValidateInputRow;
  Match: Boolean;
begin
  SetLength(Values, 2);

  Values[0] := 25;
  Values[1] := &#39;BE&#39;;

  Match := FilterBuilder.ValidateFilterRow(Values);
end;</pre>

<p>The values are matched against the configured data columns. In this example, the first value is compared with <code>Age</code>, while the second value is compared with <code>Country</code>.</p>

<p>If the current filter is:</p>

<pre class="delphi" name="code">Age &gt; 18 AND Country = &#39;BE&#39;</pre>

<p>The row above will match because <code>25</code> is larger than <code>18</code> and the country value is <code>BE</code>.</p>

<p>This allows you to use exactly the same filtering logic regardless of where your data is stored.</p>

<p>You decide what should happen when the data matches.</p>

<ul>
<li>Show or hide rows</li>
<li>Highlight matching records</li>
<li>Filter object collections</li>
<li>Implement your own filtering logic</li>
</ul>

<p>If you&#39;re working with multiple rows, you can validate the complete dataset in a single call.</p>

<pre class="delphi" name="code">ResultArray := FilterBuilder.ValidateFilterArray(InputArray, True);</pre>

<p>This returns an array of Boolean values indicating which rows satisfy the filter. The second parameter controls how the input array is organized. When it is set to <code>True</code>, the input array is treated as row-based data.</p>

<p>Several FNC controls use this functionality internally, but it is equally useful in your own applications where no built-in filtering mechanism exists.<br><br></p>

<h3>Why This Matters</h3>

<p>By separating the filter logic from the generated filter text, the FilterBuilder offers several advantages:</p>

<ul>
<li>You no longer build complex filter strings manually.</li>
<li>The generated filter text can be assigned directly to a <code>TDataSet</code>.</li>
<li>Existing filter text can be parsed back into a structured model.</li>
<li>Nested groups become much easier to create and maintain.</li>
<li>The same filter can generate different output formats.</li>
<li>You can validate data directly without relying on a specific component.</li>
</ul>

<p>The FilterBuilder forms the foundation for all filtering components in the FNC framework.</p>

<p>Whether you want to generate filter text, parse existing expressions, validate data, or build a visual filtering interface, everything starts with this structured filter model.<br><br></p>

<h3>Next Step</h3>

<p>Now that we&#39;ve built a structured filter model, it&#39;s time to make it easier to use.</p>

<p>In the next blog post, we&#39;ll take a look at the <b>TTMSFNCFilterDialog</b>, which uses the FilterBuilder internally to let users create complex filters through a visual interface&#151;without ever having to write a filter expression themselves.</p>

		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿The full power of TMS ALL-ACCESS is within your reach!]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2490</link>
		<author>Aaron Decramer</author>
		<pubDate>Wed, 24 Jun 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		<div><img src="https://www.tmssoftware.com/site/img/upgrade_all_access.png" style="width: 829px;" alt="TMS Software Delphi  Components "><br></div><div><br></div><div>You already know the productivity, reliability and long-term value of TMS products. But did you know there is a simple way to take your development workflow even further?</div><div><br></div><div>With <a href="https://www.tmssoftware.com/site/tmsallaccess.asp" target="_blank">TMS ALL-ACCESS </a>you get everything in one powerful package designed for Windows, web, cross-platform and server development. And the best part? If you already own TMS licenses, they are taken into account to offer you the best possible upgrade price.</div><div><br></div><div>Why developers upgrade:</div><div>ðŸ”¹Full access to our complete product suite, now and future releases</div><div>ðŸ”¹Early access to beta versions and upcoming innovations</div><div>ðŸ”¹Priority support across the entire ecosystem</div><div>ðŸ”¹One simple yearly renewal of just 595&#128;</div><div>ðŸ”¹A single license covering all TMS products</div><div>ðŸ”¹Access to new tools like <a href="https://www.tmssoftware.com/site/tmsaistudio.asp" target="_blank">TMS AI Studio</a>, <a href="https://www.tmssoftware.com/site/tmsfncuipack-grid.asp" target="_blank">TMS FNC DataGrid</a>, <a href="https://www.tmssoftware.com/site/tmswebintro.asp" target="_blank">TMS WEB Core</a> components including TWebDataGrid and more</div><div><br></div><div>It&#146;s a straightforward way to keep your toolbox complete, without having to think about separate licenses or missing out on new releases.</div><div><br></div>Curious what your upgrade would look like? Feel free to contact our sales team, they&#146;ll be happy to assist: <a href="mailto:sales@tmssoftware.com" target="_blank">sales@tmssoftware.com</a><br><div><br></div>
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[ï»¿SVG Export in TMS FNC Chart]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2487</link>
		<author>Pieter Scheldeman</author>
		<pubDate>Wed, 24 Jun 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>ï»¿
		
		
		<p><span style="font-family: Montserrat, sans-serif; font-size: 18px; font-weight: bold;">Intro</span></p>
<p>Exporting charts is not only about taking a screenshot. Reports, dashboards, documentation, and web pages often need output that stays sharp at any size. This post shows how <strong><a href="https://www.tmssoftware.com/site/tmsfncchart.asp" target="_blank">TMS FNC Chart</a></strong> exports a professional mixed chart to SVG across FMX, VCL and WEB using the same core approach: render the chart through <code>ITMSFNCGraphicsExport</code> into <code>TTMSFNCGraphicsSVG</code>.</p>
<p><img src="data:image/png;base64,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cXO6Z9wY8fnSj9fDf/SDmD4v2uLv1vUKvvsOi5DRvGbNv57N/XUnIqKWgcEMERGRibdnD2zftBLRC16w+F99mGZ/CD5ZtwVxm34UXw8Z0A/rlkdajJkw/jZ8/Z8l4mtzK97+p8X9J4y/DV99EmUxprFWvP1Pi31qBELg9OK0Jyw+vy5urpgw/jaLU3duhLdnjzr7yUx68D6L19djyIB+FsvM1m/+CUdPpiPsyQewdnkkJoy/zWIZziBlXzz75MQ6+//cf+9dFq8HKftanPQEU8D19X+W4NGJ91i8Gffz8cSjE+/BvWOvvnFvrMcfuBfRC14Q79vFzRXPPjkR0fOflw4FbvLnUp/mqhOYvqY7v47Fi9OeqPf39vV/ltT52jSHsCcfwIvTnhDryc/HE9ELXsB946/O0LoRK6P/Ve/f0ztGDxU3Em/urzsREbUMspKSEiMA6LOLMXrw9U83JiIiasvyCorx1ItviLNBYNqHQjiqmWqXZEQu/RQwhU1xK16XDiEiIiIiM6nH0jljhoiIyBbCjALz2RmRSz+1mDnT3u0/dFx83l5OOyIiIiK6UZwxQ0RERDcsadfvmD4vGjAtE9q+aaV0CBERERFJcMYMERER3ZDH/1G7SawQynRxc7W6bwoRERER1cVghoiIiJrEhPG3Yd3ySLts3EpERETUWnEpExERERERERGRHXApExERERERERGRHTGYISIiIiIiIiKyEwYzRERERERERER2wmCGiIiIiIiIiMhOGMwQEREREREREdkJgxkiIiIiIiIiIjthMENEREREREREZCcMZoiIiIiIiIiI7ITBDBERERERERGRnTCYISIiIiIiIiKyEwYzRERERERERER2wmCGiIiIiIiIiMhOGMwQEREREREREdkJgxkiIiIiIiIiIjthMENEREREREREZCcMZoiIiIiIiIiI7ITBDBERERERERGRnTCYISIiIiIiIiKyEwYzRERERERERER2wmCGiIiIiIiIiMhOGMwQEREREREREdkJgxkiIiIiIiIiIjuRlZSUGAFAn12M0YP7SftJYuUX36L49CFpc7szdepUbNiwQdpM7RBrgQSsBRKwFsgc64EErAUSsBZIwFqoxWCmkVZ+8S3mPPuotLnd0ev1UCgU0mZqh1gLJGAtkIC1QOZYDyRgLZCAtUAC1gKQeiydS5mIiIiIiIiI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" style="width: 100%;" data-filename="image.png" alt="TMS Software Delphi  Components tmsfncchart"><br></p>

<h4>Quick Highlights</h4>
<ul>
<li><p><strong>One export flow</strong> works across FMX and VCL with framework-specific units and the same chart export concept.</p></li>
<li><p><strong>TTMSFNCGraphicsSVG</strong> captures the chart as real SVG output, preserving paths, text, markers, labels, and annotations.</p></li>
<li><p>The sample combines an area series, bar series, and line series in one dashboard-style chart, making the export visually rich enough for real-world use.</p></li>
</ul>
<p><br></p>

<h4>Building a Mixed Chart for Export</h4>
<p>The sample builds a regional revenue dashboard with three coordinated series: operating profit as an area chart, revenue as colored bars, and the plan as a line with markers. This gives the SVG export a representative mix of filled shapes, strokes, labels, markers, legend items, and annotations.</p>
<pre class="delphi" name="code">ProfitSerie := FChart.Series.Add;
ProfitSerie.LegendText := &#39;Operating profit&#39;;
ProfitSerie.ChartType := ctArea;
ProfitSerie.AutoYRange := arCommonZeroBased;
ProfitSerie.YValues.Positions := [ypLeft];
ProfitSerie.XValues.Positions := [xpBottom];
ProfitSerie.XGrid.Visible := True;
ProfitSerie.YGrid.Visible := True;

RevenueSerie := FChart.Series.Add;
RevenueSerie.LegendText := &#39;Revenue&#39;;
RevenueSerie.ChartType := ctBar;
RevenueSerie.Labels.Visible := True;
RevenueSerie.Labels.Format := &#39;%.0f&#39;;

TargetSerie := FChart.Series.Add;
TargetSerie.LegendText := &#39;Plan&#39;;
TargetSerie.ChartType := ctLine;
TargetSerie.Stroke.Width := 3;
TargetSerie.Markers.Visible := True;
</pre>
<p>Each revenue bar receives its own color through <code>MakeGraphicsColor</code>, while the line series adds markers and an annotation to demonstrate that detailed chart elements are included in the SVG output.</p>
<p><span style="background-color: #eef6ff; border-left: 4px solid #2492d1; padding: 6px 10px; display: inline-block;"><strong>Highlight:</strong> SVG export is especially useful for mixed charts because text, grid lines, markers, bars, and annotations stay crisp in documentation, reports, and web pages.</span></p>
<p><br></p>

<h4>Configuring the Chart Presentation</h4>
<p>The chart is configured with a white background, subtle axis colors, a top-right legend, and a clear title. The goal is to make the exported file immediately usable in a report or presentation without extra styling.</p>
<pre class="delphi" name="code">FChart.Fill.Color := gcWhite;
FChart.Stroke.Color := MakeGraphicsColor(205, 214, 222);
FChart.Title.Text := &#39;Regional Revenue, Profit and Plan&#39;;
FChart.Title.Height := 56;
FChart.Title.Font.Size := 20;
FChart.Title.Font.Color := MakeGraphicsColor(27, 49, 76);

FChart.Legend.Visible := True;
FChart.Legend.Position := lpTopRight;
FChart.Legend.Fill.Color := gcWhite;
FChart.Legend.Font.Color := gcDarkslategray;

FChart.XAxis.Positions := [xpBottom];
FChart.YAxis.Positions := [ypLeft];
</pre>
<p>The same visual setup is used in the FMX and VCL demos, so the exported result remains consistent across frameworks.</p>
<p><br></p>

<h4>Exporting the Chart to SVG</h4>
<p>The actual export is compact. The chart implements <code>ITMSFNCGraphicsExport</code>, so the sample creates a <code>TTMSFNCGraphicsSVG</code> instance with the chart dimensions, starts an SVG scene, and asks the chart to export itself into that graphics context.</p>
<pre class="delphi" name="code">SVG := TTMSFNCGraphicsSVG.Create(ExportWidth, ExportHeight);
try
  SVG.BeginScene;
  try
    Exporter := FChart as ITMSFNCGraphicsExport;
    Exporter.Export(SVG, RectF(0, 0, ExportWidth, ExportHeight));
  finally
    SVG.EndScene;
  end;

  TFile.WriteAllText(FileName, SVG.Build, TEncoding.UTF8);
finally
  SVG.Free;
end;
</pre>
<p>The <code>SVG.Build</code> call returns the complete SVG document as text. From there, the result can be written to disk, downloaded in a browser, embedded in HTML, or passed into another document generation workflow.</p>
<p><span style="background-color: #eef6ff; border-left: 4px solid #2492d1; padding: 6px 10px; display: inline-block;"><strong>Highlight:</strong> The chart is not converted to a bitmap first. The export path writes vector output directly through the FNC graphics abstraction.</span></p>
<p><br></p>

<h4>Output</h4>
<p>The SVG is saved to the user&#39;s documents folder and then opened with the system default SVG viewer. This makes the demo easy to run and easy to inspect.</p>
<pre class="delphi" name="code">function TFormExportSVG.ExportFileName: string;
begin
  Result := TPath.Combine(TPath.GetDocumentsPath,
    &#39;TMSFNCChart_SVG_Export.svg&#39;);
end;
</pre>
<pre class="delphi" name="code">TFile.WriteAllText(FileName, SVG.Build, TEncoding.UTF8);
TTMSFNCUtils.OpenFile(FileName);
</pre>
<p>The resulting file is plain SVG and can be opened in a browser, inserted into documentation, edited in a vector graphics tool, or embedded directly into a web page.</p>
<p><br></p>

<h4>Conclusion</h4>
<p><a href="https://www.tmssoftware.com/site/tmsfncchart.asp" target="_blank">TMS FNC Chart</a> makes SVG export a straightforward Delphi workflow: build the chart, create <code>TTMSFNCGraphicsSVG</code>, export through <code>ITMSFNCGraphicsExport</code>, and save the result. The same pattern works across FMX, VCL and WEB, making it easy to deliver sharp, scalable chart output from desktop and web applications.</p>

		
		
		<br><br></P>]]></description>
	</item>
	</channel></rss>
