This article shows how to build a program running on Windows using XML and JS without depending on web browser.
Introduction
If you can use JavaScript, it's possible for you to build a desktop program without depending on the web browser. Yes, it's true. As I had exported all of the necessary APIs of soui4
to JavaScript, it's possible for a js programmer to develop a traditional desktop program now. Similar to designing a web page, one can finish a desktop program by preparing resources such as image, color, font and using them to write a layout of user interface to an XML file, and then write a js program to control logic of your program using this framework. During the procedure, you need not know anything of C or C++.
Background
Usually, to make your idea running on a desktop computer, you need learn a program language such as C, C#, Pascal, etc. They can build your code to an execute file. However, JavaScript can't do this work because it is running on web browser. Traditionally, we use C/C++ to do this work despite their obvious shortcomings. For example, one has to install a huge develop tool such as Visual Studio, and one has to write code, compile them, link them in order to get an executable program, and once the program was dispatched to a client, logic of the program usually was fixed, that means it is difficult to change its behavior.
Using script language such as js, lua, py, etc. is a common way for dealing with the previous problem. However, in most of the cases, the script language is usually a supplementary tool to extend their capability.
In this article, I'd like to introduce you to a framework, with which you can finish a desktop program using JavaScript completely.
Actually, I had implemented a similar work except for using lua as the script language. In which work, a small part of basic APIs was exported to lua environment, which will make it more like a demo than a practicable framework (The main reason is that I'm not familiar with Lua). See Run Client in Lua Script completely.
Introduction of Projects
As we know, quickjs is a high performance JavaScript runtime. Somebody maybe knows that SOUI is a high performance directui
library. Both of them are build using C++.
If we can export the interfaces of SOUI to JavaScript, we would get a new framework, with which one designs UI in XML and writes logic in JS. This work is done by module soui4js
now.
Before explaining how the code works, let's have a glance at the file structure of the project.
The project includes core module soui4js and a dependance module qjsbind. Other folders including extctrl, jsvodplayer, sliveplayer are server for the player demo.
depends contains 4 subfolders that include quickjs, soui4, sdl2 and vodplayer.
quickjs
and soui4
are two core modules. sdl2
and vodplayer
are server for the player demo.
Before running the demo, run copy_bin.bat first. It will copy dependent DLLs to debug and release folders.
Then open soui4js.sln and build all. Make sure all modules were built successfully.
Now, you will find xliveplayer.exe is ready in debug or release folder depending on the configuration you had selected.
Run xliveplayer.exe and you should see the UI look like the following snapshot:
You are a liar! All codes you provided here were wrote in C++. Where is JavaScript?
Take it easy! Please give me more patience.
You may see quite a few files in debug/release folder. Actually, most of them are server for the live player demo.
The modules required for building a desktop program are quickjs, soui4 DLLs and soui4js.dll.
The module of xliveplayer.exe is the host program that runs JavaScript program. Code used by xliveplayer.exe is fixed and shall not be changed in most of the cases.
All of the work you need to code is write a main.js and provider a main function.
Run xliveplayer.exe will load main.js and run the main function automatically. As xliveplayer.exe implements only relative fixed logic, to avoid rebuild a simliar js host, you can change its name to what as you want simply.
Now, it's time to explain the structure of main.js. The main.js contained in the demo is relatively complex. To be simple, here, I used another project to explain.
The zip file contains a main.js and a uires.zip. Unzip it to a folder (for example, d:\md5calc), and use command xliveplayer.exe d:\md5calc to load the md5calc
.
If it run succeed, you can drag files to the UI and you will see the following UI.
This program is quite simple:
- It loads uires.zip as resources.
- It creates a main window which contains a
listview
widget and shows the window. - It enters a message loop and waits for user input.
Now, let's have a look at the code:
import * as soui4 from "soui4";
import * as os from "os";
import * as std from "std";
var <code>g_workDir</code>="";
class MainDialog extends soui4.JsHostWnd{
constructor(){
super("layout:dlg_main");
this.onEvt = this.onEvent;
}
};
function main(inst,workDir,args)
{
soui4.log(workDir);
g_workDir = workDir;
let theApp = soui4.GetApp();
let souiFac = soui4.CreateSouiFactory();
let resProvider = soui4.CreateZipResProvider
(theApp,workDir +"\\uires.zip","souizip");
if(resProvider == 0){
soui4.log("load res from uires.zip failed");
return -1;
}
let resMgr = theApp.GetResProviderMgr();
resMgr.AddResProvider(resProvider,"uidef:xml_init");
resProvider.Release();
let hwnd = soui4.GetActiveWindow();
let hostWnd= new MainDialog();
hostWnd.Create(hwnd,0,0,0,0);
hostWnd.SendMessage(0x110,0,0);
hostWnd.ShowWindow(1);
souiFac.Release();
let ret= theApp.Run(hostWnd.GetHwnd());
hostWnd=null;
soui4.log("js quit");
return ret;
}
globalThis.main=main;
import *
as soui4
from "soui4
";
Most important, using the code to import soui4
APIs, you can use it to show UI and implement your logic and everything.
Todo List
- Debug the program is relative difficult now. I have to watch log to make sure code is run as expected or not. There is a repo demo how to debug quickjs in https://github.com/koush/vscode-quickjs-debug, If time is available, I'd like to incorporate it into this work.
Points of Interest
Using this framework, we can do most of work in JavaScript. If you are familiar with C++, you can provide extend widgets to js and you can do everything that a traditional program to do. Do you think so? Thank you for your patience!
History
- 9th February, 2023: Version 1.0
- 7th July, 2023: Version 1.1