EvoCorp Home    Delphi::Advance

 

 

   

 

Browser Helper Object Stub

Browser Helper Objects represent one of the easiest channels for boosting your objects into the same process space as Internet Explorer, providing your code with the ability to hook in to browser events, components and modules.

Whilst developing your own BHO objects is not terribly hard, it can be a tedious process if you've never created one before. Once you're able to get your object loaded in Internet Explorer, the only piece of information you're given is an IUnknown interface that represents a "site" - the place where Internet Explorer has decided you belong within its framework. Where do you go from here, where is the web browser interface and how do I connect to events generated by the web browser?

Fortunately the BhoShell unit implements a BHO that once loaded, is able to find the web browser associated with your "site" and connects to it for any events that it might generate. This means that any inherited BHO's you create from BhoShell automatically know about the browser and can automatically connect to its events, such as "BeforeNavigate2". Not only that, but BhoShell also contains the class factory required to automate registration of your object as a BHO.

So, what are the core components of BhoShell?

  TBrowserHelperObject   TBrowserHelperObject represents the base class for all Browser Helper Objects. It contains the mechanics to connect to and disconnect from the associated IWebBrowser2 interface when installed and uninstalled.
 
When you create your own BHO's from BhoShell, this is the class that you inherit from.
 
  Application   Application represents a TBrowserHelperApplication object, created when your library is loaded and released when your library is closed.
 
Application enables each TBrowserHelperObject (or child) object to identify and therefore communicate with any other TBrowserHelperObject object that has been instantiated within the current Internet Explorer process.
 
  TBrowserHelperFactory   TBrowserHelperFactory is the BHO registration factory that you must use when registering your COM object as the default COM registration factories do not contain the facilities to register BHO objects.
 
Please see the sample below for more information on using TBrowserHelperFactory.

Important notes when developing a BHO

Internet Explorer and Windows Explorer both load BHO's.

Generally speaking this is not important as most people don't design their BHO's for Windows Explorer; as such if your BHO is loaded by Windows Explorer it simply chews up memory space. Accordingly BhoShell will, by default determine whether or not the host is Internet Explorer and if not, will not install the application or any browser helper objects.

Another important thing to know when developing BHO's is that if you choose "File|New|Window" from within Internet Explorer, a new browser helper object will be created for that window but because it's created from within the same process, your library will not be loaded a second time. Therefore I don't recommend the use of global variables specific to each BHO object instance, as you might well have multiple BHO's trying to access the one variable simultaneously.

Example

unit MyBhoUnit;
interface
uses
  SysUtils, Windows, ActiveX, ComObj, BhoShell;

const
  // CLSID_MyBhoObject represents the class ID by which I want
  // my BHO to be known. You can create your own CLSID by pressing
  // Ctrl-Shift-G.
  SCLSID_MyBhoObject = '{F89CEB6F-335E-43EC-BD6B-7F72D7801158}';
  CLSID_MyBhoObject: TCLSID = SCLSID_MyBhoObject;

type
  TMyBhoObject = class(TBrowserHelperObject)
  private
    procedure BeforeNavigate(Sender: TObject; const pDisp: IDispatch;
      var URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
      var Cancel: WordBool);
    procedure NavigateComplete(Sender: TObject;
      const pDisp: IDispatch; var URL: OleVariant);
  protected
    procedure DoEventsConnected; override;
    procedure DoEventsDisconnected; override;
  end;

implementation
uses
  ComServ;

{ TMyBhoObject }

procedure TMyBhoObject.BeforeNavigate(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);
var sUrl: string;
begin
  sUrl := Url;
  MessageBox(WebBrowser.HWND, pChar('Navigating to'#13#10 + sUrl), '',
    MB_OK or MB_SYSTEMMODAL or MB_ICONEXCLAMATION);
end;

procedure TMyBhoObject.DoEventsConnected;
begin
  inherited;
  // DoEventsConnected is called after the event
  // handler for the web browser window has been
  // connected to the web browser.
 
  // We want to personally handle the before navigate
  // and navigate complete events (in this case just
  // to show a message box, but more serious uses might
  // be to log or prevent specific Internet usage).
  Events.BeforeNavigate2 := BeforeNavigate;
  Events.NavigateComplete2 := NavigateComplete;
end;

procedure TMyBhoObject.DoEventsDisconnected;
begin
  inherited;
  // Actually, we don't use this method, but if we needed to
  // do something in response to the event handler being
  // disconnected then this is where we'd do it :)
end;

procedure TMyBhoObject.NavigateComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var sUrl: string;
begin
  sUrl := Url;
  MessageBox(WebBrowser.HWND, pChar('Navigating to'#13#10 + sUrl +
    #13#10'complete...'), '', MB_OK or MB_SYSTEMMODAL or MB_ICONEXCLAMATION);
end;

initialization
  // We use the default TBrowserHelperFactory class provided
  // by BhoShell for the registration of our BHO classes. If
  // we were to use the default TComObjectFactory instead of
  // TBrowserHelperFactory then TMyBhoObject would be registered
  // successfully as a COM object, but wouldn't be registered as
  // a browser helper object (i.e., ignored by Internet Explorer).
  TBrowserHelperFactory.Create(ComServer, TMyBhoObject,
    CLSID_MyBhoObject, '', '', ciMultiInstance, tmApartment);

end.
 

Requirements

Download Code

BhoShell.pas can be downloaded here.

Microsoft Internet Explorer is a registered trademark of Microsoft Corporation.