TMS Software. All-Access

New blog series coming about extending TMS WEB Core with popular JS libraries

We are pleased to announce that a new blog article series is coming with Andrew Simard with the working title: “Extend TMS WEB Core with JS Libraries with Andrew”. Every week, TMS WEB Core power user Andrew Simard, will offer insights into working with popular JavaScript libraries from TMS WEB Core and share tips, tricks, code and projects. Andrew shares for quite some time already tips, tricks & insights for TMS WEB Core users via our Support Center in a special topic you can find here. The first series of +/- 20 blog articles is already planned and will come to you from April 2022. Watch our blog to learn all about it!    Want to get to know Andrew Simard already? See Andrew in the replay of the TMS WEB Core power users webinar we held a couple of weeks ago where Andrew presents his project he is building with help of TMS WEB Core.

Read More

TMS WEB Core for Visual Studio Code 1.9.8 available now!

We’re pleased to inform that TMS WEB Core for Visual Studio Code 1.9.8 is available. With TMS WEB Core for Visual Studio Code, you can develop web client applications with Object Pascal and using a RAD component based approach. In the last year, we worked very hard to not only fine-tune TMS WEB Core project compatibility between Delphi and Visual Studio Code but also to ensure the features and framework are in sync. Last week we released TMS WEB Core for Delphi and all improvements this latest release brought are today available in TMS WEB Core for Visual Studio Code. This ensures that you or the colleagues in your team have the freedom of choice to develop web client applications from the Delphi IDE on Windows or from the Visual Studio Code IDE directly on Windows, macOS or a Linux desktop machine. Among the many framework improvements, we want to highlight in this blog two new core features. Direct forms support The “Direct form” type, is a form that isn’t using its own unique HTML template file but lives in the application main HTML file. This facilitates that such web client application can be started directly from the file system (no HTTP(s) server needed) and also that it loads faster. You can still bind WEB Core controls to HTML elements but here, the HTML elements will need to be added to the main application HTML file. Note that in a TMS WEB Core web client application, you can mix direct forms with regular forms using a HTML template. To add a direct form to your TMS WEB Core web client application in Visual Studio Code, use this new repository item: To understand better what direct forms can mean for you, check out this video too where it is demonstrated when used from the Delphi IDE. JavaScript Libraries Manager When developing web client applications, it’s a kind of no-brainer to take advantage of existing JavaScript and CSS libraries. Things that come to mind are the Bootstrap, jQuery, Google Material icons, Fontawesome libraries and many more. Most likely, you have your own favorite JavaScript libraries you want to use together with TMS WEB Core web client apps. The JavaScript Libraries Manager allows you to directly pick your preferred library from a list and the IDE will add the proper reference to the project HTML file. At the same time, you can add your own preferred libraries for later convenient reuse. Get started! If you are a TMS ALL-ACCESS user, you automatically have access to the full & latest version of TMS WEB Core for Visual Studio Code.  Get in touch with our team or check out our support center for technical assistance or for sharing your ideas & thoughts to steer further development.

Read More

Detect if a point is in a coordinate based polygon in Delphi

In this blog post, we explained how to measure the area of a polygon defined by coordinates. TMS FNC Maps v3.0.3.0 adds a way to detect a point (coordinate) inside a polygon. In this short blog post, we want to show you how to work with this new functionality. Load GeoJSON First of all, we are going to load our GeoJSON file with coordinates that define the surface area of Germany. TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.LoadGeoJSONFromFile(‘germany.geojson’); TMSFNCMaps1.EndUpdate; Then, we style the polygons loaded by the LoadGeoJSONFromFile method. The complete code to load and style polygons is demonstrated below. procedure LoadGeoJSON; var p: TTMSFNCMapsPolygon; I: Integer; begin TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.LoadGeoJSONFromFile(‘germany.geojson’); for I := 0 to TMSFNCMaps1.Polygons.Count – 1 do begin p := TMSFNCMaps1.Polygons[I]; p.FillOpacity := 0.4; p.FillColor := gcGreenyellow; p.StrokeOpacity := 0.4; p.StrokeColor := gcGreen; end; TMSFNCMaps1.EndUpdate; end; Detecting a coordinate inside a polygon To detect whether or not a coordinate lies inside a polygon, the polygon collection item class exposes a ContainsPoint function. For the purpose of this sample, we used the non visual TTMSFNCGeocoding component and retrieved the coordinates for cities that lie inside and outside of Germany. procedure DetectPoints; var c1, c2, c3, c4: TTMSFNCMapsCoordinateRec; const v = ‘Coordinate inside polygon’; n = ‘Coordinate outside polygon’; begin c1 := TMSFNCGeocoding1.GetGeocodingSync(‘Groningen’); c2 := TMSFNCGeocoding1.GetGeocodingSync(‘Dresden’); c3 := TMSFNCGeocoding1.GetGeocodingSync(‘Munich’); c4 := TMSFNCGeocoding1.GetGeocodingSync(‘Augustenborg’); if TMSFNCMaps1.Polygons[0].ContainsPoint(c1) then TMSFNCMaps1.ShowPopup(c1, v) else TMSFNCMaps1.ShowPopup(c1, n); if TMSFNCMaps1.Polygons[0].ContainsPoint(c2) then TMSFNCMaps1.ShowPopup(c2, v) else TMSFNCMaps1.ShowPopup(c2, n); if TMSFNCMaps1.Polygons[0].ContainsPoint(c3) then TMSFNCMaps1.ShowPopup(c3, v) else TMSFNCMaps1.ShowPopup(c3, n); if TMSFNCMaps1.Polygons[0].ContainsPoint(c4) then TMSFNCMaps1.ShowPopup(c4, v) else TMSFNCMaps1.ShowPopup(c4, n); end; The result output is shown below. Alternative detection The ContainsPoint function at polygon collection item level internally calls the IsPointInArea, which is defined in the *.TMSFNCMapsCommonTypes.pas unit. To use this function, you need to define an array of coordinates. This function can be used without the need to define a polygon inside the Polygons collection.  function IsPointInArea(ALatitude: Double; ALongitude: Double; ACoordinatesArray: TTMSFNCMapsCoordinateRecArray): Boolean; Explore! Go ahead and download TMS FNC Maps. Explore the features and demos and feel free to leave a comment on this blog.

Read More

Q1 2022 : 3 months – 3 milestones – 3 new products in TMS ALL-ACCESS

Here, spring starts today March 21 and soon we are already closing the first quarter of 2022. So with the year well underway, it is time for a short look back at what the year brought so far for Delphi developers using TMS products.  While there has already been the usual flow of product update releases with new features & improvements, so far we also released 3 new products in 2022: TMS MemInsight This brings run-time memory allocation inspection, exception call stack logging, thread inspection and more. The unique angle of TMS MemInsight is that it gives you a run-time view on what is happening in your application as opposed to tools that only provide the information when the application closes, or worse, crashes. This gives the Delphi developer a powerful tool in the hands to inspect, analyze and improve where possible the memory allocation in applications.   GraphQL for Delphi When your applications work with GraphQL, whether it is at the client side or at the server side, our full GraphQL spec-compliant library for Delphi, empowers you to build applications that take advantage of GraphQL. GraphQL is rapidly getting traction as alternative or something to add in addition to classic REST API endpoints for data access. It empowers the client application to control the data communication. With GraphQL for Delphi, you can use the library for creating servers that respond correct to GraphQL requests. Watch the introduction webinar again here. GraphQL for Delphi is available stand-alone or as part of TMS ALL-ACCESS TMS FNC AppTools This is the latest addition to the FNC family of universal components. Universal components can be used in Delphi & C++Builder VCL, FireMonkey apps, Delphi TMS WEB Core apps and LCL Lazarus applications. TMS FNC AppTools focuses on typical desktop application use-cases. So far, it has a non-visual component for persisting the state of forms at the time the user quits the application to bring it back in exactly the same state when the user restarts. It has a component to temporarily password-lock an application to prevent non-authorized people to see sensitive data for example. And it has an automatic application updater component. With this component, it is possible to automatically update a Windows, macOS or Linux desktop application from updated files available on a HTTP(s) server. The component takes care of update version detection, update download and automatic replacement of existing files with updated files and restarting the new version of the application. Users already having our VIP ticket called TMS ALL-ACCESS received these 3 new products this quarter in addition to numerous product updates so far. This includes updates to TMS VCL UI Pack, TMS FNC Maps, TMS Business Subscription, TMS WEB Core and many more… In short, we deliver with TMS ALL-ACCESS literally what the name stands for: access to all our products, all our services, all our technical support and all our new upcoming new products or product update releases. If you did not yet obtain your TMS ALL-ACCESS VIP ticket or your overlooked to renew your TMS ALL-ACCES subscription for this year, contact our sales team to get the best possible deal to (re)enter the TMS ALL-ACCESS VIP area. Our sales team will offer you the best possible upgrade deal based on the existing products you might already have purchased in the past!

