AfxNova progress

Started by José Roca, November 14, 2025, 11:37:56 PM

Previous topic - Next topic

Paul Squires

Hi José,

I have gotten back to updating Tiko code and am just about ready to post the version 1.3.1 update. I can grab your most recent AfxNova repository files now, or I can wait a bit longer if you'd like to add anything before I publish the Tiko update. Just let me know.

Thanks,
Paul
Paul Squires
PlanetSquires Software

José Roca

Hi Paul,

Everything I have uploaded is working fine as far as I know, so there is no need to delay the release of the new version of Tiko.

As you can see, I'm working to provide access to the latest technologies, such as WebView2 and Direct2D. Direct2D, DirectWrite, and WIC can already be used if you manage the object lifetimes yourself and call the methods directly. I'm currently working on wrapper classes to make them easier to use by providing constructors, automatic memory management, and overloaded methods.

I have already finished wrapping the most important interfaces, but wrapping the entire set will take time, since Direct2D is a whole ecosystem. The advantages of Direct2D are that it is faster, offers higher quality, and is fully DPI‑aware — all essential qualities for modern 4K displays.

Paul Squires

Excellent, thanks! I will use your latest repository files. Very exciting new code you're working on! I look forward to using it when you are finished. AfxNova makes coding in FB so much easier and these new technologies will make it even better.
Paul Squires
PlanetSquires Software

José Roca

My next step will be to take full advantage of the WebView2 control and turn it into a true "super control".
 
I'm planning to write a canvas class that allows drawing anything you need: graphics, images, text, shapes, and more. The idea is to expose a classic, easy‑to‑use API on the outside, while internally generating the required HTML, CSS, and JavaScript to perform the rendering.

This approach will make it possible to build all kinds of document‑related features:

- invoices and reports
- barcodes and QR codes
- embedded images
- tables and layouts
- previews and printouts
- charts and visualizations
- even animations

Basically, anything you can do on a modern web page will be available through a simple, traditional API.


The WebView2 control also has a localized context menu and/or shortcuts that allow to save, copy, rotate images, zoom and printing.

José Roca

Mi idea is working.

I'm currently developing a new graphics engine based on Microsoft WebView2, wrapped inside a custom class that exposes a clean and easy‑to‑use API.

The goal is simple: give you a powerful 2D drawing system without requiring you to learn HTML, CSS, or JavaScript

Under the hood, the engine uses an HTML5 <canvas> element and JavaScript to perform all rendering. This means you automatically benefit from:


- GPU‑accelerated drawing
- smooth rendering with no flicker
- high‑resolution text and shapes
- automatic scrolling when the canvas is larger than the control
- modern browser‑level performance

But you never have to deal with any of that complexity.

Instead, you work with a very simple and intuitive API, for example:

pCanvas->DrawText("Hello World", 100, 100, "red", 40)
pCanvas->DrawLine(50, 50, 300, 200, "blue", 4)
pCanvas->DrawCircle(200, 200, 50, "purple", 3)

No fonts to create.
No pens or brushes.
No device contexts.
No GDI or Direct2D setup.
Just straightforward drawing commands.

If you do know HTML, CSS, or JavaScript, you can extend the system even further. But if you don't, the API will give you what you need to draw text, shapes, images, and more.

In short, this project aims to provide a modern, lightweight, and extremely easy graphics language, built on top of WebView2 but completely hiding the web technologies behind a clean and friendly interface.

Johan Klassen

Good day José Roca  :)
this is great stuff, I can see that creating a GUI applications using your WebView2 class will be easy, even for me, thank you ;D

Paul Squires

Reminds me a lot of the Tauri project and what they've accomplished as an alternative to Electron.
https://v2.tauri.app/

Tauri is cross platform and written in Rust.
Paul Squires
PlanetSquires Software

José Roca

#37
The idea is simple. I already have a class, CWebView2, to allow to embed an instance of WebView2 in any window. CWebView2Canvas extends CWebView2, calls the BASE constructor to create the instance of WebView2 and...

Uses this tiny html script to create a canvas:


  DIM s AS STRING = $"<html>"
  s += "<body style='margin:0; padding:0; overflow:auto;'>"
  s += $"<canvas id='cv' width='" & STR(cvWidth) & "' height='" & STR(cvHeight) & "'></canvas>"
  s += $"</body>"
  s += $"</html>"

Uses this tiny JavaScript function to get the context when the web page is loaded:

  DIM JS_INIT AS STRING = $"var cv, ctx;"
  JS_INIT += "window.onload = function() {"
  JS_INIT += "    cv = document.getElementById('cv');"
  JS_INIT += "    ctx = cv.getContext('2d');"
  JS_INIT += "};"

