Page 3 of 3

Re: WebUI wrapper

Posted: Fri Jan 12, 2024 10:37 pm
by swhite
Hi

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 */
My attempt to convert this to PB.

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

Re: WebUI wrapper

Posted: Fri Jan 12, 2024 11:42 pm
by idle
you need to link to the import lib for the DLL, not the static lib

Code: Select all

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    ImportC "webui-2-x64.lib"
    ;ImportC "webui-2-static-x64.lib"
    CompilerCase #PB_OS_Linux
get a copy of the Dll
open a cmd window in the folder and type polib webui-2-x64.dll (or what ever its named)
and polib will generate the import lib

Re: WebUI wrapper

Posted: Sat Jan 13, 2024 10:13 am
by infratec
Hm ...

with PB 5.73 and compilation of PJSIP, I ran into similar problems (security ...)
You can disable this at compile time in the VS compiler settings.

Re: WebUI wrapper

Posted: Sat Jan 13, 2024 7:07 pm
by swhite
Hi

I changed the code to

ImportC webui-2.dll

and now I get the following error

---------------------------
PureBasic - Linker error
---------------------------
error: Invalid machine type in object 'webui-2.dll'.

idle wrote: Fri Jan 12, 2024 11:42 pm you need to link to the import lib for the DLL, not the static lib

Code: Select all

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    ImportC "webui-2-x64.lib"
    ;ImportC "webui-2-static-x64.lib"
    CompilerCase #PB_OS_Linux
get a copy of the Dll
open a cmd window in the folder and type polib webui-2-x64.dll (or what ever its named)
and polib will generate the import lib

Re: WebUI wrapper

Posted: Sat Jan 13, 2024 8:40 pm
by idle
You need to build an import library for the dll. Look at the code snippet it's not importing the dll.
Use polink found in the pb compilers folder and simply type polink with the path to the dll and it will generate the import library.
Like
Polink d :\dir\some.dll
Will spit out some.lib which is the import lib to the named dll. You importc some.lib not some.dll

Re: WebUI wrapper

Posted: Sun Jan 14, 2024 3:35 am
by swhite
Thanks I missed the part about generating the file. It works perfectly now.

Re: WebUI wrapper

Posted: Sun Jan 14, 2024 3:50 am
by idle
swhite wrote: Sun Jan 14, 2024 3:35 am Thanks I missed the part about generating the file. It works perfectly now.
Great. :D

Re: WebUI wrapper

Posted: Tue Jan 16, 2024 6:57 pm
by himogec152
Post a PR on GitHub when you are done with updating so others can use it :)

Re: WebUI wrapper

Posted: Mon Feb 05, 2024 11:14 pm
by swhite
Hi

I tried this code with the new 2.42. version and it does not work. The webpage is displayed but Purebasic ends after 30 seconds. So it appears that webui_wait() function does not detect the Browser even though it is running.

I tried it with PB 6.03 64bit and PB 5.73 64bit. The previous 2.3 version did work.

Simon

infratec wrote: Sun Jun 11, 2023 10:45 pm Working version:

Code: Select all

; /*
;   WebUI Library 2.3.0
;   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

Re: WebUI wrapper

Posted: Tue Feb 06, 2024 1:37 pm
by infratec
Ups...

yes, I can agree that 2.4.x is not working.

Re: WebUI wrapper

Posted: Sun Feb 18, 2024 9:50 pm
by infratec
2.4.2 works.

Tested with PB6.10b6 x64 on Win10 x64

WebUI.zip

Open WebUI.pbi and select a test.

The main trick is: You always need to insert a <script> tag, else (firefox) did not work with the PB code.
Look at the html code in the PB example or the minimal example.
Without the <script> tag the page cloese after 30s timeout and the event callback is not called.

Re: WebUI wrapper

Posted: Mon Feb 19, 2024 5:34 pm
by swhite
Thank-you for pointing that out. It does work once I add the webui.js script.

Simon

Re: WebUI wrapper

Posted: Tue Feb 27, 2024 12:08 am
by skinkairewalker
In macOs Sonoma 14.3.1 I'm having a problem, in all the examples, even after compiled, the icon keeps jumping... why does this happen?

screenshot 1: https://prnt.sc/94WnQeihjCij
screenshot 2: https://prnt.sc/I32cmwGrTvLA

Re: WebUI wrapper

Posted: Tue Mar 19, 2024 4:25 pm
by himogec152
skinkairewalker wrote: Tue Feb 27, 2024 12:08 am In macOs Sonoma 14.3.1 I'm having a problem, in all the examples, even after compiled, the icon keeps jumping... why does this happen?

screenshot 1: https://prnt.sc/94WnQeihjCij
screenshot 2: https://prnt.sc/I32cmwGrTvLA
I guess macOS icon has a non fixed issue:
https://github.com/webui-dev/webui/issues/278