2013-10-09 35 views
3

我有一个webbrowser使用webkit运行在单声道c#中。我想允许页面在浏览器中调用一个函数,然后浏览器根据传递的参数执行操作。我似乎无法做到。我如何让一个js函数使用webkit与c#交互?

HTML页面是下一个

<html> 
<head> 
<title>ola</title> 
</head> 
<body> 
<button onclick="window.external.Test('called from script code');">test</button> 
</body> 
</html> 

的webkit.cs

using System; 
using System.Collections; 
using System.Runtime.InteropServices; 
using Gtk; 
using GLib; 

namespace WebKit 
{ 
class DOMDocument : GLib.Object 
{ 
    public DOMDocument (IntPtr raw) : base (raw) {} 

    [DllImport ("webkit-1.0")] 
    private static extern IntPtr webkit_dom_document_get_elements_by_tag_name (IntPtr raw, IntPtr str1ng); 

    public DOMNodeList get_elements_by_tag_name (string tag) 
    { 
    IntPtr intPtr = Marshaller.StringToPtrGStrdup (tag); 
    IntPtr result = webkit_dom_document_get_elements_by_tag_name(base.Handle, intPtr); 
    Marshaller.Free (intPtr); 
    return new DOMNodeList(result); 
    } 
} 

// http://www.opensource.apple.com/source/WebKit/WebKit-7533.16/gtk/tests/testdomdocument.c 
class DOMNodeList: GLib.Object, IEnumerable 
{ 
    public DOMNodeList (IntPtr raw) : base (raw) {} 

    [DllImport ("webkit-1.0")] 
    private static extern IntPtr webkit_dom_node_list_item (IntPtr raw, int element); 

    [DllImport ("webkit-1.0")] 
    private static extern int webkit_dom_node_list_get_length (IntPtr raw); 

    public IEnumerator GetEnumerator() 
    { 
    for (int i = 0; i < webkit_dom_node_list_get_length(base.Handle); i++) { 
    yield return new DOMNode(webkit_dom_node_list_item(base.Handle, i)); 
    } 
    } 
} 

class DOMNode : GLib.Object 
{ 
    public DOMNode (IntPtr raw) : base (raw) {} 


} 

class DOMElement : GLib.Object 
{ 
    public DOMElement (IntPtr raw) : base (raw) {} 


} 

class DOMHTMLElement : GLib.Object 
{ 
    public DOMHTMLElement (IntPtr raw) : base (raw) {} 

    [DllImport ("webkit-1.0")] 
    private static extern IntPtr webkit_dom_html_element_get_inner_text(IntPtr raw); 

    public string get_inner_text() 
    { 
    IntPtr data = webkit_dom_html_element_get_inner_text(base.Handle); 
    return Marshaller.PtrToStringGFree(data); 
    } 
} 

class ExtendedWebSettings : WebKit.WebSettings { 
    public void g_object_set(string name, GLib.Value value) { 
    SetProperty(name, value); 
    } 

    public GLib.Value g_object_get(string name) { 
    return GetProperty(name); 
    } 
} 

class ExtendedWebView : WebKit.WebView { 
    [DllImport ("webkit-1.0")] 
    private static extern IntPtr webkit_web_view_get_dom_document (IntPtr raw); 

    public DOMDocument get_dom_document() 
    { 
    return new DOMDocument(webkit_web_view_get_dom_document(base.Handle)); 
    } 

    public event CreateWebViewHandler CreateWebView 
    { 
    add 
    { 
    Signal signal = Signal.Lookup (this, "create-web-view", typeof(CreateWebViewArgs)); 
    signal.AddDelegate (value); 
    } 
    remove 
    { 
    Signal signal = Signal.Lookup (this, "create-web-view", typeof(CreateWebViewArgs)); 
    signal.RemoveDelegate (value); 
    } 
    } 

    public event WebViewReadyHandler WebViewReady 
    { 
    add 
    { 
    Signal signal = Signal.Lookup (this, "web-view-ready", typeof(WebViewReadyArgs)); 
    signal.AddDelegate (value); 
    } 
    remove 
    { 
    Signal signal = Signal.Lookup (this, "web-view-ready", typeof(WebViewReadyArgs)); 
    signal.RemoveDelegate (value); 
    } 
    } 

    public event NewWindowPolicyDecisionRequestedHandler NewWindowPolicyDecisionRequested 
    { 
    add 
    { 
    Signal signal = Signal.Lookup (this, "new-window-policy-decision-requested", typeof(NewWindowPolicyDecisionRequestedArgs)); 
    signal.AddDelegate (value); 
    } 
    remove 
    { 
    Signal signal = Signal.Lookup (this, "new-window-policy-decision-requested", typeof(NewWindowPolicyDecisionRequestedArgs)); 
    signal.RemoveDelegate (value); 
    } 
    } 