Read More

TMS WEB Core v1.9.8.0 Sentina for Delphi is here

We are pleased to announce the availability of TMS WEB Core v1.9.8.0 Sentina. The new release is a further step in making Object Pascal RAD component based web client application development from the Delphi IDE as productive and seamless as possible.  Among the new features are: New : TApplication.CreateFormDirect() method added + IDE integration for direct formsAllows to open forms not having a HTML template but use the project HTML template instead New : TWebListBox.ElementItemClassName property addedAllows to specify a CSS class for items in the TWebListBox New : Bootstrap hints for Bootstrap forms support addedWhen Form.CSSLibrary is set to cssBootstrap, controls will use Bootstrap hints Among the improvements are: Improved : Popup dialog close button positionThe dialog caption and the dialog close button in particular now look better Improved : Actualized materials icons design-time listThe design-time selectable material icons list is significantly extended Improved : High DPI support for design-time editors in Delphi 11 / 11.1When designing forms in Delphi 11 with high DPI form designer, control positioning is improved in resulting web app Other fixes & improvements Direct forms See for yourself what we mean with the new direct forms support in this new release. We created this video especially for you to show the difference between default forms that have a unique HTML template file per forms and direct forms that do not have a HTML template file and therefore are displayed within the context of the project HTML file. Get started Discover how you can create web client applications with zero deployment requirements and that work from a single application code-base on any machine or device that has a browser. Download the fully functional and not time-limited TMS WEB Core trial version to explore at your own pace how you can benefit from it!  For all users with an active TMS WEB Core license, TMS WEB Core v1.9.8.0 Sentina is a free update. If you have an expired license, login on our website to find the best upgrade option or contact our sales by email. 

Read More

Introducing TMS FNC AppTools

