在 Awesomium 中,我可以从 JavaScript 调用应用程序方法吗?

15

我在互联网上搜寻了很久,但是可能问错了问题。我有一个使用Awesomium Web控件的C# WinForms应用程序。我能否从加载页面的javascript中调用应用程序中定义的方法?如果可以,如何做到?(提供示例js代码将非常感激)。谢谢!

3个回答

32

具体方法取决于您使用的 Awesomium 版本。在即将发布的 1.7 版本(目前为 1.7 RC3)和之前的版本中,这个过程发生了一些变化。请注意,1.7 版本有一个改进,即当 JS 调用应用程序上的方法时,.NET 方法现在可以返回值。我不认为在 1.7 之前可能实现这一点。

以下是两种方法:

test.html(适用于两个版本)

...
<script type="text/javascript">

    function myMethod() {
        document.write("In myMethod, calling .NET but expecting no return value.<br/>");

        jsobject.callNETNoReturn();
    }

    function myMethodExpectingReturn() {
        document.write("In myMethodExpectingReturn, calling .NET and expecting return value.<br/>");

        var returnVal2 = jsobject.callNETWithReturn("foo");
        document.write("Got value from .NET: " + returnVal2 + "<br/>");
    }

    function myMethodProvidingReturn(whatToReturn) {
        var returnVal =  whatToReturn + "bar";
        document.write("Returning '" + returnVal + "' to .NET.");

        return returnVal;
    }
</script>
...

版本 1.7

Form1.cs

public Form1()
{
    InitializeComponent();

    //webView is an instance of WebControl defined in your form
    webView.DocumentReady += WebViewOnDocumentReady;

    webView.Source = new Uri("test.html");
}

private void WebViewOnDocumentReady(object sender, UrlEventArgs urlEventArgs)
{
    webView.DocumentReady -= WebViewOnDocumentReady;

    JSObject jsobject = webView.CreateGlobalJavascriptObject("jsobject");

    jsobject.Bind("callNETNoReturn", false, JSHandler);
    jsobject.Bind("callNETWithReturn", true, JSHandler);

    webView.ExecuteJavascript("myMethod()");
    webView.ExecuteJavascript("myMethodExpectingReturn()");
    var result = webView.ExecuteJavascriptWithResult("myMethodProvidingReturn('foo')");
    Console.WriteLine(result.ToString());
}

private void JSHandler(object sender, JavascriptMethodEventArgs args)
{
    if (args.MustReturnValue)
    {
        Console.WriteLine("Got method call with return request");
        args.Result = "Returning " + args.Arguments[0];
    }
    else
    {
        Console.WriteLine("Got method call with no return request");
    }
}

版本 1.6

Form.cs

public Form1()
{
    InitializeComponent();

    //webView is an instance of WebControl defined in your form
    webView.DomReady += WebViewOnDomReady;

    webView.Source = new Uri("test.html");
}

private void WebViewOnDomReady(object sender, EventArgs eventArgs)
{
    webView.DomReady -= WebViewOnDomReady;

    webView.CreateObject("jsobject");
    webView.SetObjectCallback("jsobject", "callNETNoReturn", JSHandler);

    webView.ExecuteJavascript("myMethod()");

    var result = webView.ExecuteJavascriptWithResult("myMethodProvidingReturn('foo')");
    Console.WriteLine(result.ToString());
}

private void JSHandler(object sender, JSCallbackEventArgs args)
{
    Console.WriteLine("Got method call with no return request");
}

绑定(bind)现已被弃用。我们能否更新这个答案以反映较新的版本? - Dagrooms
1
@Dagrooms,我不再使用Awesomium。 我已经切换到一个开源的替代品,CEFSharp(github.com/cefsharp/CefSharp)。首先,与Awesomium不同,它可以免费进行商业使用。更重要的是,Awesomium的当前版本(1.7.5)运行在Chromium 18上,并且在HTML5测试中得分较低(在html5test.com的555个测试中仅有335个)。CEFSharp运行在Chromium 39上,在HTML5测试中得分更高(在html5test.com的555个测试中有470个)。为了那些仍在使用Awesomium的人着想,请随意编辑我的回答或发布您自己的回答。 - HotN

2
在C ++中:(.NET绑定可能类似)
定义回调类:
class TestListener : public Awesomium::WebViewListener {
public:
    virtual void onCallback(
        Awesomium::WebView* caller,
        const std::wstring& objectName,
        const std::wstring& callbackName,
        const Awesomium::JSArguments& args
    ) {
        if (objectName == L"myApi" && callbackName == L"doMagicFoo") {
            cout << "callback called with " << args.size() << " args\n";
        }
    }

    //...implement all the other pure virtual functions...  
};

然后在设置您的 WebView 时:

TestListener bob;
webView->setListener(&bob);
webView->createObject(L"myApi");
webView->setObjectCallback(L"myApi", L"doMagicFoo");

然后在您的HTML/JS中:

<button onclick="myApi.doMagicFoo('super', 45)">do native call</button>

0

针对较新版本

从 JavaScript 调用:

webControl1.LoadingFrameComplete += LoadingFramecompleted;

public void LoadingFramecompleted(object sender, FrameEventArgs e){
    //after loading complete create global object
    JSObject obj = webControl1.CreateGlobalJavascriptObject("jsobject");
    obj.Bind(myMethod);
}

private JSValue myMethod(object sender, JavascriptMethodEventArgs e)
{
    MessageBox.Show("hello world");
    return "My response";
}

JavaScript 内部

jsobject.myMethod(); //myMethod is the method name defined in c#

调用JavaScript

webControl1.ExecuteJavascript("SayHello()");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接