На выбор — два похожих решения. Боюсь, ни одно из них полностью Вас не устроит, хотя — может, пойдет и так

Первый вариант — просто вывести сразу окошко 'Открыть с помощью', без меню. В WinXP оно довольно мощное.
Второй — вывести целиком все предлагаемое Explorer контекстное меню. Как отфильтровать конкретно подменю "Открыть с помошью", с учетом того, что Win может быть локализованным, — не знаю. Есть мысль после вызова QueryContextMenu найти в меню такое подменю (WinAPI GetSubMenu), в котором есть опция, которой соответствует canonical verb 'openas' (см. IContextMenu::GetCommandString), и выводить только это подменю. Если такого подменю нет, то 'openas' соответствует какой-то команде из самого контекстного меню, и ее можно отыскать опять же при помощи GetCommandString. Остальные элементы меню можно удалить
Ну, и собственно код:
//Uses ShlObj, ComObj, Windows;
procedure TForm1.Button1Click(Sender: TObject);
var
L:IShellLink;
CM:IContextMenu2; //Если надо отображать меню, то CM должна быть видима из TForm1
//(т.е. надо переместить объявление туда или вообще сделать CM глобальной)
IKI:_CMINVOKECOMMANDINFO;
Menu:HMenu;
begin
L:=CreateComObject(ProgIDToClassID('lnkfile')) as IShellLink;
L.SetPath('c:\image1.jpg'); //Поставьте сюда имя нужного Вам файла
CM:=L as IContextMenu2;
Menu:=CreatePopupMenu;
CM.QueryContextMenu(Menu,0,0,$7fff,0); //Опрос меню нужен обязательно
L:=nil;
//Это - если запускаем окно Open As сразу, без отображения меню:
IKI.cbSize:=sizeof(IKI);
IKI.hwnd:=self.Handle;
IKI.fMask:=0;
IKI.lpVerb:=pchar('openas'); // Вот canonical verb, о котором я говорил
IKI.lpParameters:=pchar('c:\image1.jpg');
IKI.lpDirectory:=nil;
IKI.nShow:=SW_SHOWNORMAL;
CM.InvokeCommand(IKI);
CM:=nil; //Оно больше не надо
// Код для инициации отображения:
// P:=Button1.ClientToScreen(Point(Button1.Width,Button1.Height));
// TrackPopupMenu(Menu,0, P.X, P.y, 0, handle, 0);
//Ну и убиваем меню
DestroyMenu(Menu);
end;
Если меню надо отображать, то придется еще добавить:
//В TForm1:
procedure WMCommand(var M:TWMCommand);message WM_COMMAND;
procedure WndProc(var Message:TMessage); override;
//Реализация:
procedure TForm1.WndProc(var Message: TMessage);
begin
if (Message.Msg = WM_INITMENUPOPUP) or
(Message.Msg = WM_MENUCHAR) or
(Message.Msg = WM_DRAWITEM) or
(Message.Msg = WM_MEASUREITEM) then CM.HandleMenuMsg(Message.Msg,Message.WParam,Message.LParam)
else
inherited;
end;
procedure TForm1.WMCommand(var M: TWMCommand);
var
IKI:_CMINVOKECOMMANDINFO;
begin
if M.Ctl<>0 then inherited
else
begin
IKI.cbSize:=sizeof(IKI);
IKI.hwnd:=self.Handle;
IKI.fMask:=0;
IKI.lpVerb:=pchar(M.ItemID);
IKI.lpParameters:=nil;
IKI.lpDirectory:=nil;
IKI.nShow:=SW_SHOWNORMAL;
CM.InvokeCommand(IKI);
end;
end;
С уважением, Slicer