TMS WEB Electron
Electron is an open source library for creating cross-platform desktop applications with HTML,
CSS, and JavaScript. Combined with TMS WEB Core, Delphi developers can also create
applications for Windows, macOS and Linux by writing the code only once. More information on
Electron can be found on the offical website: https://www.electronjs.org/
The minimum required Electron version is: 8.0.0
. If you already have Electron installed but the
version is lower than 8.0.0
, then the minimum required version will be installed globally. If a
project needs a specific lower version, please install it locally.
Your first TMS Web Electron Application
To create a new Electron application from TMS WEB Core, select the “TMS Web Electron Application” from the wizard:
It generates a project similar to a TMS Web PWA Application, but instead of the manifest and serviceworker files, it has generated a main javascript file, a package file and 3
icons for the different platforms:
To every Electron application the package.json
is the starting point. This is where the engine will search for the main javascript file that it can run. Both the default generated package.json
and main.js
are capable of creating, running and packaging an application, but they can be further customized by editing them.
The icon files can be changed through the project options:
When Electron: Version is not specified, the default Electron packager version installed on the
machine is used. If you have multiple different Electron packager versions installed on the
machine, you can specify here at project level what Electron packager version to use. As there
have been quite a few breaking changes between versions before Electron 6
and from Electron
6
, a compiler define that you can use in your application code was introduced:
Building the application
In Debug mode, pressing F9
will compile the source code, then start up the Electron engine and
launch the application.
There are however small differences between the available 6
Build modes.
- Build-Win32/Build-Win64 will create a packaged 32/64-bit Windows application. If
F9
was pressed for building, then it will launch the application after packaging it. -
Build-Linux32/Build-Linux64 will create a packaged 32/64-bit Linux application. After copying the application to a Linux machine, it can be run.
-
Build-Mac32/Build-Mac64 currently only copies the source files to the Build folder, because it’s not possible to create a packaged macOS application on a Windows machine. The application can be created by copying the source code and running electron-packager on the Mac.
Building on a Mac
If you are unfamiliar with macOS in general and you have no idea how to start with building, you can follow these steps:
Prepare the system by installing NodeJS. Use npm in the terminal to install electron-packager.
//for global installation:
npm install electron-packager -g
//for local installation:
npm install electron-packager
This produced a packaged application that can run on your Mac. It’s recommended to sign the application if it’s for distribution. More information about that can be found here: https://www.electronjs.org/docs/latest/tutorial/code-signing
Migrate your application to newer versions
With WEB Core v1.4
we had to introduce changes that are not backwards compatible due to changes in the Electron framework. Below you will find a few steps to help you get started with migrating your application.
Replace the main.js file
This is required for every project! The new code depends on the new main.js
file. If you wish to work on a project that was created under previous versions, you will first need to replace the main.js
. If you modified the main.js then you need to copy your code to the new main.js file as well.
Dialog callbacks
The dialogs now require callbacks if you want to return any results and not just show a message. Here are two code snippets to show you the file opening:
Before WEB Core v1.4
:
procedure TForm1.WebButton1Click(Sender: TObject);
var
sl: TElectronStringList;
begin
if ElectronOpenDialog1.Execute then
begin
sl := TElectronStringList.Create;
sl.LoadFromFile(ElectronOpenDialog1.FileName);
Meditor.Lines.Assign(sl);
sl.Free;
end;
end;
From WEB Core v1.4
:
procedure TForm1.OpenDialogCallback(FileNames: TJSElectronStringDynArray);
var
sl: TElectronStringList;
begin
if Length(FileNames) > 0 then
begin
sl := TElectronStringList.Create;
try
sl.LoadFromFile(FileNames[0]);
MEditor.Lines.Assign(sl);
finally
sl.Free;
end;
end;
end;
procedure TForm1.WebButton1Click(Sender: TObject);
begin
ElectronOpenDialog1.Execute(@OpenDialogCallback);
end;
Remove the Sender parameter from TElectronIPCCommunication.OnMessage
The Sender
parameter allowed you in the past to send a message directly back to the
sender. Unfortunately with the removal of the remote module we don't have access to
the BrowserWindow
object from the renderer processes anymore.
Remove TElectronIPCMain related codes
TElectronIPCMain
had to be removed from our code because it was also depending on the remote module. If you need something from the main process, you need to send a message from the IPCRenderer
and handle the request and response yourself. You can see quite a few examples of this in our source code.
Accessing the Developer Tools
When the application is deployed in Debug mode Electron adds a default menubar to the application if a TElectronMainMenu
has not been added to the main form. The Developer Tools can be accessed with View > Toggle Developer Tools or via the Ctrl+Shift+I
shortcut. This might be enough if something occasionally needs to be checked. To force any window to have the Developer Tools opened after the given window is shown, use the following code in the form’s OnCreate
event:
Drag and drop
Electron provides support for drag and drop functionality. There’s a difference between dragging into and dragging out of an application. In both cases the dragging needs be detected by an event, but at this moment these events for TMS Web components are not yet completed. Until then with some simple javascript, the dragging event detection can be handled.
From desktop to Electron
Dragging something into the application is actually a feature that is supported by HTML5
. Normally the full file path would not be accessable due to a security feature. Electron removes this limitation as Electron applications are meant to run on a desktop using native features of the operating system.
procedure TForm1.WebFormCreate(Sender: TObject);
type
TDropProc = reference to procedure(ElectronFL: TJSElectronFileList);
var
el: TJSHTMLElement;
LDropProc: TDropProc;
begin
el := WebMemo1.ElementHandle;
LDropProc := @HandleFileDragDrop;
asm
el.ondragover = (e) => {
e.preventDefault();
};
el.ondrop = (e) => {
e.preventDefault();
let efl = e.dataTransfer.files;
LDropProc(efl);
}
end;
end;
procedure TForm1.HandleFileDragDrop(ElectronFL: TJSElectronFileList);
var
esl: TElectronStringList;
ef: TJSElectronFile;
begin
esl := TElectronStringList.Create;
ef := ElectronFL[0]; //use the first file in case of multiple files
esl.LoadFromFile(ef.path);
WebMemo1.Lines.Assign(esl);
esl.Free;
end;
From Electron to desktop
Dragging something out of an Electron application is supported, but the file must already exist on the local file system. If the file does not exist, it’s up to the developer to create it on the fly based on the contents from the application. If the file is present, then it takes two steps to drag something:
-
Send a message in the drag start handler via
TElectronDragAndDrop
with the path to the file that should be dragged out. -
Set a dragging icon through
TElectronDragAndDrop
(for example in theOnCreate
event of the form). Setting an empty icon path might work on Windows but not on other platforms.
If some code needs to be executed when the dragging is happening, ElectronDragAndDrop
has
an OnStartDrag
event which can be assigned.
procedure TForm1.WebFormCreate(Sender: TObject);
procedure DoDragEvent(Sender: TObject);
begin
//Code
end;
begin
ElectronDragAndDrop.OnStartDrag := DoDragEvent;
end;
Fonts
Sometimes a nice looking application that has been created, does not look the same on another platform, because the font differs. But why is the font not being shown as set? This is due to the fact that different platforms can have different sets of fonts installed. If the used font is not installed, then of course it cannot be used by the application. If this behavior is not desired, it can be fixed by adding a font manually: The first step is to add the font file to the project
Add the following code to the project html file
<style>
@font-face {
font-family: 'RobotoRegular';
src: url(Roboto-Regular.ttf) format('truetype');
}
</style>
Set up your project with local databases
Currently we provide support for the following database management systems:
The setup for development (= Debug configuration) and production (= Build-Platform configuration) is identical.
-
Add the correct dependency to the package.json file, and set the version based on your preferences. Example for mysql:
-
Build the project without running it. Based on which configuration you picked the output folder will be created (TMSWeb/Debug, TMSWeb/Build-...).
-
Open a commandline prompt / terminal in the output folder and install the module you'd like to use. Keep in mind that if you
Clean
your project, you'll need to install it again. - Now you can build and run your project again.