    [DefaultSignalHandler (Type = typeof(WebView), ConnectionMethod = "OverrideCreateWebView")] 
    protected virtual WebView OnCreateWebView (WebFrame frame) 
    { 
    ExtendedWebView webView = new ExtendedWebView(); 
    Value empty = Value.Empty; 
    ValueArray valueArray = new ValueArray (2u); 
    Value[] array = new Value[2]; 
    array [0] = new Value (this); 
    valueArray.Append (array [0]); 
    array [1] = new Value (frame); 
    valueArray.Append (array [1]); 
    GLib.Object.g_signal_chain_from_overridden (valueArray.ArrayPtr, ref empty); 
    Value[] array2 = array; 
    for (int i = 0; i < array2.Length; i++) 
    { 
    Value value = array2 [i]; 
    value.Dispose(); 
    } 
    return webView; 
    } 

    [DefaultSignalHandler (Type = typeof(WebView), ConnectionMethod = "OverrideNewWindowPolicyDecisionRequested")] 
    protected virtual int OnNewWindowPolicyDecisionRequested (WebFrame frame, NetworkRequest request, WebNavigationAction navigation_action, WebPolicyDecision policy_decision) 
    { 
    Value val = new Value (GType.Int); 
    ValueArray valueArray = new ValueArray (3u); 
    Value[] array = new Value[5]; 
    array [0] = new Value (this); 
    valueArray.Append (array [0]); 
    array [1] = new Value (frame); 
    valueArray.Append (array [1]); 
    array [2] = new Value (request); 
    valueArray.Append (array [2]); 
    array [3] = new Value (navigation_action); 
    valueArray.Append (array [3]); 
    array [4] = new Value (policy_decision); 
    valueArray.Append (array [4]); 
    GLib.Object.g_signal_chain_from_overridden (valueArray.ArrayPtr, ref val); 
    Value[] array2 = array; 
    for (int i = 0; i < array2.Length; i++) 
    { 
    Value value = array2 [i]; 
    value.Dispose(); 
    } 
    int result = (int)val; 
    val.Dispose(); 
    return result; 
    } 

    [DefaultSignalHandler (Type = typeof(WebView), ConnectionMethod = "OverrideWebViewReady")] 
    protected virtual bool OnWebViewReady (WebFrame frame) 
    { 
    Value empty = Value.Empty; 
    ValueArray valueArray = new ValueArray (2u); 
    Value[] array = new Value[2]; 
    array [0] = new Value (this); 
    valueArray.Append (array [0]); 
    array [1] = new Value (frame); 
    valueArray.Append (array [1]); 
    GLib.Object.g_signal_chain_from_overridden (valueArray.ArrayPtr, ref empty); 
    Value[] array2 = array; 
    for (int i = 0; i < array2.Length; i++) 
    { 
    Value value = array2 [i]; 
    value.Dispose(); 
    } 
    return true; 
    } 
} 

public delegate void WebViewReadyHandler (object o, WebViewReadyArgs args); 

public class WebViewReadyArgs : SignalArgs 
{ 
    // 
    // Properties 
    // 

    public WebFrame Frame 
    { 
    get 
    { 
    return (WebFrame)base.Args [0]; 
    } 
    } 
} 

public delegate void CreateWebViewHandler (object o, CreateWebViewArgs args); 

public class CreateWebViewArgs : SignalArgs 
{ 
    // 
    // Properties 
    // 

    public WebFrame Frame 
    { 
    get 
    { 
    return (WebFrame)base.Args [0]; 
    } 
    } 
} 

public delegate void NewWindowPolicyDecisionRequestedHandler (object o, NewWindowPolicyDecisionRequestedArgs args); 

public class NewWindowPolicyDecisionRequestedArgs : SignalArgs 
{ 
    // 
    // Properties 
    // 

    public WebFrame Frame 
    { 
    get 
    { 
    return (WebFrame)base.Args [0]; 
    } 
    } 

    public NetworkRequest Request 
    { 
    get 
    { 
    return (NetworkRequest)base.Args [1]; 
    } 
    } 

    public WebNavigationAction NavigationAction 
    { 
    get 
    { 
    return (WebNavigationAction)base.Args [2]; 
    } 
    } 

    public WebPolicyDecision PolicyDecision 
    { 
    get 
    { 
    return (WebPolicyDecision)base.Args [3]; 
    } 
    } 
} 

} 

和Main.cs

using System; 
using Gtk; 
using GLib; 
using WebKit; 
using System.Timers; 
//using Notifications; 
using System.Text.RegularExpressions; 

