将菜单项添加到单元';使用ToolsAPI的DelphiIDE中的s选项卡上下文菜单

将菜单项添加到单元';使用ToolsAPI的DelphiIDE中的s选项卡上下文菜单,delphi,toolsapi,Delphi,Toolsapi,我想知道我需要使用哪些服务/接口来向DelphiIDE中源文件的右键单击菜单添加一个项 例如,如果我右键单击一个单元的选项卡,它有“关闭页面”、“关闭所有其他页面”、“属性”等项。如果可能,我想向该菜单添加自定义项 我查看了ToolsAPI单元,但不知道从哪里开始。我假设有一个接口可以用来枚举项目和添加项目,但我不知道从哪里开始查找 如果不可能,我会选择代码编辑器的上下文菜单 也许网上有一些样品,但我还在寻找,没有找到 感谢您的帮助。雷米·勒博通过他的链接为您指明了正确的方向 GExperts指

我想知道我需要使用哪些服务/接口来向DelphiIDE中源文件的右键单击菜单添加一个项

例如,如果我右键单击一个单元的选项卡,它有“关闭页面”、“关闭所有其他页面”、“属性”等项。如果可能,我想向该菜单添加自定义项

我查看了ToolsAPI单元,但不知道从哪里开始。我假设有一个接口可以用来枚举项目和添加项目,但我不知道从哪里开始查找

如果不可能,我会选择代码编辑器的上下文菜单

也许网上有一些样品,但我还在寻找,没有找到


感谢您的帮助。

雷米·勒博通过他的链接为您指明了正确的方向 GExperts指南

如果你以前没有做过这类事情,它仍然可以 要开始编写自己的IDE外接程序,一定要有一定的性能,所以 我在下面列出了一个如何向代码编辑器的 弹出菜单

显然,你要做的是创建一个新的包,将下面的单元添加到其中, 然后在IDE中安装该包。调用单元中的
寄存器

执行在编辑器弹出菜单中安装新项所需的操作

确保在安装包时代码编辑器处于打开状态。这个 原因是,正如您将看到的,代码检查是否存在活动编辑器 当时。我留下了如何确保添加弹出项,即使有 此时没有激活的代码编辑器。提示:如果您查看ToolsAPI.Pas单元 您正在使用的Delphi版本,您会发现它包括各种通知程序, 您可以使用至少其中一个的通知来延迟检查是否存在 在编辑器可能处于活动状态之前,该编辑器处于活动状态

顺便说一句,代码将菜单项添加到上下文菜单中,上下文菜单在编辑器窗口本身而不是活动选项卡上弹出。IDE插件的一部分乐趣在于尝试是否可以得到您想要的东西。我自己还没有尝试过,但我怀疑将菜单项添加到其中一个编辑器选项卡的上下文菜单会有那么困难——因为Delphi IDE是一个Delphi应用程序,正如您从下面的代码中看到的,您可以使用FindComponent(或只是迭代组件集合)来查找您想要的内容。但是,如果可以的话,最好通过ToolsAPI接口定位对象。请参见下面的更新

interface

uses
  Classes, Windows, Menus, Dialogs, ToolsAPI;

type

   TIDEMenuItem = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
     function GetName: string;
     function GetIDString: string;
     function GetMenuText: string;
     function GetState: TWizardState;
     procedure Execute;
   end;

   TIDEMenuHandler = class(TObject)
     procedure HandleClick(Sender: TObject);
   end;

procedure Register;

implementation

var
  MenuItem: TMenuItem;
  IDEMenuHandler: TIDEMenuHandler;
  EditorPopUpMenu : TPopUpMenu;

procedure TIDEMenuItem.Execute;
begin
  ShowMessage('Execute');
end;

function TIDEMenuItem.GetIDString: string;
begin
  Result := 'IDEMenuItemID';
end;

function TIDEMenuItem.GetMenuText: string;
begin
  Result := 'IDEMenuItemText';
end;

function TIDEMenuItem.GetName: string;
begin
  Result := 'IDEMenuItemName';
end;

function TIDEMenuItem.GetState: TWizardState;
begin
  Result := [wsEnabled];
end;

procedure TIDEMenuHandler.HandleClick(Sender: TObject);
begin
  ShowMessage(TIDEMenuItem(Sender).GetName + ' Clicked');
end;

procedure AddIDEMenu;
var
  NTAServices: INTAServices40;
  EditorServices: IOTAEditorServices;
  EditView: IOTAEditView;
begin
  NTAServices := BorlandIDEServices as INTAServices40;

  EditorServices := BorlandIDEServices as IOTAEditorServices;
  EditView := EditorServices.TopView;

  if Assigned(EditView) then begin
    EditorPopUpMenu := TPopUpMenu(EditView.GetEditWindow.Form.FindComponent('EditorLocalMenu'));
    Assert(EditorPopUpMenu <>Nil);

    IDEMenuHandler := TIDEMenuHandler.Create;
    MenuItem := TMenuItem.Create(Nil);
    MenuItem.Caption := 'Added IDE editor menu item';
    MenuItem.OnClick := IDEMenuHandler.HandleClick;
    EditorPopUpMenu.Items.Add(MenuItem)
  end
  else
    ShowMessage('Code editor not active');
end;

procedure RemoveIDEMenu;
begin
  if MenuItem <> Nil then begin
    EditorPopUpMenu.Items.Remove(MenuItem);
    FreeAndNil(MenuItem);
    IDEMenuHandler.Free;
  end;
end;

procedure Register;
begin
  RegisterPackageWizard(TIDEMenuItem.Create);
  AddIDEMenu;
end;

initialization

