繁体   English   中英

使用ToolsAPI在Delphi IDE中将菜单项添加到单位的选项卡上下文菜单

[英]Add menu item to unit's tab context menu in Delphi IDE using ToolsAPI

我正在寻找要在Delphi IDE中将项目添加到源文件的右键菜单中所需的服务/接口。

例如,如果我右键单击某个设备的选项卡,则其中包含“关闭页面”,“关闭所有其他页面”,“属性”等项目。如果可能,我想向该菜单添加自定义项目。

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

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

也许网上有一些样品,但是我还在寻找,没有发现。

任何帮助表示赞赏。

雷米·勒博(Remy Lebeau)指向GExperts指南的链接为您指明了正确的方向。

如果您以前没有做过这种事情,那么开始编写自己的IDE加载项仍然会有一些性能,因此,我在下面提供了一个如何向其中添加项的最小示例。代码编辑器的弹出菜单。

显然,您要做的是创建一个新程序包,向其添加下面的单元,然后在IDE中安装该程序包。 在单元中调用Register可以完成将新项目安装到编辑器弹出菜单中所需的操作。

在安装软件包时,请确保代码编辑器已打开。 如您所见,原因是该代码检查当时是否有活动的编辑器。 我留下了如何确保即使当前没有活动的代码编辑器,也要添加弹出项的方法。 提示:如果查看所使用的任何版本的Delphi的ToolsAPI.Pas单元,您会发现它包含各种通知程序,并且您可以使用至少其中之一的通知来推迟检查是否存在是活跃的编辑器,直到有可能成为可能为止。

顺便说一句,该代码将菜单项添加到上下文菜单,该上下文菜单弹出编辑器窗口本身而不是活动选项卡。 IDE加载项的乐趣之一是尝试查看是否可以完全获得所需的乐趣。 我自己还没有尝试过,但是我怀疑将菜单项添加到一个编辑器选项卡的上下文菜单中会很困难-鉴于Delphi IDE是Delphi应用程序,如下面的代码所示,您可以使用FindComponent(或仅遍历Components集合)来查找所需的内容。 但是,如果可以,最好通过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.

更新:以下代码查找编辑器窗口的TabControl,并将菜单项添加到其上下文菜单。 但是,请注意,这并不意味着打开了第二个编辑器窗口。

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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM