CMINVOKECOMMANDINFOEX
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| cbSize | DWORD | 4 | +0 | +0 | この構造体のサイズ (バイト単位)。このメンバーは IContextMenu::InvokeCommand の呼び出し元が設定し、実装側がこれを調べることで、構造体が CMINVOKECOMMANDINFO ではなく CMINVOKECOMMANDINFOEX 構造体であることを判別できます。 | ||||||||||
| fMask | DWORD | 4 | +4 | +4 | 0、または次のフラグの 1 つ以上を設定して、目的の動作を示すとともに、構造体の他のフィールドが使用されることを示します。 CMIC_MASK_HOTKEYdwHotKey メンバーが有効です。 CMIC_MASK_ICONhIcon メンバーが有効です。Windows Vista 以降では、このフラグは使用されません。 CMIC_MASK_FLAG_NO_UIIContextMenu::InvokeCommand の実装は、コマンドの実行中にユーザー インターフェイス要素 (エラー メッセージなど) を表示できなくなります。 CMIC_MASK_UNICODEショートカット メニュー ハンドラーは、ANSI 版のメンバーではなく lpVerbW、lpParametersW、lpDirectoryW、lpTitleW の各メンバーを使用します。ショートカット メニュー ハンドラーによっては Unicode をサポートしない場合があるため、lpVerb、lpParameters、lpDirectory、lpTitle の各メンバーにも有効な ANSI 文字列を渡してください。 CMIC_MASK_NO_CONSOLEショートカット メニュー ハンドラーが新しいプロセスを作成する必要がある場合、通常は新しいコンソールが作成されます。CMIC_MASK_NO_CONSOLE フラグを設定すると、新しいコンソールの作成が抑制されます。 CMIC_MASK_HASLINKNAMElpTitle メンバーにショートカット ファイルへのフル パスが格納されています。CMIC_MASK_HASTITLE と組み合わせて使用します。 Note この値は Windows Vista 以降のシステムではサポートされません。
CMIC_MASK_HASTITLElpTitle メンバーが有効です。 Note この値は Windows Vista 以降のシステムではサポートされません。
CMIC_MASK_FLAG_SEP_VDMこのフラグは、16 ビットの Windows ベース アプリケーションを参照する場合にのみ有効です。設定した場合、ショートカットが指すアプリケーションはプライベートな仮想 DOS マシン (VDM) 内で実行されます。「解説」を参照してください。 CMIC_MASK_ASYNCOKIContextMenu::InvokeCommand の実装は、呼び出しを処理するために新しいスレッドまたはプロセスを起動でき、呼び出された関数の完了を待ってブロックする必要はありません。たとえば、動詞が "delete" の場合、IContextMenu::InvokeCommand の呼び出しはすべての項目が削除される前に戻ることがあります。これは助言的な指定であるため、このフラグを指定する呼び出し元アプリケーションは、呼び出す動詞の実装を把握していない限り、この要求が受け入れられることを保証できません。 CMIC_MASK_NOASYNCWindows Vista 以降。 IContextMenu::InvokeCommand の実装は同期的であるべきで、処理が完了する前に戻ってはなりません。これは推奨的な指定であるため、このフラグを指定する呼び出し元アプリケーションは、呼び出す動詞の実装を把握していない限り、この要求が受け入れられることを保証できません。 CMIC_MASK_SHIFT_DOWNSHIFT キーが押されています。動詞が呼び出された後に変化している可能性のあるキーボードの現在の状態を調べる代わりに、これを使用してください。 CMIC_MASK_CONTROL_DOWNCTRL キーが押されています。動詞が呼び出された後に変化している可能性のあるキーボードの現在の状態を調べる代わりに、これを使用してください。 CMIC_MASK_FLAG_LOG_USAGEIContextMenu::InvokeCommand の実装が、「最近使ったドキュメント」メニューなどの機能のために、呼び出された項目を記録しておきたい場合があることを示します。 CMIC_MASK_NOZONECHECKSゾーン チェックを実行しません。このフラグにより、ShellExecuteEx は IAttachmentExecute によって設定されたゾーン チェックをバイパスできます。 CMIC_MASK_PTINVOKEptInvoke メンバーが有効です。 | ||||||||||
| hwnd | HWND | 8/4 | +8 | +8 | ショートカット メニューの所有者であるウィンドウへのハンドル。拡張機能は、表示するメッセージ ボックスやダイアログ ボックスの所有者としてこのハンドルを使用することもできます。呼び出し元は、表示される可能性のある UI の所有者ウィンドウとして使用できる正当な HWND を指定しなければなりません。UI スレッド (既にウィンドウが作成されているスレッド) から呼び出す際に HWND を指定しないと、再入が発生し、IContextMenu::InvokeCommand の呼び出しの実装に不具合が生じる可能性があります。 | ||||||||||
| lpVerb | LPSTR | 8/4 | +16 | +12 | 実行するコマンドの言語に依存しない名前を指定する、null 終端文字列のアドレス。アプリケーションからコマンドをアクティブ化する場合、このメンバーは通常は文字列です。システムは、次のコマンド文字列に対応する定義済みの定数値を提供します。
これは固定のセットではありません。コンテキスト メニュー ハンドラーは新しい正規動詞を独自に定義でき、アプリケーションはそれらを呼び出すことができます。 正規動詞が存在するにもかかわらずメニュー ハンドラーがその正規動詞を実装していない場合は、次のハンドラーがこの動詞を処理できるように、失敗コードを返さなければなりません。これを怠ると、ShellExecute を含むシステムの機能が損なわれます。 また、ポインターの代わりに、このパラメーターには MAKEINTRESOURCE(offset) を指定することもできます。ここで offset は、実行するコマンドのメニュー識別子オフセットです。実装は IS_INTRESOURCE マクロを使用して、この代替形式が使用されていることを検出できます。ユーザーがメニュー コマンドを選択した場合、シェルはこの代替形式を使用します。 | ||||||||||
| lpParameters | LPSTR | 8/4 | +24 | +16 | 省略可能なパラメーター。シェル拡張によって挿入されたメニュー項目の場合、このメンバーは常に NULL です。 | ||||||||||
| lpDirectory | LPSTR | 8/4 | +32 | +20 | 省略可能な作業ディレクトリ名。シェル拡張によって挿入されたメニュー項目の場合、このメンバーは常に NULL です。 | ||||||||||
| nShow | INT | 4 | +40 | +24 | コマンドがウィンドウを表示する場合やアプリケーションを起動する場合に、ShowWindow 関数へ渡す SW_ 値のセット。 | ||||||||||
| dwHotKey | DWORD | 4 | +44 | +28 | コマンドによってアクティブ化されるアプリケーションに割り当てる、省略可能なキーボード ショートカット。 fMask メンバーが CMIC_MASK_HOTKEY を指定していない場合、このメンバーは無視されます。 | ||||||||||
| hIcon | HANDLE | 8/4 | +48 | +32 | コマンドによってアクティブ化されるアプリケーションに使用するアイコン。fMask メンバーが CMIC_MASK_ICON を指定していない場合、このメンバーは無視されます。 | ||||||||||
| lpTitle | LPSTR | 8/4 | +56 | +36 | ASCII のタイトル。 | ||||||||||
| lpVerbW | LPWSTR | 8/4 | +64 | +40 | Unicode の動詞。これを使用できるコマンドのために用意されています。 | ||||||||||
| lpParametersW | LPWSTR | 8/4 | +72 | +44 | Unicode のパラメーター。これを使用できるコマンドのために用意されています。 | ||||||||||
| lpDirectoryW | LPWSTR | 8/4 | +80 | +48 | Unicode のディレクトリ。これを使用できるコマンドのために用意されています。 | ||||||||||
| lpTitleW | LPWSTR | 8/4 | +88 | +52 | Unicode のタイトル。 | ||||||||||
| ptInvoke | POINT | 8 | +96 | +56 | コマンドが呼び出された位置。fMask メンバーが CMIC_MASK_PTINVOKE を指定していない場合、このメンバーは無視されます。このメンバーは Internet Explorer 4.0 より前では有効ではありません。 |
公式ドキュメント
ショートカット メニュー コマンドに関する拡張情報を格納します。この構造体は、Unicode 値を使用できるようにした CMINVOKECOMMANDINFO の拡張版です。
解説(Remarks)
IContextMenu::InvokeCommand の宣言では pici パラメーターに CMINVOKECOMMANDINFO 構造体が指定されていますが、CMINVOKECOMMANDINFOEX 構造体を受け取ることもできます。このメソッドを実装する場合は、cbSize を調べて、どちらの構造体が渡されたかを判断しなければなりません。
既定では、16 ビットの Windows ベース アプリケーションはすべて、単一の共有 VDM 内のスレッドとして実行されます。個別に実行する利点は、クラッシュしてもその 1 つの VDM が終了するだけで、別の VDM で実行されている他のプログラムは正常に動作し続けることです。また、個別の VDM で実行される 16 ビットの Windows ベース アプリケーションは、それぞれ独立した入力キューを持ちます。つまり、あるアプリケーションが一時的に応答しなくなっても、別の VDM 内のアプリケーションは入力を受け取り続けます。個別に実行する欠点は、その分だけ大幅に多くのメモリを消費することです。
CMINVOKECOMMANDINFOEX 自体は Shobjidl.h で定義されていますが、すべてのフラグを利用するには Shellapi.h もインクルードする必要があります。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// POINT (x64 8 / x86 8 バイト)
typedef struct POINT {
INT x;
INT y;
} POINT;
// CMINVOKECOMMANDINFOEX (x64 104 / x86 64 バイト)
typedef struct CMINVOKECOMMANDINFOEX {
DWORD cbSize;
DWORD fMask;
HWND hwnd;
LPSTR lpVerb;
LPSTR lpParameters;
LPSTR lpDirectory;
INT nShow;
DWORD dwHotKey;
HANDLE hIcon;
LPSTR lpTitle;
LPWSTR lpVerbW;
LPWSTR lpParametersW;
LPWSTR lpDirectoryW;
LPWSTR lpTitleW;
POINT ptInvoke;
} CMINVOKECOMMANDINFOEX;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CMINVOKECOMMANDINFOEX
{
public uint cbSize;
public uint fMask;
public IntPtr hwnd;
public IntPtr lpVerb;
public IntPtr lpParameters;
public IntPtr lpDirectory;
public int nShow;
public uint dwHotKey;
public IntPtr hIcon;
public IntPtr lpTitle;
public IntPtr lpVerbW;
public IntPtr lpParametersW;
public IntPtr lpDirectoryW;
public IntPtr lpTitleW;
public POINT ptInvoke;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure POINT
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure CMINVOKECOMMANDINFOEX
Public cbSize As UInteger
Public fMask As UInteger
Public hwnd As IntPtr
Public lpVerb As IntPtr
Public lpParameters As IntPtr
Public lpDirectory As IntPtr
Public nShow As Integer
Public dwHotKey As UInteger
Public hIcon As IntPtr
Public lpTitle As IntPtr
Public lpVerbW As IntPtr
Public lpParametersW As IntPtr
Public lpDirectoryW As IntPtr
Public lpTitleW As IntPtr
Public ptInvoke As POINT
End Structureimport ctypes
from ctypes import wintypes
class POINT(ctypes.Structure):
_fields_ = [
("x", ctypes.c_int),
("y", ctypes.c_int),
]
class CMINVOKECOMMANDINFOEX(ctypes.Structure):
_fields_ = [
("cbSize", wintypes.DWORD),
("fMask", wintypes.DWORD),
("hwnd", ctypes.c_void_p),
("lpVerb", ctypes.c_void_p),
("lpParameters", ctypes.c_void_p),
("lpDirectory", ctypes.c_void_p),
("nShow", ctypes.c_int),
("dwHotKey", wintypes.DWORD),
("hIcon", ctypes.c_void_p),
("lpTitle", ctypes.c_void_p),
("lpVerbW", ctypes.c_void_p),
("lpParametersW", ctypes.c_void_p),
("lpDirectoryW", ctypes.c_void_p),
("lpTitleW", ctypes.c_void_p),
("ptInvoke", POINT),
]#[repr(C)]
pub struct POINT {
pub x: i32,
pub y: i32,
}
#[repr(C)]
pub struct CMINVOKECOMMANDINFOEX {
pub cbSize: u32,
pub fMask: u32,
pub hwnd: *mut core::ffi::c_void,
pub lpVerb: *mut core::ffi::c_void,
pub lpParameters: *mut core::ffi::c_void,
pub lpDirectory: *mut core::ffi::c_void,
pub nShow: i32,
pub dwHotKey: u32,
pub hIcon: *mut core::ffi::c_void,
pub lpTitle: *mut core::ffi::c_void,
pub lpVerbW: *mut core::ffi::c_void,
pub lpParametersW: *mut core::ffi::c_void,
pub lpDirectoryW: *mut core::ffi::c_void,
pub lpTitleW: *mut core::ffi::c_void,
pub ptInvoke: POINT,
}import "golang.org/x/sys/windows"
type POINT struct {
x int32
y int32
}
type CMINVOKECOMMANDINFOEX struct {
cbSize uint32
fMask uint32
hwnd uintptr
lpVerb uintptr
lpParameters uintptr
lpDirectory uintptr
nShow int32
dwHotKey uint32
hIcon uintptr
lpTitle uintptr
lpVerbW uintptr
lpParametersW uintptr
lpDirectoryW uintptr
lpTitleW uintptr
ptInvoke POINT
}type
POINT = record
x: Integer;
y: Integer;
end;
CMINVOKECOMMANDINFOEX = record
cbSize: DWORD;
fMask: DWORD;
hwnd: Pointer;
lpVerb: Pointer;
lpParameters: Pointer;
lpDirectory: Pointer;
nShow: Integer;
dwHotKey: DWORD;
hIcon: Pointer;
lpTitle: Pointer;
lpVerbW: Pointer;
lpParametersW: Pointer;
lpDirectoryW: Pointer;
lpTitleW: Pointer;
ptInvoke: POINT;
end;const POINT = extern struct {
x: i32,
y: i32,
};
const CMINVOKECOMMANDINFOEX = extern struct {
cbSize: u32,
fMask: u32,
hwnd: ?*anyopaque,
lpVerb: ?*anyopaque,
lpParameters: ?*anyopaque,
lpDirectory: ?*anyopaque,
nShow: i32,
dwHotKey: u32,
hIcon: ?*anyopaque,
lpTitle: ?*anyopaque,
lpVerbW: ?*anyopaque,
lpParametersW: ?*anyopaque,
lpDirectoryW: ?*anyopaque,
lpTitleW: ?*anyopaque,
ptInvoke: POINT,
};type
POINT {.bycopy.} = object
x: int32
y: int32
CMINVOKECOMMANDINFOEX {.bycopy.} = object
cbSize: uint32
fMask: uint32
hwnd: pointer
lpVerb: pointer
lpParameters: pointer
lpDirectory: pointer
nShow: int32
dwHotKey: uint32
hIcon: pointer
lpTitle: pointer
lpVerbW: pointer
lpParametersW: pointer
lpDirectoryW: pointer
lpTitleW: pointer
ptInvoke: POINTstruct POINT
{
int x;
int y;
}
struct CMINVOKECOMMANDINFOEX
{
uint cbSize;
uint fMask;
void* hwnd;
void* lpVerb;
void* lpParameters;
void* lpDirectory;
int nShow;
uint dwHotKey;
void* hIcon;
void* lpTitle;
void* lpVerbW;
void* lpParametersW;
void* lpDirectoryW;
void* lpTitleW;
POINT ptInvoke;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; CMINVOKECOMMANDINFOEX サイズ: 64 バイト(x86)
dim st, 16 ; 4byte整数×16(構造体サイズ 64 / 4 切り上げ)
; cbSize : DWORD (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; fMask : DWORD (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; hwnd : HWND (+8, 4byte) st.2 = 値 / 値 = st.2 (lpoke/lpeek も可)
; lpVerb : LPSTR (+12, 4byte) st.3 = 値 / 値 = st.3 (lpoke/lpeek も可)
; lpParameters : LPSTR (+16, 4byte) st.4 = 値 / 値 = st.4 (lpoke/lpeek も可)
; lpDirectory : LPSTR (+20, 4byte) st.5 = 値 / 値 = st.5 (lpoke/lpeek も可)
; nShow : INT (+24, 4byte) st.6 = 値 / 値 = st.6 (lpoke/lpeek も可)
; dwHotKey : DWORD (+28, 4byte) st.7 = 値 / 値 = st.7 (lpoke/lpeek も可)
; hIcon : HANDLE (+32, 4byte) st.8 = 値 / 値 = st.8 (lpoke/lpeek も可)
; lpTitle : LPSTR (+36, 4byte) st.9 = 値 / 値 = st.9 (lpoke/lpeek も可)
; lpVerbW : LPWSTR (+40, 4byte) st.10 = 値 / 値 = st.10 (lpoke/lpeek も可)
; lpParametersW : LPWSTR (+44, 4byte) st.11 = 値 / 値 = st.11 (lpoke/lpeek も可)
; lpDirectoryW : LPWSTR (+48, 4byte) st.12 = 値 / 値 = st.12 (lpoke/lpeek も可)
; lpTitleW : LPWSTR (+52, 4byte) st.13 = 値 / 値 = st.13 (lpoke/lpeek も可)
; ptInvoke : POINT (+56, 8byte) varptr(st)+56 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; CMINVOKECOMMANDINFOEX サイズ: 104 バイト(x64)
dim st, 26 ; 4byte整数×26(構造体サイズ 104 / 4 切り上げ)
; cbSize : DWORD (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; fMask : DWORD (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; hwnd : HWND (+8, 8byte) qpoke st,8,値 / qpeek(st,8) ※IronHSPのみ。3.7/3.8は lpoke st,8,下位 : lpoke st,12,上位
; lpVerb : LPSTR (+16, 8byte) qpoke st,16,値 / qpeek(st,16) ※IronHSPのみ。3.7/3.8は lpoke st,16,下位 : lpoke st,20,上位
; lpParameters : LPSTR (+24, 8byte) qpoke st,24,値 / qpeek(st,24) ※IronHSPのみ。3.7/3.8は lpoke st,24,下位 : lpoke st,28,上位
; lpDirectory : LPSTR (+32, 8byte) qpoke st,32,値 / qpeek(st,32) ※IronHSPのみ。3.7/3.8は lpoke st,32,下位 : lpoke st,36,上位
; nShow : INT (+40, 4byte) st.10 = 値 / 値 = st.10 (lpoke/lpeek も可)
; dwHotKey : DWORD (+44, 4byte) st.11 = 値 / 値 = st.11 (lpoke/lpeek も可)
; hIcon : HANDLE (+48, 8byte) qpoke st,48,値 / qpeek(st,48) ※IronHSPのみ。3.7/3.8は lpoke st,48,下位 : lpoke st,52,上位
; lpTitle : LPSTR (+56, 8byte) qpoke st,56,値 / qpeek(st,56) ※IronHSPのみ。3.7/3.8は lpoke st,56,下位 : lpoke st,60,上位
; lpVerbW : LPWSTR (+64, 8byte) qpoke st,64,値 / qpeek(st,64) ※IronHSPのみ。3.7/3.8は lpoke st,64,下位 : lpoke st,68,上位
; lpParametersW : LPWSTR (+72, 8byte) qpoke st,72,値 / qpeek(st,72) ※IronHSPのみ。3.7/3.8は lpoke st,72,下位 : lpoke st,76,上位
; lpDirectoryW : LPWSTR (+80, 8byte) qpoke st,80,値 / qpeek(st,80) ※IronHSPのみ。3.7/3.8は lpoke st,80,下位 : lpoke st,84,上位
; lpTitleW : LPWSTR (+88, 8byte) qpoke st,88,値 / qpeek(st,88) ※IronHSPのみ。3.7/3.8は lpoke st,88,下位 : lpoke st,92,上位
; ptInvoke : POINT (+96, 8byte) varptr(st)+96 を基点に操作(8byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
; ※GUID・入れ子構造体はデフォルト型でないため、依存する #defstruct を先に定義(下記に同梱)。
#defstruct global POINT
#field int x
#field int y
#endstruct
#defstruct global CMINVOKECOMMANDINFOEX
#field int cbSize
#field int fMask
#field intptr hwnd
#field intptr lpVerb
#field intptr lpParameters
#field intptr lpDirectory
#field int nShow
#field int dwHotKey
#field intptr hIcon
#field intptr lpTitle
#field intptr lpVerbW
#field intptr lpParametersW
#field intptr lpDirectoryW
#field intptr lpTitleW
#field POINT ptInvoke
#endstruct
stdim st, CMINVOKECOMMANDINFOEX ; NSTRUCT 変数を確保
st->cbSize = 100
mes "cbSize=" + st->cbSize