Как открыть контекстное меню Windows для данного файла с помощью Delphi?

Используйте символ вертикальной черты для указания "или":

/a@(foo|bar|baz)\b/

, Если Вы не хотите группу получения, используйте символ группировки неполучения:

/a@(?:foo|bar|baz)\b/

(Конечно, я принимаю" a", хорошо для передней стороны адреса электронной почты! Необходимо заменить это подходящим regex.)

7
задан Toby Allen 18 October 2009 в 06:52
поделиться

3 ответа

I've made a quick solution for you. добавьте эти блоки в раздел «Использование»:

... ShlObj, ActiveX, ComObj

и вот ваша процедура, я просто добавляю новый параметр «HND» для переноса дескриптора TWinControl, который вы будете использовать для отображения контекстного меню.

procedure ShowSysPopup(aFile: string; x, y: integer; HND: HWND);
var
  Root: IShellFolder;
  ShellParentFolder: IShellFolder;
  chEaten,dwAttributes: ULONG;
  FilePIDL,ParentFolderPIDL: PItemIDList;
  CM: IContextMenu;
  Menu: HMenu;
  Command: LongBool;
  ICM2: IContextMenu2;

  ICI: TCMInvokeCommandInfo;
  ICmd: integer;
  P: TPoint;
Begin
  OleCheck(SHGetDesktopFolder(Root));//Get the Desktop IShellFolder interface

  OleCheck(Root.ParseDisplayName(HND, nil,
    PWideChar(WideString(ExtractFilePath(aFile))),
    chEaten, ParentFolderPIDL, dwAttributes)); // Get the PItemIDList of the parent folder

  OleCheck(Root.BindToObject(ParentFolderPIDL, nil, IShellFolder,
  ShellParentFolder)); // Get the IShellFolder Interface  of the Parent Folder

  OleCheck(ShellParentFolder.ParseDisplayName(HND, nil,
    PWideChar(WideString(ExtractFileName(aFile))),
    chEaten, FilePIDL, dwAttributes)); // Get the relative  PItemIDList of the File

  ShellParentFolder.GetUIObjectOf(HND, 1, FilePIDL, IID_IContextMenu, nil, CM); // get the IContextMenu Interace for the file

  if CM = nil then Exit;
  P.X := X;
  P.Y := Y;

  Windows.ClientToScreen(HND, P);

  Menu := CreatePopupMenu;

  try
    CM.QueryContextMenu(Menu, 0, 1, $7FFF, CMF_EXPLORE or CMF_CANRENAME);
    CM.QueryInterface(IID_IContextMenu2, ICM2); //To handle submenus.
    try
      Command := TrackPopupMenu(Menu, TPM_LEFTALIGN or TPM_LEFTBUTTON or TPM_RIGHTBUTTON or
        TPM_RETURNCMD, p.X, p.Y, 0, HND, nil);
    finally
      ICM2 := nil;
    end;

    if Command then
    begin
      ICmd := LongInt(Command) - 1;
      FillChar(ICI, SizeOf(ICI), #0);
      with ICI do
      begin
        cbSize := SizeOf(ICI);
        hWND := 0;
        lpVerb := MakeIntResourceA(ICmd);
        nShow := SW_SHOWNORMAL;
      end;
      CM.InvokeCommand(ICI);
    end;
  finally
     DestroyMenu(Menu)
  end;
End;

изменить / добавить раздел инициализации и завершения, как этот

initialization
  OleInitialize(nil);
finalization
  OleUninitialize;

, и вот как вы можете использовать эту процедуру:

procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowSysPopup(Edit1.Text,Edit1.Left,Edit1.Top, Handle);
end;

Я надеюсь, что это сработает для вас.

С уважением,

Редактировать: если вы хотите показать контекстное меню для нескольких файлов, проверьте эту статью в моем блоге

16
ответ дан 6 December 2019 в 10:51
поделиться

Хотя я согласен с Deltics в том, что это большой объем работы, информация, необходимая для большинства (если не всех) элементов, находится в свободном доступе в реестре. Руководство, указанное в ответе Deltics, выглядит хорошо и предоставит вам большинство элементов. Многие можно найти в основных записях реестра, в то время как другие нуждаются в вызовах COM-объектов.

0
ответ дан 6 December 2019 в 10:51
поделиться

Вы уверены, что хотите сделать это? Потому что, если вы это сделаете, вам фактически придется воспроизводить весь код в Windows Shell и все его поведение и взаимодействия с целым набором кода.

Контекстное меню в основном построено с помощью «расширений оболочки». Это COM DLL, зарегистрированные в системе. Когда вызывается контекстное меню, оболочка следует набору правил, которые определяют, где ей следует искать (в реестре) библиотеки DLL расширения.

Я считаю, что это полезное руководство по этим правилам .

Но найти DLL расширения - это еще не полдела. Для каждой DLL оболочка затем создает экземпляры COM-объекта (ов), зарегистрированного этой DLL, и выполняет вызовы тех объектов, на которые DLL отвечает либо настройкой, либо вызовом команд меню.

Сама оболочка не создает меню, и при этом информация, необходимая для создания меню, не доступна для запроса или чтения непосредственно из любого места - меню создается полностью динамически расширениями оболочки.

Оболочка передает дескриптор в меню каждого расширения вместе с некоторой информацией, указывающей расширению, какой идентификатор команды он должен использовать для любых элементов, добавляемых в это меню. Расширение может добавлять в дескриптор меню практически все, что ему нравится, включая подменю и т. Д., И оно вполне может добавлять различные элементы в зависимости от свойств текущего выбора файла, а не только расширения файлов (например, клиент Tortoise SVN добавляет различные пункты меню в зависимости от того, что имеет отношение к текущему состоянию SVN этих файлов).

Итак, если вы хотите создать такое меню самостоятельно, как я говорю, вам придется реплицировать всю структуру расширения оболочки (или, по крайней мере, те ее части, которые инициализируют меню, если по какой-то причине вы не хотите или не должны вызывать сами команды меню) в своем собственном коде.

Возможно, вам поможет, если вы объясните, почему вы хотите это сделать и чего пытаетесь достичь. Возможно, есть более простой способ сделать это.

2
ответ дан 6 December 2019 в 10:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: