Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
WebUI4CSharp - first steps in LA
#1
Another way to use HTML, CSS and JS in your UIs.

   

You can find WebUi4CSharp here.
 From that page:
Quote:WebUI4CSharp is a WebUI wrapper, which allows you to use any web browser as a GUI, with C# in the backend and HTML5 in the frontend.
WebUI allows you to link your console, WinForms or WPF application with a web app that runs in a web browser installed in the operating system. Originally WebUI was created to have all the UI code in the web browser and the rest of the code in your hidden C# application. However, you can also decide to have a visible C# application communicating with a HTML5 app. You can get web browser events in your desktop application, call C# functions from JS, call JS functions from C# code, execute JavaScript, etc.
WebUI4CSharp can be used console, WinForms or WPF applications for Windows.
WebUI doesn't embed a web browser in your application. It's used as a bridge between a desktop application and the web browser running an HTML5 app.
Features
  • Fully Independent (No need for any third-party runtimes)
  • Lightweight & Small memory footprint
  • Fast binary communication protocol between WebUI and the browser (Instead of JSON)
  • Multi-platform & Multi-Browser
  • Using private profile for safety
  • Original library written in Pure C
  • XML documentation.
  • Help file.

I wanted to try this out in LA several months ago, but kept running into snags with window positioning and sizing. Today I discovered that if Firefox is open on my system my code won't work properly, but if it's closed it will. There are no doubt ways around this, and there are 27(!) demo programs for the lib.

Here are a couple of files you can experiment with (main file and class file). I feel my code quality is poor at the moment, probably with unneeded usings, but it runs.

I would run it from the LA Editor if I were you, I haven't tried to make it a .exe program yet.

You should a WebUI window open, which has buttons bound to some C# functions in the 'events' file. Click a button and see the function result displayed in the 'Output' tab of the LA Editor. You should see something like this:
Quote:my_function_integer: There are 4 arguments in this event
my_function_integer 1: 123
my_function_integer 2: 456
my_function_integer 3: 789
my_function_integer 4: 12345.6789
my_function_boolean 1: True
my_function_boolean 2: False
my_function_raw_binary: 414243
my_function_with_response: 2 * 2 = 4
my_function_with_response: 4 * 2 = 8
my_function_with_response: 8 * 2 = 16

1) console_call_csharp_from_js.cs
 
Code:
Copy      Help
// script "console_call_csharp_from_js.cs"
/*/ nuget wui\WebUI4CSharp; nuget wui\WebUI4CSharp.Natives; c console_call_csharp_from_js_events.cs; /*/
using WebUI4CSharp;
using System.Windows.Forms;
using System.Threading;

script.setup(trayIcon: true, sleepExit: true);


string my_html = """
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="UTF-8">
            <script src="webui.js"></script>
            <title>Call C# from JavaScript Example</title>
            <style>
               body {
                    font-family: 'Arial', sans-serif;
                    color: white;
                    background: linear-gradient(to right, #507d91, #1c596f, #022737);
                    text-align: center;
                    font-size: 18px;
                }
                button, input {
                    padding: 10px;
                    margin: 10px;
                    border-radius: 3px;
                    border: 1px solid #ccc;
                    box-shadow: 0 3px 5px rgba(0,0,0,0.1);
                    transition: 0.2s;
                }
                button {
                    background: #3498db;
                    color: #fff;
                    cursor: pointer;
                    font-size: 16px;
                }
                h1 { text-shadow: -7px 10px 7px rgb(67 57 57 / 76%); }
                button:hover { background: #c9913d; }" +
                input:focus { outline: none; border-color: #3498db; }
            </style>
          </head>
          <body>
            <h1>WebUI - Call C# from JavaScript</h1>
            <p>Call C# functions with arguments (<em>See the logs in your terminal</em>)</p>
            <button onclick="my_function_string('Hello', 'World');">Call my_function_string()</button>
            <br>
            <button onclick="my_function_integer(123, 456, 789, 12345.6789);">Call my_function_integer()</button>
            <br>
            <button onclick="my_function_boolean(true, false);">Call my_function_boolean()</button>
            <br>
            <button onclick="my_function_raw_binary(new Uint8Array([0x41,0x42,0x43]), big_arr);">
             Call my_function_raw_binary()</button>
            <br>
            <p>Call a C# function that returns a response</p>
            <button onclick="MyJS();">Call my_function_with_response()</button>
            <div>Double: <input type="text" id="MyInputID" value="2"></div>
            <script>
              const arr_size = 512 * 1000;
              const big_arr = new Uint8Array(arr_size);
              big_arr[0] = 0xA1;
              big_arr[arr_size - 1] = 0xA2;
              function MyJS() {
                const MyInput = document.getElementById('MyInputID');
                const number = MyInput.value;
                my_function_with_response(number, 2).then((response) => {
                    MyInput.value = response;
                });
              }
            </script>
          </body>
        </html>
    """
