«« Site Rescued »»

While the site is still going to move from its current host, a new site will now take its place. More Info.

The new site may have less content, but the core will now remain. And it will now play nicely with phones! Keep an eye on the DelphiDabbler Blog for news.

How to call Delphi code from scripts running in a TWebBrowser (part 3 of 6)

Registering the external object with TWebBrowser

Registering the external object with TWebBrowser

Having implemented the COM object that extends the external object how do we tell the web browser about it?

Further reading
For detailed information about creating a container for TWebBrowser and implementing IOleClientSite and IDocHostUIHandler please see "How to customise the TWebBrowser user interface".

The answer is by creating a container object that hosts the web browser control and implements the IDocHostUIHandler interface. Any web browser control container object must also implement IOleClientSite. IDocHostUIHandler has a GetExternal method. In our implementation of this method we will pass a reference to our custom external object to the browser.

There are numerous other methods of IDocHostUIHandler that we have to implement, but we can get away with stubbing them out. In a previous article (see the "Further reading" box) I discussed IDocHostUIHandler in detail and presented a do nothing implementation – TNulWBContainer. I won't repeat that presentation here, so please check out the earlier article if you need to review how this is done.

Doing all the hard work in TNulWBContainer means that our implementation of IDocHostUIHandler and IOleClientSite, which we will call TExternalContainer, can be quite simple if we descend it from TNulWBContainer. Listing 4 has the declaration of the class, while Listing 5 shows its implementation.

  TExternalContainer = class(TNulWBContainer,
    IDocHostUIHandler, IOleClientSite)
    fExternalObj: IDispatch;  // external object implementation
    { Re-implemented IDocHostUIHandler method }
    function GetExternal(out ppDispatch: IDispatch): HResult; stdcall;
    constructor Create(const HostedBrowser: TWebBrowser);
constructor TExternalContainer.Create(
  const HostedBrowser: TWebBrowser);
  inherited Create(HostedBrowser);
  fExternalObj := TMyExternal.Create;

function TExternalContainer.GetExternal(
  out ppDispatch: IDispatch): HResult;
  ppDispatch := fExternalObj;
  Result := S_OK; // indicates we've provided script

Notice that we create an instance of our external object extension in the constructor and store it in a field of type IDispatch. We then implement GetExternal to pass back a reference to the external object in ppDispatch and return S_OK to indicate we have provided the object.

We pass a reference to the web browser control we are hosting to the constructor. This reference is simply passed on to the inherited constructor where it is recorded and notified that our object is its container. See the implementation of TNulWBContainer.Create for details of how this is done.

We have now completed the code necessary to register the external object with the web browser. In the next section we look at how to call into the external object from JavaScript.