LightWindow – an excellent LightBox implementation

LightWindow is perhaps one of the best of the LightBox-type implementations around, supporting almost every media type currently in use.

screenshot

I found a few gotchas, but these were very minor:

  1. needs XHTML pages with correct DOCTYPE for it work in IE
  2. Might need to edit lightwindow.js to correct the hardcoded paths to the skin elements
  3. Replace the first line with the second in the HTML HEAD:

You can grab the files here: http://www.stickmanlabs.com/lightwindow/lightwindow.zip

Calling Javascript from C#

Call JavaScript from C# code, passing parameters and returning results.

I came across a need to call JavaScript methods on HTML code inside a web page from a C# WinForms application. How could that language gap be bridged?

It turns out that Type.InvokeMember() does the trick when using a [Internet Explorer] WebBrowser control to load a web page.

using mshtml;
...
private AxSHDocVw.AxWebBrowser axWebBrowser1;
...
///
 /// Retrieves a reference to the HTML element containing a DIV. /// JavaScript methods are implemented on this element itself. /// 

/// A reference to the HTML element holding the JavaScript methods
private HTMLDivElementClass GetContainer()
{
 HTMLDivElementClass container = null;
 IHTMLDocument2 doc = axWebBrowser1.Document as IHTMLDocument2;

 if (null != doc)
 {
  foreach (IHTMLElement element in doc.all)
  {
   if (element.id == "My_Container")
   {
    container = element as HTMLDivElementClass;
    break;
   }
  }
 }

 return container;
}

///
 /// Gets the text from the container /// 

/// A string containing the text of the container
private string GetText()
{
 string result = null;
 HTMLDivElementClass div = GetContainer();
 if (null != div)
 {
  Type type = div.GetType();
  result = (string) type.InvokeMember(
    "GetText",
    BindingFlags.InvokeMethod,
    null,
    div,
    null);
 }   

 return result;
}

The HTML page loaded in the WebBrowser control has a DIV element with an id of “My_Container”, attached to which is a method called GetText(), which returns some arbitrary text.

Having acquired a reference to the DIV on which the JavaScript method is declared (using GetContainer()), the JavaScript method is called using the InvokeMember() method of the Type class instance; the return value is cast to a string.

Discussion

There is every reason why this should NOT work, but the implementers of the WebBrowser control decided that JavaScript methods living within the DOM should be accessible as first class object members at runtime (in this case, via IDispatch). Nice!

Result

C# code can call arbitrary JavaScript within an HTML page! The only limitation is that the return types of the JavaScript methods can be only simple types (even DateTime is too complex).

Oracle on AJAX

AJAX has received a lot of hyperbole over the last year or so, with some people renaming the web to “Web 2.0” [groan] in its honour. It allows websites to present a richer, more interactive interface, breaking the “click Next” sequential, disconnected web paradigm.

Personally, I believe that – in moderation – a bit of AJAX can be a good thing (think: Goole Maps) but that there is a danger of really breaking the normal web programming model. Google has thought about this, and have some useful guidelines for AJAX applications, along with a nice AJAX toolkit, which allows you to build applications in Java which are then compiled down to JavaScript. Anything which auto-generates compliant and working JavaScript, and therefore saves me from writing the stuff by hand, has to be A Good Thing. Writing JavaScript makes me feel unclean 😉

AJAX is here to stay, though, at least for the next couple of years. Oracle have put together a series of articles on AJAX from a JSF perspective, which explain the basics of AJAX rather nicely.