Community Pick: Many members of our community have endorsed this article.
Editor's Choice: This article has been selected by our editors as an exceptional contribution.

Add a Custom Command to the IE Context Menu

DanRollins
CERTIFIED EXPERT
Published:
Updated:
This article shows how to add commands to Internet Explorer's right-click context menu, commands that are implemented in JavaScript.  It also shows a nifty technique for downloading and saving binary files with JavaScript.

Introduction:
You may already have some applications that add items to the IE context menu; for instance, Adobe provides a command to "export" the page (or a selected portion) to a PDF file.  Wouldn't it be cool to be able to write simple scripts to do your own custom commands?  How about a way to look up the meaning of a word in a dictionary?  Or collect specific information from the page and put it into a spreadsheet?  Or highlight every occurrence of a particular word on a page or display a thumbnail preview of every linked page... the possibilities are limited only by your needs and your skills with a scripting language.

Example #1
Add a Dictionary Lookup Option to IE


The custom context menu handler is coded in the form of a short HTML document that contains basically only a <script> tag.  Let's create a simple one:

1

Open Program Files and create a new folder named MyScripts

2

Create a new text file in that folder, naming it
LookupMeaning.txt

3

Open it with Notepad and paste the following into it:
<html><body>
                      <script language="JavaScript">
                      var oWindow = window.external.menuArguments;
                      var oDocument = oWindow.document;
                      var oSelect = oDocument.selection;
                      
                      var oSelectRange = oSelect.createRange();
                      var sSelText = oSelectRange.text;
                      
                      var n= oWindow.open( "http://www.merriam-webster.com/dictionary/"+sSelText, "_blank" );
                      </script>
                      </body></html>

Open in new window

4

Save the changes, and rename the file to change the extension.
LookupMeaning.HTM
We'll talk more about the script in a minute.  For now, let's keep moving so we can see it in action.  

Add a command the the IE Context menu:

We'll need to make an addition to the Windows Registry:

1

Use RegEdit to open up the key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt
You'll probably see several "menu extensions" already there.

2

