Internet Explorer Toolbar

February 16, 2008

Introduction

Last weekend somebody asked me to write an add-in / add-on for Internet Explorer. I decided to create a new toolbar for him which contained the necessary functions he would need. Not having done this before from Visual Studio I quickly came to the realisation that there is no clear-cut way of doing this quickly. Luckily Google came to the rescue and provided a vast array of articles related to this topic. Unfortunately there are a few obstacles to overcome in order to whip up a toolbar for IE under Windows Vista and none of the articles I found contained all of the information. In this article I’ll show you the steps you’ll need to take in order to create your very own toolbar.

When looking (read as Googling) for a solution on how to develop a toolbar for Internet Explorer in Visual Studio the search results were dominiated by C++ and ATL. Now my language of choice is C#, fiddling around with C++ and ATL first wasn’t desirable.

The Active Template Library (ATL) is a set of template-based C++ classes that simplify the programming of COM objects. You could rely on the Microsoft Foundation Classes (MFC) for this too, but you can view the ATL as a lightweight alternative for quickly creating COM objects.

In order to create a toolbar for Internet Explorer you must use a band object. There are three categories of band objects, namely explorer bars, desk bands and tool bands. A band object is a COM object which implements a bunch of interfaces such as IDeskBand, IPersistStream, IObjectWithSite and so on. This COM object is contained by IE or the shell.

So far for this short introduction on band objects and COM programming. Since this isn’t the scope of this article I won’t elaborate on it. If you want to learn more about this particular part I suggest the Band Objects: A beginners tutorial from scratch article. You just need to know that the toolbar you are going to create is basically a COM object called a band object.

The interfaces which Explorer requires that a band object needs to implement aren’t readily available in one of the .NET type libraries. You have to convert them from C++ to one of the .NET languages. Luckily somebody has already done the “dirty work”. The Band Objects article by Pavel Zolnikov on CodeProject gives you everything you need. I suggest that you read this article first before continuing. You can download the necessary code from CodeProject which contains a base class aptly called BandObject.

If you want to skip the article on CodeProject then just download the source code and build a Release version of the BandObjectLib project and register the resulting BandObjectLib Dll assembly in the Global Assembly Cache (GAC).

This assembly and the assemblies containing your IE add-ons must be registered in the GAC. In order for the .NET framework to find the assemblies which implement a COM object they must be located in the GAC or in the same directory as the client application. Be sure to provide the assembly with a strong name (key pair) before attempting to register it in the cache.

Interoperability Dll

I converted the solution found on CodeProject to Visual Studio 2008 using the Visual Studio Conversion Wizard. Afterwards I removed all the projects from the solution except the BandObjectLib project. When attempting to create a Release build I received the following error:

The BandObjectLib project contains a reference to the SHDocVw.dll file. Visual Studio creates an Interop.SHDocVw.dll interop assembly and copies this to your project folder (e.g.: \BandObjectLib\obj\Debug\).

Follow these steps to get rid of this error:

Remove the original SHDocVw.dll reference and delete any Interop.SHDocVw.dll files present in your project folder and its subdirectories.

Add a reference to the SHDocVw.dll file which is located on your computer.

Build the BandObjectLib project. This will generate a new Interop.SHDocVw.dll interoperability assembly.

Open the properties for the BandObjectLib project and under the Signing tab make sure it is signed. You can used the provided BandObject.snk file or create your own using the Strong Name Tool (sn.exe).

Once this is done you need to add the Interop.SHDocVw.dll assembly to the global assembly cache (GAC).

As you may know the Global Assembly Cache (GAC) is a cache in which you can store .NET assemblies which the .NET runtime uses as a central repository. You can store multiple versions of the same assembly in the cache. That’s why they need to be strong named as mentioned earlier.

You can register an assembly in the GAC by using the command-line interface tool Gacutil.exe. To install an assembly in the cache just execute the following command:

gacutil /if NameOfAssembly.dll

To deinstall an assembly from the cache use this command:

gacutil /uf NameOfAssembly

Notice that the .dll extension has been omitted from the previous command.

By default the Gacutil.exe tool isn’t known when you call it at the command prompt. You can resolve this by adding its path to the environment variables (Computer | Properties | Advanced | Environment Variables).

I advise using the Visual Studio Command Prompt instead. Introduced in the .NET Framework 2.0 it automatically sets certain environment variables that allow you access to various .NET Framework tools. It is advisable to run this tool with Administrator credentials. Take a look at Dave Lloyd’s blog on how to do so. Although an old article this still holds true on Windows Vista.

Once the BandObjectLib assembly has been registered in the GAC you are ready to create you very own toolbar. Create a new Windows Forms Control Library project and call it SampleToolbar. Add it to the solution containing the BandObjectLib class library. Next add a reference to the BandObjectLib assembly which you created earlier. Rename the UserControl1.cs and the UserControl1 class inside it to SampleToolbar.cs and SampleToolbar.

The SampleToolbar class inherits from the BandObject class instead of System.Windows.Forms.UserControl. After changing this the SampleToolbar class should look as follows:

As you may have noticed in Listing 2 a new attribute has been applied to the SampleToolbar class. With the BandObject attribute, which is declared in the BandObjectLib library, you can specifiy which type of band object you want. Here I have choosen for a standard horizontal Explorer toolbar.

Now to complete the design part of the toolbar set its Size and MinSize property to “150 (width), 24 (height)”. For the last step set the GripStyle property of the Toolstrip to Hidden.

To get your toolbar integrated into Internet Explorer you will have to add the SampleToolbar Dll assembly to the global assembly cache. You will also have to sign this assembly in order to be able to register it to the GAC. You can use the same snk file of the BandObjectLib project or you can opt to create a new one with the sn.exe tool.

Once registered in the GAC there is one more thing you need to do if you want to use the toolbar in IE, namely you have to register it as a COM server. This is were another command-line interface tool comes to the rescue. The Assembly Registration Tool (regasm.exe) will read the metadata in an assembly and will add the necessary entries to the registry to allow COM clients to create .NET Framework classes. Once registered any COM client can use the class as if it were a COM class.

To register the SampleToolbar class within the SampleToolbars Dll assembly as a COM server you need to execute the following command from a Visual Studio Command Prompt:

regasm SampleToolbars.dll

But before you do so, make sure to make the types in your assembly visible to COM components. You can do this by setting the ComVisible attribute in the AssemblyInfo.cs file to true.

Listing 3 – AssemblyInfo.cs File

// Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]

If you have already added the SampleToolbars assembly to the GAC without this attribute set to true, then you need to register it again. You need to reregister any assembly with the GAC if you have made any changes to it! You also need to restart Internet Explorer after you have registered any new assemblies to the GAC if you wish to see the changes.

You can unregister the registered types with the following command:

regasm /unregister SampleToolbars.dll

Be sure to unregister and reregister the types again after you have changed your add-on. Changing the type (explorer bar, desk band…etc.) for example and not unregistering and reregistering the types will result in weird behaviour when IE loads your add-ons.

After the assembly has been added to the GAC and the toolbar type within it has been registered as a COM server you can access the toolbar in IE. Just start IE and select View > Toolbars and then choose the Sample Toolbar. The screenshot below shows IE 7 in action, though in Dutch.

The toolbar is displayed on the righthand side of the screen and is embedded in the main menu toolbar. Although it works properly and greets the world when you click on the “Click me” button it is still flawed. You can’t move the toolbar around, it is stuck in the main menu toolbar. This is pretty annoying and is caused by a bug in the BandObjectLib library.

Open the ComInterop.cs file from the BandObjectLib project and add the following structure.

Listing 4 – DBIMF Structure

/// <summary>/// A set of flags that define the mode of operation for the band object. /// </summary>
[Flags]
publicenum DBIMF : int
{
//The band is normal in all respects. The other mode flags modify this flag.
NORMAL = 0x0001,
//Windows XP and later
FIXED = 0x0002,
FIXEDBMP = 0x0004,
//The height of the band object can be changed. The ptIntegral member defines //the step value by which the band object can be resized.
VARIABLEHEIGHT = 0x0008,
//Windows XP and later:
UNDELETEABLE = 0x0010,
//The band object is displayed with a sunken appearance.
DEBOSSED = 0x0020,
//The band will be displayed with the background color specified in crBkgnd.
BKCOLOR = 0x0040,
//Windows XP and later:
USECHEVRON = 0x0080,
BREAK = 0x0100,
ADDTOFRONT = 0x0200,
TOPALIGN = 0x0400,
NOGRIPPER = 0x0800,
ALWAYSGRIPPER = 0x1000,
NOMARGINS = 0x2000,
}

Now you need to locate the DESKBANDINFO structure in the same file and change the type of its dwModeFlags data field from DBIM to the newly added structure type DBIMF. Also change the type of the dwMask field to DBIM. You should wind up with the following revised structure.

Listing 5 – DESKBANDINFO Structure

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
publicstruct DESKBANDINFO
{
public DBIM dwMask;
public Point ptMinSize;
public Point ptMaxSize;
public Point ptIntegral;
public Point ptActual;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
public String wszTitle;
public DBIMF dwModeFlags;
public Int32 crBkgnd;
};

If you want to learn more then take a look on MSDN on how the DESKBANDINFO structure should be implemented. The last change you need to make is in the GetBandInfo(…) method of the BandObject class which is located in the BandObject.cs File. Assign the following value to the dwModeFlags field of the dbi structure in this method:

It would be handy if you could change the value of the dwModeFlags at design time through a property of the BandObject class using the property grid. However the property grid treats this property as an enumeration and thus you can only select a single field from the drop-down list. So you need to implement your own TypeConvertor which helps you edit bit field properties. Implementing this is beyond the scope of this article, but if you are interested in doing this then I recommend the Bit Flags Type Convertor article written by Serge Gorbenko. The sources accompagnying this article already contain this type convertor and the BandObject class exposes a property called ViewMode which you can use to tweak the behaviour of the toolbar.

Now that the BandObjectLib library has been fixed it is time to rebuild the entire solution. Afterwards you have to reregister the BandObjectLib and SampleToolbar assemblies for the GAC in order for the changes to become visible.

After you have specified that the toolstrip should use its own renderer, you need to define the new toolstrip renderer class. It derives from ToolStripSystemRenderer and overrides the OnRenderToolStripBorder(…) method. This overriden method doesn’t do anything since it doesn’t have to display any borders. Listing 9 shows you how to create your own renderer.

As you can see from the screenshot above there is one more problem to be solved and that is the fact that the toolbar is not transparent. In order to fix this you need to set the BackColor property of the user control and the toolstrip to transparent. Finally you need to add the following tidbit of code to the BandObject class.

Based on this article you should now be able to create you own Internet Explorer toolbar. It starts off with a brief introduction on C++ and the Active Template Library (ATL) and how to develop add-ons for IE using band objects.

Luckily the “dirty work” was already done and based on the code from the BandObject article on CodeProject several adjustments to it were made in order to fix some problems such as making it “moveable” and applying transparency.

Several side-by issues such as working with the global assembly cache (GAC), interoperability Dll’s and COM visibility were also addressed. These not only apply to creating add-ons for Internet Explorer but to a vast array of projects and are sure to come in handy later on.

Credit is due to the author of the original BandObject article and those that supplied the fixes I found on several forums after a lot of Googling. If you have any problems, suggestions or comments be sure to let me know.

I came accross your blog and even started developing my toolbar. Thank you for the great article. I am having few problems though. At first, I used regasm and gacutil to register my toolbar. I even saw its name under View->Toolbars. However, I couldn’t see it under IE even though I set ComVisible to true. Then I decided to use gacutil /uf and regasm /unregister on my dll file. Each time I tried gacutil, I am having this error message “NTVDM.EXE stopped working”. I am working under Vista. I searched C:\Windows\GAC directory to manually remove it but it is not available. I couldn’t come up with a solution yet. I would greatly appreciate if you could suggest any solution.

Great article Geers. I have been looking for a way to make my toolbar background fit in with the IE 7 look for awhile now and you saved me!

I have one last look and feel issue though and am wondering if you have solved it… The toolstripbuttons that I place on the toolstrip do not have the same look when I hover over them as buttons on other toolbars in IE. Have you been able to change that?

Thank you!!!
I have looked and looked for ways to make my deskband transparent. All answers that I found had to implement IDeskBand2 interface, which is only available for Vista I believe. Now my deskband is transparent, but somehow there is part of it that has become black? I’m guessing the rectangle size is wrong somehow, but can’t figure out what it is…

What do you make of the notion that you shouldn’t go writing shell-related components in .NET, because it injects a dependency on whatever version of the runtime you have? Is this going to be an issue for toolbars like yours? (and the one I just finished…)

How difficult would it be to introduce the below request? Any recommendations on below options?Issue:End users are using an ERP accessed through web in IE. They are closing the IE browser and session hangs or just accidently closing with the X because it is too easy…

Option 1: Disable Close with group policy and then introduce a custom IE option to File/close with “Are you sure You want to close?’ logic. Option 2: Modify the existing Close option somehow. This needs to include the X as this is the primary issue culprit

[…] Every once in a while, I would pick up the project again, do some more Googling and try out a few more things but without any lock on getting the transparency to work. All directions pointed at implementing the IDeskBand2 interface rather than the IDeskBand, though any attempt would just crash explorer when I would add the utility to the Taskbar. So more Googling, more attempts later, I finally stumbled upon an excellent post which worked – http://cgeers.wordpress.com/2008/02/16/internet-explorer-toolbar/ […]