If the WebView2 control is ready, adds the script to the control and navigats to our tiny web page.

  IF this.IsReady THEN
      this.AddScriptToExecuteOnDocumentCreated(JS_INIT, NULL)
      this.NavigateToString(s)
  END IF

With the reference to CWebView2Canvas class we can call our wrapper functions, e.g.

DIM pCanvas AS CWebView2Canvas = CWebView2Canvas(hWin, dwsUserDataFolder)
...
...
pCanvas->DrawText("Hello World", 100, 100, "red", 40)
pCanvas->DrawLine(50, 50, 300, 200, "blue", 4)
pCanvas->DrawCircle(200, 200, 50, "purple", 3)

As WebView2 is asynchronous, the safest way is to use the CWebView2NavigationCompletedEventHandler. I provide overridable classes to implement your custom event handlers.

For the wrapper methods, I use JavaScript inside them, e.g.

' ========================================================================================
' Draws a circle.
' x, y : coordinates
' radius; Radius
' clr: The color of the pen
' nWidth : The width of the pen
' ========================================================================================
PRIVATE SUB CWebView2Canvas.DrawCircle( _
        BYVAL x AS SINGLE, BYVAL y AS SINGLE, _
        BYVAL radius AS SINGLE, _
        BYREF clr AS STRING, _
        BYVAL nWidth AS LONG = 1)

  ' // Make sure that the JS function exists
  IF m_hasDrawCircle = FALSE THEN
      DIM js AS STRING
      js = _
      "function drawCircle(x, y, radius, color, width) {" _
      & " ctx.strokeStyle = color;" _
      & " ctx.lineWidth = width;" _
      & " ctx.beginPath();" _
      & " ctx.arc(x, y, radius, 0, Math.PI * 2);" _
      & " ctx.stroke();" _
      & "}"
      this.ExecuteScript(js, NULL)
      m_hasDrawCircle = TRUE
    END IF

  ' // Call the JS function
  DIM js AS STRING
  js = "drawCircle(" _
      & STR(x) & "," & STR(y) & "," _
      & STR(radius) & ",'" _
      & clr & "'," & STR(nWidth) & ");"

  this.ExecuteScript(js, NULL)

END SUB
' ========================================================================================

If the JavaScript function does not exist, the wrapper adds it to the web page and then calls it with ExecuteScript.

As I still don't have much expertise with JavaScript, I ask the IA to write it for me.

It is not crossplatform, because WebView2 is a control for Windows, but the size of the executable of one small example with a CWindow's GUI, the CWebView2 and CWebView2Canvas classes, the event's class, DWSTRING and the wrappers for AfxNova, weights around 67 KB, not 600. As a simple example of CWindow with a button, weights 54.5 KB, this means that my WebView2 classes add 12.5 KB.

As the javascript functions are added on demand, the size of the application will grow depending on how many different ones you use. The size of the executable of the example that produces the capture below weights 82.5 KB and it is using 14 different functions.

We are not limited to graphics functions, but we can do everything: images, video, audio... and  even to use external libraries.



José Roca

#38
The embeded WebView2 control also has contextual localized menus that allow to save or copy the image, and shortcut keys. For example, you can zoom the image with Ctrl+/-, or using Ctrl and the mouswheel. Scrollbars are added automatically if needed. And Ctrl+P activates the browser printer dalog, so we have printing and print preview for free. We can generate PDF files if we choose a driver like Microsoft Print to PDF or any other that you prefer.

We can also drop images, pdf files and other objects in the control.

José Roca

I have added methods to draw text that can also be used with effects to, for example, draw logos.


José Roca

The canvas can now display images, loaded from disk or a URL. With automatic scrolling, zoom, save and copy, print and preview, and with my "on-demand" function system, I can create a massive library without bloat. The 64-bit executable is 81 KB.

hajubu

#41
Hi, I just updated my previous Html-Help for Tiko 1.3 , which is based on your md-DOCS-folder.

enclosed are two zip containing the changes , the instructions, and Readme
                    and the ready-to-use AfxNova_Web.

Readme_first_if_you_like. - Have Fun !

br. Hans (hajubu)

P.S:
ref_to_: details post May 29 - AfxNova progess

downloads available - Testpan_AfxNova_Web_260613__3fa6207 ->
  -> Planetsquires Software -> Tiko 1.3 and AfxNova Docs as integrated HelpTool


hajubu

hi, just updated  available - Testpan_AfxNova_Web_260616_690f2a3->related to the Array Macros ( Jose made a commit today )

