Для перечисления пунктов контекстного меню вы можете использовать Windows Menu functions
: GetMenuItemCount , GetMenuItemInfo , GetSubMenu .
используя эти функции я написал эту функцию
uses
JclShell,
ShlObj;
function DisplayContextMenuInfo( const Folder: IShellFolder; Item: PItemIdList; List :TStrings): Boolean;
function GetMenuItemCaption(const hSubMenu: HMENU; const MenuId: Integer): string;
var
MenuItemInfo: TMenuItemInfo;
begin
MenuItemInfo.cbSize := SizeOf(MenuItemInfo);
MenuItemInfo.fMask := MIIM_STRING;
SetLength(Result, 1024*Sizeof(Char));
MenuItemInfo.dwTypeData := PChar(Result);
MenuItemInfo.cch := Length(Result)-1;
if not GetMenuItemInfo(hSubMenu, MenuId, False, MenuItemInfo) then
RaiseLastOSError;
SetLength(Result, MenuItemInfo.cch*Sizeof(Char));
end;
Procedure LogGetMenuInfo(Menu: HMENU);
var
i : Integer;
ItemsCount : Integer;
MenuId : Cardinal;
Caption : string;
begin
ItemsCount:=GetMenuItemCount(Menu);
List.Add(Format('Number of items %d ',[ItemsCount]));
for i:= 0 to ItemsCount - 1 do
begin
MenuId:=GetMenuItemID(Menu,i);
case MenuId of
Cardinal(-1) : begin
List.Add('');
List.Add(Format('Sub Menu',[]));
LogGetMenuInfo(GetSubMenu(Menu,i));
end;
0 :
else
begin
Caption:=GetMenuItemCaption(Menu, MenuId);
List.Add(Format('MenuId (Cmd) %d Caption %s ',[MenuId,Caption]))
end;
end;
end;
end;
var
ContextMenu: IContextMenu;
Menu: HMENU;
begin
Result := False;
if (Item = nil) or (Folder = nil) then Exit;
Folder.GetUIObjectOf(0, 1, Item, IID_IContextMenu, nil, Pointer(ContextMenu));
if ContextMenu <> nil then
begin
Menu := CreatePopupMenu;
try
if Menu <> 0 then
if Succeeded(ContextMenu.QueryContextMenu(Menu, 0, 1, $7FFF, CMF_EXPLORE)) then
LogGetMenuInfo(Menu);
finally
DestroyMenu(Menu);
end;
end;
end;
и звоните таким образом
var
ItemIdList: PItemIdList;
Folder : IShellFolder;
FileName : string;
begin
FileName:= 'C:\Users\Dexter\Downloads\VirtualTreeview.pdf';
ItemIdList := PathToPidlBind(FileName, Folder);
if ItemIdList <> nil then
begin
DisplayContextMenuInfo( Folder, ItemIdList, Memo1.lines);
PidlFree(ItemIdList);
end;
end;
это заполнит строки TS, передаваемые в качестве параметра, такой информацией:
Number of items 26
MenuId (Cmd) 141 Caption Open with Adobe Reader X
MenuId (Cmd) 142 Caption &Open
MenuId (Cmd) 143 Caption &Print
MenuId (Cmd) 146 Caption Run &Sandboxed
MenuId (Cmd) 140 Caption Analizar con &AVG
Sub Menu
Number of items 28
MenuId (Cmd) 105 Caption Add To Send To
MenuId (Cmd) 106 Caption Add To Templates
MenuId (Cmd) 107 Caption Change Date && Time
MenuId (Cmd) 108 Caption Change Extension: pdf
MenuId (Cmd) 109 Caption Choose Program
MenuId (Cmd) 110 Caption Command Prompt
MenuId (Cmd) 111 Caption Copy/Move To Folder
MenuId (Cmd) 112 Caption Copy Path
MenuId (Cmd) 113 Caption Delete On Reboot
MenuId (Cmd) 114 Caption Duplicate File
MenuId (Cmd) 115 Caption Encrypt File
MenuId (Cmd) 116 Caption Explore Rooted
MenuId (Cmd) 117 Caption Extended Delete
MenuId (Cmd) 118 Caption Extended Search && Replace
теперь с помощью этой функции вы можете передать menuid (cmd), который вы хотите выполнить
function InvokeContextMenuCommand(const Comnand: Cardinal; const Folder: IShellFolder; Item: PItemIdList): Boolean;
var
ContextMenu : IContextMenu;
CommandInfo : TCMInvokeCommandInfo;
Menu : HMENU;
CallbackWindow: THandle;
begin
Result := False;
if Comnand=0 then exit;
if (Item = nil) or (Folder = nil) then Exit;
Folder.GetUIObjectOf(0, 1, Item, IID_IContextMenu, nil, Pointer(ContextMenu));
if ContextMenu <> nil then
begin
Menu := CreatePopupMenu;
try
if Menu <> 0 then
if Succeeded(ContextMenu.QueryContextMenu(Menu, 0, 1, $7FFF, CMF_EXPLORE)) then
begin
CallbackWindow:=0;
TrackPopupMenu(Menu, TPM_LEFTALIGN or TPM_LEFTBUTTON or TPM_RIGHTBUTTON or TPM_RETURNCMD, 0, 0, 0, CallbackWindow, nil);
ZeroMemory(@CommandInfo, SizeOf(CommandInfo));
CommandInfo.cbSize := SizeOf(TCMInvokeCommandInfo);
CommandInfo.hwnd := 0;
CommandInfo.lpVerb := MakeIntResourceA(Comnand - 1);
CommandInfo.nShow := SW_SHOWNORMAL;
Result := Succeeded(ContextMenu.InvokeCommand(CommandInfo));
end;
finally
DestroyMenu(Menu);
end;
end;
end;
звоните таким образом
var
ItemIdList: PItemIdList;
Folder : IShellFolder;
FileName : string;
begin
FileName:= 'C:\Users\Dexter\Downloads\VirtualTreeview.pdf';
ItemIdList := PathToPidlBind(FileName, Folder);
if ItemIdList <> nil then
begin
//calling the 141 Menuid = `Open with Adobe Reader X`
InvokeContextMenuCommand(141,Folder, ItemIdList);
PidlFree(ItemIdList);
end;
end;