Adding javascript hook to windows form with web browser

Add-in Express™ Support Service
That's what is more important than anything else

Adding javascript hook to windows form with web browser
 
George Stavrev




Posts: 17
Joined: 2011-06-30
Hi All,

I am trying to create a panel that will open after a user clicks on a toolbar button. This is common functionality in Firefox and Chrome. My approach has been to create a windows form with a web browser in it. I am able to set the url for it to be a local "panel.html" file that I have included in my project.

The problem I am running into is the ability to add a hook to "bhoModule", so that my javascript in panel.html can access add in functions. I have a Document Complete listener right now that adds the bhoModule and it works well for new tabs and new windows, but not in the panel that i am trying to create. Is there something I am missing? Basically I am trying to communicate back and forth with content scripts with c# code.

Thank you,

-George
Posted 03 Sep, 2013 20:25:08 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi George,

IE add-ons are not loaded by the WebBrowser control. So you need to initialize the 'bhoModule' field in the 'DocumentComplete' event handler of the WebBrowser control.
Posted 04 Sep, 2013 10:47:01 Top
George Stavrev




Posts: 17
Joined: 2011-06-30
Thanks Sergey,

I have tried a few things to get this working, but no luck. I got passed the point of injecting custom scripts, but adding the hook for javascript to talk to c# is not working.

I started out by adding a different listener to the windows form web browser:

this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;

I obtain the document:

var d = webBrowser.Document.DomDocument as mshtml.HTMLDocument;

and try to add bhoModule:

object scriptEngine = d.Script;
scriptEngine.GetType().InvokeMember("bhoModule", BindingFlags.SetProperty, null, scriptEngine, new object[] { this });

The above gives me an error with Name not found. (Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME)) I suspected that it might be because bhoModule is not defined, but I placed it in my html file and also in a few different scripts but still no luck.

I was able to get passed it by using a different method I found online:

dynamic window = d.parentWindow;
var windowEx = (IExpando)window;
PropertyInfo p = windowEx.AddProperty("bhoModule");
p.SetValue(windowEx, this,null);

It doesn't produce any errors and it works for the normal browser tabs, but I am still not able to get access to bhoModule from the scripts in my webBrowser control.

I have this javascript that I add to the target pages, and it never triggers when in the web browser control.


window .bhoModule = null

checkReady = () ->
    if !window .bhoModule
        window .s etTimeout(checkReady,1000)
        console.log "no bhoModule"
    else
        console.log "found bhoModule"
        a lert("found bhoModule!")

checkReady()


Any further help would be appreciated. Perhaps I am missing something?
Posted 04 Sep, 2013 20:08:06 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi George,

object scriptEngine = d.Script;
scriptEngine.GetType().InvokeMember("bhoModule", BindingFlags.SetProperty, null, scriptEngine, new object[] { this });


Is 'this' an instance of the form or the iemodule?
Posted 05 Sep, 2013 07:29:08 Top
George Stavrev




Posts: 17
Joined: 2011-06-30
Hi Sergey,

In the example code, it is instance of the form. I also tried setting it to this.webBrowser (the web browser controller), and also an instance of the IE module in the product as such (my c# could be a little rusty):

IEModule module = new IEModule()
scriptEngine.GetType().InvokeMember("bhoModule", BindingFlags.SetProperty, null, scriptEngine, new object[] { module });

I also tried setting it to null. I have a duplicate copy of the c# function I am trying to set in the windows form class.

Thanks,

-George
Posted 05 Sep, 2013 13:08:33 Top
George Stavrev




Posts: 17
Joined: 2011-06-30
A quick update:

I was able to get it working with my alternative hook:


IEModule module = new IEModule();
var d = webBrowser.Document.DomDocument as mshtml.HTMLDocument; 

dynamic window = d.parentWindow;
var windowEx = (IExpando)window;
PropertyInfo p = windowEx.AddProperty("bhoModule");
p.SetValue(windowEx, module, null);


To get it working, I had to switch the page that was being loaded to not be on my local machine. I believe this is due to some security issues in IE. Previously I would get the message that an unsafe page is trying to load content. The remote page is working! (But still not with the other method). See screenshot for details. User added an image

I would still like to have it from local, perhaps there are other options?

I set it up to open local files like so:

System.Uri uri = new System.Uri(this.GetType().Assembly.CodeBase);
string addonDir = Path.GetDirectoryName(uri.LocalPath);
string scriptDir = Path.Combine(addonDir, "Static/page.html");
this.webBrowser.Url = new System.Uri(scriptDir, System.UriKind.Absolute);
Posted 05 Sep, 2013 18:44:10 Top
Sergey Grischenko


Add-in Express team


Posts: 7233
Joined: 2004-07-05
Hi George,

Thank you for sharing your solution. To remove the warning you can use the local IIS server and open your files locally. Or you can also change the security settings of IE in order to disable the warning.
I would advise you to pass the active instance of the iemodule to the form and then you can use it in the 'SetValue' method.
Posted 06 Sep, 2013 07:43:01 Top
George Stavrev




Posts: 17
Joined: 2011-06-30
Thanks for your help Sergey. I am going to pass the instance of iemodule so that all functions are in the same place.
Posted 11 Sep, 2013 13:13:16 Top