We are proud to announce a new member of the TMS FNC family: TMS FNC AppTools!  What is TMS FNC AppTools? Compared to the rest of the FNC family (that is the family of our universal components), TMS FNC AppTools is a little bit different. It revolves exclusively around desktop application development! The reason for this is simple: desktop and mobile applications are unalike and some functionalities/features make no sense or restricted in mobile environments. This way we can fully focus on desktop specific needs. What is included? Let’s take a look at what is included in this first release! TTMSFNCAppUpdate Manage automatic internet based application updates. You can use HTTPS based locations for secure downloads. Username and password protected downloads are also supported! The entry point to the automatic update is an .INF control file. By calling TTMSFNCAppUpdate.NewVersionAvailable the component will download and look at the contents of the control file. A single control file can be used to handle the updates for 3 supported platforms at the same time. This is achieved by a platform suffix (= win, macos or linux): [update_platform] keywords [files_platform] count=N [file1_platform] keywords … [fileN_platform] keywords The TTMSFNCAppUpdate component will automatically scan the control file for the platform it is running on, which means the platform specific suffix is always needed. TTMSFNCAppUpdate gives huge flexibility after the control file has been read. When NewVersionAvailable is called, the FileList collection property will be filled with the contents of the control file. This allows you to freely remove or modify the file descriptors before continuing with the update. procedure TForm1.Button1Click(Sender: TObject); begin   if TMSFNCAppUpdate1.NewVersionAvailable then   begin     if TMSFNCAppUpdate1.FileList.Count > 0 then       TMSFNCAppUpdate1.FileList[0].URL := ‘newdownloadurl’;     TMSFNCAppUpdate1.StartUpdate;   end; end; This becomes a lot simpler if you don’t need to change the file descriptors afterwards. Just call DoUpdate which will internally use NewVersionAvailable and StartUpdate and run the whole process at once. TTMSFNCAppUpdate also supports predefined and custom prefixes that will be replaced in the path related keywords. For example: {APP} stands for the application folder. For custom prefixes you can implement the OnCustomPrefix event! Curious to see it in action? Check our first video we prepared: TTMSFNCAppFormPersist With this component you can automatically persist and restore your application windows’ position, this way the application will open all its windows where you left them. It’s also possible to save and load the position programmatically: procedure TForm1.restoreBtnClick(Sender: TObject); var   afp: TTMSFNCAppFormPersist; begin   afp := TTMSFNCAppFormPersist.Create(Self);   afp.FileName := ‘./temp_settings.ini’;   afp.LoadFormSettings;   afp.Free; end; procedure TForm1.saveBtnClick(Sender: TObject); var   afp: TTMSFNCAppFormPersist; begin   afp := TTMSFNCAppFormPersist.Create(Self);   afp.FileName := ‘./temp_settings.ini’;   afp.SaveFormSettings;   afp.Free; end; TTMSFNCAppLock Keep your current workflow and sensitive data hidden by password locking your running application when needed or if it has been idling for a while. After locking all application windows become minimized and hidden. To unlock, click the minimized application icon and use the default unlock dialog. Alternatively a custom unlocking mechanism can be used by implementing the OnQueryUnlock event. It’s also possible to unlock the application automatically by calling the Unlock method.  procedure TForm1.Button1Click(Sender: TObject); begin   //Unlock automatically after 30 seconds   Timer1.Interval := 30000;   Timer1.Enabled := True;   TMSFNCAppLock1.Lock; end; procedure TForm1.Timer1Timer(Sender: TObject); begin   Timer1.Enabled := False; […]

Read More

Custom extensibility for your Miletus application

One of the new features of TMS WEB Core v1.9.7.0 was custom extensibility for Miletus applications. But what is that exactly? To put it simply, if you are after a native API we did not cover or you have custom routines you’d like to move separately you can take advantage of dynamic libraries and write your own extensions! How it works? As the intro suggests a custom dynamic library will be needed. We’ve built in support for 4 different method types that can be used in dynamic libraries to execute them directly from a Miletus application. These are the following: procedure MyProcedureWithParameter(AData: PChar); cdecl; procedure MyProcedureWithoutParameter; cdecl; function MyFunctionWithParameter(AData: PChar): PChar; cdecl; function MyFunctionWithoutParameter: PChar; cdecl; And the corresponding promises to execute these methods are: //Resolves with nil in case of await() function ExecProc(ALibraryPath: string; AProc: string; AData: string): TJSPromise;  function ExecProc(ALibraryPath: string; AProc: string): TJSPromise; //Resolves with a string in case of await() function ExecFunc(ALibraryPath: string; AFunc: string; AData: string): TJSPromise; function ExecFunc(ALibraryPath: string; AFunc: string): TJSPromise; It’s also possible to assign a callback that can be used to send custom messages to the Miletus application at any time. The only requirement for this is to implement RegisterCallback: type   TCallback = procedure(AMessageID: Integer; AData: PChar); cdecl; var   MyCallback: TCallBack; const    MYID = 123; procedure RegisterCallback(AFunction: Pointer); cdecl; begin   @MyCallback := AFunction; end; procedure MyProcedure; cdecl; begin   //Do something and call MyCallback   MyCallback(MYID, ‘{“Name”: “My data”, “Value”: “This is my JSON formatted data”}’); end; To capture the messages sent via the callback, use the MiletusCommunication.OnCustomMessage event. And of course let’s not forget that you can load a library by calling LoadLibrary(ALibraryPath: string) and unload it by UnloadLibrary(ALibraryPath). With all the puzzle pieces layed out, let’s see how to arrange them into a nice picture. Let’s see an example In our small example we’ll take a look at how to expose the GetUserNameW Windows API to a Miletus application. Keep in mind this is for Windows only! If you want to extend your dynamic library to get the current username for macOS or Linux too, you’ll need to use/implement the OS specific calls for those platforms as well. After creating a new dynamic library project in the Delphi IDE we’ll see an empty template. From here we only need to add one function that returns the result of GetUserName from the Winapi.Windows unit. library DemoLib; uses   System.SysUtils,   System.Classes,   Winapi.Windows; {$R *.res} function GetCurrentUsername: PChar; cdecl; var   buf: array[0..255] of Char;   bufsize: DWORD; begin   bufsize := SizeOf(buf);   GetUserName(buf, bufsize);   Result := buf; end; exports   GetCurrentUsername; begin end. The next step is to use this newly created library from our Miletus application. To keep the application simple, we’ll add a TWebLabel and use that to greet the user when the application starts. As mentioned above we can call the methods directly from the dynamic library via promises. This means we’ll need to mark the TMiletusForm.OnCreate event implementation as [async], which allows us to await the results of our async calls. [async] procedure MiletusFormCreate(Sender: TObject); Now we can use the TMiletusForm.OnCreate implementation to await the LoadLibrary and ExecFunc promises. LoadLibrary resolves with a Boolean value which indicates success of the library loading. ExecFunc resolves with a string that is the result from the DLL. […]

