Notes on using the TWebBrowser component in Delphi 7

I initially used the TWebBrowser component to display help sections in my applications. This approach is quite straightforward—we store standard HTML files in a folder and call them as needed, like WebBrowser.Navigate(HelpDir + ‘index.html’);
The HTML file can include everything you need: images, cross-references, and scripts compatible with Internet Explorer.

Things became much more interesting when I wanted to display database information through it and programmatically modify the displayed content. It turns out this is entirely possible.

Adding CSS styling: CSS insertion follows standard web conventions. For example, you can add styling before the body tag:

<style type="text/css">
table {
  border-collapse: collapse; 
  border-color: #E0E0E0;
  font-size: x-small;
}
td {
  border: 1px solid;
  padding: 2px;
}
</style>

Displaying custom HTML content: To pass any HTML string to TWebBrowser, you can do the following:

var
  Doc: Variant;
begin
  if NOT Assigned(wBrowser.Document) then
    wBrowser.Navigate('about:blank');
  Doc := wBrowser.Document;
  Doc.Clear;
  Doc.Write('Hello <b>World</b>');
  Doc.Close;
end;

Scrolling to the bottom after page load: You can automatically scroll to the end of the page by adding JavaScript just before the closing body tag:

<script>window.scrollTo(0,document.body.scrollHeight);</script>

Executing JavaScript code from Delphi: You can execute arbitrary JavaScript using this approach:

var
  Doc: Variant;
begin
  if NOT Assigned(wBrowser.Document) then
    wBrowser.Navigate('about:blank');
  Doc := wBrowser.Document;
  Doc.parentWindow.execScript('alert("Hello World");', 'JavaScript');
end;

Reading element attributes: You can extract attribute values from HTML elements like this:

function GetElementIdValue(WebBrowser: TWebBrowser; TagName, TagId, TagAttrib: string): string;
var
  Document: IHTMLDocument2;
  Body: IHTMLElement2;
  Tags: IHTMLElementCollection;
  Tag: IHTMLElement;
  I: Integer;
begin
  Result := '';
  if not Supports(WebBrowser.Document, IHTMLDocument2, Document) then
    raise Exception.Create('Invalid HTML document');
  if not Supports(Document.body, IHTMLElement2, Body) then
    raise Exception.Create('Cannot find element');
  Tags := Body.getElementsByTagName(UpperCase(TagName));
  for I := 0 to Pred(Tags.length) do begin
    Tag := Tags.item(I, EmptyParam) as IHTMLElement;
    if Tag.id = TagId then 
      Result := Tag.getAttribute(TagAttrib, 0);
  end;
end;

// Usage example:
Result := GetElementIdValue(WebBrowser1, 'input', 'result', 'value');

Communicating from JavaScript to Delphi: The most interesting part—how to send data or trigger events from JavaScript code back to your Delphi application. You can accomplish this by intercepting link navigation through the OnBeforeNavigate2 event handler. Parse the URL to extract the required information, and use Cancel := true; to prevent actual navigation if needed. It’s best to use a special prefix in the URL to distinguish these calls from regular navigation. Here’s an example handler:

procedure TMyForm.WebBrowserBeforeNavigate2(Sender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);
var
  prefix: string;
  colonPos: Integer;
begin
  colonPos := Pos(':', URL);
  if colonPos > 0 then begin
    prefix := Copy(URL, 1, colonPos - 1);
    if prefix = 'event' then begin
      ShowMessage(Copy(URL, colonPos + 1, Length(URL) - colonPos));
      Cancel := TRUE;
    end;
  end;
end;

The HTML code triggering this event handler might look like:

<input id="testButton" type="button" value="test" />

Note: One limitation of this approach appears when running on Terminal Server environments with strict security policies. Users may encounter an Internet Explorer warning dialog during window initialization, though it’s often possible to add the application to security exceptions.

Leave a Comment

Your email address will not be published. Required fields are marked *