;
        

WebUIWindow window = new WebUIWindow();
window.Bind("my_function_string", WebUI_Events.my_function_string);
window.Bind("my_function_integer", WebUI_Events.my_function_integer);
window.Bind("my_function_boolean", WebUI_Events.my_function_boolean);
window.Bind("my_function_with_response", WebUI_Events.my_function_with_response);
window.Bind("my_function_raw_binary", WebUI_Events.my_function_raw_binary);
window.Show(my_html);
WebUI.Wait();
WebUI.Clean();




2) console_call_csharp_from_js_events.cs
 
Code:
Copy      Help
// class "console_call_csharp_from_js_events.cs"
/*/ nuget wui\WebUI4CSharp; nuget wui\WebUI4CSharp.Natives; /*/
using WebUI4CSharp;
using System.Windows.Forms;
using System.Threading;

/// <summary>
///
UI Events
/// </summary>
public static class WebUI_Events {
    /// <summary>
    ///
string function
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_string(ref webui_event_t e) {
        // JavaScript:
        // my_function_string('Hello', 'World`);

        
        WebUIEvent lEvent = new WebUIEvent(e);
#nullable enable
        string? str_1 = lEvent.GetString();
        string? str_2 = lEvent.GetStringAt(1);
#nullable disable    
        Console.WriteLine("my_function_string 1: {0}", str_1); // Hello
        Console.WriteLine("my_function_string 2: {0}", str_2); // World
    }
    
    /// <summary>
    ///
integer function
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_integer(ref webui_event_t e) {
        // JavaScript:
        // my_function_integer(123, 456, 789, 12345.6789);

        
        WebUIEvent lEvent = new WebUIEvent(e);
        
        UIntPtr count = lEvent.GetCount();
        Console.WriteLine("my_function_integer: There are {0} arguments in this event", count); // 4
        
        long number_1 = lEvent.GetInt();
        long number_2 = lEvent.GetIntAt(1);
        long number_3 = lEvent.GetIntAt(2);
        double float_1 = lEvent.GetFloatAt(3);
        
        Console.WriteLine("my_function_integer 1: {0}", number_1); // 123
        Console.WriteLine("my_function_integer 2: {0}", number_2); // 456
        Console.WriteLine("my_function_integer 3: {0}", number_3); // 789
        Console.WriteLine("my_function_integer 4: {0}", float_1); // 12345.6789
    }
    /// <summary>
    ///
boolean
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_boolean(ref webui_event_t e) {
        // JavaScript:
        // my_function_boolean(true, false);

        
        WebUIEvent lEvent = new WebUIEvent(e);
        bool status_1 = lEvent.GetBool();
        bool status_2 = lEvent.GetBoolAt(1);
        
        Console.WriteLine("my_function_boolean 1: {0}", status_1 ? "True" : "False"); // True
        Console.WriteLine("my_function_boolean 2: {0}", status_2 ? "True" : "False"); // False
    }
    /// <summary>
    ///
raw binary function
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_raw_binary(ref webui_event_t e) {
        // JavaScript:
        // my_function_raw_binary(new Uint8Array([0x41]), new Uint8Array([0x42, 0x43]));

        
        WebUIEvent lEvent = new WebUIEvent(e);
#nullable enable
        MemoryStream? stream = lEvent.GetStream();
#nullable disable
        if (stream != null) {
            string hexstring = Convert.ToHexString(stream.ToArray());
            Console.WriteLine("my_function_raw_binary: " + hexstring);
        }
    }

    /// <summary>
    ///
function with response
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_with_response(ref webui_event_t e) {
        // JavaScript:
        // my_function_with_response(number, 2).then(...)

        
        WebUIEvent lEvent = new WebUIEvent(e);
        long number = lEvent.GetInt();
        long times = lEvent.GetIntAt(1);
        
        long res = number * times;
        Console.WriteLine("my_function_with_response: {0} * {1} = {2}", number, times, res);
        
        // Send back the response to JavaScript
        lEvent.ReturnInt(res);
    }
}
#2
Call JS from C#.

   

I haven't used raw C# strings for this code, I've just modified the HTML from the file in the Demos repository. Introducing SetSize() and SetPosition()

console_call_js_from_csharp:
 
Code:
Copy      Help
// script "console_call_js_from_csharp.cs"
/*/ nuget wui\WebUI4CSharp; nuget wui\WebUI4CSharp.Natives; c console_call_js_from_csharp_events.cs; /*/
using WebUI4CSharp;
using System.Windows.Forms;
using System.Threading;

script.setup(trayIcon: true, sleepExit: true);

string my_html = "<!DOCTYPE html>" +
                          "<html>" +
                          "  <head>" +
                          "    <meta charset=\"UTF-8\">" +
                          "    <script src=\"webui.js\"></script>" +
                          "    <title>Call JavaScript from C# Example</title>" +
                          "    <style>" +
                          "       body {" +
                          "            font-family: 'Arial', sans-serif;" +
                          "            color: white;" +
                          "            background: linear-gradient(to right, #507d91, #1c596f, #022737);" +
                          "            text-align: center;" +
                          "            font-size: 18px;" +
                          "        }" +
                          "        button, input {" +
                          "            padding: 10px;" +
                          "            margin: 10px;" +
                          "            border-radius: 3px;" +
                          "            border: 1px solid #ccc;" +
                          "            box-shadow: 0 3px 5px rgba(0,0,0,0.1);" +
                          "            transition: 0.2s;" +
                          "        }" +
                          "        button {" +
                          "            background: #3498db;" +
                          "            color: #fff; " +
                          "            cursor: pointer;" +
                          "            font-size: 16px;" +
                          "        }" +
                          "        h1 { text-shadow: -7px 10px 7px rgb(67 57 57 / 76%); }" +
                          "        button:hover { background: #c9913d; }" +
                          "        input:focus { outline: none; border-color: #3498db; }" +
                          "    </style>" +
                          "  </head>" +
                          "  <body>" +
                          "    <h1>WebUI - Call JavaScript from C#</h1>" +
                          "    <br>" +
                          "    <h1 id=\"count\">0</h1>" +
                          "    <br>" +
                          "    <button OnClick=\"my_function_count();\">Manual Count</button>" +
                          "    <br>" +
                          "    <button id=\"MyTest\" OnClick=\"AutoTest();\">Auto Count (Every 500ms)</button>" +
                          "    <br>" +
                          "    <button OnClick=\"my_function_exit();\">Exit</button>" +
                          "    <script>" +
                          "      let count = 0;" +
                          "      function GetCount() {" +
                          "        return count;" +
                          "      }" +
                          "      function SetCount(number) {" +
                          "        document.getElementById('count').innerHTML = number;" +
                          "        count = number;" +
                          "      }" +
                          "      function AutoTest(number) {" +
                          "        setInterval(function(){ my_function_count(); }, 500);" +
                          "      }" +
                          "    </script>" +
                          "  </body>" +
                          "</html>";