see for available upd
Updated AfxNova_Web_260616_0310

see also Jose repo at Github
https://github.com/JoseRoca/AfxNova

José Roca

#43
Using JavaScript Libraries from FreeBasic via WebView2: A Powerful Hybrid Technique

One of the most exciting capabilities unlocked by embedding WebView2 into a FreeBasic application is the ability to combine native code with the full power of modern JavaScript libraries. In the attached example, I demonstrate how to draw shapes, Unicode text, and even emojis by using a class derived from CWebView2 that executes JavaScript commands from the Konva.js graphics framework.

This technique is far more than a simple trick. It represents a clean, extensible, and extremely powerful architectural pattern.

Why this technique is so effective

1. You get a modern 2D graphics engine "for free"

Konva.js is a high‑performance HTML5 canvas framework designed for shapes, layers, animations, and interactive graphics. By calling its API from FreeBasic through WebView2, you instantly gain:

* smooth vector rendering
* layers and groups
* hit‑testing and interactivity
* animations and tweens
* pixel‑perfect text rendering
* full Unicode support, including emojis

All of this without writing a single line of low‑level canvas code in FreeBasic.

2. Unicode "just works" — including emojis

Because the rendering is handled by the browser engine, you automatically inherit:

* full UTF‑8 support
* complex scripts
* emoji rendering
* font fallback
* anti‑aliasing and subpixel smoothing

This eliminates the usual headaches of Unicode text in native GUI frameworks.

I have added a property called JScript to my DWSTRING class to allow the use utf-16 strings instead of utf-8.


3. Clean separation of responsibilities

The derived classes will handle:

* generating the JavaScript code
* sending it to WebView2
* managing the canvas state
* abstracting away the browser details

Meanwhile, the JavaScript library handles:

* drawing
* layout
* animation
* event handling

This keeps the FreeBasic side clean and focused.

4. No global variables, no manual cleanup

Because the event handlers are implemented as real COM objects, they:

* register themselves
* unregister themselves in the destructor
* are released automatically when the WebView2 instance is destroyed

This means the user does not need to store pointers, call Delete, or manage lifetimes manually. The system is robust and self‑contained.

What else can we do with this technique?

The beauty of this architecture is that Konva.js is only the beginning. Any JavaScript library that runs in a browser can be controlled from FreeBasic simply by deriving a new class and exposing methods that generate the appropriate JavaScript.

Here are some possibilities.

1. Charts and data visualization

You can create a CWebView2Charts class that wraps libraries such as:

Chart.js
ECharts
D3.js
Plotly
ApexCharts

This would allow FreeBasic applications to display:

* bar charts
* line charts
* pie charts
* heatmaps
* real‑time data visualizations
* interactive dashboards

All with modern styling and smooth animations.

2. UI components and widgets

By wrapping libraries like:

* Bootstrap
* Material UI
* jQuery UI

you could embed:

* dialogs
* sliders
* tabs
* accordions
* responsive layouts

directly inside a FreeBasic application.

3. Maps and geospatial visualization

Using libraries such as:

* Leaflet
* Mapbox GL
* OpenLayers

you could display:

* interactive maps
* markers
* routes
* heatmaps
* GPS data

all controlled from FreeBasic.

4. Game‑style rendering

With libraries like:

* PixiJS
* Phaser

you could build:

* 2D games
* simulations
* particle effects
* sprite animations

inside a native FreeBasic window.

A flexible, extensible architecture

The key idea is simple:

Derive a class from CWebView2, and implement methods that generate JavaScript for the library you want to use.

Each derived class becomes a bridge between FreeBasic and a modern JavaScript framework.

This approach gives FreeBasic developers access to:

* modern graphics
* interactive UI components
* advanced visualization
* high‑level animation
* rich text and Unicode
* High DPI rendering consistency

All without rewriting existing libraries or reinventing the wheel.

Conclusion

By combining FreeBasic with WebView2 and JavaScript libraries like Konva.js, we unlock a hybrid development model that is both powerful and elegant. Native code handles performance‑critical logic, while JavaScript libraries provide modern rendering and UI capabilities.

This technique is not only practical — it is extensible. New derived classes can wrap any JavaScript framework, enabling FreeBasic applications to incorporate charts, maps, animations, widgets, and much more.

It's a modern approach that dramatically expands what FreeBasic applications can do.

P.S. I have added automatic scrollbars to the example.

José Roca

In the example attached in the previous post, clicking the mouse right button provides a localized menu with options to save or copy the content of the canvas. Ctrl+mouse wheel allows zooming, and Ctrl+P activates the Print/Preview dialog.