<?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>Tue, 7 Jul 2026 12:03: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[﻿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>
	<item>
		<title><![CDATA[﻿Mapping in Delphi & C++Builder with TMS FNC Maps]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2485</link>
		<author>Bart Holvoet</author>
		<pubDate>Fri, 19 Jun 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>﻿
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		<br>
<p>TMS FNC Maps has been a cornerstone of cross-platform mapping in Delphi and C++ Builder for several years now, and with the release of <strong>v4.6</strong>, the API integrations for all major mapping service providers have been brought up to date. Before diving into what changed, this post is also a good opportunity to take a step back and look at everything TMS FNC Maps offers: especially for developers who are just getting started or are looking to get more out of their existing setup.</p><p><br></p>
<h3><img src="https://www.tmssoftware.com/site/img/fnc/maps/fncmapsoverview_icons2.png" style="width: 828px;" alt="TMS Software Delphi  Components tmsfncmaps"><br></h3><h3><br></h3><h3>What is TMS FNC Maps?</h3>
<p><a href="https://www.tmssoftware.com/site/tmsfncmaps.asp">TMS FNC Maps</a> is a cross-framework, cross-platform and cross-service mapping component library for Delphi and C++ Builder. The core idea is simple but powerful: you should never be locked in to a single mapping provider. Switching between mapping services requires nothing more than changing a single property: no code changes, no component swaps, no rewrites.</p>
<p>The library currently supports the following mapping services:</p><p><br></p>
<table style="border:0px;border-collapse:collapse;"><tbody><tr><td style="width:33%"><img src="https://www.tmssoftware.com/site/img/google_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">Google Maps</h4></td><td style="width:33%"><img src="https://www.tmssoftware.com/site/img/here_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">Here Maps</h4></td><td style="width:33%"><img src="https://www.tmssoftware.com/site/img/azure_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">Microsoft Azure Maps</h4></td></tr><tr><td><img src="https://www.tmssoftware.com/site/img/mapbox_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">MapBox</h4></td><td><img src="https://www.tmssoftware.com/site/img/logos/leaflet_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">Leaflet</h4></td><td><img src="https://www.tmssoftware.com/site/img/openlayers_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">OpenLayers</h4></td></tr><tr><td><img src="https://www.tmssoftware.com/site/img//fnc/icons/apple_mapkit_js.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">Apple MapKit</h4></td><td><img src="https://www.tmssoftware.com/site/img/tomtom_icon.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">TomTom</h4></td><td><img src="https://www.tmssoftware.com/site/img/logos/openstreetmap-nominatim.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">OpenStreetMap Nominatim</h4></td></tr><tr><td><img src="https://www.tmssoftware.com/site/img/logos/openrouteservice.jpg" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">OpenRouteService</h4></td><td><img src="https://www.tmssoftware.com/site/img/logos/geoapify.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-top: 5px !important; max-width: 42px !important; height: 42px !important; width: 42px !important;"><h4 style="color: rgb(0, 158, 227); margin-top: 10px;">GeoApify</h4></td><td><br></td></tr></tbody></table><p><br></p><p>TMS FNC Maps targets <strong>VCL</strong>, <strong>FireMonkey</strong> and <strong>TMS WEB Core</strong> and runs on Windows, macOS, iOS, Android and all major browsers. Write your mapping code once and deploy it everywhere.</p>

<hr>
<h3>Feature highlights</h3>
<h4>Markers, shapes and overlays</h4>
<p>Add markers, polylines, polygons, circles and rectangles to any map with just a few lines of code. Custom styled HTML/JavaScript overlays allow you to design fully interactive elements that sit on top of the map. Marker clustering is supported for Google Maps and OpenLayers, keeping your maps clean when displaying large datasets.<br><br></p><p style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif;"><img src="https://www.tmssoftware.com/site/img/blog/tmsfncmaps-here-markers-icon.png" alt="TMS Software Delphi  Components " style="max-width: 100%; width: 50%;"><br></p><p><br></p>
<h4>Directions and routing</h4>
<p>The <code>TTMSFNCDirections</code> component provides route calculation across multiple providers. Travel modes include car, bicycle, walking, public transport and truck (where supported by the provider). Waypoints, optimized ordering and step-by-step turn instructions are all available, and results can be displayed directly on the map.<br><br><img src="https://www.tmssoftware.com/site/img/blog/tmsfncmaps_google_routes_map.png" style="width: 50%;" alt="TMS Software Delphi  Components tmsfncmaps"><br><br></p>
<h4>Geocoding and reverse geocoding</h4>
<p><code>TTMSFNCGeoCoding</code> handles address-to-coordinate and coordinate-to-address lookups across all supported providers. Switching providers for geocoding is, again, just a property change.<br><br></p>
<h4>GPX and GeoJSON support</h4>
<p>TMS FNC Maps includes built-in support for importing and exporting <strong>GPX</strong> and <strong>GeoJSON</strong> files. This makes it straightforward to visualize routes from fitness trackers, navigation devices or any other standard source.<br><br></p>
<h4>Static maps</h4>
<p>The <code>TTMSFNCStaticMap</code> component retrieves a static map image for a given location, zoom level and map type. The resulting image can be displayed using the companion <code>TTMSFNCMapsImage</code> component. Useful for reports, thumbnails or any context where an interactive map is not required.<br><br></p>
<h4>Additional data components</h4>
<ul>
<li><code>TTMSFNCTimeZone</code>: retrieves timezone information for a coordinate</li>
<li><code>TTMSFNCTollCost</code>: calculates toll costs along a route with per-segment detail&nbsp;</li>
<li><code>TTMSFNCElevation</code>: retrieves elevation data for a path or set of coordinates<br><br></li>
</ul>
<h4>Custom tile servers</h4>
<p>For OpenLayers and Leaflet, custom tile servers can be configured. This opens up use cases with private mapping infrastructure, satellite imagery providers or specialist geographic data services.<br><br><img src="https://www.tmssoftware.com/site/img/blog/tmsfncmaps-leaflet-openstreetmap.png" style="width: 50%;" alt="TMS Software Delphi  Components tmsfncmaps"><img src="https://www.tmssoftware.com/site/img/blog/tmsfncmaps-leaflet-opentopomap.png" style="width: 50%;" alt="TMS Software Delphi  Components tmsfncmaps"><br><br></p>
<hr>
<h4></h4><h3>News</h3>API versions updated
<p>Mapping providers do not stand still. They continuously release new API versions with improved endpoints, tighter security requirements and better data quality, while phasing out older versions. Keeping TMS FNC Maps aligned with these changes is essential to ensure your applications keep working reliably.</p>
<p>In <b>TMS FNC Maps</b>&nbsp;<strong>v4.6</strong>, the following service integrations have been updated:</p>
<ul>
<li><strong>HERE Maps</strong>: updated to v3.2&nbsp;</li>
<li><strong>MapBox</strong>: updated to v3.24.0</li>
<li><strong>Azure Maps</strong>: updated to v4</li>
<li><strong>OpenLayers</strong>: updated to v10.9</li>
</ul>
<p><strong>TTMSFNCGoogleMaps</strong> always uses the latest available Google Maps JavaScript API version automatically. If needed, a specific API version can be assigned manually to pin your application to a known-good version.</p>
<p>All other supported services have also been reviewed and confirmed compatible with their current API endpoints.</p>
<p>These are behind-the-scenes updates. Existing code using TMS FNC Maps requires no changes. Simply update to v4.6 and your application will automatically benefit from the current API integrations across all providers.</p>
<hr>
<h3>Resources</h3>
<p>There is a wealth of material available to help you get the most out of TMS FNC Maps.<br><br></p>
<h4>Documentation</h4>
<ul><li><a href="http://download.tmssoftware.com/doc/tmsfncmaps" target="_blank"><b>Full online documentation</b></a> is available, it covers getting started, component reference and code examples.&nbsp;</li><li><a href="https://www.tmssoftware.com/site/cloudkey.asp" target="_blank"><b>API key setup for each provider</b></a>&nbsp;explains how to register your application so you can obtain an application key&nbsp;<br><br></li></ul>
<h4>Blog posts</h4>
<p>A large number of dedicated blog posts covering TMS FNC Maps have been published on the TMS Software blog, ranging from first steps to advanced topics. A few highlights:</p>
<ul>
<li><a href="https://www.tmssoftware.com/site/blog.asp?post=1132" target="_blank"><b>Comparing mapping services in TMS FNC Maps for Delphi</b></a><br>a practical guide to choosing the right mapping service for your application</li>
<li><a href="https://www.tmssoftware.com/site/blog.asp?post=1133" target="_blank"><b>Comparing directions services in TMS FNC Maps for Delphi</b></a><br>an in-depth look at the directions services supported across providers</li>
<li><a href="https://www.tmssoftware.com/site/blog.asp?post=1135" target="_blank"><b>Comparing geocoding services in TMS FNC Maps for Delphi</b></a><br>a side-by-side comparison of geocoding capabilities per service</li>
<li><a href="https://www.tmssoftware.com/site/blog.asp?post=1231" target="_blank"><b>Using Consistent and Customizable Markers in TMS FNC Maps</b></a><br>how to go beyond default marker icons with fully custom styles</li>
<li><a href="https://www.tmssoftware.com/site/blog.asp?post=1233" target="_blank"><b>Visualize your routes with TMS FNC Maps</b></a><br>a practical project using Google StreetView and GPX route data</li>
<li><a href="https://www.tmssoftware.com/site/blog.asp?post=2464" target="_blank"><b>Simplify Mapping Across Platforms with TMS FNC Maps</b></a><br>a broad overview of combining mapping services</li>
</ul>
<p>Browse all TMS FNC Maps blog posts <a href="https://www.tmssoftware.com/site/blog.asp?blogfilter=true&amp;blogfilterproduct=tmsfncmaps" target="_blank">here</a>.<br><br></p>
<h4>Videos</h4>
<p>A growing library of video tutorials covering TMS FNC Maps is available on the <a href="https://www.tmssoftware.com/site/videos.asp" target="_blank">TMS Software videos page</a>. Highlights include:</p>
<ul>
<li><span style="font-weight: 700;"><a href="https://www.tmssoftware.com/site/videos.asp?v=532" target="_blank">Maps with Delphi using TMS FNC Maps</a></span>&nbsp;<br>an extensive multi-part series by C&#233;sar Cardoso (Code4Delphi) covering installation, setup, practical examples and more</li><li><span style="font-weight: 700;"><a href="https://www.tmssoftware.com/site/videos.asp?v=169" target="_blank">Gjalt&#39;s 101: Find your way in TMS FNC Maps</a></span><br>a beginner-friendly introduction</li><li><a style=""><b></b></a><b><a href="https://www.tmssoftware.com/site/videos.asp?v=352" target="_blank">TMS FNC Maps: Support for Leaflet</a><br></b>a walkthrough of integrating Leaflet for Windows and web applications</li><li><span style="font-weight: 700;"><a href="https://www.tmssoftware.com/site/videos.asp?v=439" target="_blank">Fixing Google Maps API Errors in Delphi Applications with TMS FNC Maps</a></span>&nbsp;<br><span style="color: rgb(51, 51, 51); font-family: Roboto, sans-serif;">learn how to fix Google Maps API errors in Delphi applications with this quick guide<br><br></span></li>
</ul>
<h4>Book</h4>
<p>For a deep dive, the book <strong>Hands-on with Delphi: FNC Maps</strong> by Holger Flick is available on Amazon. It covers the component library in detail with practical examples and is highly recommended for anyone looking to build serious mapping applications.<br></p><div class="row product-title link list-product-blue" style="margin-left: 0px; color: rgb(51, 51, 51); font-family: Roboto, sans-serif; font-size: 16.8px; margin-bottom: 0px;"><a href="https://www.amazon.com/Software-Hands-Delphi-Cross-framework-Cross-platform/dp/B08GRN6RFN/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B088BJLLWG&amp;linkCode=as2&amp;tag=tmssoftware-20&amp;linkId=3730767b4e261c8ae501f9f14c6bd9eb.asp" style="outline: 0px; color: black !important; text-decoration: none !important;"><img src="https://www.tmssoftware.com/site/img/blog/handson_book_2.png" alt="TMS Software Delphi FNC Components TMS FNC Maps" style="margin-top: 5px !important; max-width: 200px !important; height: auto !important; width: 200px !important;"></a></div><div><br></div>
<p><a href="https://www.amazon.com/Software-Hands-Delphi-Cross-framework-Cross-platform/dp/B08GRN6RFN/"><b>Discover the book on Amazon</b></a><br><br></p>

<h4><span style="color: inherit;">Support</span></h4>
<p>If you have any questions or run into anything after updating, the dedicated <a href="https://support.tmssoftware.com/c/fnc/tms-fnc-maps"><b>TMS FNC Maps support category</b></a> is the right place to go.</p>
		
<hr>
<h3>Getting the update</h3>
<p>TMS FNC Maps v4.6 is available now. All license holders, including <strong>TMS ALL-ACCESS</strong> and <strong>TMS FNC Component Studio</strong> subscribers, can install the update directly via <a href="https://www.tmssoftware.com/site/tmssmartsetup.asp"><b>TMS Smart Setup</b></a>.</p>
<p>Not yet a customer? <a href="https://www.tmssoftware.com/site/tmsfncmaps.asp"><b>Discover TMS FNC Maps</b></a> and start with a free trial.</p>

		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[﻿Filtering in Delphi: From Strings to Structured Logic]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2489</link>
		<author>Gjalt Vanhouwaert</author>
		<pubDate>Thu, 18 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>Filtering data is something we all do.</p><p>
Whether it&#146;s a grid, a dataset, or a list of objects&#151;at some point, users want to narrow things down.</p>

<p>In Delphi, the most common starting point is still the <code>Filter</code> property on a <code>TDataSet</code>.</p>

<pre class="delphi" name="code">DataSet.Filter := &#39;Age &gt; 18 AND Country = &#39;&#39;BE&#39;&#39;&#39;;
DataSet.Filtered := True;</pre>

<p>It works.<br>
But once you go beyond simple cases, it quickly becomes harder to manage.</p>

<h3>Where It Starts to Break Down</h3>

<p>The main issue is that filtering is just&#133; a string.</p>

<p>That means:</p>
<ul>
<li>No structure</li>
<li>No validation before execution</li>
<li>No guidance while building it</li>
</ul>

<p>And as developers, we might get away with that.<br>
But even then, it&#146;s not always pleasant to work with.</p>

<p>A slightly more complex example:</p>

<pre class="delphi" name="code">([YearOfBirth] &lt; 2008 AND [Subscription Country] = &#39;BE&#39;) OR ([YearOfBirth] &lt; 2005 AND [Subscription Country] = &#39;US&#39;)</pre>

<p>Now imagine:</p>
<ul>
<li>Typing this manually</li>
<li>Making sure field names are correct</li>
<li>Keeping brackets balanced</li>
<li>Debugging when something doesn&#146;t work</li>
</ul>

<p>There&#146;s no help.<br>
You only find out something is wrong <b>after</b> applying the filter.</p>

<h3>What About End Users?</h3>

<p>This is where things really fall apart.</p>

<p>We can&#146;t realistically expect users to write expressions like that.</p>

<p>Even if we wrap it in a UI:</p>
<ul>
<li>They still need to understand field names</li>
<li>They still need to understand operators</li>
<li>They still need to think in syntax</li>
</ul>

<p>That&#146;s not how users think about filtering.</p>

<p>They think in terms of:</p>
<ul>
<li>&#147;Show me adults&#148;</li>
<li>&#147;Only items from Belgium&#148;</li>
<li>&#147;Orders after this date&#148;</li>
</ul>

<p>Not:</p>

<pre class="delphi" name="code">(Age &gt; 18 AND Country = &#39;BE&#39;)</pre>

<h3>The Core Problem</h3>

<p>If you look at it from a bit of distance, the issue is not filtering itself.</p>

<p>It&#146;s how we represent it.</p>

<p>Right now:</p>
<ul>
<li>We store logic as a <b>string</b></li>
<li>We build it manually</li>
<li>We validate it too late</li>
</ul>

<p>What we&#146;re missing is:</p>
<ul>
<li>A <b>structured way</b> to define filters</li>
<li>Something that reflects actual logic (not just text)</li>
<li>A way to validate before applying</li>
</ul>

<h3>A Different Approach</h3>

<p>Instead of thinking in strings, you can break a filter down into smaller parts:</p>

<ul>
<li>A <b>field</b> (what are we filtering on?)</li>
<li>An <b>operator</b> (how do we compare?)</li>
<li>A <b>value</b> (what are we comparing against?)</li>
</ul>

<p>Something like:</p>

<pre class="delphi" name="code">Age &gt; 18</pre>

<p>Becomes:</p>
<ul>
<li>Field: <code>Age</code></li>
<li>Operator: <code>&gt;</code></li>
<li>Value: <code>18</code></li>
</ul>

<p>And once you have that, you can start combining them:</p>
<ul>
<li>With AND / OR</li>
<li>In groups</li>
<li>Even nested if needed</li>
</ul>

<p>At that point, you&#146;re no longer dealing with a string.<br>
You&#146;re working with a <b>model of your filter logic</b>.</p>

<p>And that opens the door to:</p>
<ul>
<li>Validation before execution</li>
<li>Reusable logic across controls</li>
<li>And eventually&#133; user-friendly ways to build filters</li>
</ul>

<h3>Where This Leads</h3>

<p>Once filtering is structured instead of string-based, a few things become possible:</p>

<ul>
<li>You can <b>generate different output formats</b> (DataSet, SQL, OData, &#133;)</li>
<li>You can <b>validate filters safely before applying them</b></li>
<li>You can build <b>UI on top of the logic</b>, instead of parsing text afterward</li>
</ul>

<p>That&#146;s the direction we started exploring.</p>

<p>Not by replacing filtering entirely,<br>
but by putting a layer in between:<br>
something that understands filter logic<br>
and can translate it where needed</p>

<h3>Next Step</h3>

<p>In the next post, we&#146;ll look at how this structured approach can be implemented in practice:</p>
<ul>
<li>how filters are built internally</li>
<li>how grouping and nesting works</li>
<li>and how this solves a lot of the issues mentioned here</li>
</ul>

		
		
		
		
		
		<br><br></P>]]></description>
	</item>
	<item>
		<title><![CDATA[﻿Free native Barcode & QR Code Generation in VCL Applications]]></title>
		<link>https://www.tmssoftware.com/site/blog.asp?post=2488</link>
		<author>Bruno Fierens</author>
		<pubDate>Wed, 17 Jun 2026 12:00:00 +0000</pubDate>
		<description><![CDATA[<P>﻿
		
		<div><b>Barcodes </b>and <b>QR codes</b> are everywhere: product labels, invoices, tickets, warehouse apps, mobile links, asset tracking and more. With Bar&amp;QRCodes4D, Delphi developers can add this functionality directly to VCL applications with <b>native Delphi code</b>.</div><div>The open-source library is available on GitHub:</div><div><a href="https://github.com/tmssoftware/Bar_QRCodes4D" target="_blank">https://github.com/tmssoftware/Bar_QRCodes4D</a><br><br></div><div>It contains native barcode and QR code generator components for Delphi VCL applications, including sample projects for barcode and QR code generation.<br><br><h4>Adding a Barcode Component</h4><div>After installing or adding the units to your project, barcode generation starts with the TTMSBarCode component.</div><div><pre class="delphi" name="code">uses
  TMSBarCode;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TMSBarCode1.BarcodeType := tbcCODE128;
  TMSBarCode1.Value := &#39;TMS-123456789&#39;;
end;</pre></div><div>The component renders the barcode directly in the VCL form.</div><div><br></div><div><img src="https://www.tmssoftware.com/site/img/blog/barcode4d.png" style="width: 828px;" alt="TMS Software Delphi  Components "><br><br></div><div><b>Choosing the Barcode Type</b><br><br></div><div>The barcode component supports several common barcode formats. For example, to generate an EAN-13 barcode:<br></div><div><pre class="delphi" name="code">procedure TForm1.GenerateEAN13;
begin
  TMSBarCode1.BarcodeType := tbcEAN13;
  TMSBarCode1.Value := &#39;5412345678908&#39;;
end;</pre>For Code 39:</div><div><pre class="delphi" name="code">procedure TForm1.GenerateCode39;
begin
  TMSBarCode1.BarcodeType := tbcCODE39;
  TMSBarCode1.Value := &#39;TMSCODE39&#39;;
end;</pre></div><br><div>For Interleaved 2 of 5:</div><div><pre class="delphi" name="code">procedure TForm1.GenerateITF;
begin
  TMSBarCode1.BarcodeType := tbcITF;
  TMSBarCode1.Value := &#39;1234567890&#39;;
end;</pre><br></div><div><b>Customizing the Barcode</b></div><div><br>The barcode appearance can be customized with properties such as bar color, background color, module width, margins and text display.<br><pre class="delphi" name="code">procedure TForm1.SetupBarcodeStyle;
begin
  TMSBarCode1.BarColor := clBlack;
  TMSBarCode1.BackgroundColor := clWhite;
  TMSBarCode1.ModuleWidth := 2;
  TMSBarCode1.BarHeight := 100;
  TMSBarCode1.Margin := 10;
  TMSBarCode1.DisplayValue := True;
end;</pre></div><div>This makes it easy to adapt the barcode output for screen display, label printing or report generation.<br><br></div><div><b>Checking for Encoding Errors</b><br><br></div><div>When generating barcodes dynamically, it is useful to validate the value before printing or exporting.</div><div><pre class="delphi" name="code">procedure TForm1.ValidateBarcode;
var
  LPattern: string;
  LText: string;
begin
  if TMSBarCode1.TryEncode(LPattern, LText) then
    ShowMessage(&#39;Barcode generated successfully&#39;)
  else
    ShowMessage(TMSBarCode1.LastError);
end;</pre></div><div>This is especially helpful when using barcode formats that require numeric input or fixed-length values.<br><br></div><div><b>Exporting a Barcode to PNG</b></div><div>Barcodes can also be exported to image files.</div><div><pre class="delphi" name="code">procedure TForm1.SaveBarcodeAsPNG;
begin
  TMSBarCode1.SaveToPNG(&#39;c:\temp\barcode.png&#39;);
end;</pre></div><br><div><b>Exporting a Barcode to SVG</b></div><div>For high-quality scalable output, SVG export is also available.</div><div><pre class="delphi" name="code">procedure TForm1.SaveBarcodeAsSVG;
begin
  TMSBarCode1.SaveToSVG(&#39;c:\temp\barcode.svg&#39;);
end;</pre></div><div>SVG export is particularly useful for printing, label design and integration with document workflows.</div><div><br></div><h4>Generating QR Codes</h4><div>QR code generation is just as straightforward with the QR code component.</div><div><pre class="delphi" name="code">uses
  TMSQRCode;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TMSQRCode1.Value := &#39;https://www.tmssoftware.com&#39;;
end;</pre><div>This instantly creates a QR code that can be scanned with a phone camera.</div><div><br></div><div><img src="https://www.tmssoftware.com/site/img/blog/qrcode4d.png" style="width: 828px;" alt="TMS Software Delphi  Components "><br></div><div><br></div><div><b>Generating a QR Code from User Input</b></div><div>A common scenario is generating a QR code from a value entered by the user.</div><div><pre class="delphi" name="code">procedure TForm1.ButtonGenerateClick(Sender: TObject);
begin
  TMSQRCode1.Value := EditQRCodeText.Text;
end;</pre><div>This can be used for URLs, contact details, product IDs, internal references or any other text value.</div></div><div><br></div><div><div><b>Exporting a QR Code</b></div></div></div></div><div>QR codes can also be exported to PNG or SVG.</div><div><pre class="delphi" name="code">procedure TForm1.SaveQRCode;
begin
  TMSQRCode1.SaveToPNG(&#39;c:\temp\qrcode.png&#39;);
  TMSQRCode1.SaveToSVG(&#39;c:\temp\qrcode.svg&#39;);
end;</pre><h4>Printing from VCL</h4></div><div>Because the components render natively, they can be used in normal VCL printing workflows.</div><div><pre class="delphi" name="code">uses
  Vcl.Printers;

procedure TForm1.PrintBarcode;
begin
  Printer.BeginDoc;
  try
    TMSBarCode1.PaintTo(Printer.Canvas.Handle, 100, 100);
  finally
    Printer.EndDoc;
  end;
end;</pre><div>This keeps barcode generation fully inside the Delphi application, without external tools or online services.</div><div><br><h4>Why Native Delphi Code Matters</h4><div>Using a native Delphi barcode and QR code library has several advantages:</div><div>&#149;<span style="white-space:pre">	</span>no external DLL deployment</div><div>&#149;<span style="white-space:pre">	</span>no server-side generation required</div><div>&#149;<span style="white-space:pre">	</span>no internet dependency</div><div>&#149;<span style="white-space:pre">	</span>full Delphi source availability</div><div>&#149;<span style="white-space:pre">	</span>easy integration in existing VCL projects</div><div>&#149;<span style="white-space:pre">	</span>direct PNG and SVG export</div><div>For applications that need reliable local code generation, this keeps deployment simple and predictable.<br><br></div><h4>Conclusion</h4><div>Bar&amp;QRCodes4D brings native barcode and QR code generation to Delphi VCL applications in a clean and practical way. With support for common barcode formats, QR code rendering and export to PNG and SVG, it is a useful open-source library for adding machine-readable codes to business applications.</div><div>The full source code and demo projects are available on GitHub:<br><img src="https://www.tmssoftware.com/site/img/blog/github.png" style="width: 239.913px; height: 88.9531px;" alt="TMS Software Delphi  Components "><br><a href="https://github.com/tmssoftware/Bar_QRCodes4D" target="_blank" style="background-color: white; font-family: sans-serif;">https://github.com/tmssoftware/Bar_QRCodes4D</a>&nbsp;</div></div><div><br></div><br></div>
		
		
		
		<br><br></P>]]></description>
	</item>
	</channel></rss>