Very helpful. I’ve created a transparent toolbar for my taskbar in vista and it works just fine. The only problem is that my button controls are rendered with an opaque background and not the translucent black that I would have expected. Any ideas ?

hi,
I am working on one cutom tool bar. Tool bar is unchecked on IE when we first install it. I am doing it in c#. I have got some other problems by using “Setbroserbar” which is there in code project.

Hello to all,
I am developing IT toolbar.
and i need that user is not allow to disable this addons/toolbar by tools->manage addons but administrator is optional.
For that i use band object’s to enable, visiable etc but that are not effecting.ther than that i read on many sites that when addons is enable/disable then it call ‘UIActivateIO” function.but in my code that function is also not calling.

there is a problem with that. although the fact that ie > view > toolbars menu has the item I developed, it is not working at all. Because I can’t see the toolbar I develoeped and it is impossible to have it checked in internet explorer.

The only difference between your project and mine is I also try to have it with assemblyguid.

A very helpful & nicely written article about creating IE toolbars. I was googling around on how to part of creating IE toolbars in .net and I read a lot of articles, then I came across yours and I realized that it is one of the best articles I have read on this topic.

i got all things working fine.. but i caught into one probs that only ” X ” button is shown to me instead of toolbar on the LHS …also i am not able to move the toolbar…. no handle to grab it is there!!! ..plz help out..!!

Great article Geers. I followed your indications to create a IE toolbar and I added some textbox but I have the following problems: the backspace key and the direction keys don’t work. I used SetTopLeve() method and I resolved these problems but the tab key doesn’t work!Can you help me to resolve this problem?
Thanks!!!

Thanks for the good article which could have saved me a lot of time. After much struggle, I got almost everything working, except that there is a ‘X’ button in the toolbar. I found this page when trying to get rid of this ‘X’ button.

Regarding the transparent background color of the band, Amy got a problem with partial background being black, and nobody has answered the question. I encountered the same problem first, but I figured out how to make it work properly. The problem is in the overridden OnPaintBackground function: The rectangle used is clipped. Replace this line
Rectangle rec = new Rectangle(e.ClipRectangle.Left,
…
with
Rectangle rec = this.ClientRectangle;
should solve this problem.

I got this toolbar work on XP for IE 6, 7 and 8, but the same code doesn’t work on Windows 7 – I don’t have time to figure it out yet. The one for IE 6, the toolbar didn’t show up initially, but it can be made visible from View > Toolbar menu.

As reported by Mitech, I also see a ‘X’ button automatically added to the beginning of the toolbar, which happens on IE 8 only. Anybody has an idea how to remove it?

I also have experienced that sometimes the toolbar doesn’t show up in IE. I never figured exactly why, but it seems to be a problem registering the component.

The problem with W7 seems to be in insufficient rights, with which runs IE8 under W7. When rights granted, some derived toolbar worked for me fine. But how to grant only particuilar rights (=not admin), or how to make it run standart way, I dont know.

Hi,
Thanks for Nice article. I am trying to develop the customize search using the band object in Windows Explorer. My problem is that i wanted to show the result in right pane of explorer similar the search you do in XP. My question is that how can i acheive this using the band object.
I am really stuck with this issue. I will really appreciate your help in this.

My toolbar does’nt do anything! I buid it with VS2010,added in GAC, registered with ragasm, everything works fine. I see it in View->Toolbars in IE (7), but when I check it to be visible it is not appearing and it is unchecked again. The same thing is happened with the full project from codeproject (Pavel Zolnikov).

P.S. The toolbar also appear in menu of windows explorer, and there is the same problem, does not appear after check it in the View->Toolbars->Sample Toolbar

Hey. I have been trying to build the project as you said but it won’t let me build giving me this error. Error 3 error PRJ0019: A tool returned an error code from “Performing Post-Build Event…” RegisterLib RegisterLib
I don’t know what is this. Can you help me out?

Thank you Christophe Geers,
I implemented your code and succeeded. It works well with Internet Explorer 32 bit, but not working with the 64 bit version. I changed the target platform of my toolbar project to x64 and compiled it without success. Later after some googling I have been suggested to add this line in the post-build command box- “%Windir%\Microsoft.NET\Framework64\v2.0.50727\regasm” “$(TargetPath)”
to register the 64 compiled dll with 64 bit Regasm, and did the same. Form there onwards I can see my toolbar name in the ‘Toolbars’ section as well as in ‘Manage Ad-ons’ section in 64 bit IExplorer. Unfortunately when I click on it doesn’t even show a tick mark on it. Nothing new is shown on the upper side of the IExplorer. Pls help to solve this issue, bcoz my client may have to run the toolbar on both 32 and 64 bit versions of IExplorer.