Delphi IDE Menu integration - INTAServices

Posted

技术标签:

【中文标题】Delphi IDE Menu integration - INTAServices【英文标题】: 【发布时间】:2012-09-28 01:23:42 【问题描述】:

我使用 INTAServices40 在 Delphi 中成功安装了我的菜单项,但问题是 - 下次 Delphi 启动时菜单丢失?!实际上,安装了两个菜单项;帮助菜单下的一个总是显示(IOTAWizardMenu),但工具菜单下的一个(测试菜单项)在下次 Delphi 启动时丢失。如何解决这个问题?

unit TESTMENU;

interface    
uses
   ToolsAPI, Classes, Windows, vcl.Menus, vcl.dialogs;    
type
   TCustomMenuItem = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
     function GetIDString: string;
     function GetName: string;
     function GetState: TWizardState;
     // Launch the AddIn
     procedure Execute;
     function GetMenuText: string;
   end;

   TCustomMenuHandler = class(TObject)
    // Handle custom menu
     procedure HandleClick(Sender: TObject);
   end;

procedure Register;

implementation    
var
  mnuitem: TMenuItem;
  CustomMenuHandler: TCustomMenuHandler;

procedure TCustomMenuItem.Execute;
begin
  ShowMessage('IOTAWizardMenu based menu item');
end;

function TCustomMenuItem.GetIDString: string;
begin
  Result := 'TMS.MenuSample';
end;

function TCustomMenuItem.GetMenuText: string;
begin
  Result := 'IOTAWizardMenu';
end;

function TCustomMenuItem.GetName: string;
begin
  Result := 'TMSMenuSample';
end;

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

procedure TCustomMenuHandler.HandleClick(Sender: TObject);
begin
  ShowMessage('INTAServices40.MainMenu based menu item');
end;   

procedure AddIDEMenu;
var
  NTAServices: INTAServices40;    
begin
  NTAServices := BorlandIDEServices as INTAServices40;

  // avoid inserting twice
  if NTAServices.MainMenu.Items[9].Find('TEST') = nil then
  begin
    CustomMenuHandler := TCustomMenuHandler.Create;

    mnuitem := TMenuItem.Create(nil);
    mnuitem.Caption := 'TEST';
    mnuitem.OnClick := CustomMenuHandler.HandleClick;
    NTAServices.MainMenu.Items[9].Add(mnuitem)
  end;
end;

procedure RemoveIDEMenu;
var
  NTAServices: INTAServices40;
begin
  if Assigned(mnuitem) then
  begin
    NTAServices := BorlandIDEServices as INTAServices40;
    NTAServices.MainMenu.Items[9].Remove(mnuitem);
    mnuitem.Free;
    if Assigned(CustomMenuHandler) then
      CustomMenuHandler.Free;
  end;
end;

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

initialization
  mnuitem := nil;    
  CustomMenuHandler := nil;    
finalization
  RemoveIDEMenu;
end.

所以,我的第一个问题是如何在每次 Delphi 启动时显示菜单项 TEST。另外,我想在菜单项 TEST 旁边添加图标。有什么方向吗?

谢谢

编辑: 我刚刚发现我的包裹延迟加载。看网上的人说 ForceDemandLoadState(dlDisable) 应该被调用。但是,这对我也没有帮助....

【问题讨论】:

OTA 插件必须作为安装到 IDE 中并在每次运行 IDE 时加载的包来实现。假设您确实创建了一个包,您是否确认该包在下次 IDE 重新启动时正在加载? 我确实检查了它并且它正在加载。问题是 - 即使我手动添加一个包 (bpl),菜单项也没有显示。只有当我重新编译包时才会显示菜单项。 这是哪个版本的Delphi? 【参考方案1】:

NTAServices.MainMenu.Items[9] 可能会在 IDE 加载其包时在不同时间返回不同的内容,还有一些菜单项的子项在运行时由 IDE 管理(例如窗口菜单)。

您可以按名称查找帮助菜单项组件:

procedure AddIDEMenu;
var
  HelpMenu: TComponent;
begin
  HelpMenu := Application.MainForm.FindComponent('HelpMenu');
  if (HelpMenu is TMenuItem) and (TMenuItem(HelpMenu).Find('TEST') = nil) then
  begin
    CustomMenuHandler := TCustomMenuHandler.Create;

    mnuitem := TMenuItem.Create(nil);
    mnuitem.Caption := 'TEST';
    mnuitem.OnClick := CustomMenuHandler.HandleClick;

    TMenuItem(HelpMenu).Add(mnuitem);
  end;
end;

procedure RemoveIDEMenu;
var
  HelpMenu: TComponent;
begin
  if Assigned(mnuitem) then
  begin
    HelpMenu := Application.MainForm.FindComponent('HelpMenu');
    if HelpMenu is TMenuItem then
      TMenuItem(HelpMenu).Remove(mnuitem);
    mnuitem.Free;
    CustomMenuHandler.Free;
  end;
end;

【讨论】:

这对我不起作用...问题是下次启动 Delphi 时菜单项不显示。 它对我有用。尝试调试以查看您的情况出了什么问题。

以上是关于Delphi IDE Menu integration - INTAServices的主要内容,如果未能解决你的问题,请参考以下文章

Delphi - 如何自定义 IDE 布局

Delphi-IDE:如何改变类完成的工作方式?

Delphi 2010如何设置IDE打开项目对话框的初始文件夹

Delphi 10.2 IDE界面

帮助解决奇怪的 Delphi 5 IDE 问题

如何将方法挂钩到 Delphi 7 IDE 中的 Edit 事件?