Preamble
Before you start, I highly recommend you read Pavel Zolnikov's article entitled "Extending Explorer with Band Objects using .NET & Windows Forms" first.
Pavel wrote a fantastic article explaining the ins & outs of using COM Interop to write your own customizable band objects for Explorer using .NET 2003. Without that article, this one wouldn't have come about, so kudos to Pavel.
Introduction
One of the niceties about the .NET 2.0 environment is the rich suite of form controls that have been included for form design. While the 2003 environment was great and all, it was missing a lot of the funky controls such as tool strips and dropdown buttons that we've come to expect as standard in a nice Explorer bar UI. My goal was to design a nice neat tool bar solution so that I had several shortcut links to the sites and systems I used most often, and also to provide 'at-a-glance' information by displaying data in a label which updated on a regular basis.
The 2003 to 2005 Jump
Porting Pavel's 2003 BandObjectLib code to 2005 was a relatively painless experience, so I'll just skim through a few of the minor details:
- The first thing to do was to create a standard Windows Class Library.
- The ComInterop.cs, BandObject.cs, and Attributes.cs files were taken verbatim from the 2003 project and copied to the 2005 project.
- All
[assembly: ]
attribute code was removed and placed in the AssemblyInfo.cs file instead.
- References to
SHDocVw
(COM tab), System.Drawing
, and System.Windows.Forms
(.NET tab) were added.
- And finally, a strongly named key was added to the library to allow it to be added to the GAC. This is an easier endeavor in the new IDE as you can directly create a .snk file for a project by right-clicking the project file, selecting 'Properties', selecting the 'Signing' tab, and choosing to sign the assembly with a new Strong Named Key.
- The final step was to add a post build event to the Project Properties > "Build Events", to add the successfully compiled assembly into the Global Assembly Cache. In VS2005, the gacutil.exe utility is no longer located in the framework folder but in the VS2005/SDK folder under C:\Program Files\. So you may need to alter this script depending on your installation and path setup.
cd $(ProjectDir)bin\Debug
"C:\Program Files\Microsoft Visual Studio 8\
SDK\v2.0\Bin\gacutil" /if CustomToolbar.dll
"C:\Program Files\Microsoft Visual Studio 8\
SDK\v2.0\Bin\gacutil" /if Interop.SHDocVw.dll
Note * If you plan on using this software yourself, be aware that Strongly Named Libraries in the GAC are treated as being distinct and separate if they have differing version numbers, so I'd recommend keeping the Assembly Version number in the lib as some static value. E.g.:
[assembly: AssemblyVersion("1.0.0.0")]
Building Our First Toolbar
So we're ready to build our first toolbar. Setting up the project is easy enough. In the attached code, I've just created it as an additional project within the same solution. It's a class library project. It requires direct references to the strong named DLLs in the bin folder of our BandObjectLib project which have already been installed in the GAC. And it needs a strong named key and a static Assembly Version Number.
Step 1. Adding the BandObject Control
Since the BandObject
class is essentially a beefed up derived class of UserControl
, we can simply add a UserControl
to our project and then alter the code-behind so that our control extends a BandObject
instead. In this example, I'm creating a horizontal Explorer Toolbar. Since this control will be exposed through COM, we need to specify a GUID attribute to uniquely identify the class. The GUID attribute is part of the System.Runtime.InteropServices
namespace.
using BandObjectsLib;
using System.Runtime.InteropServices;
and
[Guid("AE07101B-46D4-4a98-AF68-0333EA26E113")]
[BandObject("My Toolbar", BandObjectStyle.Horizontal
| BandObjectStyle.ExplorerToolbar
| BandObjectStyle.TaskbarToolBar, HelpText = "My First Toolbar")]
public class MyToolBar : BandObject
{ ...
Step 2. Building the Toolbar
You have all the facilities of a standard UserControl
at your finger tips through the designer canvas, so feel free to add anything you want from simple buttons to mini-browsers to completely separate forms which popup on a click event. In my example, I've added a ToolStrip
and populated it with some standard toolstrip controls: buttons, dropdown buttons, labels, textboxes, separators, and progress bars.
Step 3. Embedded Resources
To make the bar look a little more aesthetically pleasing, I've embedded some PNG images (thanks to www.famfamfam.com's silk icon collection) to an Embedded Resource File in my project and then set the button images. Simply set your toolstrip buttons to display "ImageAndText" or "Image", and specify an image from your resx file. When you compile your toolbar, all the image files will be embedded in the DLL, so there's no need for any installation directories and file bundles. Resource files are very convenient for embedding all sorts of dynamic resources or for making your toolbar multi-lingual.
this.tsbtn1.Image = global::BandObjectsExample.Resources.redcircle;
this.tsbtn1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.tsbtn1.ImageTransparentColor = System.Drawing.Color.Magenta;
Step 4. Code Behind
In my example, I've created a couple of sample buttons to pop open some websites using your system's default browser.
private void OpenWebPage(string url)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = url;
process.Start();
}
As an example of a status polling facility, I've created a quick and dirty routine to poll my Winamp web interface for the currently playing track and to display it on a label at the end of the strip. This is performed on a timer which ticks every 30 seconds. Be careful though about having multiple instances of your toolbar (e.g., in multiple browsers) as this might have an adverse effect on your system if the task being performed on the timer occurs very often or is very processor intensive. For my Winamp ticker, I only ever have one instance running on my taskbar beside the system clock.
Step 5. Building Your Toolbar
Once you've finished designing your toolbar in the IDE designer, then it's time to build it and take it for a test drive. You'll need to add a post build job to this project also. The first task is to install your toolbar DLL in the Global Assembly Cache. Since it's going to be used through COM, you'll also need to register your assembly using the Regasm utility contained in the framework installation folder.
cd $(ProjectDir)bin\Debug
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil" /if MyToolbar.dll
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm" MyToolbar.dll
Note * By default, .NET 2.0 assemblies are set to be invisible to COM. In your AssemblyInfo.cs file, you'll find an attribute called [Assembly:ComVisible]
. This attribute states whether or not the types in your .NET assembly should be exposed to COM. You have to set this value to true
, otherwise the Regasm program will not be able to see your toolbar and the registration will fail.
[assembly: ComVisible(true)]
Step 6. Using the Toolbar
Once you've successfully built and registered your toolbar, it should appear on the right click menu of your taskbar and the toolbar context menu in the Internet Explorer. It's worth pointing out that Explorer caches COM objects when they are first loaded, so after doing a rebuild, you might not necessarily see the updates in your toolbar. There are a couple of ways of getting around this such as changing your folder settings to launch folders in new Explorer instances, or to kill the Explorer exe (not recommended :) ) from your Task Manager.
Ideas, Ideas, Ideas
The sky really is the limit for these band object controls. In my example, I've only shown the ToolStrip
control, populated with some buttons and other simple controls. I've added some additional functionalities such as a ContextMenu
and the timer control, but there's nothing stopping you from adding any control available. Post them to CodeProject if you come up with a good one :)
- You might want to make a vertical toolbar with a mini
WebBrowserControl
for viewing your favorite web portal.
- You could write your own RSS ticker to sit on your taskbar beside the clock and rotate through your favorite RSS-feeds.
- Or maybe you could write an SMS sender to login to your mobile operator's website and send a text message through your account.
Husband, son, brother, I grok technologiy. I write code. I take photos. I teach & practice Krav Maga. I play football. I eat good-food. I drink nice-wine.