Click here to Skip to main content
15,886,578 members
Articles / Programming Languages / Javascript

Build a Desktop Program using XML and JavaScript without C/C++

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
8 Feb 2023CPOL5 min read 6.4K   17   6  
Introducing a new framework for building client program using XML and JS
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.

Image 1

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:

Image 2

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 quickjssoui4 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.

Image 3

This program is quite simple:

  1. It loads uires.zip as resources. 
  2. It creates a main window which contains a listview widget and shows the window.
  3. It enters a message loop and waits for user input.

Now, let's have a look at the code:

JavaScript
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();
	// show how to load resource from a zip file
	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);  //send init dialog message.
	hostWnd.ShowWindow(1);           //1==SW_SHOWNORMAL
	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

  1. 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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --