The TMS WebGMaps v3.1 update includes map styles and SVG markers

We’re pleased to announce TMS WebGMaps v3.1 has been released today. TMS VCL WebGMaps is our component for VCL development that exposes a myriad of geographical functions for integration in Delphi or C++Builder Windows applications while TMS FMX WebGMaps offers the same functionality for cross-platform FireMonkey applications on Windows, Mac, iOS and Android.

In this new version we introduce the functionality to display the map in a custom style. You can use the pre-defined Night Mode style or any other custom style.

The code needed for this is just one line of code:

    WebGMaps1.MapOptions.MapStyle := mstNightMode; 

The code needed for this is just two lines of code:

  WebGMaps1.MapOptions.CustomStyle.Text := '[JSON Object]';
  WebGMaps1.MapOptions.MapStyle := mstCustom;

Use the Google Maps Platform Styling Wizard as a quick way to generate your own JSON styling object.

Another new feature are SVG Markers. This technique allows to display markers with a custom shape based on a SVG path. Several pre-defined shapes are available as well as the possibility to add your own custom SVG path.

Adding markers with a custom shape is very easy as this code snippet shows:

var
  m: TMarker;
begin
  m := WebGMaps1.Markers.Add(WebGMaps1.MapOptions.DefaultLatitude, WebGMaps1.MapOptions.DefaultLongitude);
  m.Shape := msStar;
  m.ShapeColor := clYellow;
  m.ShapeScale := 2;
  WebGMaps1.UpdateMapMarker(m);

  m := WebGMaps1.Markers.Add(WebGMaps1.MapOptions.DefaultLatitude + 0.1, WebGMaps1.MapOptions.DefaultLongitude - 0.1);
  m.Shape := msStar;
  m.ShapeColor := clYellow;
  WebGMaps1.UpdateMapMarker(m);

  m := WebGMaps1.Markers.Add(WebGMaps1.MapOptions.DefaultLatitude - 0.1, WebGMaps1.MapOptions.DefaultLongitude - 0.1);
  m.Shape := msFavorite;
  WebGMaps1.UpdateMapMarker(m);

  m := WebGMaps1.Markers.Add(WebGMaps1.MapOptions.DefaultLatitude + 0.1, WebGMaps1.MapOptions.DefaultLongitude + 0.1);
  m.Shape := msHome;
  m.ShapeColor := clSkyBlue;
  m.ShapeScale := 2;
  WebGMaps1.UpdateMapMarker(m);
end;

Today’s update also includes other smaller new features and improvements.
We look forward to learn about your interesting integrations of TMS WebGMaps in your applications!

Read More

Read More

When generics and VCL controls bite you: memory overwrites when you show the control usually ending up in access violations

Recently I got bitten by the 2013 reported http://qc.embarcadero.com/wc/qcmain.aspx?d=112101 (too bad the site is gone and the WayBack machine doesn’t have it archived) as a result of [WayBack] delphi – Why do I get access violations when a control’s class name is very, very long? – Stack Overflow. It got reentered as [RSP-18399] Buffer overflow in TWinControl.CreateParams() – Embarcadero Technologies but since that requires logon, it’s not search machine indexed so it’s very hard to find unless you know where to look. So I spent a quite some time to find out what was wrong: Since Delphi 1, the [WayBack] Controls.TCreateParams Record has a 64-byte WinClassName field that’s blindingly copied by the TWinControl.CreateParams without range checking. The structure is used by the [WayBack] TWinControl.CreateWnd Method to call the Windows API [WayBack] RegisterClass function that takes a [WayBack] WNDCLASS structure with a lpszClassName field that supports up to 256 characters and it fails when it’s longer. That overwrite cause spurious other errors depending on the memory that gets overwritten. It took almost a day to figure out the cause of the error was this field, then an hour or to track that down to the long class names created by generic code. To my surprise, I found back [WayBack] This issue caused coworkers and me quite a few hours wasted:Long story short – refactor some forms/frames to class names longer than 64 chars and boom… – Stefan Glienke – Google+. As of Delphi 8 (yes, that version that a lot of people want to forget, but did bring a few good things), the structure was defined as below, and the code intialising also got improved: Params.WinClassName := ClassName; ... Params.WinClassName := Format('%s.%d', [Params.WinClassName, AppDomain.CurrentDomain.GetHashCode]); So there it’s a string that – if it is too long – will get rejected by the Windows API anyway just like the native Delphi VCL implementation should have done 20+ years ago. The sad part for FMX users: that structure and code got blindingly copied to the FMX.Controls.Win unit. {$IF DEFINED(CLR)} TCreateParams = record Caption: string; Style: DWORD; ExStyle: DWORD; X, Y: Integer; Width, Height: Integer; WndParent: HWND; Param: IntPtr; WindowClass: TWndClassInfo; WndProc: TFNWndProc; WinClassName: string; end; {$ELSE} TCreateParams = record Caption: PChar; Style: DWORD; ExStyle: DWORD; X, Y: Integer; Width, Height: Integer; WndParent: HWnd; Param: Pointer; WindowClass: TWndClass; WinClassName: array[0..63] of Char; end; {$ENDIF} –jeroen
Read More