public partial class MainWindow: Gtk.Window 
{ 
    private Timer notifications = new Timer(2000); 
    private ExtendedWebView webView; 
    private bool recent_notification = false; 

    public MainWindow (string url): base (Gtk.WindowType.Toplevel) 
    { 
    Build(); 
    url ="http://127.0.0.1/csharp/"; 
    webView = new ExtendedWebView(); 
    ExtendedWebSettings settings = new ExtendedWebSettings(); 
    settings.g_object_set ("user-agent", new GLib.Value ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0")); 
    settings.g_object_set ("enable-spell-checking", new GLib.Value (true)); 
    webView.TitleChanged += HandleTitleChanged; 
    webView.Settings = settings; 
    webView.NewWindowPolicyDecisionRequested += HandleNewWindowPolicyDecisionRequested; 
    webView.CreateWebView += HandleCreateWebView; 
    webView.Open(url); 
    webView.LoadFinished += new LoadFinishedHandler (OnLoadFinished); 
    VBox vbox1 = new VBox(); 
    vbox1.PackStart(webView); 
    this.Add(vbox1); 
    this.ShowAll(); 
    } 

    private void OnLoadFinished (object o, LoadFinishedArgs args) 
    { 
    String testVar = "[ { \"id\" : \"4578\" },{ \"id\" : \"4579\" }]"; 
    Console.WriteLine("Executei isto por aqui...."); 
    webView.ExecuteScript("scriptTeste(" + testVar + ");"); 
    Console.WriteLine("Executei isto por aqui...."); 
    } 


    void HandleCreateWebView (object o, CreateWebViewArgs args) 
    { 
    Window info = new Window(""); 
    info.DefaultWidth = 1000; 
    info.DefaultHeight = 700; 
    VBox vbox2 = new VBox(); 
    WebView child = new WebView(); 
    child.NavigationRequested += HandleNavigationRequested1; 
    vbox2.PackStart(child); 
    info.Add (vbox2); 
    info.ShowAll(); 
    args.RetVal = child; 
    } 

    void HandleNavigationRequested1 (object o, NavigationRequestedArgs args) 
    { 
    // Destroy the window if it was already opened in the browser 
    if (args.Request.Uri.Contains ("&URL=")) { 
     WebView self = (WebView)o; 
     VBox container = (VBox)self.Parent; 
     Window parent = (Window)container.Parent; 
     parent.Destroy(); 
     args.RetVal = 1; 
    } 
    } 

    void HandleNewWindowPolicyDecisionRequested (object o, NewWindowPolicyDecisionRequestedArgs args) 
    { 
    string URL = System.Web.HttpUtility.UrlDecode(Regex.Split(args.Request.Uri, "&URL=")[1]); 
    System.Diagnostics.Process.Start(URL); 
    } 

    void HandleElapsed (object sender, ElapsedEventArgs e) 
    { 
    if (recent_notification) { 
     notifications.Interval = 5000; 
     recent_notification = false; 
    } 
    /* if (!recent_notification && webView.SearchText ("Reminders", true, true, true)) { 
     Notification notify = new Notification ("Outlook Notification", ""); 
     notify.Urgency = Urgency.Normal; 
     notify.Show(); 
     recent_notification = true; 
     notifications.Interval = 30000; 

    }*/ 
    } 

    void HandleTitleChanged (object o, TitleChangedArgs args) 
    { 
    this.Title = args.Title; 
    } 


    protected void OnDeleteEvent (object sender, DeleteEventArgs a) 
    { 
    Application.Quit(); 
    a.RetVal = true; 
    } 
} 

如果你想在C#项目正是在这里https://github.com/dmulder/owa_browse/

提前致谢。

回答

2

您需要从旧派生出新的web视图类,并重写:

public class MyDerived: WebView 
{ 
... 

    public const string COM_COMMAND_INIT = "http://mypresetcommand/?"; 
    protected override void OnResourceRequestStarting(WebKit.WebFrame web_frame, WebKit.WebResource web_resource, WebKit.NetworkRequest request, WebKit.NetworkResponse response) 
    { 
     // check if this is a command 
     if (request.Uri.ToLower().StartsWith(COM_COMMAND_INIT)) 
     { 
      // this is a com command. Responding with responce. 
      string cmnd = web_resource.Uri.Substring(COM_COMMAND_INIT.Length); 
      // HANDLE COMMAND HERE. 
      return; 
     } 
     base.OnResourceRequestStarting(web_frame, web_resource, request, response); 
    } 
} 

一旦你做到了这一点,你可以简单地做一个AJAX调用C#应用程序从网页内。替换“myresetcommand /?”与自己的不可缓解的网址。您可以通过WebView中的ExecuteScript进行响应。

相关问题