finalization
  RemoveIDEMenu;
end.
接口
使用
类、窗口、菜单、对话框、ToolsAPI;
类型
TIDEMenuItem=类(TNotifierObject、IOTAWizard、IOTAMenuWizard)
函数GetName:string;
函数GetIDString:string;
函数GetMenuText:string;
函数GetState:TWizardState;
程序执行;
结束;
TIDEMenuHandler=类别(TObject)
程序HandleClick(发送方:TObject);
结束;
程序登记册;
实施
变量
菜单项:TMenuItem;
IDEMenuHandler:潮汐管理者;
EditorOpupMenu:TPopUpMenu;
程序TIDEMenuItem.Execute;
开始
ShowMessage('Execute');
结束;
函数TIDEMenuItem.GetIDString:string;
开始
结果:='IDEMenuItemID';
结束;
函数TIDEMenuItem.GetMenuText:string;
开始
结果:='IDEMenuItemText';
结束;
函数TIDEMenuItem.GetName:字符串;
开始
结果:='IDEMenuItemName';
结束;
函数TIDEMenuItem.GetState:TWizardState;
开始
结果:=[wsEnabled];
结束;
程序整理员.手柄点击(发送者:TObject);
开始
ShowMessage(TIDEMenuItem(Sender).GetName+“单击”);
结束;
程序补充;
变量
NTAServices:INTAServices40;
编辑服务:IoEditorServices;
EditView:IoDaeditView;
开始
NTAServices:=作为INTAServices的设备40;
EditorServices:=作为IoEditorServices的设备;
EditView:=EditorServices.TopView;
如果已分配(编辑视图),则开始
EditorOpupMenu:=TPopUpMenu(EditView.GetEditWindow.Form.FindComponent('EditorLocalMenu');
断言(EDITORPOPMENU Nil);
IDEMenuHandler:=TIDEMenuHandler.Create;
MenuItem:=TMenuItem.Create(无);
MenuItem.Caption:=“添加了IDE编辑器菜单项”;
MenuItem.OnClick:=IDEMenuHandler.HandleClick;
EditorOpupMenu.Items.Add(菜单项)
结束
其他的
ShowMessage(“代码编辑器未激活”);
结束;
程序删除菜单;
开始
如果MenuItem Nil,则开始
EditorOpupMenu.Items.Remove(菜单项);
FreeAndNil(MenuItem);
自由;
结束;
结束;
程序登记册;
开始
RegisterPackageWizard(TIDEMenuItem.Create);
阿迪德梅努;
结束;
初始化
定稿
移除Demenu;
结束。
更新:以下代码查找编辑器窗口的选项卡控件,并将菜单项添加到上下文菜单中。但是,请注意,这并不能解释第二个编辑器窗口是否打开

procedure AddIDEMenu;
var
  NTAServices: INTAServices40;
  EditorServices: IOTAEditorServices;
  EditView: IOTAEditView;
  TabControl : TTabControl;

  function FindTabControl(AComponent : TComponent) : TTabControl;
  var
    i : Integer;
  begin
    Result := Nil;
    if CompareText(AComponent.ClassName, 'TXTabControl') = 0 then begin
      Result := TTabControl(AComponent);
      exit;
    end
    else begin
      for i := 0 to AComponent.ComponentCount - 1 do begin
        if CompareText(AComponent.Components[i].ClassName, 'TXTabControl') = 0 then begin
          Result := TTabControl(AComponent.Components[i]);
          exit;
        end
        else begin
          Result := FindTabControl(AComponent.Components[i]);
          if Result <> Nil then
            exit;
        end;              
      end;
    end;
  end;

begin
  NTAServices := BorlandIDEServices as INTAServices40;

  EditorServices := BorlandIDEServices as IOTAEditorServices;
  EditView := EditorServices.TopView;

  if Assigned(EditView) then begin
    TabControl := FindTabControl(EditView.GetEditWindow.Form);
    Assert(TabControl <> Nil, 'TabControl not found');
    EditorPopUpMenu := TabControl.PopupMenu;
    Assert(EditorPopUpMenu <> Nil, 'PopUP menu not found');
    //EditorPopUpMenu := TPopUpMenu(EditView.GetEditWindow.Form.FindComponent('EditorLocalMenu'));
    Assert(EditorPopUpMenu <>Nil);

    IDEMenuHandler := TIDEMenuHandler.Create;
    MenuItem := TMenuItem.Create(Nil);
    MenuItem.Caption := 'Added IDE editor menu item';
    MenuItem.OnClick := IDEMenuHandler.HandleClick;
    EditorPopUpMenu.Items.Add(MenuItem)
  end
  else
    ShowMessage('No editor active');
end;
程序添加菜单;
变量
NTAServices:INTAServices40;
编辑服务:IoEditorServices;
EditView:IoDaeditView;
TabControl:TTabControl;
函数FindTabControl(a组件:t组件):TTabControl;
变量
i:整数;
开始
结果:=无;
如果CompareText(AComponent.ClassName,'TXTabControl')=0,则开始
结果:=TTabControl(A成分);
出口
结束
否则开始
对于i:=0到AComponent.ComponentCount-1,请开始
如果CompareText(AComponent.Components[i].ClassName,‘TXTabControl’)=0,则开始
结果:=TTabControl(成分[i]);
出口
结束
否则开始
结果:=FindTabControl(组件[i]);
如果结果为零,则
出口
结束;
结束;
结束;
结束;
开始
NTAServices:=作为INTAServices的设备40;
EditorServices:=作为IoEditorServices的设备;
EditView:=EditorServices.TopView;
如果已分配(编辑视图),则开始
TabControl:=F