WebUIWindow window = new WebUIWindow();
window.Bind("my_function_count", WebUI_Events.my_function_count);
window.Bind("my_function_exit", WebUI_Events.my_function_exit);
window.SetSize(350, 550);
window.Show(my_html);
window.SetPosition(100, 100);
wait.ms(2000);
window.SetPosition(900, 100);
wait.ms(2000);
window.SetPosition(100, 100);
WebUI.Wait();
WebUI.Clean();

console_call_js_from_csharp_events:
 
Code:
Copy      Help
// class "console_call_js_from_csharp_events.cs"
/*/ nuget wui\WebUI4CSharp; nuget wui\WebUI4CSharp.Natives;  /*/

using WebUI4CSharp;
/// <summary>
///
UI Events
/// </summary>
public static class WebUI_Events
{
    /// <summary>
    ///
Exit function
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_exit(ref webui_event_t e)
    {

        // Close all opened windows
        WebUI.Exit();
    }


    /// <summary>
    ///
count function
    /// </summary>
    ///
<param name="e"></param>
    public static void my_function_count(ref webui_event_t e)
    {

        // This function gets called every time the user clicks on "my_function_count"
        WebUIEvent lEvent = new WebUIEvent(e);
#nullable enable
        WebUIWindow? window = lEvent.Window;
#nullable disable
        if (window != null)
        {

            string response;

            if (!window.Script("return GetCount();", 0, out response, 64))
            {

                if (!window.IsShown())
                {

                    Console.WriteLine("Window closed.");
                }

                else
                {
                    Console.WriteLine("JavaScript Error: %s", response);
                }

                return;
            }


            // Get the count
            int count = Convert.ToInt32(response);

            // Increment
            count++;

            // Generate a JavaScript
            string js = $"SetCount({count});";

            // Run JavaScript
            window.Run(js);
        }
    }
}
#3
Thanks much mate!
#4
[attachment=1372]Here's an example with Semantic UI. The class file needed is also included.
webui-forum.cs:
 
Code:
Copy      Help
// script "webui-forum.cs"
/*/ nuget wui\WebUI4CSharp; nuget wui\WebUI4CSharp.Natives; c csharp_from_js_events.cs; /*/
using WebUI4CSharp;
using System.Windows.Forms;
using System.Threading;

script.setup(trayIcon: true, sleepExit: true);

