One of my favorite area of interest is to create applications that help users in their work via integrating content from different systems. Since significant amount of content is available on web servers, most of the users run web browsers to achieve the required information.
When you have to integrate web content with your application there are two main directions. Either you integrate the web browser control into your application or just vice versa, you push your application into the browser itself, typically by creating a browser add-in.
Of course, you can create Java applets, ActiveX controls, Silverlight or Flash applications to make your web content richer, but that is another story.
Since unfortunately there is no out-of-the-box tool in Visual Studio that would make creation of IE add-ins easier, one should either create the add-in using C++ or get a free or commercial wrapper to work with managed code as described by Christophe Geers in this post in more details.
For my example I chose a commercial product, Add-in Express for Internet Explorer because it provides all of the features I need in a very convenient way. You can find some introductory and more advanced texts, how-to articles and tutorials about the product on their site as well.
I created the sample toolbar using an earlier version of the product (Add-in Express 2008 .NET for Internet Explorer) I had access to and Visual Studio 2008. Hopefully the same code will work with the 2010 version of Add-in Express that supports Visual Studio 2010 as well.
In this post I will show you a simple example for Internet Explorer add-in that interacts with the content and events of the browser. For the sake of the sample I chose two features you might be familiar with from Google Toolbar:
- Show highlighted text in the search box: This feature displays the selected text from the HTML page to a text box. When the user clicks on the Go button, the text is submitted to Google.
- WordTranslator: When the user holds the mouse pointer over a word, a pop-up is displayed with the selected word. In this case I omit the actual translation. User can switch this feature off by clicking on the Disable link button in the pop-up, or using the Popup Enabled check box.
See the following images for illustration the add-in in action:
Let’s see the most interesting challenges and codes of the implementation.
One of the key points in the add-in to capture and handle HTML events, for example when the selection changed, the mouse is moving, down or up and a key is down. First it seemed to be trivial but it turned out that when you handle an event it somehow hides other HTML events to be fired, so standard IE functionality was broken. Fortunately I found this post from Rick Strahl. The article describes the exact symptoms I experienced and led me to the correct track.
More about the ResetTimer method later.
The DHTMLEvent delegate and DHTMLEventHandler are in fact the same you find on Rick’s page.
We attach the event handlers by calling the AttachEvents method both in the OnConnect and DocumentComplete events of the toolbar to ensure the cases when the add-in is first loaded into the browser and when a new page is loaded into the browser. If we do not re-attach the event handlers each time a new page is loaded, handlers would refer to a page not existing any more in the browser and events won’t be triggered as expected.
I found that referencing the HTMLDocumentObj when there is no page loaded yet into the browser throws an exception, so I wrapped in into a try / catch block.
When the selection is changed, we set the text of the text box back to the original, empty value:
When the mouse button is up we try to get the current selection and interpret it as text. If it is successful, we copy the value into the text box.
By pressing the Go button, the text (if not empty) in the text box will be submitted to Google.
The event handler for the mouse movement is responsible for tracking the mouse position in the document and for getting the word in the mouse position. It also starts and stops the timer that commands the pop-up window.
Note, that instead of checking for equality we check for a distance around the original location using an extension method of Point. This is necessary because the mouse move event is not triggered on every minor mouse movement so the actual mouse location might slightly differ from the location we experience in the mouse move event handler. Checking for equality would cause the pop-up display extremely unlikely in the case of a large screen resolution.
On a timer tick we check if the mouse pointer is still on the original location where it was when the timer was started. If it is and there is a word at the mouse position we display the pop-up.
The code of the PopUpForm is fairly simple. Note, that the Disable link button directly set the value of the related check box of the toolbar.
When the mouse button or any key is down we reset the timer and hides the pop-up. Note, that we do the same in the DocumentComplete event handler as well (not shown here).
See the following methods for details of the calls:
As you can see, the code contains a lot of trace method to make it easier to check the working the add-in using DebugView.
You can found the sample solution here. If you would like to work with that it requires the Add-in Express for IE to be installed in your environment.
The solution was tested on Windows Server 2008 / IE7 and Windows Server 2008 R2 / IE8.
Tips for working with Add-in Express:
- Although the Add-in Express solution may contain a setup project I found that after running the setup at the first time to register the add-in, it is more comfortable to use a post-build command like this to deploy the new .dll to the application folder on each build:
- copy $(TargetPath) "C:\Program Files\Default Company Name\SelectionAddOnSetup" /y
- I suggest you to close all instances of IE before building to avoid file locks.
- Sometimes it happens that despite you close all the IE windows, the target files are locked by a process so the build fails. In this case it is the quickest to kill Windows Explorer process from Task Manager and restart a new instance.
Known issues of the sample toolbar:
- The toolbar might be not displayed the first time in IE if there is other toolbars. In this case hide other toolbars first and try to disable and enable the add-in again.
- Sometimes only the title of the toolbar is displayed when you enable it. In this case check that the Lock the Toolbars setting is off in IE.
- The sample implementation does not handle HTML frames (including IFrames).
- If the user switches the input focus using the Alt + Tab keys (or Shift + Alt + Tab) the pop-up is displayed over the other application.
- The Popup Enabled setting is not shared between IE windows and not persisted between browsing sessions.