I have tried to update this wrapper for the newest version of WebUI v2.4.2 however, I have run into a linker problem and am not sure what I have done wrong. I have included the WebUI include file and my attempt to update the wrapping in PureBasic. Everything worked in version 2.3. This problem only started when I began to use version 2.4.2.
Here is the message I get when I try to compile my code.
---------------------------
PureBasic - Linker error
---------------------------
error: Unresolved external symbol '__security_cookie' - referenced from 'webui-2-static.lib(webui.obj)'.
POLINK: error: Unresolved external symbol '__security_check_cookie' - referenced from 'webui-2-static.lib(webui.obj)'.
POLINK: error: Unresolved external symbol 'strtoll' - referenced from 'webui-2-static.lib(webui.obj)'.
POLINK: error: Unresolved external symbol '_dupenv_s' - referenced from 'webui-2-static.lib(webui.obj)'.
POLINK: error: Unresolved external symbol 'strdup' - referenced from 'webui-2-static.lib(webui.obj)'.
POLINK: error: Unresolved external symbol '__stdio_common_vsprintf' - referenced from 'webui-2-static.lib(webui.obj)'.
POLINK: error: Unresolved external symbol '__GSHandlerCheck' - referenced from 'webui-2-static.lib(webui.obj)'.
---------------------------
Any suggestion about what I need to fix?
Code: Select all
/*
WebUI Library 2.4.2
http://webui.me
https://github.com/webui-dev/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under MIT License.
All rights reserved.
Canada.
*/
#ifndef _WEBUI_H
#define _WEBUI_H
#define WEBUI_VERSION "2.4.2"
// Max windows, servers and threads
#define WEBUI_MAX_IDS (256)
// Max allowed argument's index
#define WEBUI_MAX_ARG (16)
// Dynamic Library Exports
#if defined(_MSC_VER) || defined(__TINYC__)
#ifndef WEBUI_EXPORT
#define WEBUI_EXPORT __declspec(dllexport)
#endif
#else
#ifndef WEBUI_EXPORT
#define WEBUI_EXPORT extern
#endif
#endif
// -- C STD ---------------------------
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined(__GNUC__) || defined(__TINYC__)
#include <dirent.h>
#endif
// -- Windows -------------------------
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <direct.h>
#include <io.h>
#include <shellapi.h>
#include <tchar.h>
#include <tlhelp32.h>
#define WEBUI_GET_CURRENT_DIR _getcwd
#define WEBUI_FILE_EXIST _access
#define WEBUI_POPEN _popen
#define WEBUI_PCLOSE _pclose
#define WEBUI_MAX_PATH MAX_PATH
#endif
// -- Linux ---------------------------
#ifdef __linux__
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST access
#define WEBUI_POPEN popen
#define WEBUI_PCLOSE pclose
#define WEBUI_MAX_PATH PATH_MAX
#endif
// -- Apple ---------------------------
#ifdef __APPLE__
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/syslimits.h>
#include <sys/time.h>
#include <unistd.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST access
#define WEBUI_POPEN popen
#define WEBUI_PCLOSE pclose
#define WEBUI_MAX_PATH PATH_MAX
#endif
// -- Enums ---------------------------
enum webui_browsers {
NoBrowser = 0, // 0. No web browser
AnyBrowser = 1, // 1. Default recommended web browser
Chrome, // 2. Google Chrome
Firefox, // 3. Mozilla Firefox
Edge, // 4. Microsoft Edge
Safari, // 5. Apple Safari
Chromium, // 6. The Chromium Project
Opera, // 7. Opera Browser
Brave, // 8. The Brave Browser
Vivaldi, // 9. The Vivaldi Browser
Epic, // 10. The Epic Browser
Yandex, // 11. The Yandex Browser
ChromiumBased, // 12. Any Chromium based browser
};
enum webui_runtimes {
None = 0, // 0. Prevent WebUI from using any runtime for .js and .ts files
Deno, // 1. Use Deno runtime for .js and .ts files
NodeJS, // 2. Use Nodejs runtime for .js files
};
enum webui_events {
WEBUI_EVENT_DISCONNECTED = 0, // 0. Window disconnection event
WEBUI_EVENT_CONNECTED, // 1. Window connection event
WEBUI_EVENT_MOUSE_CLICK, // 2. Mouse click event
WEBUI_EVENT_NAVIGATION, // 3. Window navigation event
WEBUI_EVENT_CALLBACK, // 4. Function call event
};
// -- Structs -------------------------
typedef struct webui_event_t {
size_t window; // The window object number
size_t event_type; // Event type
char* element; // HTML element ID
size_t event_number; // Internal WebUI
size_t bind_id; // Bind ID
} webui_event_t;
// -- Definitions ---------------------
/**
* @brief Create a new WebUI window object.
*
* @return Returns the window number.
*
* @example size_t myWindow = webui_new_window();
*/
WEBUI_EXPORT size_t webui_new_window(void);
/**
* @brief Create a new webui window object using a specified window number.
*
* @param window_number The window number (should be > 0, and < WEBUI_MAX_IDS)
*
* @return Returns the window number.
*
* @example size_t myWindow = webui_new_window_id(123);
*/
WEBUI_EXPORT size_t webui_new_window_id(size_t window_number);
/**
* @brief Get a free window number that can be used with
* `webui_new_window_id()`.
*
* @return Returns the first available free window number. Starting from 1.
*
* @example size_t myWindowNumber = webui_get_new_window_id();
*/
WEBUI_EXPORT size_t webui_get_new_window_id(void);
/**
* @brief Bind a specific html element click event with a function. Empty
* element means all events.
*
* @param window The window number
* @param element The HTML ID
* @param func The callback function
*
* @return Returns a unique bind ID.
*
* @example webui_bind(myWindow, "myID", myFunction);
*/
WEBUI_EXPORT size_t webui_bind(size_t window, const char* element, void (*func)(webui_event_t* e));
/**
* @brief Show a window using embedded HTML, or a file. If the window is already
* open, it will be refreshed.
*
* @param window The window number
* @param content The HTML, URL, Or a local file
*
* @return Returns True if showing the window is successed.
*
* @example webui_show(myWindow, "<html>...</html>"); | webui_show(myWindow,
* "index.html"); | webui_show(myWindow, "http://...");
*/
WEBUI_EXPORT bool webui_show(size_t window, const char* content);
/**
* @brief Same as `webui_show()`. But using a specific web browser.
*
* @param window The window number
* @param content The HTML, Or a local file
* @param browser The web browser to be used
*
* @return Returns True if showing the window is successed.
*
* @example webui_show_browser(myWindow, "<html>...</html>", Chrome); |
* webui_show(myWindow, "index.html", Firefox);
*/
WEBUI_EXPORT bool webui_show_browser(size_t window, const char* content, size_t browser);
/**
* @brief Set the window in Kiosk mode (Full screen)
*
* @param window The window number
* @param status True or False
*
* @example webui_set_kiosk(myWindow, true);
*/
WEBUI_EXPORT void webui_set_kiosk(size_t window, bool status);
/**
* @brief Wait until all opened windows get closed.
*
* @example webui_wait();
*/
WEBUI_EXPORT void webui_wait(void);
/**
* @brief Close a specific window only. The window object will still exist.
*
* @param window The window number
*
* @example webui_close(myWindow);
*/
WEBUI_EXPORT void webui_close(size_t window);
/**
* @brief Close a specific window and free all memory resources.
*
* @param window The window number
*
* @example webui_destroy(myWindow);
*/
WEBUI_EXPORT void webui_destroy(size_t window);
/**
* @brief Close all open windows. `webui_wait()` will return (Break).
*
* @example webui_exit();
*/
WEBUI_EXPORT void webui_exit(void);
/**
* @brief Set the web-server root folder path for a specific window.
*
* @param window The window number
* @param path The local folder full path
*
* @example webui_set_root_folder(myWindow, "/home/Foo/Bar/");
*/
WEBUI_EXPORT bool webui_set_root_folder(size_t window, const char* path);
/**
* @brief Set the web-server root folder path for all windows. Should be used
* before `webui_show()`.
*
* @param path The local folder full path
*
* @example webui_set_default_root_folder("/home/Foo/Bar/");
*/
WEBUI_EXPORT bool webui_set_default_root_folder(const char* path);
/**
* @brief Set a custom handler to serve files.
*
* @param window The window number
* @param handler The handler function: `void myHandler(const char* filename,
* int* length)`
*
* @return Returns a unique bind ID.
*
* @example webui_set_file_handler(myWindow, myHandlerFunction);
*/
WEBUI_EXPORT void webui_set_file_handler(size_t window, const void* (*handler)(const char* filename, int* length));
/**
* @brief Check if the specified window is still running.
*
* @param window The window number
*
* @example webui_is_shown(myWindow);
*/
WEBUI_EXPORT bool webui_is_shown(size_t window);
/**
* @brief Set the maximum time in seconds to wait for the browser to start.
*
* @param second The timeout in seconds
*
* @example webui_set_timeout(30);
*/
WEBUI_EXPORT void webui_set_timeout(size_t second);
/**
* @brief Set the default embedded HTML favicon.
*
* @param window The window number
* @param icon The icon as string: `<svg>...</svg>`
* @param icon_type The icon type: `image/svg+xml`
*
* @example webui_set_icon(myWindow, "<svg>...</svg>", "image/svg+xml");
*/
WEBUI_EXPORT void webui_set_icon(size_t window, const char* icon, const char* icon_type);
/**
* @brief Base64 encoding. Use this to safely send text based data to the UI. If
* it fails it will return NULL.
*
* @param str The string to encode (Should be null terminated)
*
* @example webui_encode("Hello");
*/
WEBUI_EXPORT char* webui_encode(const char* str);
/**
* @brief Base64 decoding. Use this to safely decode received Base64 text from
* the UI. If it fails it will return NULL.
*
* @param str The string to decode (Should be null terminated)
*
* @example webui_decode("SGVsbG8=");
*/
WEBUI_EXPORT char* webui_decode(const char* str);
/**
* @brief Safely free a buffer allocated by WebUI using `webui_malloc()`.
*
* @param ptr The buffer to be freed
*
* @example webui_free(myBuffer);
*/
WEBUI_EXPORT void webui_free(void* ptr);
/**
* @brief Safely allocate memory using the WebUI memory management system. It
* can be safely freed using `webui_free()` at any time.
*
* @param size The size of memory in bytes
*
* @example char* myBuffer = (char*)webui_malloc(1024);
*/
WEBUI_EXPORT void* webui_malloc(size_t size);
/**
* @brief Safely send raw data to the UI.
*
* @param window The window number
* @param function The JavaScript function to receive raw data: `function
* myFunc(myData){}`
* @param raw The raw data buffer
* @param size The raw data size in bytes
*
* @example webui_send_raw(myWindow, "myJavascriptFunction", myBuffer, 64);
*/
WEBUI_EXPORT void webui_send_raw(size_t window, const char* function, const void* raw, size_t size);
/**
* @brief Set a window in hidden mode. Should be called before `webui_show()`.
*
* @param window The window number
* @param status The status: True or False
*
* @example webui_set_hide(myWindow, True);
*/
WEBUI_EXPORT void webui_set_hide(size_t window, bool status);
/**
* @brief Set the window size.
*
* @param window The window number
* @param width The window width
* @param height The window height
*
* @example webui_set_size(myWindow, 800, 600);
*/
WEBUI_EXPORT void webui_set_size(size_t window, unsigned int width, unsigned int height);
/**
* @brief Set the window position.
*
* @param window The window number
* @param x The window X
* @param y The window Y
*
* @example webui_set_position(myWindow, 100, 100);
*/
WEBUI_EXPORT void webui_set_position(size_t window, unsigned int x, unsigned int y);
/**
* @brief Set the web browser profile to use. An empty `name` and `path` means
* the default user profile. Need to be called before `webui_show()`.
*
* @param window The window number
* @param name The web browser profile name
* @param path The web browser profile full path
*
* @example webui_set_profile(myWindow, "Bar", "/Home/Foo/Bar"); |
* webui_set_profile(myWindow, "", "");
*/
WEBUI_EXPORT void webui_set_profile(size_t window, const char* name, const char* path);
/**
* @brief Set the web browser proxy_server to use. Need to be called before `webui_show()`.
*
* @param window The window number
* @param proxy_server The web browser proxy_server
*
* @example webui_set_proxy(myWindow, "http://127.0.0.1:8888");
*/
WEBUI_EXPORT void webui_set_proxy(size_t window, const char* proxy_server);
/**
* @brief Get the full current URL.
*
* @param window The window number
*
* @return Returns the full URL string
*
* @example const char* url = webui_get_url(myWindow);
*/
WEBUI_EXPORT const char* webui_get_url(size_t window);
/**
* @brief Allow a specific window address to be accessible from a public network
*
* @param window The window number
* @param status True or False
*
* @example webui_set_public(myWindow, true);
*/
WEBUI_EXPORT void webui_set_public(size_t window, bool status);
/**
* @brief Navigate to a specific URL
*
* @param window The window number
* @param url Full HTTP URL
*
* @example webui_navigate(myWindow, "http://domain.com");
*/
WEBUI_EXPORT void webui_navigate(size_t window, const char* url);
/**
* @brief Free all memory resources. Should be called only at the end.
*
* @example
* webui_wait();
* webui_clean();
*/
WEBUI_EXPORT void webui_clean();
/**
* @brief Delete all local web-browser profiles folder. It should called at the
* end.
*
* @example
* webui_wait();
* webui_delete_all_profiles();
* webui_clean();
*/
WEBUI_EXPORT void webui_delete_all_profiles();
/**
* @brief Delete a specific window web-browser local folder profile.
*
* @param window The window number
*
* @example
* webui_wait();
* webui_delete_profile(myWindow);
* webui_clean();
*
* @note This can break functionality of other windows if using the same
* web-browser.
*/
WEBUI_EXPORT void webui_delete_profile(size_t window);
/**
* @brief Get the ID of the parent process (The web browser may re-create
* another new process).
*
* @param window The window number
*
* @return Returns the the parent process id as integer
*
* @example size_t id = webui_get_parent_process_id(myWindow);
*/
WEBUI_EXPORT size_t webui_get_parent_process_id(size_t window);
/**
* @brief Get the ID of the last child process.
*
* @param window The window number
*
* @return Returns the the child process id as integer
*
* @example size_t id = webui_get_child_process_id(myWindow);
*/
WEBUI_EXPORT size_t webui_get_child_process_id(size_t window);
/**
* @brief Set a custom web-server network port to be used by WebUI.
* This can be useful to determine the HTTP link of `webui.js` in case
* you are trying to use WebUI with an external web-server like NGNIX
*
* @param window The window number
* @param port The web-server network port WebUI should use
*
* @return Returns True if the port is free and usable by WebUI
*
* @example bool ret = webui_set_port(myWindow, 8080);
*/
WEBUI_EXPORT bool webui_set_port(size_t window, size_t port);
// -- SSL/TLS -------------------------
/**
* @brief Set the SSL/TLS certificate and the private key content, both in PEM
* format. This works only with `webui-2-secure` library. If set empty WebUI
* will generate a self-signed certificate.
*
* @param certificate_pem The SSL/TLS certificate content in PEM format
* @param private_key_pem The private key content in PEM format
*
* @return Returns True if the certificate and the key are valid.
*
* @example bool ret = webui_set_tls_certificate("-----BEGIN
* CERTIFICATE-----\n...", "-----BEGIN PRIVATE KEY-----\n...");
*/
WEBUI_EXPORT bool webui_set_tls_certificate(const char* certificate_pem, const char* private_key_pem);
// -- JavaScript ----------------------
/**
* @brief Run JavaScript without waiting for the response.
*
* @param window The window number
* @param script The JavaScript to be run
*
* @example webui_run(myWindow, "alert('Hello');");
*/
WEBUI_EXPORT void webui_run(size_t window, const char* script);
/**
* @brief Run JavaScript and get the response back.
* Make sure your local buffer can hold the response.
*
* @param window The window number
* @param script The JavaScript to be run
* @param timeout The execution timeout
* @param buffer The local buffer to hold the response
* @param buffer_length The local buffer size
*
* @return Returns True if there is no execution error
*
* @example bool err = webui_script(myWindow, "return 4 + 6;", 0, myBuffer, myBufferSize);
*/
WEBUI_EXPORT bool webui_script(size_t window, const char* script, size_t timeout,
char* buffer, size_t buffer_length);
/**
* @brief Chose between Deno and Nodejs as runtime for .js and .ts files.
*
* @param window The window number
* @param runtime Deno | Nodejs
*
* @example webui_set_runtime(myWindow, Deno);
*/
WEBUI_EXPORT void webui_set_runtime(size_t window, size_t runtime);
/**
* @brief Get an argument as integer at a specific index
*
* @param e The event struct
* @param index The argument position starting from 0
*
* @return Returns argument as integer
*
* @example long long int myNum = webui_get_int_at(e, 0);
*/
WEBUI_EXPORT long long int webui_get_int_at(webui_event_t* e, size_t index);
/**
* @brief Get the first argument as integer
*
* @param e The event struct
*
* @return Returns argument as integer
*
* @example long long int myNum = webui_get_int(e);
*/
WEBUI_EXPORT long long int webui_get_int(webui_event_t* e);
/**
* @brief Get an argument as string at a specific index
*
* @param e The event struct
* @param index The argument position starting from 0
*
* @return Returns argument as string
*
* @example const char* myStr = webui_get_string_at(e, 0);
*/
WEBUI_EXPORT const char* webui_get_string_at(webui_event_t* e, size_t index);
/**
* @brief Get the first argument as string
*
* @param e The event struct
*
* @return Returns argument as string
*
* @example const char* myStr = webui_get_string(e);
*/
WEBUI_EXPORT const char* webui_get_string(webui_event_t* e);
/**
* @brief Get an argument as boolean at a specific index
*
* @param e The event struct
* @param index The argument position starting from 0
*
* @return Returns argument as boolean
*
* @example bool myBool = webui_get_bool_at(e, 0);
*/
WEBUI_EXPORT bool webui_get_bool_at(webui_event_t* e, size_t index);
/**
* @brief Get the first argument as boolean
*
* @param e The event struct
*
* @return Returns argument as boolean
*
* @example bool myBool = webui_get_bool(e);
*/
WEBUI_EXPORT bool webui_get_bool(webui_event_t* e);
/**
* @brief Get the size in bytes of an argument at a specific index
*
* @param e The event struct
* @param index The argument position starting from 0
*
* @return Returns size in bytes
*
* @example size_t argLen = webui_get_size_at(e, 0);
*/
WEBUI_EXPORT size_t webui_get_size_at(webui_event_t* e, size_t index);
/**
* @brief Get size in bytes of the first argument
*
* @param e The event struct
*
* @return Returns size in bytes
*
* @example size_t argLen = webui_get_size(e);
*/
WEBUI_EXPORT size_t webui_get_size(webui_event_t* e);
/**
* @brief Return the response to JavaScript as integer.
*
* @param e The event struct
* @param n The integer to be send to JavaScript
*
* @example webui_return_int(e, 123);
*/
WEBUI_EXPORT void webui_return_int(webui_event_t* e, long long int n);
/**
* @brief Return the response to JavaScript as string.
*
* @param e The event struct
* @param n The string to be send to JavaScript
*
* @example webui_return_string(e, "Response...");
*/
WEBUI_EXPORT void webui_return_string(webui_event_t* e, const char* s);
/**
* @brief Return the response to JavaScript as boolean.
*
* @param e The event struct
* @param n The boolean to be send to JavaScript
*
* @example webui_return_bool(e, true);
*/
WEBUI_EXPORT void webui_return_bool(webui_event_t* e, bool b);
// -- Wrapper's Interface -------------
/**
* @brief Bind a specific HTML element click event with a function. Empty element means all events.
*
* @param window The window number
* @param element The element ID
* @param func The callback as myFunc(Window, EventType, Element, EventNumber, BindID)
*
* @return Returns unique bind ID
*
* @example size_t id = webui_interface_bind(myWindow, "myID", myCallback);
*/
WEBUI_EXPORT size_t webui_interface_bind(size_t window, const char* element,
void (*func)(size_t, size_t, char*, size_t, size_t));
/**
* @brief When using `webui_interface_bind()`, you may need this function to easily set a response.
*
* @param window The window number
* @param event_number The event number
* @param response The response as string to be send to JavaScript
*
* @example webui_interface_set_response(myWindow, e->event_number, "Response...");
*/
WEBUI_EXPORT void webui_interface_set_response(size_t window, size_t event_number, const char* response);
/**
* @brief Check if the app still running.
*
* @return Returns True if app is running
*
* @example bool status = webui_interface_is_app_running();
*/
WEBUI_EXPORT bool webui_interface_is_app_running(void);
/**
* @brief Get a unique window ID.
*
* @param window The window number
*
* @return Returns the unique window ID as integer
*
* @example size_t id = webui_interface_get_window_id(myWindow);
*/
WEBUI_EXPORT size_t webui_interface_get_window_id(size_t window);
/**
* @brief Get an argument as string at a specific index
*
* @param window The window number
* @param event_number The event number
* @param index The argument position
*
* @return Returns argument as string
*
* @example const char* myStr = webui_interface_get_string_at(myWindow, e->event_number, 0);
*/
WEBUI_EXPORT const char* webui_interface_get_string_at(size_t window, size_t event_number, size_t index);
/**
* @brief Get an argument as integer at a specific index
*
* @param window The window number
* @param event_number The event number
* @param index The argument position
*
* @return Returns argument as integer
*
* @example long long int myNum = webui_interface_get_int_at(myWindow, e->event_number, 0);
*/
WEBUI_EXPORT long long int webui_interface_get_int_at(size_t window, size_t event_number, size_t index);
/**
* @brief Get an argument as boolean at a specific index
*
* @param window The window number
* @param event_number The event number
* @param index The argument position
*
* @return Returns argument as boolean
*
* @example bool myBool = webui_interface_get_bool_at(myWindow, e->event_number, 0);
*/
WEBUI_EXPORT bool webui_interface_get_bool_at(size_t window, size_t event_number, size_t index);
/**
* @brief Get the size in bytes of an argument at a specific index
*
* @param window The window number
* @param event_number The event number
* @param index The argument position
*
* @return Returns size in bytes
*
* @example size_t argLen = webui_interface_get_size_at(myWindow, e->event_number, 0);
*/
WEBUI_EXPORT size_t webui_interface_get_size_at(size_t window, size_t event_number, size_t index);
#endif /* _WEBUI_H */
Code: Select all
#WEBUI_VERSION = "2.4.2"
#WEBUI_MAX_IDS = 512
Enumeration webui_browsers
#NoBrowser
#AnyBrowser
#Chrome
#Firefox
#Edge
#Safari
#Chromium
#Opera
#Brave
#Vivaldi
#Epic
#Yandex
#ChromiumBased
EndEnumeration
Enumeration webui_runtimes
#None
#Deno
#NodeJS
EndEnumeration
Enumeration webui_events
#WEBUI_EVENT_DISCONNECTED
#WEBUI_EVENT_CONNECTED
#WEBUI_EVENT_MOUSE_CLICK
#WEBUI_EVENT_NAVIGATION
#WEBUI_EVENT_CALLBACK
EndEnumeration
Structure webui_event_t Align #PB_Structure_AlignC
window.i ; The window object number
event_type.i ; Event type
*element ; HTML element ID
event_number.i ; Internal WebUI
bind_id.i ; Bind ID
*data ; JavaScript data
EndStructure
PrototypeC PrototypeC_webui_event(*e.webui_event_t)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
ImportC "webui-2-static.lib"
CompilerCase #PB_OS_Linux
ImportC "webui-2-x64.so"
CompilerCase #PB_OS_MacOS
;ImportC "webui-2-x64.dyn"
ImportC "webui-2-static-x64.a"
CompilerEndSelect
; Create a new webui window object.
webui_new_window()
; Create a new webui window object.
webui_new_window_id(window_number.i)
; Get a free window ID that can be used with `webui_new_window_id()`
webui_get_new_window_id.i()
; Bind a specific html element click event with a function. Empty element means all events.
webui_bind.i(window.i, element.p-Ascii, webui_event.PrototypeC_webui_event)
; Show a window using a embedded HTML, or a file. If the window is already
webui_show.i(window.i, content.p-Ascii)
; Same as webui_show(). But with a specific web browser.
webui_show_browser(window.i, content.p-Ascii, browser.i)
; Set the window in Kiosk mode (Full screen)
webui_set_kiosk(window.i, status.i)
; Wait until all opened windows get closed.
webui_wait()
; Close a specific window only. The window object will still exist.
webui_close(window.i)
; Close a specific window and free all memory resources.
webui_destroy(window.i)
; Close all opened windows. webui_wait() will break.
webui_exit()
; Set the web-server root folder path.
webui_set_root_folder.i(window.i, path.p-Ascii)
; Set the default web-server root folder path.
webui_set_default_root_folder(path.p-Ascii);
; -- Other ---------------------------
; Check a specific window if it's still running
webui_is_shown.i(window.i)
; Set the maximum time in seconds to wait for browser to start
webui_set_timeout(second.i)
; Set the default embedded HTML favicon
webui_set_icon(window.i, icon.p-Ascii, icon_type.p-Ascii)
; Allow the window URL to be re-used in normal web browsers
;webui_set_multi_access(window.i, status.b)
; Navigate to URL
webui_navigate(window.i, url.p-ascii)
; -- JavaScript ----------------------
; Run JavaScript quickly with no waiting for the response.
webui_run(window.i, script.p-Ascii)
; Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
webui_script.i(window.i, script.p-Ascii, timeout.i, *buffer, buffer_length.i)
; Chose between Deno and Nodejs runtime for .js and .ts files.
webui_set_runtime(window.i, run_time.i)
; Parse argument as integer.
webui_get_int.q(*e.webui_event_t)
; Parse argument as string.
webui_get_string.i(*e.webui_event_t)
; Parse argument as boolean.
webui_get_bool.i(*e.webui_event_t)
; Return the response to JavaScript as integer.
webui_return_int(*e.webui_event_t, number.i)
; Return the response to JavaScript as string.
webui_return_string(*e.webui_event_t, const.p-Ascii)
; Return the response to JavaScript as boolean.
webui_return_bool(*e.webui_event_t, bool.i)
; Base64 encoding. Use this to safely send text based data to the UI. If it fails it will return NULL.
webui_encode.i(*char)
; Base64 decoding. Use this to safely decode received Base64 text from the UI. If it fails it will return NULL.
webui_decode.i(char.p-Ascii)
; Safely free a buffer allocated by WebUI, For example when using webui_encode().
webui_free(*ptr)
; -- Interface -----------------------
; Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind(). The func is (Window, EventType, Element, Data, EventNumber)
webui_interface_bind.i(window.i, element.p-Ascii, *func)
; When using `webui_interface_bind()` you may need this function to easily set your callback response.
webui_interface_set_response(window.i, event_number.i, response.p-Ascii)
; Check if the app still running or not. This replace webui_wait().
webui_interface_is_app_running.i()
; Get window unique ID
webui_interface_get_window_id.i(window.i)
; Get a unique ID. Same ID as `webui_bind()`. Return > 0 if bind exist.
webui_interface_get_bind_id.i(window.i, element.p-Ascii)
EndImport
infratec wrote: Sun Jun 11, 2023 10:45 pm Working version:Code: Select all
; /* ; WebUI Library 2.4.2 ; http://webui.me ; https://github.com/webui-dev/webui ; Copyright (c) 2020-2023 Hassan Draga. ; Licensed under MIT License. ; All rights reserved. ; Canada. ; */ CompilerIf Not #PB_Compiler_Thread CompilerError "Enable threadsafe in compiler options" CompilerEndIf CompilerIf #PB_Compiler_IsMainFile EnableExplicit CompilerEndIf #WEBUI_VERSION = "2.3.0" #WEBUI_MAX_IDS = 512 Enumeration webui_browsers #AnyBrowser #Chrome #Firefox #Edge #Safari #Chromium #Opera #Brave #Vivaldi #Epic #Yandex EndEnumeration Enumeration webui_runtimes #None #Deno #NodeJS EndEnumeration Enumeration webui_events #WEBUI_EVENT_DISCONNECTED #WEBUI_EVENT_CONNECTED #WEBUI_EVENT_MULTI_CONNECTION #WEBUI_EVENT_UNWANTED_CONNECTION #WEBUI_EVENT_MOUSE_CLICK #WEBUI_EVENT_NAVIGATION #WEBUI_EVENT_CALLBACK EndEnumeration Structure webui_event_t Align #PB_Structure_AlignC window.i ; The window object number event_type.i ; Event type *element ; HTML element ID *data ; JavaScript data event_number.i ; Internal WebUI EndStructure PrototypeC PrototypeC_webui_event(*e.webui_event_t) CompilerSelect #PB_Compiler_OS CompilerCase #PB_OS_Windows ImportC "webui-2-x64.lib" ;ImportC "webui-2-static-x64.lib" CompilerCase #PB_OS_Linux ImportC "webui-2-x64.so" CompilerCase #PB_OS_MacOS ;ImportC "webui-2-x64.dyn" ImportC "webui-2-static-x64.a" CompilerEndSelect ; Create a new webui window object. webui_new_window() ; Create a new webui window object. webui_new_window_id(window_number.i) ; Get a free window ID that can be used with `webui_new_window_id()` webui_get_new_window_id.i() ; Bind a specific html element click event with a function. Empty element means all events. webui_bind.i(window.i, element.p-Ascii, webui_event.PrototypeC_webui_event) ; Show a window using a embedded HTML, or a file. If the window is already webui_show.i(window.i, content.p-Ascii) ; Same as webui_show(). But with a specific web browser. webui_show_browser(window.i, content.p-Ascii, browser.i) ; Set the window in Kiosk mode (Full screen) webui_set_kiosk(window.i, status.i) ; Wait until all opened windows get closed. webui_wait() ; Close a specific window only. The window object will still exist. webui_close(window.i) ; Close a specific window and free all memory resources. webui_destroy(window.i) ; Close all opened windows. webui_wait() will break. webui_exit() ; Set the web-server root folder path. webui_set_root_folder.i(window.i, path.p-Ascii) ; -- Other --------------------------- ; Check a specific window if it's still running webui_is_shown.i(window.i) ; Set the maximum time in seconds to wait for browser to start webui_set_timeout(second.i) ; Set the default embedded HTML favicon webui_set_icon(window.i, icon.p-Ascii, icon_type.p-Ascii) ; Allow the window URL to be re-used in normal web browsers webui_set_multi_access(window.i, status.b) ; -- JavaScript ---------------------- ; Run JavaScript quickly with no waiting for the response. webui_run(window.i, script.p-Ascii) ; Run a JavaScript, and get the response back (Make sure your local buffer can hold the response). webui_script.i(window.i, script.p-Ascii, timeout.i, *buffer, buffer_length.i) ; Chose between Deno and Nodejs runtime for .js and .ts files. webui_set_runtime(window.i, run_time.i) ; Parse argument as integer. webui_get_int.q(*e.webui_event_t) ; Parse argument as string. webui_get_string.i(*e.webui_event_t) ; Parse argument as boolean. webui_get_bool.i(*e.webui_event_t) ; Return the response to JavaScript as integer. webui_return_int(*e.webui_event_t, number.i) ; Return the response to JavaScript as string. webui_return_string(*e.webui_event_t, const.p-Ascii) ; Return the response to JavaScript as boolean. webui_return_bool(*e.webui_event_t, bool.i) ; Base64 encoding. Use this to safely send text based data to the UI. If it fails it will return NULL. webui_encode.i(*char) ; Base64 decoding. Use this to safely decode received Base64 text from the UI. If it fails it will return NULL. webui_decode.i(char.p-Ascii) ; Safely free a buffer allocated by WebUI, For example when using webui_encode(). webui_free(*ptr) ; -- Interface ----------------------- ; Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind(). The func is (Window, EventType, Element, Data, EventNumber) webui_interface_bind.i(window.i, element.p-Ascii, *func) ; When using `webui_interface_bind()` you may need this function to easily set your callback response. webui_interface_set_response(window.i, event_number.i, response.p-Ascii) ; Check if the app still running or not. This replace webui_wait(). webui_interface_is_app_running.i() ; Get window unique ID webui_interface_get_window_id.i(window.i) ; Get a unique ID. Same ID as `webui_bind()`. Return > 0 if bind exist. webui_interface_get_bind_id.i(window.i, element.p-Ascii) EndImport CompilerIf #PB_Compiler_IsMainFile Enumeration WebUI_Examples #PB_Forum_Example #WEBUI_Example_C_call_c_from_js #WEBUI_Example_C_call_js_from_c #WEBUI_Example_C_minimal #WEBUI_Example_C_serve_a_folder #WEBUI_Example_C_text_editor EndEnumeration #WebUI_Example = #PB_Forum_Example CompilerSelect #WebUI_Example CompilerCase #PB_Forum_Example ProcedureC webui_event_proc(*e.webui_event_t) Debug "webui_event_proc" Debug "Window : " + Str(*e\window) Select *e\event_type Case #WEBUI_EVENT_CALLBACK Debug "Event_Type : callback" Case #WEBUI_EVENT_CONNECTED Debug "Event_Type : connected" Case #WEBUI_EVENT_DISCONNECTED Debug "Event_Type : disconnected" Case #WEBUI_EVENT_MOUSE_CLICK Debug "Event_Type : mouse click" Case #WEBUI_EVENT_MULTI_CONNECTION Debug "Event_Type : multi connection" Case #WEBUI_EVENT_NAVIGATION Debug "Event_Type : navigation" Case #WEBUI_EVENT_UNWANTED_CONNECTION Debug "Event_Type : unwanted connection" EndSelect Debug "Element ID : " + PeekS(*e\element, -1, #PB_Ascii) If *e\data Debug "Data : " + PeekS(*e\data, -1, #PB_Ascii) EndIf Debug "Event_Number: " + Str(*e\event_number) EndProcedure Define.i window window = webui_new_window() webui_bind(window, "button_1", @webui_event_proc()) webui_show(window, "<html><body><button id='button_1'>Click me!</button></body></html>") webui_wait() CompilerCase #WEBUI_Example_C_call_c_from_js ProcedureC my_function_string(*e.webui_event_t) Protected *str ; JavaScript: ; webui_fn('MyID_One', 'Hello'); *str = webui_get_string(*e) Debug "my_function_string: " + PeekS(*str, -1, #PB_Ascii) ; Hello ; Need Multiple Arguments? ; ; WebUI support only one argument. To get multiple arguments ; you can send a JSON string from JavaScript then decode it. ; Example: ; ; my_json = my_json_decoder(str); ; foo = my_json[0]; ; bar = my_json[1]; EndProcedure ProcedureC my_function_integer(*e.webui_event_t) Protected number.q ; JavaScript: ; webui_fn('MyID_Two', 123456789); number = webui_get_int(*e) Debug "my_function_integer: " + Str(number) ; 123456789 EndProcedure ProcedureC my_function_boolean(*e.webui_event_t) Protected status.i ; JavaScript: ; webui_fn('MyID_Three', true) status = webui_get_bool(*e) ; True If status Debug "my_function_boolean: True" Else Debug "my_function_boolean: False" EndIf EndProcedure ProcedureC my_function_with_response(*e.webui_event_t) Protected number.q ; JavaScript: ; const result = webui_fn('MyID_Four', number); number = webui_get_int(*e) number = number * 2 Debug "my_function_with_response: " + Str(number) ; Send back the response To JavaScript webui_return_int(*e, number) EndProcedure Define my_html$, my_window.i my_html$ = "" my_html$ + ~"<html>" my_html$ + ~" <head>" my_html$ + ~" <title>Call C from JavaScript Example</title>" my_html$ + ~" <style>" my_html$ + ~" body {" my_html$ + ~" color: white;" my_html$ + ~" background: #0F2027;" my_html$ + ~" text-align: center;" my_html$ + ~" font-size: 16px;" my_html$ + ~" font-family: sans-serif;" my_html$ + ~" }" my_html$ + ~" </style>" my_html$ + ~" </head>" my_html$ + ~" <body>" my_html$ + ~" <h2>WebUI - Call C from JavaScript Example</h2>" my_html$ + ~" <p>Call C function with argument (<em>See the logs in your terminal</em>)</p>" my_html$ + ~" <br>" my_html$ + ~" <button onclick=\"webui_fn('MyID_One', 'Hello');\">Call my_function_string()</button>" my_html$ + ~" <br>" my_html$ + ~" <br>" my_html$ + ~" <button onclick=\"webui_fn('MyID_Two', 123456789);\">Call my_function_integer()</button>" my_html$ + ~" <br>" my_html$ + ~" <br>" my_html$ + ~" <button onclick=\"webui_fn('MyID_Three', true);\">Call my_function_boolean()</button>" my_html$ + ~" <br>" my_html$ + ~" <br>" my_html$ + ~" <p>Call C function and wait for the response</p>" my_html$ + ~" <br>" my_html$ + ~" <button onclick=\"MyJS();\">Call my_function_with_response()</button>" my_html$ + ~" <br>" my_html$ + ~" <br>" my_html$ + ~" <input type=\"text\" id=\"MyInputID\" value=\"2\">" my_html$ + ~" <script>" my_html$ + ~" function MyJS() {" my_html$ + ~" const MyInput = document.getElementById('MyInputID');" my_html$ + ~" const number = MyInput.value;" my_html$ + ~" webui_fn('MyID_Four', number).then((response) => {" my_html$ + ~" MyInput.value = response;" my_html$ + ~" });" my_html$ + ~" }" my_html$ + ~" </script>" my_html$ + ~" </body>" my_html$ + ~"</html>" ; Create a window my_window = webui_new_window() ; Bind HTML elements With C functions webui_bind(my_window, "MyID_One", @my_function_string()) webui_bind(my_window, "MyID_Two", @my_function_integer()) webui_bind(my_window, "MyID_Three", @my_function_boolean()) webui_bind(my_window, "MyID_Four", @my_function_with_response()) ; Show the window webui_show(my_window, my_html$) ; webui_show_browser(my_window, my_html, Chrome) ; Wait Until all windows get closed webui_wait() CompilerCase #WEBUI_Example_C_call_js_from_c ProcedureC my_function_exit(*e.webui_event_t) webui_exit() EndProcedure ProcedureC my_function_count(*e.webui_event_t) ; This function gets called every time the user clicks on "MyButton1" ; Create a buffer To hold the response Protected *response, Count.i *response = AllocateMemory(64) ; Run JavaScript If Not webui_script(*e\window, "return GetCount();", 0, *response, 64) Debug "JavaScript Error: " + PeekS(*response, -1, #PB_Ascii) ProcedureReturn EndIf Debug PeekS(*response, -1, #PB_Ascii) ; Get the count count = Val(PeekS(*response, -1, #PB_Ascii)) ; Increment count + 1 ; Generate a JavaScript ; Run JavaScript (Quick Way) webui_run(*e\window, "SetCount(" + Str(Count) + ")") EndProcedure Define my_html$, my_window.i my_html$ = ~"<html>" my_html$ + ~" <head>" my_html$ + ~" <title>Call JavaScript from C Example</title>" my_html$ + ~" <style>" my_html$ + ~" body {" my_html$ + ~" color: white;" my_html$ + ~" background: #0F2027;" my_html$ + ~" text-align: center;" my_html$ + ~" font-size: 16px;" my_html$ + ~" font-family: sans-serif;" my_html$ + ~" }" my_html$ + ~" </style>" my_html$ + ~" </head>" my_html$ + ~" <body>" my_html$ + ~" <h2>WebUI - Call JavaScript from C Example</h2>" my_html$ + ~" <br>" my_html$ + ~" <h1 id=\"MyElementID\">Count is ?</h1>" my_html$ + ~" <br>" my_html$ + ~" <br>" my_html$ + ~" <button id=\"MyButton1\">Count</button>" my_html$ + ~" <br>" my_html$ + ~" <br>" my_html$ + ~" <button id=\"MyButton2\">Exit</button>" my_html$ + ~" <script>" my_html$ + ~" var count = 0;" my_html$ + ~" function GetCount() {" my_html$ + ~" return count;" my_html$ + ~" }" my_html$ + ~" function SetCount(number) {" my_html$ + ~" const MyElement = document.getElementById('MyElementID');" my_html$ + ~" MyElement.innerHTML = 'Count is ' + number;" my_html$ + ~" count = number;" my_html$ + ~" }" my_html$ + ~" </script>" my_html$ + ~" </body>" my_html$ + ~"</html>"; ; Create a window my_window = webui_new_window() ; Bind HTML elements With C functions webui_bind(my_window, "MyButton1", @my_function_count()) webui_bind(my_window, "MyButton2", @my_function_exit()) ; Show the window webui_show(my_window, my_html$) ; webui_show_browser(my_window, my_html, Chrome) ; Wait Until all windows get closed webui_wait() CompilerCase #WEBUI_Example_C_minimal Define my_window.i my_window = webui_new_window(); webui_show(my_window, "<html>Hello</html>") webui_wait() CompilerCase #WEBUI_Example_C_serve_a_folder #MyWindow = 1 #MySecondWindow = 2 ProcedureC exit_app(*e.webui_event_t) ; Close all opened windows webui_exit() EndProcedure ProcedureC events(*e.webui_event_t) ; This function gets called every time ; there is an event If *e\event_type = #WEBUI_EVENT_CONNECTED Debug "Connected." ElseIf *e\event_type = #WEBUI_EVENT_DISCONNECTED Debug "Disconnected." ElseIf *e\event_type = #WEBUI_EVENT_MOUSE_CLICK Debug "Click." ElseIf *e\event_type = #WEBUI_EVENT_NAVIGATION Debug "Starting navigation to: " + PeekS(*e\Data, -1, #PB_Ascii) EndIf EndProcedure ProcedureC switch_to_second_page(*e.webui_event_t) ; This function gets called every ; time the user clicks on "SwitchToSecondPage" ; Switch To `/second.html` in the same opened window. webui_show(*e\window, "second.html") EndProcedure ProcedureC show_second_window(*e.webui_event_t) ; This function gets called every ; time the user clicks on "OpenNewWindow" ; Show a new window, And navigate To `/second.html` ; If it's already open, then switch in the same window webui_show(#MySecondWindow, "second.html") EndProcedure ; Create new windows webui_new_window_id(#MyWindow) webui_new_window_id(#MySecondWindow) ; Bind HTML element IDs With a C functions webui_bind(#MyWindow, "SwitchToSecondPage", @switch_to_second_page()) webui_bind(#MyWindow, "OpenNewWindow", @show_second_window()) webui_bind(#MyWindow, "Exit", @exit_app()) webui_bind(#MySecondWindow, "Exit", @exit_app()) ; Bind events webui_bind(#MyWindow, "", @events()) ; Make Deno As the `.ts` And `.js` interpreter webui_set_runtime(#MyWindow, #Deno) ; Show a new window ; webui_set_root_folder(MyWindow, "_MY_PATH_HERE_"); ; webui_show_browser(MyWindow, "index.html", Chrome); webui_show(#MyWindow, "index.html") ; Wait Until all windows get closed webui_wait() CompilerCase #WEBUI_Example_C_text_editor #FULL_FILE_BUFFER_SIZE = (2 * 1024 * 1024) ; 2 MB Global *FULL_FILE_BUFFER *FULL_FILE_BUFFER = AllocateMemory(#FULL_FILE_BUFFER_SIZE, #PB_Memory_NoClear) Global JAVASCRIPT_BUFFER$ Global FILE_PATH$ ProcedureC Close(*e.webui_event_t) Debug "Exit." ; Close all opened windows webui_exit() EndProcedure ProcedureC Save(*e.webui_event_t) Protected file.i Debug "Save." ; Save Data received from the UI file = CreateFile(#PB_Any, FILE_PATH$) If file WriteString(file, PeekS(*e\Data, -1, #PB_Ascii)) CloseFile(file) EndIf EndProcedure ProcedureC Open(*e.webui_event_t) Protected bytes_read.i, file.i, *file_encoded, *path_encoded, *file_path Debug "Open." ; Open a new file ; Open file And save the path To FILE_PATH FILE_PATH$ = OpenFileRequester("Choose a text file", "", "All|*.*", 0) If Len(FILE_PATH$) = 0 ProcedureReturn EndIf ; Read the full content To FULL_FILE_BUFFER file = ReadFile(#PB_Any, FILE_PATH$) If file bytes_read = ReadData(file, *FULL_FILE_BUFFER, Lof(file)) If bytes_read <> Lof(file) CloseFile(file) ProcedureReturn EndIf CloseFile(file) EndIf ; Send file content ; Encode the full content To base64 *file_encoded = webui_encode(*FULL_FILE_BUFFER) If *file_encoded = #Null ProcedureReturn EndIf JAVASCRIPT_BUFFER$ = "addText('" + PeekS(*file_encoded, -1, #PB_Ascii) + "')" webui_run(*e\window, JAVASCRIPT_BUFFER$) ; Send file name ; Encode the file path To base64 *file_path = Ascii(FILE_PATH$) *path_encoded = webui_encode(*file_path) FreeMemory(*file_path) If *path_encoded = #Null webui_free(*file_encoded) ProcedureReturn EndIf JAVASCRIPT_BUFFER$ = "SetFile('" + PeekS(*path_encoded, -1, #PB_Ascii) + "')" webui_run(*e\window, JAVASCRIPT_BUFFER$) ; Clean webui_free(*file_encoded) webui_free(*path_encoded) ; // Add line by line example: ; FILE *file = fopen(FILE_PATH, "r"); ; If(file == NULL) ; Return; ; char line[1024] = {0}; ; While (fgets(line, 1024, file) != NULL) { ; // Line ; char* line_encoded = webui_encode(line); ; If(line_encoded != NULL) { ; char js[1024] = {0}; ; // JS ; sprintf(js, "addLine('%s')", line_encoded); ; // Send ; webui_run(e->window, js); ; // Clean ; webui_free(line_encoded); ; } ; } ; fclose(file); EndProcedure Define MainWindow.i MainWindow = webui_new_window() ; Bind HTML element IDs With a C functions webui_bind(MainWindow, "Open", @Open()) webui_bind(MainWindow, "Save", @Save()) webui_bind(MainWindow, "Close", @Close()) ; Show a new window webui_show(MainWindow, "ui/MainWindow.html") ; Wait Until all windows get closed webui_wait() CompilerEndSelect CompilerEndIf