Extending the TWebBrowser external object to execute Delphi code: how to access my form components?
<p>I'm following the <a href="http://www.delphidabbler.com/articles?article=22&amp;part=1" rel="nofollow">How to call Delphi code from scripts running in a TWebBrowser</a> DelphiDabbler tutorial (by Peter Johnson) to allow Delphi to listen to <code>TWebBrowser</code> JavaScript events.</p>

<p>This works up to the point where I see my Delphi procedures getting called. However, from in there I need to update some form labels, and I see no way to access my form from those procedures.<br />
The DelphiDabbler example code nicely circumvents 'direct form access' by <a href="http://delphidabbler.com/articles?article=22&amp;part=5" rel="nofollow">creating</a> <code>THintAction.Create(nil);</code> which will do it's thing:</p>

<blockquote>
  <p>This let's us decouple our external object implementation quite nicely from the program's form</p>
</blockquote>

<p>But I want to access my form! Data to be passed are integers and strings.<br />
I could use PostMessage() and WM_COPYDATA messages, but these would still need the form handle. And isn't there a 'direct' route to the form?</p>

<p>Relevant code:</p>

<pre><code>type
   TWebBrowserExternal = class(TAutoIntfObject, IWebBrowserExternal, IDispatch)
   protected
      procedure SetVanLabel(const ACaption: WideString); safecall;  // My 3 procedures that are called...
      procedure SetNaarLabel(const AValue: WideString); safecall;   // ... declared in the type library.
      procedure SetDistanceLabel(AValue: Integer); safecall;
   public
      constructor Create;
      destructor Destroy; override;
   end;

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

constructor TExternalContainer.Create(const HostedBrowser: TWebBrowser);
begin
   inherited Create(HostedBrowser);
   fExternalObj := TWebBrowserExternal.Create;
end;
</code></pre>

<p>The form has a <code>property FContainer: TExternalContainer;</code>, in the FormCreate I do <code>fContainer := TExternalContainer.Create(WebBrowser);</code> (parameter is the design time <code>TWebBrowser</code>), so the 
<code>TExternalContainer.fExternalObj</code> is assigned to that.</p>

<p><strong>Question</strong>:</p>

<pre><code>  procedure TWebBrowserExternal.SetDistanceLabel(AValue: Integer);
  begin
     // **From here, how do I send AValue to a label caption on my form?**
  end;
</code></pre>

<p>I must confess that interfaces are not my forte ;-)</p>

<p>[Added:] Note: My forms are all created dynamically, there is no TForm instance in the current unit.</p>