IE6, IE7, IE8 add-on development in VB.NET, C#:
tabbing, windowing and threading, instancing

Add-in Express™
for Internet Explorer® and Microsoft® .net

Add-in Express Home > Add-in Express for Internet Explorer > Online Guide > IE add-on: tabs, windows, threads, instances and messages

How Your Add-on Loads into IE

How to create IE add-ons - Flash video

Shims

Internet Explorer is unmanaged while an Add-in Express based add-on is a managed class library. Therefore, there must be some software located between IE and your add-on; the software, or the shim, follows the rules for IE add-ons and, at appropriate moment, loads the .NET Framework and starts the add-on.

Add-in Express Loader

An Add-in Express based IE add-on is supplied with a special precompiled shim - Add-in Express Loader. The loader supplied as 32-bit and 64-bit DLLs (adxloader.dll, adxloader64.dll) is designed to fulfill the following basic tasks: it loads the .NET Framework, creates a unique AppDomain for the add-on, and loads the add-on into the AppDomain. Advanced options are provided to the developer by the manifest file (adxloader.dll.manifest) that may have the following look:

<?xml version="1.0" encoding="utf-8"?>
<configuration></configuration>
<a name=" MyIEAddon1, PublicKeyToken=f9f39773da5c568a"></a>
<loadersettings privileges="administrator" generatelogfile="true"
  shadowcopyenabled="true" configfilename=" MyIEAddon1.dll.config"></loadersettings>
<logfilelocation></logfilelocation>C:\MyLog.txt</logFileLocation>
 </loaderSettings>
</configuration>

The loader allows generating a log file containing useful information about errors on the add-in loading stage. The file is located here: My Documents\Add-in Express\adxloader.log. Also, you can disable the Shadow Copy feature of the Add-in Express Loader, which is enabled by default (see Deploying – Shadow Copy?). The privileges attribute accepts the "user" string indicating that the installer generated by an Add-in Express based setup project can be run with non-administrator privileges. The only user-installable IE extension type is IE Bar. All other project types require using the "administrator" string for this attribute.

When an Add-in Express based project is being built, the loader files are copied from the Loader folder of your project to the output directory of the setup project(s).

How your IE Add-on works

IE Module basics

The version of IE is available in IEVersion. IEObj provides the IE application COM object. For the currently loaded mshtml.HTMLDocument, see HTMLDocument (HTMLDocumentObj). Note that COM objects (and all classes defined in mshtml are COM classes) can't cross the process boundaries; so you need to create a method returning information provided by a COM object rather than using the COM object directly in your code.

You use Bars and Toolbars properties to get a collection of <Item> objects (ADXIEBarItem or ADXIEToolBarItem); every <Item> object provides access to an <Obj> property (BarObj or ToolBarObj), which returns an appropriate Add-in Express class type (ADXIEBar or ADXIEToolbar).

Tabbing

The IsTabbedBrowsingEnabled property of the IE module informs you whether tabbing is enabled or not. When the user opens a tab, the OnTabCreated and then OnTabActivated events are raised. At appropriate moments OnTabMoved and OnTabClosed occur. You can activate any given tab programmatically only if ADXIEModule.IsQuickTabsEnabled is true; this means that the Quick Tabs feature in IE7 and IE8 is enabled. To activate a tab, you call TabActivate; this causes OnTabChanging and OnTabChanged events to fire. In IE 6, you use the OnConnect event of the module to get to know when a window is opened and use the HTML Events component to handle the OnActivate event of the Window HTML element.

Note that all tab-related methods work asynchronously. The tab-related methods are TabActivate, TabFirst, TabLast, TabNext and TabPrevious methods that activate the current, first, last, next and previous tabs respectively. Another tab-related method is TabClose. It closes the current tab (also asynchronously).

Windowing and threading

Internet Explorer opens its windows in separate threads. Once an IE window is opened, IE creates an instance of your module, toolbar, or IE bar; the instance fires the OnConnect event; the instance fires the OnDisconnect event when the current tab (window in IE6) is closing. You can identify an instance of the IE module by the ID of the thread that opens that window. Note that ADXIEBar and ADXIEToolbar provide the Module property that you can cast to your module type. Below you will find how different Internet Explorer versions open their windows.

  • IE6 opens IE windows in several threads running within several processes.
  • IE7 may open several main windows in the same or in different processes if tabbing is enabled and depending on the way you open IE windows; each main window contains tab windows running in threads of their own.
  • IE8 may open several main windows. Each of them runs in several threads of the same process and contains tab windows that run in threads of their own if tabbing is enabled and depending on the way you open IE windows as well on the operating system that you use.

And here are some useful properties:

  • Process ID - ADXIEModule.ProcessID
  • Thread ID - ADXIEModule.ThreadID
  • IE main window - ADXIEModule.MainWindowHandle, ADXIEBar.MainWindowHandle, ADXIEToolbar.MainWindowHandle
  • IE tab window - ADXIEModule.ParentHandle, ADXIEBar.ParentHandle, ADXIEToolbar.ParentHandle; in IE6, this property returns the same value as MainWindowHandle
  • Tabbing is enabled - ADXIEModule.IsTabbedBrowsingEnabled
  • IE Module - ADXIEBar.Module, ADXIEToolbar.Module

Instancing

In whatever way a tab (or window in IE 6) is opened, this creates a new instance of the add-on (ADXIEModule). This also creates new instances of toolbars, IE bars, main menu items, and context menu items; all of them work in the same thread. The only thing that works in another thread or even process (IE 8) is the commands that you add on the Command Bar toolbar (IE 7 and IE 8 only); an instance of the commands is created for every main IE window (ADXIEModule.MainWindowHandle).

So, your IE module is created for every IE tab. The total number of module instances is available in the GetModuleCount property. You can access any module instance using either GetModuleByIndex or GetModuleByThread; make sure that you supply these methods with proper values provided by GetModuleIndex and ThreadID.

You can call any public property or method of any module instance even if it runs in other process. This is implemented via Remoting. For that reason, such calls are synchronous. Mshtml-related classes cannot cross process boundaries; you need to create a method that returns the needed  information instead.


'...
Public Class MyIEBar1
 Inherits AddinExpress.IE.ADXIEBar

 Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
 Friend WithEvents Button1 As System.Windows.Forms.Button
'...

 Private Sub Button1_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles Button1.Click
 'System.Diagnostics.Debugger.Launch()
 Me.ListBox1.Items.Clear()
 Dim theModule As MyIEAddon1.IEModule = _
 CType(Me.Module, MyIEAddon1.IEModule)
 For i As Integer = 0 To theModule.GetModuleCount - 1
 Dim aModule As MyIEAddon1.IEModule = _
 CType(theModule.GetModuleByIndex(i), MyIEAddon1.IEModule)
 Me.ListBox1.Items.Add(aModule.GetURL())
 Next
 End Sub
End Class

'...
Public Class IEModule
 Inherits AddinExpress.IE.ADXIEModule
'...
 Friend Function GetURL() As String
 Return Me.HTMLDocument.url
 End Function
End Class

Messaging

The SendMessage, SendMessageToInstance and SendMessageToAll methods provide an asynchronous way to invoke the functionality of the current, specified or of all instances of a module, toolbar, or Explorer bar. This is implemented by sending a custom window message to a hidden add-on, toolbar, or IE bar window via the Win32 API. For that reason SendMessageToInstance provides the nativeHandle parameter, a proper value for which is obtained using the NativeWindowHandle property (available for ADXIEModule, ADXIEBar, and ADXIEToolbar). You can also use the FindNativeWindows method provided by ADXIEModule, ADXIEBar, and ADXIEToolbar. This method allows finding hidden windows that belong to the same main window or process in IE. On the receiver side, you filter incoming messages (there will be a huge lot of non-related window messages!) and invoke the functionality required in the OnSendMessage event.

Note. You may need to use SendMessage (it sends messages to the current IE module) because some things aren't possible to do in a given event.

The code below demonstrates using SendMessageToAll to keep the same state of a checkbox through all instances of an IE bar.


Friend Class MessageConstants
 'window messages
 Public Shared ReadOnly WM_USER As Integer = 1024
 'custom
 Public Shared ReadOnly WM_CHECKED As Integer = WM_USER + 10000
 Public Shared ReadOnly WM_UNCHECKED As Integer = WM_USER + 10001
End Class

'...
Public Class MyIEBar1
 Inherits AddinExpress.IE.ADXIEBar

 Friend WithEvents CheckBox1 As System.Windows.Forms.CheckBox

 Private IsProgrammaticChange As Boolean = False
'...
 Private Sub CheckBox1_CheckedChanged( _
 ByVal sender As System.Object, ByVal e As System.EventArgs) _
 Handles CheckBox1.CheckedChanged

 'System.Diagnostics.Debugger.Launch()
 If IsProgrammaticChange Then Exit Sub
 'do my stuff
 If Me.CheckBox1.Checked Then
 Me.SendMessageToAll(MessageConstants.WM_CHECKED, _
 IntPtr.Zero, IntPtr.Zero)
 Else
 Me.SendMessageToAll(MessageConstants.WM_UNCHECKED, _
 IntPtr.Zero, IntPtr.Zero)
 End If
 End Sub

 Private Sub MyIEBar1_OnSendMessage( _
 ByVal e As AddinExpress.IE.ADXIESendMessageEventArgs) _
 Handles MyBase.OnSendMessage

 If e.Message = MessageConstants.WM_CHECKED Then
 IsProgrammaticChange = True
 Me.CheckBox1.Checked = True
 IsProgrammaticChange = False
 ElseIf e.Message = MessageConstants.WM_UNCHECKED Then
 IsProgrammaticChange = True
 Me.CheckBox1.Checked = False
 IsProgrammaticChange = False
 End If
 End Sub
End Class

Building Explorer bars and context menus <<

>> Tips on Internet Explorer add-ons

Back to Add-in Express for Internet Explorer homepage

Have any questions? Ask us right now!