ContextMenu リファレンス
シェルのコンテキストメニュー(IContextMenu)を扱うオブジェクトのリファレンスです。
記法: P=プロパティ、M=メソッド。
目次
1. 取得方法
| 方法 | 説明 |
|---|---|
api.ContextMenu(Items [, FV]) |
指定した FolderItems / FolderItem のコンテキストメニューを作る。Items は FolderItem・FolderItems・パス文字列・IDataObject など。FV(FolderView)を渡すと、メニューの動作(IShellBrowser サイト)がそのビューに関連付けられる。失敗すると空を返す |
FV.ViewMenu([flags]) |
ビュー(背景または選択項目)のコンテキストメニューを返す。flags 省略時は背景のメニュー |
api.ContextMenu(dllPath/CLSID, ..., Item, Items, hKey, subKey, FV) |
シェル拡張(IShellExtInit)を直接読み込んでメニューオブジェクトを作る(引数7個)。dllPath と CLSID の組、IDList(Item)、対象(Items)、レジストリキー(hKey と subKey)、サイトとなるビュー |
7引数形式は、特定のシェル拡張だけのメニューを取り出すための上級者向けの形式です。
2. メソッド
| 名前 | 説明 |
|---|---|
QueryContextMenu(hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags) |
メニュー項目を hMenu に追加する。5個すべての引数が必要。成功すると IContextMenu::QueryContextMenu の戻り値(HRESULT。最大コマンドID+1 が入る)を返す。1つのオブジェクトにつき1回しか実行されない(2回目以降は何も行わず、値も返さない) |
InvokeCommand(fMask, hwnd, Verb, Parameters, Directory, nShow, dwHotKey, hIcon) |
コマンドを実行する。8個すべての引数が必要。HRESULT を返す(下記) |
GetCommandString(idCmd, uFlags) |
コマンドの動詞/ヘルプ文字列を返す。idCmd は QueryContextMenu に渡した idCmdFirst を引いた0始まりの番号。uFlags は GCS_*。idCmd が 65535 を超える場合は空文字列を返す。引数なしで呼ぶと true を返す |
HandleMenuMsg(uMsg, wParam, lParam) |
IContextMenu2 / IContextMenu3 のメッセージ処理。オーナー描画のサブメニュー(「送る」など)の WM_INITMENUPOPUP / WM_DRAWITEM / WM_MEASUREITEM / WM_MENUCHAR を渡す。戻り値は LRESULT |
Items() |
このメニューの対象を FolderItems で返す |
2.1 InvokeCommand の引数
| 引数 | 内容 |
|---|---|
fMask |
CMIC_MASK_*(CMINVOKECOMMANDINFOEX.fMask)。文字列パラメータがANSIで表現できない場合は内部で CMIC_MASK_UNICODE が追加される |
hwnd |
親ウィンドウ(通常は te.hwnd) |
Verb |
数値ならメニュー内のコマンド番号(idCmd - idCmdFirst)、文字列なら動詞名("open"、"delete"、"properties" など) |
Parameters |
パラメータ文字列(通常は null) |
Directory |
作業ディレクトリ。null/省略相当の場合は、関連付けたビューの現在フォルダのパスを使う。ただし、ファイルシステム上のフォルダでなければ指定しなかったものとして扱われる |
nShow |
SW_*(通常は SW_SHOWNORMAL) |
dwHotKey |
ホットキー(通常は 0) |
hIcon |
アイコンのハンドル(通常は 0) |
- 戻り値: 実行した場合は
IContextMenu::InvokeCommandの HRESULT(S_OK=0が成功)、例外時はE_UNEXPECTED。 - 動詞番号が 65535 を超える数値のときはコマンドを実行せず、戻り値は
0になります。 - 動詞名が
mountのコマンドを実行した場合、内部でマウント時刻を記録します(ドライブ表示更新のため)。 te.OnInvokeCommandを設定している場合は、実行前にOnInvokeCommand(ContextMenu, fMask, hwnd, Verb, Parameters, Directory, nShow, dwHotKey, hIcon)が呼ばれます。その戻り値がS_OK(0)なら、既定の実行は行われず、InvokeCommandはS_OKを返します。
3. プロパティ
| 名前 | 種別 | 説明 |
|---|---|---|
hmenu |
P(読み) | QueryContextMenu に渡した hMenu |
indexMenu |
P(読み) | QueryContextMenu に渡した indexMenu |
idCmdFirst |
P(読み) | QueryContextMenu に渡した最初のコマンドID |
idCmdLast |
P(読み) | QueryContextMenu に渡した最後のコマンドID |
uFlags |
P(読み) | QueryContextMenu に渡した CMF_* フラグ |
FolderView |
P(読み) | 関連付けられた FolderView(api.ContextMenu の第2引数や FV.ViewMenu() で設定されたもの)。無ければ空 |
QueryContextMenu を呼ぶ前は、hmenu など上5つのプロパティは 0 を返します。
4. 関連イベント
| イベント | 説明 |
|---|---|
te.OnInvokeCommand |
InvokeCommand の実行前に呼ばれる。上記のとおり、0(S_OK)を返すと既定の実行をキャンセルできる |
te.OnShowContextMenu |
コンテキストメニューを表示するときのイベント。sync1.js の実装での引数は (Ctrl, hwnd, msg, wParam, pt, ContextMenu) |
te.OnMenuMessage |
メニューのメッセージを受け取るイベント。sync1.js の実装での引数は (Ctrl, hwnd, msg, wParam, lParam)(ステータス表示の更新などに使われている) |
5. 定数
consts.js で定義されています。
CMF_*(QueryContextMenu の uFlags)
CMF_NORMAL = 0 / CMF_DEFAULTONLY = 1 / CMF_VERBSONLY = 2 / CMF_EXPLORE = 4 / CMF_NOVERBS = 8 / CMF_CANRENAME = 0x10 / CMF_NODEFAULT = 0x20 / CMF_INCLUDESTATIC = 0x40 / CMF_ITEMMENU = 0x80 / CMF_EXTENDEDVERBS = 0x100 / CMF_DISABLEDVERBS = 0x200 / CMF_ASYNCVERBSTATE = 0x400 / CMF_OPTIMIZEFORINVOKE = 0x800 / CMF_SYNCCASCADEMENU = 0x1000 / CMF_DONOTPICKDEFAULT = 0x2000
GCS_*(GetCommandString の uFlags)
GCS_VERB = 4 / GCS_HELPTEXT = 5 / GCS_VALIDATE = 6 / GCS_VERBICON = 0x14
その他
CMIC_MASK_HOTKEY / CMIC_MASK_ICON / CMIC_MASK_FLAG_NO_UI / CMIC_MASK_UNICODE / CMIC_MASK_NO_CONSOLE(InvokeCommand の fMask)、SW_SHOWNORMAL = 1、TPM_RIGHTBUTTON = 2、TPM_RETURNCMD = 0x100(api.TrackPopupMenuEx に渡して選択コマンドを戻り値で受け取る)
6. 使用例
const FV = te.Ctrl(CTRL_FV);
const Items = FV.SelectedItems();
// 1. 選択項目のメニューを作って表示 → 実行
const ContextMenu = api.ContextMenu(Items, FV);
if (ContextMenu) {
const hMenu = api.CreatePopupMenu();
ContextMenu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_NORMAL | CMF_CANRENAME);
const pt = api.Memory("POINT");
api.GetCursorPos(pt);
const nVerb = api.TrackPopupMenuEx(hMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, te.hwnd, null, ContextMenu);
if (nVerb) {
ContextMenu.InvokeCommand(0, te.hwnd, nVerb - ContextMenu.idCmdFirst, null, null, SW_SHOWNORMAL, 0, 0);
}
api.DestroyMenu(hMenu);
}
// 2. 動詞名で直接実行(メニューを出さない)
const cm = api.ContextMenu(Items, FV);
const hm = api.CreatePopupMenu();
cm.QueryContextMenu(hm, 0, 1, 0x7FFF, CMF_NORMAL); // 実行前に一度は QueryContextMenu が必要
cm.InvokeCommand(0, te.hwnd, "properties", null, null, SW_SHOWNORMAL, 0, 0);
api.DestroyMenu(hm);
// 3. コマンドの動詞名を調べる
const verb = cm.GetCommandString(nVerb - cm.idCmdFirst, GCS_VERB);
HandleMenuMsgは、QueryContextMenuで作ったメニューのうちサブメニュー(「送る」など)を読み取る前にContextMenu.HandleMenuMsg(WM_INITMENUPOPUP, hMenu, 0)と呼んで初期化する用途で、script/sync1.jsが使用しています。