Right click on MenuExt and select New > KeyCreate the nre registry keyAn item labeled New Key #1 appears.  Rename it to: Lookup &Meaning
(Note: The ampersand (&) sets a menu hot key of M

3

Now double-click the (Default) item in the right-hand pane.
Enter the full path of the .HTM file we created earlier, prefixing it with file://   For instance:

    file://C:\Program Files\MyScripts\LookupMeaning.HTM

4

Right-click in the right-hand pane and select New > DWORD Value
set the Name to Contexts and the Value to 10 ( 0x00000010 = 16).Set the (Default) and Contexts values

5

The next time you open a new IE browser window, the command will be available on the Context Menu.  Go ahead, and give it a try. Open a new IE, highlight any word (typically by double-clicking it), then right-click on that, and select Lookup Meaning (or press M).The value set in step #4 is important.  It specifies when IE will display the item on the context menu.   It can be a combination of these values:
Description      hex  decimal
                      Default         0x01        1 (when no selection; i.e, entire page)
                      Images          0x02        2
                      Controls        0x04        4
                      Tables          0x08        8
                      Text selection  0x10       16
                      Anchor          0x20       32

Open in new window

So, if you want the menu item to be available when right-clicking on an Image, you would set the Contexts value to 2.  If you want it available when clicking on a text selection OR an Image, set it to 18 (0x12).

Here's a RegEdit import file that you can use in lieu of the above manual steps:
Windows Registry Editor Version 5.00
                      
                      [HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\Lookup &Meaning]
                      @="file://C:\\Program Files\\MyScripts\\LookupMeaning.HTM"
                      "Contexts"=dword:00000010

Open in new window



About the Example #1 Script
The key element of the script is the line:
var oWindow = window.external.menuArguments;

Open in new window

That provides access to the IE window object.  Once you have access to a window object, you can access the document object, and that opens the door to to the entire DOM (Document Object Model) -- so you can do whatever you want.  In Example #1, we collect the current text selection, and then open a new window to a dictionary site, passing it the selected text in the URL.  The functionality is not particularly convenient because the new page is likely to popup behind the active window (depending on your popup-blocker settings), but it's just an example.

Example #2
Save Image with a Unique Filename


This second example illustrates a useful technique for downloading binary data -- it might be an image, a ZIP file, video clip, or any other binary resource.  I needed this ability as part of a project that downloaded all images from a website to the local hard disk.  Later, I was tasked with a more interactive variation in which the client wanted to be able point-and-click to select a image to download.  

There were a couple of problems to overcome.  First, some images are wrapped in an <A> tag, so if you drag it onto the desktop, you get a shortcut to a page rather than an image (dragging to the desktop also displays a "Windows Security Warning" box that needs to be avoided).  The other problem was that, in some cases, the site had used the same filename for some top-level images with a result that even right-clicking and choosing Save Image As... is a bit of a hassle.  The client wanted to be able to automatically rename the file so as to avoid the "Confirm File Replace" prompt.

Example #2 also illustrates how to identify the DOM element that has been clicked.  We use the window.event object to obtain the coordinates, and then the document.elementFromPoint() function to isolate the image object.  

To set this up, follow the registry-setting steps from above, but set:
  (Default) REG_SZ              file://C:\Program Files\MyScripts\SavePicUnique.htm
  Contexts  REG_DWORD 0x00000002 (2)

And create the HTML file named SavePicUnique.HTM with this script:
<html><body>
                      <script language="JavaScript">
                      
                      var MyDlPath="c:\\temp\\dlPix\\";  // end in \
                      
                      //-- Get the window and document objects
                      var oWindow = window.external.menuArguments;
                      var oDocument = oWindow.document; 
                      
                      //--- get the element on which the mouse was clicked
                      var x= window.external.menuArguments.event.clientX;
                      var y= window.external.menuArguments.event.clientY;
                      var oImg= oDocument.elementFromPoint(x,y);
                      
                      //var oReq= new oWindow.XMLHttpRequest; // no good: Access Denied!
                      
                      var oReq = new ActiveXObject( "Microsoft.XMLHTTP" );  // works
                      oReq.open( "GET", oImg.src, false );  // false= wait for download done
                      oReq.send();     // it's in cache, so actually no wait...
                      
                      //------- obtain the original filename 
                      var fso = new ActiveXObject( "Scripting.FileSystemObject" );
                      var sFileName= fso.GetFileName( oImg.src );
                      
                      var sLocalFile= MyDlPath + sFileName;
                      //------------------------- rename if already used
                      if ( fso.FileExists( sLocalFile ) ) {
                          var oDt= new Date();
                          var nOffsetDot= sFileName.lastIndexOf(".");
                          var sFile= sFileName.substring( 0,nOffsetDot );
                          var sExt=  sFileName.substring( nOffsetDot );
                          sLocalFile= MyDlPath + sFile + oDt.valueOf() + sExt;	
                      }
                      //-------------- use ADODB (of all things!) to save the file
                      var adTypeBinary = 1;
                      var adTypeText=    2;
                      var adSaveCreateOverWrite= 2;
                      var oStrm= new ActiveXObject( "ADODB.Stream" );
                      oStrm.type= adTypeBinary ;
                      
                      oStrm.open();
                      oStrm.write( oReq.responseBody );
                      oStrm.saveToFile( sLocalFile, adSaveCreateOverWrite );
                      oStrm.close();
                      </script>
                      </body></html>

Open in new window


The sequence in lines 11-13 obtains the image object so that I know the URL.  The binary image file is downloaded in lines 17-19.  At this point, the image is usually already in the local cache, so the "download" is basically instantaneous.  I use the FileSystemObject ActiveX object and a bit of string shuffling to come up with a unique filename.  Finally, lines 34-44 show the trick with the ADODB.Stream ActiveX object to push the file onto the disk.

ActiveX objects?!?  

Yes, indeed!  Since this Context Menu handler is running as an extension of the browser, you can instantiate ActiveX object as needed without seeing the dreaded security warnings.  It's not some external site that is taking the action, it is you -- your code on your computer -- running a trusted application.  Note, however, that not all of the rules go out the window.  If you try to use the Native XMLHttpRequest object (as in line 15) you'll raise an error -- it's  cross-domain access-denial issue.  But the functionality is basically the same when done with the external object.

Conclusion:
We looked at how to write a custom right-click context menu handler for Internet Explorer -- with a tweak to the Registry and just a few lines of JavaScript code.  You could use VBS just as easily.  The first example opens a new browser window to a URL that is determined by a user-selected word on any web page.  The second example illustrates a more complex set of functions, including how to programmatically download binary files from a web host to your local computer by using the XMLHttp and ADODB.Stream ActiveX objects.  You'll find more examples here.

Resources:

Some EE-useful JavaScripts for the IE Context Menu
(a set of four short utility scripts that use the context-menu technique.  They are some good examples for accessing the browser DOM, etc.)

Adding Entries to the Standard Context Menu
http://msdn.microsoft.com/en-us/library/aa753589(VS.85).aspx

XMLHttpRequest Object
http://msdn.microsoft.com/en-us/library/ms535874(VS.85).aspx

Stream Object (ADO)
http://msdn.microsoft.com/en-us/library/ms675032(VS.85).aspx

Browser Bot -- Automate Browsing Sequences PART THREE
(discusses some techniques for accessing HTML documents)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
If you liked this article and want to see more from this author,  please click the Yes button near the:
      Was this article helpful?
label that is just below and to the right of this text.   Thanks!
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1
8,677 Views
DanRollins
CERTIFIED EXPERT

Comments (4)

CERTIFIED EXPERT

Commented:
Got it to work, with sone fumbiling around. Still to try out the second script.

Thanks for the writing. Of course, voted yes.

Ravi.
CERTIFIED EXPERT

Commented:
Just a few improvement suggestions ----

Yes in the top example, you are referring to My Documents

"Open My Documents and create a new folder named MyScripts
Create a new text file in that folder, naming it
LookupMeaning.txt"

later it becomes Program Files

confusing ... :-) However, I got it right.

also you need to bold out 10 only in place of 0x10 in the line
    Right-click in the right-hand pane and select New > DWORD Value
    set the Name to Contexts and the Value to 0x10 (16).

Thats why I said, fumbled....

One more thing, the reghack needs to be placed just above the manual steps for creating the regedit, I am the type of person who would simply like to merge the stuff to the Registry. I am across it but after practising everything,

Ravi.
CERTIFIED EXPERT
Author of the Year 2009

Author

Commented:
Thanks for the feedback!  I made the correction to the folder name and the registry input value.  However, I always show the manual steps for a RegEdit change before showing the .REG script itself ... after all this *is* a "Tutorial" :-)
CERTIFIED EXPERT

Commented:
Dan

Thanks for implementing the suggestions. Regarding the Reghack, you are right, It *is* a tutorial, so it should be that way.

Ravi.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.