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:

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:
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: 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: 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: 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,… – Allen Drennan – Google+ –jeroen Related: For my research list: Delphi and ZeroMQ
Read More

More service than ever for Delphi development with TMS certified consulting partners

Over the past couple of years, it has become clear to us that for many individual software developers and in many companies where Delphi is used as the main software development tool, the challenges have not become easier:

  • It is not easy to find software developers, let alone good Delphi developers
  • Where Windows knowledgde was fine 10 years ago, these days knowledge of macOS, iOS, Linux, Android, web technologies is mandatory to be relevant
  • Architectures are shifting towards microservices based backends, use of push notifications etc…
  • There are more highly complex libraries, SDKs, REST services, components than ever to choose from

It has always been the goal of TMS software from our first days to deliver easy to use software components that take out a lot of deep technical challenges out of software development and allowing our users to focus on the business logic. While we also always aim to deliver fast & professional support services for our components, the needs of our customers also often exceed what regular product based support can offer. We see more and more customers wanting:

  • Assistance in setting up new architectures
  • Outsourcing specific component integrations or entire project developments
  • On-site training & consulting
  • Migrations of existing projects to unicode, cross-platform or web
  • Temporarily extra resources for projects
  • Help in getting started entirely new web projects with TMS WEB Core and/or FNC components
  • – …

Therefore, we’ve started our network of TMS certified consulting partners. These are partner companies we know, have a long term relationship with and that we know have deep and expert level knowledge in Delphi and our TMS software component products. Important is the presence of these partners in the same time-zone, speaking the same language, directly reachable by phone or in the office.

We have created a special landing page for our partners where you can find a partner nearby. With this launch, we can already present 5 TMS certified consulting partners in 3 continents: FlixEngineering in the USA (English), our branch in Brazil for South America (Portuguese & English), C-Quel for the Benelux (Dutch, French, English), Kassebaum Engineering for Germany, Swiss, Austria (German, English) and Softacom for entire Europe (English, Russian). We have added the areas of expertise of our different consulting partners on the landing page. While our consulting partners have expert level knowledge in Delphi and our components, there is also a direct line and close collaboration with our development team. So, our partners are always backed by our component development team and have an insight in our internal developments, upcoming products, … so the partners can at all times make the best possible & well-informed decisions for helping Delphi users.

Visit the partners landing page for more information and details!

We also plan for extending our network of consulting partners in the coming months and years. Especially in the areas of Asia, Australia, South Europe, South Africa where there is also a lot of Delphi development with TMS components going on. If your organisation is interested in becoming such partner, feel free to reach out & discuss.

One thing is clear, as a Delphi developer working with TMS components, you are never alone. Your projects with Delphi and TMS components are guaranteed for success with our team that is always ready for excellent component specific support via email or our forums and our partners offering a wide range of services beyond this.

Read More

Read More

Procrastination Books

"Books. I like 'em." -- bumper sticker Contrary to the title, these are not books on the art of procrastination. I've just been dragging my feet making a post about new Delphi books. Delphi Programming Projects by William Duarte Delphi is a cross-platform programming language and software development kit that supports rapid application development for Microsoft Windows, Apple Mac OS X
Read More

Persistence with Spring4D

My blog tagline is certainly no accident.  I have been interested in persistence frameworks for a long time, and thought I would use Spring4D’s Marshmellow ORM for a project.  Spring4D has been around for quite some time and just had it’s first conference in Italy so I figured the framework was mature and warranted a closer look.  I had previously used the Spring4D DI container, and decided this time to use Spring4D collections as well to avoid as much code bloat as possible. The first thing I discovered is that the Spring persistence layer aka Marshmellow has a very unfortunate name.  Trying to google it with “delphi” leads to all sorts of hits related that Android version.  The next thing I learned is that development has been put on hold as of September 2018 due to a lack of resources.  This is unfortunate, as there are not that many open source ORMs that use the newer language features of Delphi when compared C# or Java. The third thing I quickly learned is that other than the Tests, there is not a whole lot of documentation available.  There is the reference help which is really not that helpful.  It doesn’t contain descriptions of the class interactions or architecture and has no examples of usage.  Really it’s not much more informative than drilling through the code.  The best source of “getting started” help that I could find is the previous bitbucket repo. There is of course also the google groups if you need to get clarification of something, and reading previous posts can help you from running into common issues. As a newbie, it’s not clear how the [InheritenceAttribute()] works so I will have to investigate it further. I assume if the last descendant in a class hierarchy is the only one marked as an entity, it will by default have all the fields marked with the Column() attribute in all ancestor classes. Another thing that is not particularly clear from any documentation is how the underlying datatype employed by the database is determined.  There are really only 3 pertinent parameters supplied to the Column() attribute, namely length, precision and scale.  Length only applies to string types and precision, scale to numeric.  It is unclear how precision and scale effectively change the numeric datatype and it’s corresponding precision or scale, other than for Integer datatypes you specify 0,0 for precision,scale. I’m sure all this will become clear as I use the framework more, but some more thorough ‘Getting Started’ documentation would have been really nice.
Read More