Read More

Automatically work with data backup in the cloud from your Delphi app

Automatically accessing files in cloud storage, making backups, sharing files with other users, distributing application resources via a cloud storage service … all these use-cases became a common practice in recent years. And with TMS FNC Cloud Pack, this becomes easy and seamless to add it to your Delphi VCL Windows applications, cross-platform FireMonkey applications for Windows, macOS, iOS, Android and Linux or TMS WEB Core web client applications. Our colleague Holger Flick explains how you can easily automate access to files stored in the cloud, on the biggest and most well-known cloud storage service providers. What’s more, when you write code once for a given cloud storage service, you can, with just switching properties, change to another cloud storage service provider and use 100% the same code. This includes Dropbox, Google Drive, Microsoft OneDrive, Hubic, Box, … This way, you can even let your end-users decide with what cloud storage service they want to work.  See how it works step by step in this new “How it works with Holger” video: Get started today Discover how TMS FNC Cloud Pack can save you tons of work and start taking advantage of cloud services seamlessly. TMS FNC Cloud Pack can be used simultaneously on these frameworks TMS FNC Cloud Pack can be used simultaneously on these operating systems/browsers TMS FNC Cloud Pack can be used simultaneously on these IDEs

Read More

Calculate square meters of an area in your favorite map service

TMS FNC Maps v3.0 brings a major new feature (more about HTML/CSS element containers in this blog), but along with it, a lot of smaller fixes and improvements. Basically each update brings quality of life improvements. Moving forward from the legacy TMS WebGMaps & WebOSMaps, which were based on the deprecated Internet Explorer technology, we need to port features that were available in those products. We always ask ourselves the question whether those features were implemented in an easy and intuitive way and with TMS FNC Maps our goal is to strive towards a more complete experience by analyzing each feature and then implement it in a way that benefits your application and the developer behind it. One of those improvements is a function that allows polygon area calculation. GeoJSON Polygons in TMS FNC Maps can be displayed by adding a collection of coordinates. Typically, those coordinates come from a database, or a file, or requested from a REST service in GeoJSON format (https://geojson.org/). In this sample, we used the coordinates of Germany. The code below demonstrates how to load GeoJSON data from a file. TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.LoadGeoJSONFromFile(‘germany.geojson’); TMSFNCMaps1.EndUpdate; This will render the following polygon on the map. (map service used in the screenshot is MapBox) The polygon appearance can be changed. The code below demonstrates how to change the opacity of the polygon as well as fill and stroke color. var p: TTMSFNCMapsPolygon; begin p := TMSFNCMaps1.Polygons[0]; p.FillOpacity := 0.4; p.FillColor := gcGreenyellow; p.StrokeOpacity := 0.4; p.StrokeColor := gcGreen; Measuring the area The purpose of this blog post is to show how to calculate the polygon area in square meters (or square kilometer in the demonstrated sample). In the unit *.TMSFNCMapsCommonTypes.pas there is a MeasureArea function that accepts an array of coordinates. We already loaded our polygon from a GeoJSON file and have the coordinates available. var p: TTMSFNCMapsPolygon; m: Double; begin p := TMSFNCMaps1.Polygons[0]; //calculate area in square kilometers m := MeasureArea(p.Coordinates.ToArray) / 1000000; Displaying the results We now have the area in square kilometers of our polygon area. We can display it anywhere in our application, but this sample would not be complete without a demonstration of one of the most exciting features since TMS FNC Maps v3.0. For displaying the results, we chose the Element Containers feature (see this blog for more information). The complete code snippet can be found below as well as the final result. procedure TMapForm.RenderPolygon; var p: TTMSFNCMapsPolygon; m: Double; h: TStringList; e: TTMSFNCMapsElementContainer; begin TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.LoadGeoJSONFromFile(‘germany.geojson’); TMSFNCMaps1.EndUpdate; p := TMSFNCMaps1.Polygons[0]; p.FillOpacity := 0.4; p.FillColor := gcGreenyellow; p.StrokeOpacity := 0.4; p.StrokeColor := gcGreen; //calculate area in square kilometers m := MeasureArea(p.Coordinates.ToArray) / 1000000; h := TStringList.Create; try h.Add(‘The surface area of Germany is approximately ‘ + Format(‘%.0f km²’, [m]) + ”); e := TMSFNCMaps1.AddElementContainer(h, nil, nil, poTopRight); e.UseDefaultStyle := False; finally h.Free; end; TMSFNCMaps1.EndUpdate; end; procedure TMapForm.FormCreate(Sender: TObject); begin TMSFNCMaps1.HeadLinks.AddStyleSheetLink(‘https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css’); TMSFNCMaps1.HeadLinks.AddScript(‘https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js’); TMSFNCMaps1.HeadLinks.AddScript(‘https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js’); TMSFNCMaps1.ReInitialize; end; Excited? Go ahead and download TMS FNC Maps. Explore the features and demos and feel free to leave a comment on this blog.

Read More

Upcoming interactive webinar: TMS WEB Core real-life apps and the best tips & tricks

On March 10 at 16h00 UTC (17h00 CET), we have another ‘first’ at TMS Web Academy: a webinar co-presented by five (5!) TMS WEB Core users who meanwhile have serious experience under their belt in building web applications with Delphi and TMS WEB Core and with apps deployed live.  Together with 5 co-presenters, we will show you these real-life web client applications, give an architectural overview and furthermore, share loads of tips and tricks to help building web client apps with Delphi faster and better. A very interesting part of the co-presenter team is each has used TMS WEB Core from a different angle. This not only highlights the flexibility of TMS WEB Core but also gives you an insight in the wide range of possibilities to create apps with TMS WEB Core. Co-presenters We’re extremely thankful and pleased with the bundled expertise we have for you on this webinar. Here is the list of long-time Delphi developers and TMS WEB Core power users with their specific area of expertise: – Dave Akerman  Building TMS WEB Core Miletus Raspberry Pi apps accessing the Raspberry Pi hardware directly – Russell Weetch  Building huge real-life TMS WEB Core web client apps driven by XData backends TMS Web Academy v2.5 This upcoming webinar experience with 5 co-presenters will also take advantage of the new release v2.5 of TMS Web Academy. The TMS Web Academy is built with TMS WEB Core itself. This new version will allow us to switch presenters & screen sharing live during the webinar. While useful for co-presented webinars, this new v2.5 feature will also help us when we introduce training sessions via the TMS Web Academy platform, allowing the presenter to see screens of users and have a more lively interaction.    Register now & participate! Register here for your unique opportunity to ask questions directly to 5 TMS WEB Core power users and exchange techniques, discuss technical choices and more… during the webinar on March 10, 2022 at 16h00 UTC (17h00 CET)

Read More