Windows Forms WebControl and Mozilla

on Tuesday, September 04, 2007
It's been a while since I've blogged about the status of Mono's MWF WebControl - I kept adding stuff, then I wanted to settle it down on the tree, and then I went on vacation and ran out of net (but not out of fish.. yum!). So now that I'm fed up with fish and my net is back, let's talk about the latest webcontrol milestone.

The code is split up into three components: the WebBrowser and related classes inside MWF (Mono's winforms implementation); Mono.Mozilla, a new class library on the tree that gets called from MWF; and xulbrowser, a c/c++ library that actually does all the talking to mozilla.

Since a picture is worth a thousand words, the image on the right gives an overview of how these components relate to one another. I didn't want to clutter it too much with arrows, so I didn't put arrows upwards, but of course the communication goes both ways.

Mono.Mozilla is essentially a managed wrapper that exposes an interface to MWF so that the WebBrowser* classes can call methods like Navigate, and register for events coming from mozilla. This interface is the only publicly accessible way to talk to the browser windows, so that things are nice and neat and the wrapper can be free to hide those little pesky details that WebBrowser and friends don't really care about.

Although Mono.Mozilla is, well, Mozilla-oriented, it is neatly divided into two namespaces: Mono.WebBrowser, where the public interface resides, and Mono.Mozilla, where the pinvokes to the unmanaged library reside, so you'll never see the Mono.Mozilla namespace called from inside MWF directly. This has the nice side effect of making it easier (or at least doable) to plug in another browser toolkit in the future if need be.

So what's done and working right now on WebControl? Well, the easiest way to implement an API is to have test applications, so I plucked up the UsingTheWebControl sample from msdn and added it to our roster of winforms test apps. From it's description:
This sample contains three tabs. The first tab demonstrates the use of the WebBrowser control in a simple browser application.

The second tab uses the WebBrowser control as a local HTML document viewer.

The third tab demonstrates the use of the WebBrowser.Document HTMLDocument model, together with the WebBrowser.ObjectForScripting prorperty, to implement Form-to-Browser two-way communication. In this scenario, the WebBrowser control is used to load an HTML document template that is populated with data managed by the Form, as a means of supporting custom printing of application data.

The WebBrowser control on Mono is complete enough for the sample to work with the first two tabs, i.e., loading, refreshing, navigation are all there, as well as focus, activation, mouse and key events so that you can actually browse the web (as opposed to, say, just looking at it... which is a fine thing to do in itself, sure, but probably not that useful in the long run). Https support is already in as well.

This sample is particularly nice in that it hits a lot of not-so-used areas, such as manipulating the Document to load custom data. This, btw, is done on the third tab, which isn't working yet.

The sample is available from the /winforms/webbrowser/UsingWebBrowser directory on svn trunk. To get it working, you will need to use the latest mono on svn.

You will also need to get the /mozembed directory from svn, which contains the xulbrowser library. Just build mono, do the usual autogen.sh, make, make install on /mozembed, make the UsingWebBrowser-port directory, and then go to bin and run the application there.

11 comments:

Markus said...

Great job!

Is the GTK# Mozilla widget just as good? If not, is it at all possible to use (any of) your code to enhance/replace that widget?

Yub said...

wf-apps is only available on non-anonymous svn? Do you plan do release it on anonsvn?

Thanks

Garuma said...

\o/ , Kudos for the hard work shana :) .

andreia|gaita said...

Thanks guys :)

@markus:
The GTK# mozilla widget is just a wrapper of the gtkmozembed widget that comes with mozilla, so it should do everything that gtkmozembed does. gtkmozembed is pretty complete, and since it comes with mozilla, it even uses some private apis that the xulbrowser can't (won't) use. I haven't looked at the gtk# control directly, so I don't know how good it's actually working, though.

@yub:
Ah, darn it, you're right, I keep forgetting that that particular directory isn't replicated. I'll go move it to another publically accessible spot now.

@garuma:
:D

Alexandre Gomes said...

Those are lovely news. In fact the timming is almost perfect as I was starting to digg into this subject:

Can we use this with MWF@Windows, that is, without Mono? I suspect that we would need to hack something to avoid both classes to have the same namespace, but other more important is: do this bindings work at all in Windows?

andreia|gaita said...

@alexandre:

Sure, one of the reasons for not using the gtkmozembed widget to do this was so that we could have a non-gtk dependent control for non-gtk platforms, like windows. I was hoping to not be gtk-dependent on linux as well, but since mozilla is all gtk anyway, that ended up not being doable.

You can build the library on windows with vs 2003 or 2005, there are solutions in there for that. Mono.Mozilla is purely managed, but you can't use .net's webbrowser classes directly, of course, since those bind into IE, so you'll need to hook up to Mono.Mozilla's public interface directly if you want to do that.

You'll need the xulrunner sdk from mozilla to build the library, and you'll need extra files that aren't in the sdk - you can get those in the /mozembed/build directory. Either that, or build and install xulrunner directly from the mozilla sources, which is not a very difficult thing to do, their build system is pretty optimized for windows.

Sandriman said...

Nice one shana. I was just about to wonder why it's been so quiet :)

andreia|gaita said...

@sandriman:

ssshhhh... I'm hunting wabbits... ;)

João said...

OMG!

A portuguese mentioned by Miguel deIcaza!

I love you, marry me please.

Great job, by the way. We should go out for a coffee to discuss open sores stuff. :)

Much love and big hugs,
João

Anonymous said...

I am very glad to see this work being done. There are a lot of .Net WinForms apps that use the WebBrowser control extensively for displaying reports, data, rich text/html editing etc.

I use the webBrowser + MSHTML to get fine grained access to the DOM, hook into callbacks, etc. Will this type of interaction be possible with Mono.Mozila + MWF.WebBrowser?

andreia|gaita said...

@anonymous:

The Mono.Mozilla library will have more DOM access than the winforms api allows (one of the reasons it was done separately), so apps can use it without being limited if they want to.

As for direct mshtml support, that is far, far trickier, and not in the works right now.