IEの右クリックメニュー(コンテキストメニュー)は、レジストリの項目によって定義できます。オリジナルメニューを追加したい場合には、対応するレジストリエントリーを追加するだけです。

ちょー有名な技ですので。わざわざ説明することでもないのですが、投稿ページを作っている建前上、一応こんなページを作っておきます。

このページに書かれているようなことは、Microsoft Power Toysの説明ページ(日本語版)やうりゅさんちのサポート掲示板などからも入手可能です。

レジストリの設定

メニューのレジストリはHKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExtにあります。

レジストリエディタなどで実際に確認してみた方が分かりやすいと思いますが、ここの直下のサブキー名が表示されるメニューそのものになっています。

(例)
HKEY_CURRENT_USER
+---Software
    +----Microsoft
         +----Internet Explorer
              +----MenuExt
                   +----新規ウィンドウで開く    (値)c:\script\newURLOpen.html
                   |    contexts                    (値)DWORDで示されるフラグ値(各ビットごとのフラグ値)
                   |    Flags                       (値)DWORDで示されるフラグ値(0or1のみ)
                   :

メニュー名サブキーの値が、対応するスクリプトファイル名です。通常はHTMLファイルです。その実体はJavaScriptやVBScriptで、様々なアクションはこれらスクリプトで実現される訳です。ファイル名はフルパスでなければなりません。

実際にはスクリプトしか必要ないので<script>タグしか記述されていない場合もあれば、きちんと<html><body>タグから記述されたHTMLファイル形式の場合もありますが、どちらでも正常に稼動する仕様のようです。

メニュー名サブキー下には二つのオプション値がありえます。

一つはcontextsで、このメニューが、右クリックメニューがどのような状態の時に表示されるかを示します。値はDWORDとなっており、各ビットがそれぞれの状態での表示/非表示を示すフラグ(0が非表示、1が表示)となっています。

contextsの意味
第0ビット 0x00000001
(10進では1)
デフォルト(CONTEXT_MENU_DEFAULT)常に表示される
第1ビット 0x00000010
(10進では2)
画像(CONTEXT_MENU_IMAGE)画像上でメニューが表示された時
第2ビット 0x00000100
(10進では4)
コントロール(CONTEXT_MENU_CONTROL)フォームのコントロール上でメニューが表示された時
第3ビット 0x00001000
(10進では8)
テーブル(CONTEXT_MENU_TABLE)テーブル上でメニューが表示された時
第4ビット 0x00010000
(10進では16)
テキスト選択(CONTEXT_MENU_TEXTSELECT)テキストが選択されてメニューが表示された時
第5ビット 0x00100000
(10進では32)
リンク(CONTEXT_MENU_ANCHOR)リンク上でメニューが表示された時
第6ビット 0x01000000
(10進では64)
その他(CONTEXT_MENU_UNKNOWN)上記以外の場合にメニューが表示された時

最上位ビットは必ず0となります。

各値はOR演算されることで、複数の状態を示せます。例えば、0x00000110(6)は画像とコントロールを示します。

contextsが存在しない場合は全てがオンとして扱われるようです。R-Click! Unionでもそのように扱います。

次のオプションはFlagsです。スクリプトがモーダルダイアログとして動作するかどうかを示します。

Flagsの意味
0x00000000(10進では0)通常モード
0x00000001(10進では1)モーダルダイアログモード

Flagsは0か1かしか取りません。また省略時は通常モードとして取り扱われます。

通常、スクリプトは右クリックメニューから呼び出されると、その呼び出しウィンドウ上で動作するかのように実行され、一度実行されるとそのまま終了します。例えばスクリプトファイルが<body>タグが存在していても、元々のウィンドウが既にある以上、表示する方法もなく、実質上<script>タグしか実行しようがないのです。

これに対してモーダルモードが指定されると、モーダルダイアログが常に表示されます。スクリプトファイルはこのダイアログで実行されます。<body>タグ内のコンテンツもこのダイアログに表示可能です。

ほとんどの場合は通常モードで問題無いと思いますが、ユーザーに何らかの入力を行わせたり、明示的に何らかの表示を行いたい場合には便利です。但し、モーダルですので、元のウィンドウにはこのダイアログが終了しない限りフォーカスが戻りませんので、注意しましょう。

*注*このモーダルダイアログでは実は文字選択が行えません。従って単なるサブウィンドウとしての使い勝手は悪いです。そうした場合にはwindow.openなどで別ウィンドウを開いた方がいいでしょう。

スクリプトの書き方

スクリプトはJavaScriptかVBScriptで記述出来ます。普通のHTMLファイルのように記述すれば問題ありません。<script>タグだけでも問題なく動作します。モーダルモードの場合には、通常の<body>タグ内にコンテンツを記述すれば、これも問題なくダイアログに表示されます。尚、ここでは作者の趣味により、JavaScriptベースで進めさせてもらいます。VBSriptでなければ出来ない機能なども場合によってはあるようですので、注意して下さい。

以下はもっとも簡単なスクリプトの例です。

<script type="text/javascript">
alert("単にメッセージをポップアップするだけです");
</script>

とは言っても、扱いたいのは、呼び出し元ウィンドウに対するアクションですから、呼び出し元ウィンドウにアクセスする手段が無ければ何の意味もありません。

基本となるのはexternal.menuArgumentsという特別なオブジェクトです。これは呼び出し元ウィンドウのwindowオブジェクトそのものです。ここから全てのアクセスが広がりそうですね。

通常はこのexternal.menuArgumentsを元に以下のようなオブジェクトを作成して様々なアクションを記述します。

使用されるオブジェクト一覧
external.menuArguments呼び出し元ウィンドウのwindowオブジェクト。通常のwindowオブジェクトのように、ここから呼び出し元ウィンドウのdocumentオブジェクトなどを辿れる
(例) var parentwin = external.menuArguments;
external.menuArguments.document呼び出し元ウィンドウのdocumentオブジェクト。ここからコンテンツ内容を辿れる。
(例) var parentdoc = external.menuArguments.document;
external.menuArguments.event呼び出し元ウィンドウのeventオブジェクト。メニュー表示イベントを示す。
(例) var srcEvent = external.menuArguments.event;
external.menuArguments.event.type

以下のような文字列のいずれかが格納されており、イベント元タイプが判別出来ます。contextsと同じ種類です。contextsを複数指定した場合にはどのイベントが発生したか分からないので、ここの値からイベントを判別してスクリプトを分岐する必要があります。

  • MenuExtDefault
  • MenuExtImage
  • MenuExtControl
  • MenuExtTable
  • MenuExtTextSelect
  • MenuExtAnchor
  • MenuExtUnknown
(例) var EventType = external.menuArguments.event.type;
external.menuArguments.event.clientX
external.menuArguments.event.clientY
イベントの発生した時のマウス位置。
external.menuArguments.document.elementFromPointイベント発生元オブジェクトを取得出来る。マウス位置から判別する。
(例) var EventElement = parentdoc.elementFromPoint( srcEvent.clientX, srcEvent.clientY );
external.menuArguments.document.selectionテキスト選択時にselectionオブジェクトを取得出来る。selectionを元に選択されているHTML文字列などを取得可能。
(例) var sel = external.menuArguments.document.selection;
var sel_html = sel.createRange().htmlText;
  • 例えば、選択されたテキストから検索エンジンで検索したい場合にはexternal.menuArguments.document.selectionから選択文字列を取得して、検索エンジンへの検索用URLを作って別ウィンドウからジャンプでもすればよいです。
  • external.menuArguments.document.elementFromPointではイベントオブジェクト自身が取得出来るので、例えばそのコントロールのテキストを取得したり置き換えたり出来ます。
  • external.menuArguments.documentはdocumentオブジェクトそのものですので、呼び出し元ウィンドウ全体にアクセス可能です。通常のスクリプトの要領で記述すればよいですね。

ほとんどの場合、上記の三つの方法から様々なアクションが可能です。スクリプト掲示板に幾つかサンプルも載せておきますので、参考にしてみて下さい。