FNC Code Gems: Helpers for Base64 encoding and decoding

In the last post, I looked at methods to help you get information about connected displays and determine the path name for common folders. Let’s look at something very valuable when you want to convert binary data into a string: Base64 encoding.This is somewhat tricky if you have to consider all the different platforms and frameworks. FNC makes it very easy!

Again, the class TTMSFNCUtils offers awesome methods to get results quickly:

class function FileToBase64(const AFile: TTMSFNCUtilsFile): string;
class function Decode64(const AValue: string; 
                        const AURL: Boolean = False): string;
class function Encode64(const AValue: string; 
                        const AURL: Boolean = False): string; overload;
class function Encode64(const AValue: TBytes; 
                        const AURL: Boolean = False): string; overload;  

Not only are there methods to encode and decode strings, there is also FileToBase64 which allows you to retrieve the Base64 string for a file using a single line of code:

LBase64String := TTMSFNCUtils.FileToBase64( 'mydata.bin' );

Ignore the data type of AFile to specify the filename. In VCL and FMX the type TTMSFNCUtilsFile it is mapped to a string. However, for web applications you cannot specify a local file name and the method has to be invoked differently. There is no inverse function for this as it is already a one-liner in Delphi now to store a string or a byte array into a file using TFile from System.IOUtils.

In order to encode a string, call Encode64; call Decode64 to decode a string:

LMyBase64String := TTMSFNCUtils.Encode64( 'testtest', false );
LMyTestString   := TTMSFNCUtils.Decode64( LMyBase64String, false );

Remember, these methods are available for VCL, FMX, LCL, and TMS Web Core.

Read More

Read More

One Codebase – Multiple Targets


This week we focused on FNC, with a series of media content, brought to you via Facebook, Twitter, blog posts and other media channels. We wanted to focus on what FNC is by highlighting each framework and its corresponding operating systems individually. Here is a sample of what this looks like for the WEB.

We plan on using this for communication, promotion, technical articles, and we believe this will allow you, as a customer, have a better understanding on what FNC is. Below is an overview of what FNC offers, and what it can potentially mean for your application.

TMS FNC Controls can be simultaneously used on these frameworks:

  • VCL
  • WEB
  • FMX
  • LCL

TMS FNC Controls can be simultaneously used on these operating systems/browsers:

TMS FNC Controls can be simultaneously used on these IDE’s:

One Codebase

With FNC, we aim for one code base, that can be re-used on all the supported frameworks and eventually target multiple operating systems. We started with FMX and VCL, and thanks to the high level of abstraction we added LCL support which gave us access to Unix operating systems. Recently, we have added WEB support as well via TMS WEB Core. As an example, we have created an FNC overview demo to demonstrate the “one-codebase – multiple targets” principle.

We are currently also working very hard on a BETA of FNC, which brings a lot of small improvements and fixes, but also brings 2 new components: TTMSFNCPDFLib and TTMSFNCGraphicsPDFIO. In case you missed the blog post demonstrating these 2 components, check out the blog post at the following URL: https://www.tmssoftware.com/site/blog.asp?post=560. The blog post focusses on creating a report in PDF completely generated client-side in the webbrowser. It shows how to mix custom PDF content and existing FNC components and of course also works on the “one codebase – multiple targets” principle explained in this blog post.

We want your feedback!

Please feel free to leave a comment, send us an email with suggestions on this approach and what we can improve in our communication. We want you to get a smile out of your application, because a smiling application, is a smiling customer!

Read More

Read More

Ate too much candy? Calculate and export your BMI to PDF with FNC for the WEB!

Ate too much candy?

We all have those moments in life where we are proud of what we have achieved, be it in sports, school, at work… . Whenever we have reached a goal, were hard work lies at the base of it, we tend to reward ourselves with something that makes us even more excited of what we have achieved. For me, that something is candy. I know, I should be eating less of it, but hey!, I have earned it! As I’m obviously eating too much of it, I created a BMI calculation app to track if I should stop eating, or if there is still room for one tiny sweet piece of candy.

FNC for the web!

The application, which calculates the BMI, is written with the help of TMS FNC UI Pack, TMS FNC Dashboard Pack and TMS WEB Core and is running in the webbrowser. It allows entering your name, height (cm) and your weight (kg). The calculate button will indicate your BMI in the grid, allowing you to know if you should loose or gain some weight, or if you are absolutely perfect.

PDF for the web!