How to get Login Dialogs Appearing on the TaskBar

Most of the applications I have worked on in Delphi are database apps that may present a splash form quickly followed by a login dialog.  If the user fails to authenticate, the application needs to terminate gracefully.  The only way to do so cleanly is to modify the DPR code with some conditional logic. I’ve seen scenarios where after the main form was created the login dialog was invoked and if authentication failed everything was torn down. This complicates the shutdown logic, and often didn’t work well, encouraging a call to Halt() and sometimes leaving the process in memory. Any long time Delphi user knows that messing with the generated DPR code in Delphi can cause all sorts of grief later when Delphi tries to auto create forms and add units to the uses clause.  That is out of scope for this post, suffice to say that it is possible to write something like this: var User :TUser; begin Screen.Cursor := crAppStart; try Application.Initialize; Application.MainFormOnTaskbar := True; Application.Title := 'My Secure App'; Application.CreateForm(TMainDm, MainDm); finally Screen.Cursor := crDefault; end; User := TfrmLogin.Login ( function (const UserName,Password :string) :TObject begin Result := MainDm.Session.FindWhere<TUser>( Restrictions.&And( Restrictions.Eq('UserName',UserName), Restrictions.Eq('Password',Password) ) ).FirstOrDefault; end, { UserName can be passed as first parameter so don't have to type it in all the time } ParamStr(1), 3 {credential retries available } ) as TUser; if User <> nil then begin Application.CreateForm(TfrmMain, frmMain); frmMain.CurrentUser := User; Application.Run; end; end. The problem is that the Login Dialog does not appear on the Windows Taskbar. If it is hidden behind other windows, the user may think the application has not been launched and attempt to start another instance. There is no easy way for the user to bring the login dialog to the foreground short of closing other windows that may be in front of it. Putting the form on the taskbar solves this. As a quick solution I looked at the SetMainForm method in the Vcl.Forms unit, and decided to extract the ChangeAppWindow() procedure since it is not available outside of the Forms unit. Then I simply called it from this event, and voila! a taskbar button showing the Login form. procedure TfrmLogin.FormCreate(Sender: TObject); begin ChangeAppWindow(handle,True,True); end; I’m sure there are reasons why this method is not exposed as a public TApplication class procedure, but perhaps it could be with a usage caveat.
Read More

The Story of an intern at TMSSoftware

Hello, this is the intern speaking (or writing) about his experience at TMSSoftware.
I’m a second year graduate student in programming-informatics who has been given the opportunity to do my internship here at TMSSoftware.

Getting started

My first week starting here was interesting as I had no real background experience in Delphi or Object Pascal, as the primary languages I learned at school were Java and C#. Thankfully, I had a lot of resources available, which includes the Object Pascal Handbook by Marcu Cantù. So getting started went smooth.

My internship was split up into three parts, were the first part was to study and test different REST services. The second part was based on implementing the APIs such as Google Translate and Microsoft Vision. The third part involved using the implementation in an application called TMS Vision.

TMS Vision should allow visually impaired people to be informed about their environment by simply tapping on their mobile phone and getting a spoken response in the native language. That response can be a series of keywords, or a short description on the object that has been recognized by the camera.

Used technologies

Doing my internship at TMSSoftware, I got access to the newest tools TMS had to offer.
With the TMS FNC Cloud Pack I had the foundation to build a set of classes that implement the services needed to send and receive data via REST. For the GUI, I used FNC. For those not yet familiar with ‘FNC’ , these are what we call Framework Neutral Components. This means that these components can be simultaneously used with different frameworks, are fully cross platform, can be used from Delphi, C++Builder and Lazarus and most spectacularly can be used to create web applications with TMS WEB Core. Read more about FNC for the web here.

TMS FNC Controls can be simultaneously used on these frameworks:

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

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

Because TMS FNC Cloud Pack contains a core layer to handle asynchronous REST request, it became really easy to send and receive data.

Example of translating text via the Google Translate API. In the code below, the TTMSFNCSimpleCloudBase class allows you to quickly send and receive data via REST without OAuth 2.0 authentication flow requirements.

// form class private variables
  c: TTMSFNCSimpleCloudBase;
  target : string;

procedure TGoogleTranslateForm.Button1Click(Sender: TObject);
  c.Request.Host := '';
  c.Request.Path := '/language/translate/v2';
  c.Request.Query := 'q=' + TTMSFNCUtils.URLEncode(Edit1.Text) +'&format=text'+
   '&target=' + target + '&key=' + c.Authentication.Key;
  c.Request.Method := rmGET;

Also parsing the request result data was very easy with TMS FNC Core, which exposes a set of ready to use functions for parsing JSON.

procedure TGoogleTranslateForm.DoGetList(const ARequestResult: TTMSFNCCloudBaseRequestResult);
  j, jd, ja, jav: TJSONValue;
  I: Integer;
  siso, sname: string;
  l: TLanguage;
  if ARequestResult.ResultString  ''  then
    j := TTMSFNCUtils.ParseJSON(ARequestResult.ResultString);
      jd := TTMSFNCUtils.GetJSONValue(j, 'data');
      if Assigned(jd) then
        ja := TTMSFNCUtils.GetJSONValue(jd, 'languages');
        if Assigned(ja) and (ja is TJSONArray) then
          for I := 0 to TTMSFNCUtils.GetJSONArraySize (ja as TJSONArray) - 1do
            jav := TTMSFNCUtils.GetJSONArrayItem(ja as TJSONArray, I);
            if Assigned(jav) then
              siso := TTMSFNCUtils.GetJSONProp(jav, 'language');
              sname := TTMSFNCUtils.GetJSONProp(jav, 'name');

(Code snippets were written for Google Translate in the first week of the internship)
Here is an example to test the REST API for Google Translate.

Starting on components

After getting used to the different platforms, investigating and testing the various cloud services to be implemented in TMS Vision, I got started on transferring the sample code into components that work cross-platform. Doing the internship here, made this easy as the TMS FNC Cloud Pack already provided a solid base to work on, and additionally my colleagues were eager to lend their advice when I needed help.

Here is an example of how the final code looks with the Google Translate component.

procedure TGoogleTranslateForm.FormCreate(Sender: TObject);
  c := TTMSFNCCloudGoogleTranslate.Create;
  TLanguage := TStringList.Create;
  c.Authentication.Key := 'My-API-Key';
  c.OnIsoLanguageList  := doLanguageList;
  c.OnTranslate := DoTranslate;

procedure TGoogleTranslateForm.Button1Click(Sender: TObject);
  if FTarget  '' then 
    c.Translate(Edit1.Text, FTarget)
    c.Translate(Edit1.Text) ;

This shows how compact your final code can be.

TMS Vision

I decided to use the knowledge I collected to make an application that works cross-framework and cross-platform to assist people who are visually impaired. The application allowed them to be informed about the environment around them. There were some critical parts in TMS Vision related to the Google Vision and Microsoft Vision APIs that involved uploading the picture taken from the camera. The data required by Google Vision, for example, needed to be in a base64 string. This was handled by the TTMSFNCUtils.FileToBase64 function included in TMS FNC Core. Below you can see a code snippet that uses this functionality to upload the picture data to Google Vision.

procedure TTMSFNCCustomCloudGoogleVision.AnalysePicture(const AFile: TTMSFNCUtilsFile);
 basestring :String;
    basestring := TTMSFNCUtils.FileToBase64(AFile);
    Request.Host := Service.BaseURL;
    Request.Path := '/v1/images:annotate';
    Request.Method := rmPOST;
    Request.AddHeader('Content-Type','application/json; charset=utf-8');
    Request.Query := 'key='+Authentication.Key;
    Request.PostData := '{"requests": [{"image": {"content":"'+      
    basestring+'"}'+',"features": [{"type": "LABEL_DETECTION"},{"type":    
    "OBJECT_LOCALIZATION","maxResults": 5},{"type": "WEB_DETECTION"}]}]}' ;
    ExecuteRequest({$IFDEF LCLWEBLIB}@{$ENDIF}DoRequestAnalyse);

Example of how the application looks now. The layout of the app has been created with the TMS FNC UI Pack, and runs on TMS WEB Core. The application is a PWA that is installable on the device.


Right now I’m in my second half of my internship and can say I enjoyed every moment of it,
gaining access to the tools of TMSSoftware and the wide variety of FNC components, made programming in Delphi or Pascal a lot easier than I thought.

I’m still expanding my knowledge of Delphi and Object Pascal and I plan to expand the TMS Vision application with other API services such as Google speech to text to remove the need to interact with the screen manually by implementing voice commands.

Author: Brutin Bjorn

Read More

Read More