When generics and VCL controls bite you: memory overwrites when you show the control usually ending up in access violations

Recently I got bitten by the 2013 reported http://qc.embarcadero.com/wc/qcmain.aspx?d=112101 (too bad the site is gone and the WayBack machine doesn’t have it archived) as a result of [WayBack] delphi – Why do I get access violations when a control’s class name is very, very long? – Stack Overflow. It got reentered as [RSP-18399] Buffer overflow in TWinControl.CreateParams() – Embarcadero Technologies but since that requires logon, it’s not search machine indexed so it’s very hard to find unless you know where to look. So I spent a quite some time to find out what was wrong: Since Delphi 1, the [WayBack] Controls.TCreateParams Record has a 64-byte WinClassName field that’s blindingly copied by the TWinControl.CreateParams without range checking. The structure is used by the [WayBack] TWinControl.CreateWnd Method to call the Windows API [WayBack] RegisterClass function that takes a [WayBack] WNDCLASS structure with a lpszClassName field that supports up to 256 characters and it fails when it’s longer. That overwrite cause spurious other errors depending on the memory that gets overwritten. It took almost a day to figure out the cause of the error was this field, then an hour or to track that down to the long class names created by generic code. To my surprise, I found back [WayBack] This issue caused coworkers and me quite a few hours wasted:Long story short – refactor some forms/frames to class names longer than 64 chars and boom… – Stefan Glienke – Google+. As of Delphi 8 (yes, that version that a lot of people want to forget, but did bring a few good things), the structure was defined as below, and the code intialising also got improved: Params.WinClassName := ClassName; ... Params.WinClassName := Format('%s.%d', [Params.WinClassName, AppDomain.CurrentDomain.GetHashCode]); So there it’s a string that – if it is too long – will get rejected by the Windows API anyway just like the native Delphi VCL implementation should have done 20+ years ago. The sad part for FMX users: that structure and code got blindingly copied to the FMX.Controls.Win unit. {$IF DEFINED(CLR)} TCreateParams = record Caption: string; Style: DWORD; ExStyle: DWORD; X, Y: Integer; Width, Height: Integer; WndParent: HWND; Param: IntPtr; WindowClass: TWndClassInfo; WndProc: TFNWndProc; WinClassName: string; end; {$ELSE} TCreateParams = record Caption: PChar; Style: DWORD; ExStyle: DWORD; X, Y: Integer; Width, Height: Integer; WndParent: HWnd; Param: Pointer; WindowClass: TWndClass; WinClassName: array[0..63] of Char; end; {$ENDIF} –jeroen
Read More

Firemonkey/Isometric at master · tothpaul/Firemonkey

This shows you how to do 2.5D isometric projection in Delphi using Firemonkey: [WayBack] Firemonkey/Isometric at master · tothpaul/Firemonkey. [WayBack] Isometric projection – Wikipedia. Via: [WayBack] I wonder what the best approach would be to use FireMonkey to develop an isometric 2.5D game in the “classic” way… – Fl Ko – Google+ –jeroen
Read More

Changes between GExperts 1.3.12 and 1.3.13