var js_script = $"alert('Hi LA!')";
string my_html = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="webui.js"></script>    
    <title>LA Forum - WebUI Example</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
    <style>
        body {
            padding: 0;
            margin: 0;
            display: flex;
            height: 100vh;
        }

        header {
            display: flex; position: fixed;
            color: white; background: #2185d0;
            user-select: none; width: 100vw;
        }
        header > * { padding: 5px; }
        header > span { flex-grow: 1; -webkit-app-region: drag; }
        header > div {
            cursor: pointer; font-family: Webdings;
            padding-left: 1em; padding-right: 1em;
        }
        header > div:hover { background: #1678c2; }
        header > div:last-child:hover { background: #dc3545; }
        header > div:nth-last-child(2) { display: none; }
        body.ahk-maximized header > div:nth-last-child(2) { display: block; }
        body.ahk-maximized header > div:nth-last-child(3) { display: none; }

        .sidebar {
            width: 100px;
            padding-top: 40px;
            position: fixed;
            height: 100%;
        }
        .sidebar > .ui.menu { width: 100%; }

        .content {
            margin-left: 100px;
            padding: 20px;
            width: calc(100% - 100px);
            padding-top: 50px;
        }

    </style>
</head>
<body>
    <header>
        <span>Semantic UI</span>
        <div onclick="ahk.gui.Minimize()">0</div>
        <div onclick="ahk.gui.Maximize()">1</div>
        <div onclick="ahk.gui.Restore()">2</div>
        <div onclick="ahk.gui.Hide()">r</div>
    </header>
    
    <nav class="sidebar">
        <div class="ui secondary vertical pointing menu">
            <a class="item active" data-tab="buttons">Buttons</a>
            <a class="item" data-tab="forms">Forms</a>
            <a class="item" data-tab="modals">Modals</a>
            <a class="item" data-tab="tables">Tables</a>
        </div>
    </nav>
    
    <div class="content">
        <div class="ui tab active" data-tab="buttons">
            <h3 class="ui header">Buttons</h3>
            <button onclick="button1()" class="ui button">Please do something when I'm clicked!</button>
            <button onclick="alert('You clicked Primary')" class="ui primary button">Primary</button>
            <button onclick="alert('You clicked Secondary')" class="ui secondary button">Secondary</button>
    </div>
        
    <div class="ui tab" data-tab="forms">
            <h3 class="ui header">Forms</h3>
            <form class="ui form">
                <div class="field">
                    <label>Name</label>
                    <input type="text" placeholder="Enter name">
                </div>
                <button class="ui button" type="submit">Submit</button>
            </form>
    </div>
        
        <div class="ui tab" data-tab="modals">
            <h3 class="ui header">Modals</h3>
            <button class="ui button" id="show-modal">Show Modal</button>
             <div class="ui modal" style="width: 300px !important; margin-left: auto !important; margin-right: auto !important;"> <!-- Added style here -->
                <div class="header" style="text-align:center">Modal Title</div>
                <div
                    class="content"
                    style="
                    height:100px;
                    max-width:250px;
                    text-align:left;
                    font-family:Lucida Handwriting;
                    font-size:12px;
                    margin: auto;
                    border: 3px solid #73AD21;"
                >
                <p>This is a simple modal window.</p>
                <p>Style as you see fit.</p>
                </div>
                <div class="actions">
                    <button class="ui button" id="hide-modal">Close</button>
                </div>
            </div>
        </div>
        
        <div class="ui tab" data-tab="tables">
            <h3 class="ui header">Tables</h3>
            <table class="ui celled table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Age</th>
                        <th>Job</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>John</td>
                        <td>30</td>
                        <td>Developer</td>
                    </tr>
                    <tr>
                        <td>Jane</td>
                        <td>28</td>
                        <td>Designer</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

    <script>
        $('.menu .item').tab();
        $('#show-modal').click(function() {
            $('.ui.modal').modal('show');
        });
        $('#hide-modal').click(function() {
        $('.ui.modal').modal('hide');
        });
    </script>
</body>
</html>
"""
;

WebUIWindow window = new WebUIWindow();
window.Run(js_script);
window.Bind("button1", WebUI_Events.button1);
window.SetSize(800, 400);
window.Show(my_html);
window.SetPosition(100, 100);

WebUI.Wait();
WebUI.Clean();

csharp_from_js_events.cs (class file):
 
Code:
Copy      Help
/*/ nuget wui\WebUI4CSharp; nuget wui\WebUI4CSharp.Natives; /*/
using WebUI4CSharp;
using System.Windows.Forms;
using System.Threading;

/// <summary>
///
Events for WebUI
/// </summary>
public static class WebUI_Events
{
    
    /// <summary>
    ///
button1 test for forum post on webui
    /// </summary>
    ///
<param name="e"></param>
    public static void button1(ref webui_event_t e) {
        // JavaScript:
        // my_function_with_response(number, 2).then(...)

        
        WebUIEvent lEvent = new WebUIEvent(e);
        Console.WriteLine("LA did this");
        dialog.show("ZZZZ ...", title: "Sleeping");
        
        // Send back the response to JavaScript
        //lEvent.ReturnInt(res);

    }
    
}


Attached Files Image(s)
   


Forum Jump:


Users browsing this thread: 1 Guest(s)