The BMI application is allowing you to export your data to PDF. Typically, when generating a report, invoice, or any other PDF data file in the browser, this is done on a back end server. The costs to handle the load, scalability can quickly rise and the maintenance gives a lot of headaches. With the TTMSFNCPDFLib and TTMSFNCGraphicsPDFIO components that are both used in the BMI application you no longer need a backend to generate a PDF in your web application. The components completely generate the PDF at the client-side (front end).

The TTMSFNCPDFLib component is used to generate the PDF, and the TTMSFNCGraphicsPDFIO component is a bridge to export FNC UI controls such as the TTMSFNCPlanner, TTMSFNCGrid, TTMSFNCChart and many more. In the BMI web application, both are used to combine the custom PDF exporting capabilities with the TTMSFNCGrid and TTMSFNCWidgetGauge components.

The code behind this is actually very simple.

procedure TPDFLibBMILogic.GeneratePDF;
  fn: string;
  o: TTMSFNCPDFIOExportObjectArray;
  r: TTMSFNCPDFIOExportRectArray;
  ms: TMemoryStream;
  fn := TPath.GetSharedDocumentsPath + PathDelim + 'BMI.pdf';
  fn := TPath.GetDocumentsPath + PathDelim + 'BMI.pdf';
  fn := 'BMI.pdf';
  p.Options.Header := 'BMI Report for ' + FName;
  SetLength(o, 2);
  o[0] := FGauge;
  o[1] := FGrid;
  SetLength(r, 2);
  r[0] := RectF(50, 180, 50 + FGauge.Width, 180 + FGauge.Height);
  r[1] := RectF(50 + FGauge.Width + 50, 180, 50 + FGauge.Width + 50 + FGrid.Width, 180 + FGrid.Height);
  ms := TMemoryStream.Create;
    p.Save(ms, o, r);

The result, when clicking on the “Export To PDF” button, is shown below

Play with the demo yourself!

Curious on how the demo works, or if you want to know if you can eat more candy? Below is a link that shows the demo live! Note that the components, demo is currently not yet released, but we are working hard on a beta of FNC that is coming real soon, so stay tuned!


Read More

Read More

TMS WEB Core v1.2 tips & tricks part 8: 3D Charts made easy

One of the big new features in TMS WEB Core v1.2 Padua is the built-in support for 3D graphics. This is accomplished by providing Object Pascal components and classes that wrap the powerful ThreeJS / WebGL libraries for rendering 3D graphics in the browser. This technology is meanwhile supported on every mainstream browser, including on mobile devices.

As always, the goal of TMS WEB Core is to offer OO RAD Component based we development, so, integrating 3D graphics in your TMS WEB Core web client applications becomes a piece of cake. So, let’s immediately jump to writing the code as an inspiration to get you started exploring the wonderful 3D web world.

When interfacing with an existing JavaScript libraries is done from a TMS WEB Core application, we have made it equally easy to setup the link references to these libraries. In case of 3D we will need the ThreeJS library. So, from the project context menu in the Delphi IDE select “Manage JavaScript Libraries” and from there check to use ThreeJS.

Next, put a TWebThreeJSChart on the form and you can start defining series for your chart. Since climate change is a bit a “hot” topic (pun intended) in the last years everywhere, for our sample we got the idea to render the average month temperatures in Belgium (where our main TMS office is located) for the past 3 years. We got the data from a website that lists the temperature measurements since 1833. You can find the data here.

The series we want to display are a series with all months of the year and a series for years. A series is of the type TThreeJsChartSeries and is created with the X and Y axis labels via:

  aSeries: TThreeJsChartSeries;

  aSeries := TThreeJsChartSeries.Create(
   TJSArray.New('2017', '2018', '2019'));

As you can see, we can create in Object Pascal a dynamic JavaScript array that ThreeJS needs via TJSArray.New(values).

Next, let’s add values for each month for the 3 years to the series. This is done for a month via:

  aSeries.addLegendRow('Jan', TJSArray.New(1.1, 6.0, 3.0));

Other than this, all we need is to setup things like title, X-axis label, Y-axis label, Z-axis label, Z-axis maximum and step value and the formatting of the values along the Z-Axis. When this is ready, to display the series, we simply clear any possible previous series that were setup and then assign the series created and call WebThreeJsChart.createChart.

One more property available in a series is the property TThreeJsChartSeries.ChartType. The 3D chart supports following types: ctBarChart, ctCylinderChart, ctConeChart, ctLineChart, ctAreaChart.

The total code becomes:

procedure TForm1.InitChart(AType: TThreeJSChartType);
  aSeries: TThreeJsChartSeries;
  aSeries := TThreeJsChartSeries.Create(
    TJSArray.New('2017', '2018', '2019')

  aSeries.addLegendRow('Jan', TJSArray.New(1.1, 6.0, 3.0));
  aSeries.addLegendRow('Feb', TJSArray.New(6.1, 0.8, 7.0));
  aSeries.addLegendRow('Mar', TJSArray.New(9.6, 5.4, 8.5));
  aSeries.addLegendRow('Apr', TJSArray.New(8.8, 13.0, 11.0));
  aSeries.addLegendRow('May', TJSArray.New(15.5, 16.3, 12.0));
  aSeries.addLegendRow('Jun', TJSArray.New(19.2, 18.1, 0));
  aSeries.addLegendRow('Jul', TJSArray.New(18.3, 22.0, 0));
  aSeries.addLegendRow('Aug', TJSArray.New(18.1, 19.4, 0));
  aSeries.addLegendRow('Sep', TJSArray.New(14.1, 15.4, 0));
  aSeries.addLegendRow('Oct', TJSArray.New(13.3, 12.6, 0));
  aSeries.addLegendRow('Nov', TJSArray.New(6.6, 7.4, 0));
  aSeries.addLegendRow('Dec', TJSArray.New(4.4, 5.8, 0));

  aSeries.valueAxisMarkMaximum := 30;
  aSeries.valueAxisMarkStep := 5;
  aSeries.ChartType := AType;
  aSeries.valueFormatFloat := '#,##0°C';
  aSeries.Title := 'Average month'#13#10'temperatures Belgium';
  aSeries.ValueAxisTitle := 'Temp';
  aSeries.LegendAxisTitle := 'Months';
  aSeries.CategoryAxisTitle := 'Year';

  WebThreeJsChart1.Series := aSeries;

Finally, we want to add one more additional tip and that is a frequently asked question how we can easily center a control in the browser window using pure Object Pascal code instead of what is in web development more commonly done using HTML/CSS. Well, the good news is that in Object Pascal this is also very easy. Add an event hanlder for Form.OnResize and write the code:

procedure TForm1.WebFormResize(Sender: TObject);
  if WebThreeJsChart1.Width 

This results in the chart with the numbers we have till now, May 2019:

or better discover it live here

There is much more than doing just 3D charts with ThreeJS and TMS WEB Core, there are also samples for creating surface charts, show 3D model files or setup your own 3D scenes. Discover these and more exciting features in TMS WEB Core that let you create web client applications with unprecedented capabilities.

You can download the trial version, 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

Delphi Now Has Linux UI Support

Just announced, FMXLinux has been licensed from KSDev for inclusion in the Enterprise and Architect editions of RAD Studio and related products (Delphi & C++ Builder).  The product is available via GetIt for all current subscribers. Since I have been following FMXLinux’s development for some time, I immediately installed the licensed version.  Unfortunately, the IDE experience is the same as the trial I previously installed directly from KSDev. I created a new Multi-device application with tabbed navigation from the wizard.  Looking at the list of target platforms (Android, Mac OS, iOS, Windows) I didn’t see Linux.  Fair enough, the templates on which the application is based do not contain the new UI platform.  Perhaps in a subsequent release since as per Marco’s introduction the product has not been fully integrated into the IDE. I went to add the new platform to the solution, by Rt. clicking The Target Platforms node in the project manager and it is greyed out.  If I delete a target it is re-enabled, but the list of targets I can add only contains the one I just deleted.  Rt. Clicking on the Application node in Projects window, there is an option “Add Linux Platform”.  Now I get a Linux 64 bit target platform node. This is covered in Marco’s introduction, but he doesn’t mention that attempting to add a component to my UI doesn’t work.  I can’t add a button to my form until I switch to another target platform, and then switch back so I can actually deploy and test on Linux.  This has been a known issue with the trial, and I was hopeful that such a poor user experience would be fixed now that EMBT has licensed the product.  For now, it’s an issue you will have to work around, and I’m sure it will be corrected in a future release. While only major Linux distros are currently supported (Ubuntu, RedHat and possibly a couple others) the team at KSDEV are working to support others including the more obscure ones like Elementary OS.  I for one am very pleased that Delphi finally can target Linux with GUI applications making it a complete XPlatform desktop solution for all 3 major targets.
Read More

TMS WEB Core v1.2 tips & tricks part 5: Accessing microphone and camera

Over the years, increasingly new web APIs have given web developers access to areas of the operating system that were originally only accessible from native applications. This is also the case with the microphone and camera that is attached to a desktop computer or integrated in laptops, tablets and smartphones.

As the main vision and mission of TMS WEB Core is to bring OO RAD component based development for web client applications, it is expected that TMS WEB Core also brings easy to use components for using your device microphone or cameras (yes that is plural as it is possible to select between front and back cameras on a mobile device for example) from a TMS WEB Core application.

Security / privacy

An important first remark to make is that before a web client application can access a microphone or camera, user authorization is required. So, clearly, no web client application can secretly in the back listen to your conversations or watch what you are doing! Together with this authorization is also the requirement that the web application comes from a HTTPS URL so there is a reliable identification of the author or company hosting the application possible. So, when your TMS WEB Core application runs from a HTTPS domain and you want to access a microphone or camera, the user will see a prompt to allow this access:


To use the microphone, we have introduced the non-visual component TWebMediaCapture. This component can be used to capture audio via the microphone when TWebMediaCapture.Capture is set to mctAudio. The standard recording mode is mrmManual. This means that recording is started by calling WebMediaCapture.Start and the recording is stopped by calling WebMediaCapture.Stop. After the recording is stopped, the data that was recorded is asynchronously returned via the event OnStopCapture that has the event signature:

TMediaCaptureCloseEvent = procedure(Sender: TObject; ABinary: TJSUint8Array; ABase: string) of object;

This event returns the audio via a JavaScript array or as a base64 encoded string.

An important remark is that different browsers might have a different default audio file format. In the Chrome browser this is the webm format for example, in Firefox it is ogg.

With this component, we have created a TMS WEB Core dictaphone app. You can discover this application here: https://download.tmssoftware.com/tmsweb/demos/tmsweb_Dictaphone/

The code to start and stop the recording is simply done from a click on an image:

procedure TForm1.WebImageControl1Click(Sender: TObject);
  if not FRecording then
    FRecording := True;
    WebImageControl1.URL := GetStopImage;
    FRecording := False;
    WebImageControl1.URL := GetRecordImage;

The code to capture the recorded data is here:

procedure TForm1.WebMediaCapture1StopCapture(Sender: TObject;
  ABinary: TJSUint8Array; ABase: string);
  if WebIndexedDbClientDataset1.RecordCount > 0 then
    WebIndexedDbClientDataset1.RecNo := 1;

  WebIndexedDbClientDataset1.FieldByName('descr').AsString := WebEdit1.Text;
  WebIndexedDbClientDataset1.FieldByName('time').AsDateTime := Now;
  WebIndexedDbClientDataset1.FieldByName('base').AsString := ABase;
  WebEdit1.Text := 'SoundClip ' + IntToStr(WebIndexedDbClientDataset1.RecordCount + 1);

This code shows another interesting concept, that is to store the recorded audio in an IndexedDB dataset. That is a dataset hosted in your browser which is private and accessible at a later time, so you can listen again to captured audio snippets when you open the web application again at a later time.

One more interesting option is to let the microphone record automatically when a certain audio level is reached. To use the TWebMediaCapture this way, set WebMediaCapture.RecordingMode to mrmAudio. With the properties WebMediaCaptature.Sensitivity, WebMediaRecorder.FFTSize, WebMediaRecorder.SmoothingTimeConstant it can be controlled at what noise level and what duration of the noise level the recording will start and stop.


Thanks to the new TWebCamera component, taking pictures from a TMS WEB Core web client application is equally easy. Drop the component on the form and start the camera by calling WebCamera.Start. To take a picture, call one of the three properties depending on the format you wish for the captured image data:

property WebCamera.SnapShotAsBase64: string;
property WebCamera.SnapShotAsImageData: TJSImageData;
property WebCamera.SnapShotAsUint8Array: TJSUint8Array;

A very simple use is to call WebCamera.SnapShotAsBase64 and assign the result to a HTML image element, i.e. what is wrapped in TWebImageControl via:

WebImageControl1.URL := WebCamera1.SnapShotAsBase64;

The image format returned van be selected between JPEG or PNG with WebCamera.BaseFormat.

As mentioned, TWebCamera can handle multiple cameras. To select a camera, the property WebCamera.CameraType can be used that can select between rear, front or default camera. To detect the cameras available, the TWebCamera.CameraDevices collection can be used. You can use:

for i := 0 to WebCamera.CameraDevices.Count - 1 do

For camera & microphone use, we have published 3 demos you can discover at: https://www.tmssoftware.com/site/tmswebcoreintro.asp#demos
There is even a camera demo that integrates with a QR and barcode scanning library so you can detect and decode pictures taken from a QR code or barcode. Of course, the TMS WEB Core distribution contains the full source code of these demos

Discover these and more exciting features in TMS WEB Core that let you create web client applications with unprecedented capabilities.

You can download the trial version, 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

Android – The case of the vanishing file

I’m relatively new to the Android development platform, coming from the Windows desktop. One of the great things about recent editions of Delphi is it’s ability target numerous other platforms. One of the worst things about recent versions of Delphi is it’s ability to target platforms you are not as familiar with. If your use case is atypical, you can quickly find yourself swimming in shark infested waters. You never know what is going to byte you, a bug in the platform, a bug in Delphi RTL or FMX code, a bug in your code, or just your lack of knowledge about the platform. Today I was trying to figure out why files I was saving to the Documents folder on my Android LG5 were visible from the Android File Manager, but not present when I connected the phone to a Windows, or Ubuntu desktop. Turns out there is a long outstanding bug in Android that google has not even acknowledged. In order to see new files when connecting to a device using the MTP protocol, you may need to re-boot the Android device before the files appear. Indeed once I did so, my files appeared and I could copy them off to my PC. You may want to comment on this motion to get the issue re-opened and addressed. Hopefully this helps someone else avoid spending a lot of time scratching their head…
Read More

UWP and Windows App Platform

UWP and Windows App Platform As you have probably seen, over the last month there has been some discussion around UWP (Universal Windows Platform) and the current focus, or change of focus, for Microsoft in terms of how developers should build applications for their mainstream operating system, Windows 10. There have been claims and counterclaims, making the entire debate quite interesting. Needless to say, Microsoft directions for building Windows applications is of critical importance to most of our customers, and also for us as at Embarcadero, given RAD Studio has a strong focus on Windows development. For a summary of Microsoft point of view, you can read this interview by Mary Jo Foley of Microsoft Corporate Vice President of the Windows Developer Platform Kevin Gallo: https://www.zdnet.com/article/microsoft-wants-to-close-the-uwp-win32-divide-with-windows-apps/ But let me start from the beginning and recap Microsoft plans (and how Embarcadero addressed those). UWP Holy Grail and WinRT A few years back, when Microsoft introduced Windows 10 for desktop the company still had high hopes for its twin Windows 10 Phone operating system. We know the phone ended up being a big failure for Microsoft, but at the time they were betting heavily on it. The idea behind UWP was to create a new common API and core operating system infrastructure that would allow the same application to run on all versions of Windows (including also Xbox and HoloLens). Technically, Windows 10 came with a new "core" called WinRT (initially introduced in Windows 8), a subsystem you can target with a specific API. This is not a .NET API, but more of a native, C++ type of API. Side Note: Turns out that WinRT is "invocation compatible" with COM and it can be easily mapped to Delphi interfaces -- which is what Embarcadero did offering direct support for this new platform API. There were other key tenets: increased security (as apps run more in isolation and are safer in their memory management), more stability (with more responsive UIs and async processes), and that could allow Windows become a more stable ecosystem. So why didn't all developers jumped to UWP and WinRT? Microsoft offered a variety of programming languages (C# and .NET, C++, even JavaScript) and they expected large adoption. However, UWP came with its own UI design guidelines (wide spaced controls, full screen mode) and technical specifications (almost all code requiring to be asynchronous) that hampered development. Nice, modern, but quite different from any other API, platform and UX -- and so difficult to adopt by developer, particularly if the target is more than one platform. Basically none of the existing code was ready to run there, regardless of the programming language you picked. And doing a full rewrite is not something developers (and their companies) are keen on doing. Cross the Bridge or Stay on the Trusted Side? After the initial dismal adoption (which allowed developers to publish app on the store -- but a store that wasn't well maintained) Microsoft started promoting a set of "bridges" to allow bringing existing code to the new UWP platform. There was a bridge for Android apps support on Windows Phone, one for Objective-C conversion, and one to allow Win32 native apps to become part of UWP. Now these were non-universal UWP platform apps, given they could run only on one of the versions of Windows 10, desktop or mobile. This ended up only adding to the confusion. Moreover, Microsoft kept indicating these bridges were meant to help converting your applications to the new model, one form and one module at a time -- rather than all at once. But the destination was still supposed to be a complete rewrite of your code. "If you have a million lines of code, you want to move to the new platform over time", Microsoft was officially stating. But it was obvious developers didn't really want to do ANY rewrite of their code for moving it from Windows to Windows 10! Considering all old applications kept running smoothly and the brand new features offered by the operating system were fairly limited. Now again, RAD Studio (as well as Visual Studio) started offering support for the Desktop Bridge, but our goal was only letting developers target new APIs available only on the WinRT side (like notifications or BLE) and be able to deploy applications on the Windows Store -- for easier distribution, taking advantage of low commissions, and additional monetization options (via subscriptions). Is Microsoft Giving Up? This brings us to today and the recent "announcements" by Microsoft. An interesting POV is at: https://mspoweruser.com/uwp-is-dead-because-windows-apps-are-dead/ The company has apparently just come to the realization that no matter their insistence developers are not going to rewrite applications to target the Windows operating system. In fact they keep using WinForms and MFC (on Microsoft developer tools side) or VCL (on the RAD studio one) or other native libraries. These days Microsoft is clearly downplaying UWP as a development model. Notice that there are also reports of the fact XBox apps are now being built with Electron, a JavaScript desktop library: https://www.onmsft.com/news/new-electron-powered-xbox-app-leaks-hours-before-e3 The claim development for the Windows platform has stopped seems fairly exaggerated. There are still a lot of business applications written for Windows, and also real time control systems and games. While a lot of consumer apps moved to the web and mobile, investment on Windows development is still a significant portion of the IT budget -- even though maintenance of existing applications is likely a significant part of it. In any case, this is only one side of the scenario. The APPX model of the desktop bridge implies apps run "partially sand-boxed". They cannot be elevated with admin permission, they can access only their "view" of the registry and operating system. Granted, they can still do damage, but the store vetting procedure should also help filtering out the bad guys. The concept around UWP / APPX is applications can be more easily isolated (and with .NET Core even have each their own copy of any required library). They can be installed with no admin permission and removed leaving a clean (or almost completely clean) operating system, mimicking the experience users have on phones. Now this is not just surviving to the UWP model, but Microsoft has double its effort with the MSIX technology. This sounds and it is being promoted as an "installation" technology, but it is in fact the next interaction of APPX. MSIX apps can be distributed via Windows Store or within an enterprise distribution model, allow for extra security and what Microsoft originally called "virtualization" and now dubs as "containerization" -- to piggyback on a common trend. The idea apps should live more and more in isolation is also backed by changes at the .NET level, with the idea (a key element of .NET Core) that each app should ship with its own version of .NET rather than relying on the version of library the operating system provides -- with the big advantage of reducing dependencies and allowing users to update .NET without fearing to break existing applications on their systems. And What About RAD Studio? This is how I understand the future of the Windows App platform -- a future that allows Delphi and C++Builder VCL applications to play on par with Microsoft own UI libraries and ecosystem, with a much higher degree of compatibility with existing code and investment. Windows 10 as target platform is alive and growing (within the desktop OS total, if not in absolute terms) and the VCL with its support for Windows API, COM, WinRT and APPX model has everything you need to target the platform. Our libraries integrate Windows 10 feature, High DPI support, and compatibility in a way that's unparalleled in the industry -- without forgetting a large ecosystem of great third party controls!
Read More

Even perpetual Delphi licenses require an active maintenance support to allow re-install on a fresh machine

Last month, people found out that retroactively, Embarcadero has changed the terms of the license agreements on products sold with a perpetual license: In order to re-install those products, often a bump in license count is needed. That bump now requires an active maintenance subscription which has a substantial yearly cost. This is yet another […] … Read More

Read More

GrijjyCloudLogger, remote logging for Windows, iOS, Android, macOS and Linux – grijjy blog

Interesting use-case based on ZeroMQ and Google Protocol Buffers: [WayBack] GrijjyCloudLogger, remote logging for Windows, iOS, Android, macOS and Linux – grijjy blog. Everything is Open Source at GitHub: grijjy/GrijjyCloudLogger: GrijjyCloudLogger, remote logging for Windows, iOS, Android, macOS and Linux grijjy/DelphiZeroMQ: Delphi implementation of ZeroMQ Majordomo protocol and CZMQ high level binding grijjy/GrijjyFoundation: Foundation classes used by other Grijjy repositories Via: [WayBack] The Grijjy team is proud to introduce our GrijjyCloudLogger, https://blog.grijjy.com/2017/08/22/grijjycloudlogger-remote-logging-for-windows-ios-android… – Allen Drennan – Google+ –jeroen Related: For my research list: Delphi and ZeroMQ
Read More