I had to look them up myself, so it took a while but here they are, the changes, bugfixes and improvements between the GExperts 1.3.12 (released 2018-12-22) and 1.3.13 (released yesterday, 2019-03-30): Bugfix (#105): Set Tab Order expert no longer worked with Delphi 6, 7 and 2005 (Remember what I wrote about testing these versions?)Improvements to the Uses Clause Manager:New configuration setting “GExperts caching directory”, used to store the cached identifiers per unitAdditional configuration options for the expert: Caching can now be disabled and the cache can be cleared. (Bug report #104)It is now possible to use the project’s map file rather than the dpr for getting a list of used units. This includes the VCL/RTL and possibly any 3rd party units and makes the Project tab much more useful.Bugfix (#110): Entries in the VCL/RTL list were clipped / overlapped.Bugfix (#109): When loading a form’s position only, Width and Height no longer change every time.Added additional Delphi 10.2 and 10.3 warnings to the Insert Warn Directive editor expertBugfix: The number of entries for the Favourite Files expert in the registry doubled every time the list was saved.Improvements to the Grep expert:Hint about separating multiple directories with semicolon.It can now use the project’s map file rather than the dpr for getting the list of used units. This includes all units compiled in the project not just those explicitly added to it. There is a configuration option for enabling that.Ensure that the RTL and all existing subsystem Paths (VLC, FMX, CLX) are in the drop down menu.Searching DFM files can now handle strings split into multiple lines and containing special characters stored as #<number>. (Note: This is not quite finished. The display in the Results window is broken.) (Bug report #112)Custom beep as a WAV file for the Proof Reader expert (Suggested by Philip Rayment, Patch by Achim Kalwa, Bug report #111).Bugfix (#113): Added another check for duplicate GExperts DLLs being loaded into the same IDE to prevent error message “PrivateGXMenuActionManager is not nil upon creation”Project Dependency expert:Dramatically improved performance for the indirect dependencies tab. The strings and string lists are no longer stored in and read from the UI. Also string lists are now sorted so look ups are much faster.Units in the project (root node of the tree view are now also listed)New configuration option to search for units in the library path and also in the browsing path.Bugfix (#114): Disabled editor experts still blocked the associated keyboard shortcut and could be called with this shortcut.Bugfix (#117): Editor experts could be executed even if not the code editor but the form editor was active. As you can see above, I am looking into bugs reported on Sourceforge and also feature suggestions posted there. That is my preferred way of users to report bugs and request features because it is easy for me to manage them in one place. The other channels (email via the GExperts “Send a Bug Report / Suggestion” button and the GExperts subforum in the international Delphi Praxis forum) work too, but they are much less convenient for me and some reports / requests may get lost. Also, please remember that I am working on this project in my spare time, so any additional work, e.g. creating bug reports on Sourceforge from emails I receive, takes time in which I am not working on the actual software. It’s also boring work which might discourage me from doing it and if it is getting out of hand might even make me stop working on GExperts at all. Let me close this post by thanking all those people who have worked on GExperts before me and on whose work I have been building over the years (and whose work I have also been using as a GExperts user for more than two decades as a professional software developer). And also those who continue to contribute their work and some money to this project. Discussion about this post in the international Delphi Praxis forum.
Read More

ICS V8.60 has been released

ICS V8.60 has been released at: http://wiki.overbyte.eu/wiki/index.php/ICS_Download ICS is a free internet component library for Delphi 7, 2006 to 2010, XE  to XE8, 10 Seattle, 10.1 Berlin, 10.2 Tokyo and 10.3 Rio, and C++Builder 2006 to XE3, 10.2 Tokyo and 10.3 Rio. ICS supports VCL and FMX, Win32, Win64 and MacOS targets. The distribution zip includes the latest OpenSSL 1.1.1 win32, with
Read More

Selling your Delphi apps via Microsoft Store is now Cheaper

For a few years now, Delphi has had support for the Windows Dektop Bridge. This is a Microsoft technology allowing to create UWP (Universal Windows Platform) applications based on a traditional Win32/Win64 application. Delphi IDE simplifies this process (making it smoother than with Microsoft own tools) as you ca read in the docwiki. While there are still some hurdles to enable desktop bridge apps in the store (there is an manual authorization process from Microsoft) the cost to be on the store is fairly low. Over the last year Microsoft has been increasingly pushing developers towards the Windows Store (actually, now called Microsoft Store) for applications distribution on Windows -- where it competes mostly with game distribution platforms. They even released a version of the operating system, Windows 10 S, which only allows installation of apps from the store. However, this has seen a limited traction. In terms of costs, the Microsoft Store has long offered a 85% revenue share, which is generous compared to the mobile counterparts (at 70% in general). They were offering some special rates from links to the developer site. Now they have rolled out a new and simplified revenue sharing plan. In short, for anyone who buys through an external link (that is, not browsing or searching in the store application itself) the revenue share will be at 95%. This is lower than the processing, invoicing, and payment commission costs of a direct sale -- plus you have to pay for the infrastructure and more, handle updates process, and so forth. If you sell Windows applications to the public (consumers, but also companies) I suggest you to double check the Microsoft Store distribution model, given how easy we have made turning your existing VCL and FMX apps into store apps and how generous the revenue share from Microsoft has become.
Read More

Are these really Windows compiler unsupported Delphi Intrinsic Routines?

Odd, the [WayBack/Archive.is] Delphi Intrinsic Routines – RAD Studio indicates quite a few compiler intrinsics are not available on Windows. I wonder if this list is correct: Routine Description DCC32 DCC64 DCCOSX DCCAARM DCCIOSARM DCCIOSARM64 DCCIOS32 System.AtomicCmpExchange AtomicCmpExchange is used for comparing and exchanging memory values. System.AtomicDecrement AtomicDecrement is used for decrementing memory values. System.AtomicExchange […] … Read More

Read More

Adding the 3rd dimension to TMS WEB Core

Our team is working hard on the next major release of TMS WEB Core. This will be TMS WEB Core v1.2 Padua. Padua is the next city after Brescia (1.0) and Verona (1.1) on our Mille Miglia race track.

We have shown already a preview of the support for Electron based cross platform desktop apps that will come out of the box with TMS WEB Core v1.2. The new version 1.2 will also come with numerous Object Pascal to JavaScript transpiler enhancements (Pas2JS v1.4) with most importantly the support for anonymous methods. There is a lot more coming that we will unveil in the coming weeks!

With this blog, we wanted to take you to the 3rd dimension that will be added to TMS WEB Core in v1.2, that is the support for 3D graphics based on the amazing WebGL / ThreeJS technology. Thanks to this technology, rendering 3D scenes is fluid and fast right out of any modern browser. This means Chrome, FireFox, Opera, Safari on desktop and on mobile devices.

The WebGL / ThreeJS technology is powerful but it can be quite complex and daunting. Here comes the TMS WEB Core framework with easy usable classes for taking advantage of this technology.

In the upcoming TMS WEB Core this will be exposed via 3 UI controls:

  • TWebThreeJSPaintBox
  • TWebThreeJSChart
  • TWebThreeJSMathChart

Custom 3D scenes with TWebThreeJSPaintBox

The TWebThreeJSPaintBox is a simple 3D scene renderer. Where in a regular 2D PaintBox you do the drawing with lines, rectangles, … here you can add 3D objects like cube, sphere, cylinder, text, lines, shapes, 3D models …

Adding a red sphere becomes as simple as:

var
  anObject: TThreeJsObject3D;

begin
  anObject := threeJsPaintBox.addSphere(2, clRed, 10, 8, 4);
  anObject.name := 'sphere1';
  threeJsPaintBox.Invalidate;
end;

This sphere object can now be manipulated or removed again by accessing the object by its name.

As such, the TWebThreeJSPaintBox allows to create any custom 3D scene easily using the ObjectPascal language.

3D business charts with TWebThreeJSChart

The next 3D control is the TWebThreeJSChart. This is a 3D chart with 3 axes. It allows to add series with their 3D values, select the chart type (bar, cone, line, area, cylinder, scatter) and the TWebThreeJSChart will do all that is necessary to setup the 3D scene to render the chart.

We have created a small & quick demo to demonstrate the power. This 3D chart visualizes the virtual sales results of Germany’s leading car manufacturers: Audi, BMW, Mercedes, Porsche. To make the data editable to let users play with the chart, it is displayed in a TWebStringGrid. It shows 4 columns for the sales results for the 4 car manufacturers and 12 months of the year. To configure the 3D chart from the results in the TWebStringGrid, the following code is used:

procedure TForm2.LoadSampleSeries;
var
  aSeries: TThreeJsChartSeries;
  brands: TJSArray;
  months: TJSArray;
  values: TJSArray;
  i,j,v: integer;
begin
  brands := TJSArray.new;
  months := TJSArray.new;

  // create the X-axis for the series filled with the car brand names from the string row header
  for i := WebStringGrid1.ColCount - 1 downto 1 do
    brands.push(WebStringGrid1.Cells[i,0]);

  // create the Y-axis for the series filled with the month names
  for i := 1 to WebStringGrid1.RowCount - 1 do
    months.push(WebStringGrid1.Cells[0,i]);

  // create the series in the 3D chart
  aSeries := TThreeJsChartSeries.Create(brands, months);

  // loop through the normal grid cells to pick the sales values and add these to the series
  for i := WebStringGrid1.ColCount - 1 downto 1 do
  begin
    values := TJSArray.new;
    for j := 1 to WebStringGrid1.RowCount - 1 do
    begin
      v := StrToInt(WebStringGrid1.Cells[i,j]);
      values.push(v);
    end;
    aSeries.addLegendRow(WebStringGrid1.Cells[i,0], values);
  end;

  // set the general 3D chart properties  
  aSeries.AutoMarkValueAxis := true;
  aSeries.valueFormatFloat := '#,##0';
  aSeries.valueAxisFormatFloat := ''; //use the above
  aSeries.Title := 'Monthly unit sales per brand';
  aSeries.ValueAxisTitle := 'Monthly Sales';
  aSeries.LegendAxisTitle := 'Brands';
  aSeries.CategoryAxisTitle := 'Months';
  threeJsChart.Series := aSeries;
end;

It is really as simple as this. Note that you just need to create the data series and it figures out the range of values automatically. It has an Auto range mode that is smart enough to figure out the vertical value range scale and its scale marking automatically based on the minimum and maximum values in data. You can also switch off the Auto range mode and supply your own scale marking when needed.
The code results in the following 3D chart or you can play with it directly from your browser.

Mathematical surfaces with TWebThreeJsMathChart

Finally, the last 3D control is the TWebThreeJsMathChart that is specialized in mathematical surface rendering, both with wireframe and solid surfaces.

TWebThreeJsMathChart is based on a TThreeJsMathChartSeries that is set for the 3D chart and this TThreeJsMathChartSeries implements a callback function that will query the mathematical formula calculation. The setup for the math chart and the X and Y range wherein the result needs to be calculated is set via:

begin
  aSeries := TThreeJsMathChartSeries.Create;
  aSeries.addParametricSurface(-10, +10, -10, +10, resolution, @surfaceCallBack);

  aSeries.Title := '3D Surface';
  aSeries.ZAxisTitle := 'Values';
  aSeries.YAxisTitle := 'Y-axis';
  aSeries.XAxisTitle := 'X-axis';

  threeJSMathChart.Series := aSeries;
end;

As we demonstrate a number of different mathematical functions to visualize in the demo, the callback function is implemented as:

function TForm2.surfaceCallBack(x, y: double): double;
begin
  // the function is selected via the combobox cbSeries
  case cbSeries.ItemIndex of
    1: Result := abs(x-y);
    2: Result := -x*x - y*y + 6;
    3: Result := sin(x)*x+cos(y)*y;
    4: Result := 2 * sqrt(x*x/3 + y*y/8);
    5: Result := sqrt(abs(1.5 * (x*x/3 - y*y/4) - 6));
    6: Result := 8 * (sin(x) + cos(y));
  else
    Result := x*x + y*y;
  end;
end;

It’s really nothing more than this before you can start drooling over the wonderful world of 3D mathematical functions.

You can see it live from your own browser here.

Get started

Meanwhile, you can go ahead and explore the new & exciting territories of web client development that become available for Delphi developers with TMS WEB Core! You can download the trial version that is generally available, go ahead with the standalone version you purchased or with TMS WEB Core and additional tools that are all included in TMS ALL-ACCESS. Our team looks forward to all your comments, feedback, feature-requests to help steering the development of TMS WEB Core to the next stages!

Read More

Read More

Enjoy more REST with FNC in the cloud

Intro FNC is going to the cloud! We are currently working very hard to bring FNC to the cloud in the form of a TMS FNC Cloud Pack with a set of the most popular ready-to-use cloud service implementations, but before you can throw yourself into this new bag of FNC cloud service candies, we wanted to give you an insight on what is coming and also ask you a question on which cloud service(s) you wish to see being added in the future. Cross-Platform / Cross-Framework FNC (Framework Neutral Components) is not a new story, you can find all about it on this page. FNC supports the following frameworks and platforms: FMX Windows macOS iOS Android VCL Windows LCL Windows macOS Linux WEB Classic PWA (Progressive Web Application) Electron So with FNC for the cloud, you will be able to target all of the above Frameworks and Platforms! Asynchronous While working on the FNC cloud core, we wanted to make sure that each action, whether it's retrieving a list of files, or uploading/download a file, is running seamless and doesn't interfere with the main thread. This makes your application responsive at all times and allows you to perform other tasks while waiting for the download/upload to finish, or the list of files to be loaded. This also gives the advantage that you can start multiple requests at once, and not having to wait until a specific request has finished. Of course, some requests require additional data that has been retrieved via another request, but we have made the request execution and data retrieval as flexible as possible. Below is a sample that shows the way the request is being made, and how the result is captured. procedure TRequestForm.DoRequestExecute(const ARequestResult: TTMSFNCCloudBaseRequestResult); begin //File Download Finished end; procedure TRequestForm.DownloadFile; var c: TTMSFNCSimpleCloudBase; begin c := TTMSFNCSimpleCloudBase.Create; try c.Request.Clear; c.Request.Host := 'http://myhost.com'; c.Request.Path := '/download'; c.Request.Query := 'fileid=123'; c.Request.Name := 'Download File'; c.Request.Method := rmGET; c.ExecuteRequest(DoRequestExecute); finally c.Free; end; end; There is even a small bonus when targetting FMX or VCL. You can catch the result via anonymous methods as well! Anonymous methods are also coming to TMS WEB Core in a future update, so it will be possible to not only target FMX and VCL, but also have this code working for the web! procedure TRequestForm.DownloadFile; var c: TTMSFNCSimpleCloudBase; begin c := TTMSFNCSimpleCloudBase.Create; try c.Request.Clear; c.Request.Host := 'http://myhost.com'; c.Request.Path := '/download'; c.Request.Query := 'fileid=123'; c.Request.Name := 'Download File'; c.Request.Method := rmGET; c.ExecuteRequest( procedure(const ARequestResult: TTMSFNCCloudBaseRequestResult) begin //File Download Finished end ); finally c.Free; end; end; One code base With FNC you can write your code once, and deploy it to several Frameworks / Platforms. This is also the case with FNC for the cloud. It relies on the TMS FNC Core and uses every aspect of FNC. You can write an old school VCL application and use the same code to target the recently and brand new PWA (Progressive Web Application) support in TMS WEB Core. Let us know for which Frameworks / Platforms you are writing an application with FNC. Custom development The FNC cloud core has been designed to allow you, as a developer, write a component for a service not supported out of the box in the upcoming TMS FNC Cloud Pack. There is already a lot of functionality built-in and accessible. The list below shows what can be done when writing your own service. Make GET, POST, PUT, UPDATE, DELETE and PATCH requests Support for multi-part form data via a separate form data builder class Built-in OAuth 2.0 authentication flow Built-in URL encoding, JSON parsing, file to Base64 encoding and many more Let us ask you a question We want to make sure we are not only providing a solid base for future development, we also want to know which service you are going to use. We already added a list of the most popular services, but we want to make sure that for future developments, we can accomodate to your needs. For this purpose, we want to ask you a question and vote on the service of your choice, or add a new one, if it's not already in the list. The list can be viewed at the following survey: https://www.survio.com/survey/d/N4J9X1C8L4V7K1U7V. Additionally, if you have any feedback, please comment on this blog. More REST We already want to thank you for filling in the survey and/or comment on this blog. The data will provide us with knowledge on how to improve our current developments and make the TMS FNC Cloud Pack even better. After all, we want you, as a customer, to enjoy more of that hard-earned REST after a full day of development. Stay tuned for more "FNC in the cloud" content coming in the near future!
Read More

Any opinion on RAD Server vs Node.js/LoopBack vs TMS XData vs other?

Interesting thread still: [WayBack] Any opinion on RAD Server vs Node.js/LoopBack vs TMS XData vs other? – Kyle Miller – Google+ Tools mentioned there (not limited to Delphi): From Database to Web App through REST server with TMS XData and TMS Web Core [WayBack] GitHub – andrea-magni/MARS: MARS-Curiosity Delphi REST Library [WayBack] GitHub – jeffknupp/sandman2: Automatically generate a RESTful API service for your legacy database. No code required! [WayBack] mORMot/RESTserver.dpr at master · synopse/mORMot · GitHub –jeroen  
Read More